fix mcs
This commit is contained in:
@@ -262,6 +262,54 @@ async function ensureOtp(ids: Record<string, string>): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
// Child shared-device PINs. Superuser-only rules (like `otp`) — all access
|
||||
// goes through server endpoints with session-role checks, so children can
|
||||
// never read siblings' pins via PB rules.
|
||||
async function ensurePins(ids: Record<string, string>): Promise<void> {
|
||||
if (await getCollection('pins')) return;
|
||||
const famsId = ids.fams || (await getCollection('fams'))?.id;
|
||||
const usersId = ids.users || (await getCollection('users'))?.id;
|
||||
if (!famsId || !usersId) throw new Error('fams/users collection not found');
|
||||
await createCollection({
|
||||
name: 'pins',
|
||||
type: 'base',
|
||||
listRule: null,
|
||||
viewRule: null,
|
||||
createRule: null,
|
||||
updateRule: null,
|
||||
deleteRule: null,
|
||||
fields: [
|
||||
{
|
||||
name: 'famId',
|
||||
type: 'relation',
|
||||
required: true,
|
||||
collectionId: famsId,
|
||||
maxSelect: 1,
|
||||
cascadeDelete: false
|
||||
},
|
||||
{
|
||||
name: 'userId',
|
||||
type: 'relation',
|
||||
required: true,
|
||||
collectionId: usersId,
|
||||
maxSelect: 1,
|
||||
cascadeDelete: false
|
||||
},
|
||||
{ name: 'pin', type: 'text', required: false }
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Idempotent field-add for the shared-device idle lock (0 = off, else mins).
|
||||
async function ensureSettingsFields(): Promise<void> {
|
||||
const settingsCol = await getCollection('settings');
|
||||
if (!settingsCol) return;
|
||||
const has = (n: string) => settingsCol.fields.some((f: any) => f.name === n);
|
||||
if (has('lockMins')) return;
|
||||
settingsCol.fields.push({ name: 'lockMins', type: 'number', required: false });
|
||||
await updateCollection(settingsCol.id, { fields: settingsCol.fields });
|
||||
}
|
||||
|
||||
// Platform access codes — the codes that enable access to the platform. They're
|
||||
// global (not fam-scoped) and managed via the platform admin page (superuser
|
||||
// only), so all rules are null like `otp`. A code grants a family a subscription
|
||||
@@ -404,6 +452,7 @@ async function ensureSchema(): Promise<void> {
|
||||
|
||||
await ensureUsers(ids);
|
||||
await ensureOtp(ids);
|
||||
await ensurePins(ids);
|
||||
console.log('[migrate] Schema bootstrapped.');
|
||||
}
|
||||
|
||||
@@ -473,11 +522,16 @@ export async function migrate(): Promise<void> {
|
||||
// return) so new platform collections/fields/seed land on existing installs.
|
||||
await ensureUserFields();
|
||||
await ensureFamFields();
|
||||
await ensureSettingsFields();
|
||||
await ensureBonusFields();
|
||||
await ensureTemplateFields();
|
||||
await ensureAssignedChoreFields();
|
||||
await ensureAccessCodes();
|
||||
await ensurePlatform();
|
||||
// Superuser-only collections also land on EXISTING installs (ensureSchema's
|
||||
// early return skips them). Like ensureOtp before it, ensurePins no-ops when
|
||||
// the collection already exists.
|
||||
await ensurePins({});
|
||||
await ensureDefaultSeasons();
|
||||
if (await isDemo()) {
|
||||
await seedDemoFamily();
|
||||
|
||||
Reference in New Issue
Block a user