feat(appwrite): Schema für Community-Logos, Herzen und Logo-Meldungen
- Setup-Skript: Tabellen `logos`, `logo_likes` (Mehrspalten-Index `user_logo` über userId, logoId) und `logo_reports` sowie der Bucket `logo-images` (nur PNG, höchstens 1 MiB); der Kopfkommentar nennt die neuen Objekte. Der Index-Request schickt `columns` schon als Liste, dort war nichts zu ändern. - Tests: DESIRED mit genau diesen Werten, Anlegen samt Indizes gegen den Fake-Server, --check meldet jedes fehlende Objekt (51 statt 28) mit Exit 1, bestehende Tabellen und Buckets bleiben unberührt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e1fb632cdd
commit
88abc2061d
2 files changed
+315
-20
No files matched your search
@@ -3,8 +3,9 @@
|
||||
* AirCard – Appwrite-Schema-Setup (idempotent)
|
||||
*
|
||||
* Legt im selbst gehosteten Appwrite (Projekt `aircard`) die Datenbank `aircard`,
|
||||
* die Tabellen `cards`, `gallery` und `reports` (TablesDB, mit Spalten und
|
||||
* Indizes) und die Buckets `card-images` und `gallery-images` an.
|
||||
* die Tabellen `cards`, `gallery`, `reports`, `logos`, `logo_likes` und
|
||||
* `logo_reports` (TablesDB, mit Spalten und Indizes) und die Buckets
|
||||
* `card-images`, `gallery-images` und `logo-images` an.
|
||||
* Reines `fetch`, keine Abhängigkeiten, Node 22+.
|
||||
*
|
||||
* Aufruf (vom Repo-Wurzelverzeichnis):
|
||||
@@ -40,7 +41,7 @@ const str = (key, size, required) => ({ key, type: 'string', size, required });
|
||||
|
||||
export const DESIRED = {
|
||||
database: { id: 'aircard', name: 'AirCard' },
|
||||
// Reihenfolge ist Ablauf: cards, gallery, reports (je Tabelle: Spalten, dann Indizes).
|
||||
// Reihenfolge ist Ablauf: cards, gallery, reports, logos, logo_likes, logo_reports (je Tabelle: Spalten, dann Indizes).
|
||||
tables: [
|
||||
{
|
||||
id: 'cards',
|
||||
@@ -88,6 +89,54 @@ export const DESIRED = {
|
||||
],
|
||||
indexes: [{ key: 'gallery', type: 'key', columns: ['galleryId'] }],
|
||||
},
|
||||
{
|
||||
// Community-Logos. Wie `gallery`: Zeilenrechte setzt nur die API, Clients dürfen nichts auf Tabellenebene.
|
||||
id: 'logos',
|
||||
name: 'Logos',
|
||||
permissions: [],
|
||||
rowSecurity: true,
|
||||
columns: [
|
||||
str('name', 40, true),
|
||||
str('displayName', 30, false),
|
||||
str('fileId', 36, true),
|
||||
str('ownerId', 36, true),
|
||||
{ key: 'mono', type: 'boolean', required: false, default: false },
|
||||
{ key: 'likeCount', type: 'integer', required: false, default: 0, min: 0 },
|
||||
{ key: 'hidden', type: 'boolean', required: false, default: false },
|
||||
{ key: 'reportCount', type: 'integer', required: false, default: 0, min: 0 },
|
||||
],
|
||||
indexes: [
|
||||
{ key: 'owner', type: 'key', columns: ['ownerId'] },
|
||||
{ key: 'hidden', type: 'key', columns: ['hidden'] },
|
||||
{ key: 'likes', type: 'key', columns: ['likeCount'] },
|
||||
],
|
||||
},
|
||||
{
|
||||
// Ein Herz je Konto und Logo: Zeilen-ID hash32("<logoId>|<userId>"), lesen darf nur das Konto selbst; geschrieben wird nur über die API.
|
||||
id: 'logo_likes',
|
||||
name: 'Logo Likes',
|
||||
permissions: [],
|
||||
rowSecurity: true,
|
||||
columns: [str('logoId', 36, true), str('userId', 36, true)],
|
||||
indexes: [
|
||||
{ key: 'logo', type: 'key', columns: ['logoId'] },
|
||||
// Mehrspalten-Index: die Reihenfolge der Spalten zählt (und wird verglichen).
|
||||
{ key: 'user_logo', type: 'key', columns: ['userId', 'logoId'] },
|
||||
],
|
||||
},
|
||||
{
|
||||
// Nur Admins lesen (Label `admin`); geschrieben wird ausschließlich über die API.
|
||||
id: 'logo_reports',
|
||||
name: 'Logo Reports',
|
||||
permissions: ['read("label:admin")'],
|
||||
rowSecurity: false,
|
||||
columns: [
|
||||
str('logoId', 36, true),
|
||||
{ key: 'reason', type: 'enum', elements: ['unangemessen', 'kartendaten', 'urheberrecht', 'spam', 'sonstiges'], required: true },
|
||||
str('reporterHash', 64, true),
|
||||
],
|
||||
indexes: [{ key: 'logo', type: 'key', columns: ['logoId'] }],
|
||||
},
|
||||
],
|
||||
buckets: [
|
||||
{
|
||||
@@ -110,6 +159,17 @@ export const DESIRED = {
|
||||
compression: 'none',
|
||||
antivirus: false,
|
||||
},
|
||||
{
|
||||
// Logo-PNG (höchstens 1 MiB); die Dateirechte setzt die API je Datei.
|
||||
id: 'logo-images',
|
||||
name: 'Logo Images',
|
||||
permissions: ['create("users")'],
|
||||
fileSecurity: true,
|
||||
maximumFileSize: 1048576,
|
||||
allowedFileExtensions: ['png'],
|
||||
compression: 'none',
|
||||
antivirus: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user