107 lines
4.3 KiB
JavaScript
107 lines
4.3 KiB
JavaScript
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 {}
|
|
}
|
|
});
|