App-Speicher
Jede App bekommt einen eigenen Schlüssel-Wert-Speicher bei Methacore – für Notizen, Einstellungen, Anmeldungen, Spielstände. Du brauchst keine Datenbank und keinen Server; der Speicher gehört der App und dem Verein, in dem sie benutzt wird.
Aufbau
Ein Eintrag hat eine feste Adresse:
App → Verein → Bereich (org | user) → Sammlung → Schlüssel → Wert
| Teil | Bedeutung |
|---|---|
| App | kommt aus dem Token: die App, zu der der OAuth-Client gehört. Eine App sieht nie den Speicher einer anderen. |
| Verein | der Verein des Tokens. Dieselbe App hat in jedem Verein einen eigenen Speicher. |
| Bereich | org – geteilt mit allen Mitgliedern des Vereins, die die App benutzen (Standard). user – nur für das angemeldete Mitglied. |
| Sammlung | frei wählbarer Name, z. B. notizen |
| Schlüssel | eindeutig innerhalb der Sammlung |
| Wert | beliebiges JSON: Text, Zahl, Objekt, Liste |
Regeln
| Regel | Wert |
|---|---|
| Namen von Sammlungen und Schlüsseln | 1–64 Zeichen aus A–Z a–z 0–9 _ - |
| Kontingent | 10 MB je App und Verein, beide Bereiche zusammen |
| Gemessen wird | Schlüssel plus Wert als kompaktes JSON, in Bytes |
| Überschritten | 413 App storage quota exceeded. – der Eintrag wird nicht gespeichert |
| Reihenfolge beim Auflisten | nach Schlüssel, aufsteigend |
| Seitengröße | limit 1–200, Standard 50 |
updatedAt | Unix-Zeitstempel in Sekunden |
| Scopes | mc.apps.storage:read zum Lesen, mc.apps.storage:write zum Schreiben und Löschen |
Weil die Einträge nach Schlüssel sortiert sind, eignen sich Schlüssel mit Zeitstempel vorne (2026-09-23-… oder Date.now().toString(36)) für chronologische Listen.
Im Builder
Vier Datenquellen sprechen den Speicher: storage.list, storage.get, storage.put und storage.delete. Parameter und Antworten stehen unter Datenquellen. Ohne scope gilt org.
{ "type": "call", "source": "storage.put",
"params": { "collection": "einstellungen", "key": "farbe", "value": "{{event.value}}", "scope": "user" } }
In main.js
/** @type {MethacoreHandler} */
export async function merken({ storage, event }) {
await storage.set("einstellungen", "farbe", event.value, { scope: "user" });
}
/** @type {MethacoreHandler} */
export async function laden({ storage, setState }) {
const seite = await storage.list("notizen", { limit: 100, offset: 0 });
setState("notizen", seite.items);
setState("anzahl", seite.total);
}
| Methode | Ergebnis |
|---|---|
storage.list(collection, { scope?, limit?, offset? }) | { items: [{ key, value, updatedAt }], total } |
storage.get(collection, key, { scope? }) | { key, value, updatedAt } – wirft bei unbekanntem Schlüssel (404) |
storage.set(collection, key, value, { scope? }) | legt an oder überschreibt |
storage.delete(collection, key, { scope? }) | löscht – wirft bei unbekanntem Schlüssel (404) |
Mit dem SDK (externe Apps)
import { createMethacore } from "@methacore/sdk";
const mc = createMethacore({ clientId: "cl_7d2e41a9", scopes: ["mc.apps.storage:read", "mc.apps.storage:write"] });
// Schlüssel-Wert im Bereich org
await mc.storage.kv.set("letzterExport", new Date().toISOString());
const zuletzt = await mc.storage.kv.get<string>("letzterExport"); // undefined, wenn es ihn nicht gibt
// Sammlungen
const notizen = mc.storage.collection<{ text: string }>("notizen");
const key = await notizen.add({ text: "Sattel zur Reparatur" }); // erzeugt einen Schlüssel
const alle = await notizen.all(); // lädt Seite für Seite
// Bereich des Mitglieds
const meine = mc.storage.withScope("user").collection("favoriten");
await meine.set("halle-2", { seit: Date.now() });
kv ist die Sammlung kv. get liefert beim SDK undefined statt eines Fehlers, wenn es den Schlüssel nicht gibt.
Was nicht in den Speicher gehört
- Geheimnisse – Einträge im Bereich
orgliest jedes Mitglied, das die App mitmc.apps.storage:readbenutzt. - Kopien von Methacore-Daten – lade Profil, Termine und Co. frisch über die Datenquellen. Eine Kopie veraltet und verstößt schnell gegen die Datenschutzerklärung deiner App.
- Große Dateien – der Speicher ist für strukturierte Daten gedacht, nicht als Ablage. 10 MB sind schnell voll.
Der Speicher wird nicht versioniert. Überschreiben ist endgültig, Löschen auch.