First commit

This commit is contained in:
2026-06-01 23:16:10 +02:00
commit 1ea182f68d
56 changed files with 42848 additions and 0 deletions
+106
View File
@@ -0,0 +1,106 @@
migrate((app) => {
function collectionExists(name) {
try { app.findCollectionByNameOrId(name); return true; } catch { return false; }
}
// ── households ──────────────────────────────────────────────────────────────
if (!collectionExists('households')) {
const col = new Collection({
name: 'households',
type: 'base',
listRule: '',
viewRule: '',
createRule: '',
updateRule: '',
deleteRule: '',
fields: [
{ name: 'name', type: 'text', required: true },
{ name: 'invite_token', type: 'text', required: true },
],
});
app.save(col);
}
const householdsId = app.findCollectionByNameOrId('households').id;
// ── items ────────────────────────────────────────────────────────────────────
if (!collectionExists('items')) {
const col = new Collection({
name: 'items',
type: 'base',
listRule: '',
viewRule: '',
createRule: '',
updateRule: '',
deleteRule: '',
fields: [
{ name: 'household', type: 'relation', required: true, collectionId: householdsId, cascadeDelete: true, maxSelect: 1 },
{ name: 'name', type: 'text', required: true },
{ name: 'description', type: 'text' },
{ name: 'category', type: 'text' },
{ name: 'quantity', type: 'number' },
{ name: 'unit', type: 'text' },
{ name: 'min_stock_threshold', type: 'number' },
{ name: 'on_shopping_list', type: 'bool' },
{ name: 'photo', type: 'file', maxSelect: 1, maxSize: 5242880 },
{ name: 'storage_location', type: 'text' },
{ name: 'shopping_location', type: 'text' },
{ name: 'price', type: 'number' },
{ name: 'expiry_date', type: 'date' },
{ name: 'barcode', type: 'text' },
{ name: 'added_by_device', type: 'text' },
],
});
app.save(col);
}
// ── shopping_list ────────────────────────────────────────────────────────────
if (!collectionExists('shopping_list')) {
const col = new Collection({
name: 'shopping_list',
type: 'base',
listRule: '',
viewRule: '',
createRule: '',
updateRule: '',
deleteRule: '',
fields: [
{ name: 'household', type: 'relation', required: true, collectionId: householdsId, cascadeDelete: true, maxSelect: 1 },
{ name: 'item_id', type: 'text' },
{ name: 'name', type: 'text', required: true },
{ name: 'suggested_quantity', type: 'number' },
{ name: 'unit', type: 'text' },
{ name: 'is_checked', type: 'bool' },
{ name: 'checked_by_device', type: 'text' },
{ name: 'auto_added', type: 'bool' },
],
});
app.save(col);
}
// ── members ──────────────────────────────────────────────────────────────────
if (!collectionExists('members')) {
const col = new Collection({
name: 'members',
type: 'base',
listRule: '',
viewRule: '',
createRule: '',
updateRule: '',
deleteRule: '',
fields: [
{ name: 'household', type: 'relation', required: true, collectionId: householdsId, cascadeDelete: true, maxSelect: 1 },
{ name: 'device_id', type: 'text', required: true },
{ name: 'device_name', type: 'text' },
{ name: 'fcm_token', type: 'text' },
{ name: 'notifications_enabled', type: 'bool' },
],
});
app.save(col);
}
}, (app) => {
// rollback
for (const name of ['members', 'shopping_list', 'items', 'households']) {
try { app.delete(app.findCollectionByNameOrId(name)); } catch {}
}
});