update migration of user fields
This commit is contained in:
@@ -407,6 +407,34 @@ async function ensureSchema(): Promise<void> {
|
||||
console.log('[migrate] Schema bootstrapped.');
|
||||
}
|
||||
|
||||
// Add theme + newer auth fields to `users` on installs where the collection
|
||||
// already exists (fresh installs get them via ensureUsers). Idempotent —
|
||||
// only adds missing fields. Mirrors ensureFamFields.
|
||||
async function ensureUserFields(): Promise<void> {
|
||||
const usersCol = await getCollection('users');
|
||||
if (!usersCol) return;
|
||||
const has = (n: string) => usersCol.fields.some((f: any) => f.name === n);
|
||||
const needed: any[] = [];
|
||||
if (!has('pattern')) {
|
||||
needed.push({ name: 'pattern', type: 'text', required: false });
|
||||
}
|
||||
if (!has('themeSize')) {
|
||||
needed.push({ name: 'themeSize', type: 'text', required: false });
|
||||
}
|
||||
if (!has('themeOpacity')) {
|
||||
needed.push({ name: 'themeOpacity', type: 'text', required: false });
|
||||
}
|
||||
if (!has('passwordResetToken')) {
|
||||
needed.push({ name: 'passwordResetToken', type: 'text', required: false });
|
||||
}
|
||||
if (!has('passwordResetExpiry')) {
|
||||
needed.push({ name: 'passwordResetExpiry', type: 'text', required: false });
|
||||
}
|
||||
if (needed.length) {
|
||||
await updateCollection(usersCol.id, { ...usersCol, fields: [...usersCol.fields, ...needed] });
|
||||
}
|
||||
}
|
||||
|
||||
// Add the access-gating fields to `fams` on installs where it already exists
|
||||
// (fresh installs get them via SCHEMA_PLAN). Idempotent — only adds missing
|
||||
// fields.
|
||||
@@ -443,6 +471,7 @@ export async function migrate(): Promise<void> {
|
||||
await ensureSchema();
|
||||
// Runs even when the schema already exists (unlike ensureSchema's early
|
||||
// return) so new platform collections/fields/seed land on existing installs.
|
||||
await ensureUserFields();
|
||||
await ensureFamFields();
|
||||
await ensureBonusFields();
|
||||
await ensureTemplateFields();
|
||||
@@ -960,7 +989,7 @@ function addDays(d: Date, n: number): Date {
|
||||
// Each kid's "completion personality" — Juno is reliable, Jackson solid, Jalipo spotty.
|
||||
// Maps assigned chore customName → weekday (0=Sun) → probability of completion.
|
||||
const COMPLETION_PROFILES: Record<string, Record<number, Record<string, number>>> = {
|
||||
'Juno': {
|
||||
Juno: {
|
||||
0: { default: 0.85 }, // Sun
|
||||
1: { default: 0.95 }, // Mon
|
||||
2: { default: 0.9 },
|
||||
@@ -969,7 +998,7 @@ const COMPLETION_PROFILES: Record<string, Record<number, Record<string, number>>
|
||||
5: { default: 0.85 }, // Fri
|
||||
6: { default: 0.8 } // Sat
|
||||
},
|
||||
'Jackson': {
|
||||
Jackson: {
|
||||
0: { default: 0.7 },
|
||||
1: { default: 0.9 },
|
||||
2: { default: 0.85 },
|
||||
@@ -978,7 +1007,7 @@ const COMPLETION_PROFILES: Record<string, Record<number, Record<string, number>>
|
||||
5: { default: 0.7 },
|
||||
6: { default: 0.6 }
|
||||
},
|
||||
'Jalipo': {
|
||||
Jalipo: {
|
||||
0: { default: 0.4 },
|
||||
1: { default: 0.75 },
|
||||
2: { default: 0.65 },
|
||||
@@ -1018,12 +1047,18 @@ async function seedDemoCompletions(): Promise<void> {
|
||||
|
||||
// Fetch members, assigned chores
|
||||
const [membersRes, assignedRes] = await Promise.all([
|
||||
fetch(`${PB_ENDPOINT}/api/collections/users/records?filter=${encodeURIComponent(`famId='${famId}' && role='child'`)}&perPage=10`, {
|
||||
headers: { Authorization: `Bearer ${t}` }
|
||||
}),
|
||||
fetch(`${PB_ENDPOINT}/api/collections/assigned_chores/records?filter=famId='${famId}'&perPage=100`, {
|
||||
headers: { Authorization: `Bearer ${t}` }
|
||||
})
|
||||
fetch(
|
||||
`${PB_ENDPOINT}/api/collections/users/records?filter=${encodeURIComponent(`famId='${famId}' && role='child'`)}&perPage=10`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${t}` }
|
||||
}
|
||||
),
|
||||
fetch(
|
||||
`${PB_ENDPOINT}/api/collections/assigned_chores/records?filter=famId='${famId}'&perPage=100`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${t}` }
|
||||
}
|
||||
)
|
||||
]);
|
||||
const members: any[] = (await membersRes.json())?.items || [];
|
||||
const assigned: any[] = (await assignedRes.json())?.items || [];
|
||||
@@ -1032,12 +1067,18 @@ async function seedDemoCompletions(): Promise<void> {
|
||||
|
||||
// Delete existing completions and weekly_history for the demo family
|
||||
const [oldCompsRes, oldHistoryRes] = await Promise.all([
|
||||
fetch(`${PB_ENDPOINT}/api/collections/completions/records?filter=famId='${famId}'&perPage=500`, {
|
||||
headers: { Authorization: `Bearer ${t}` }
|
||||
}),
|
||||
fetch(`${PB_ENDPOINT}/api/collections/weekly_history/records?filter=famId='${famId}'&perPage=500`, {
|
||||
headers: { Authorization: `Bearer ${t}` }
|
||||
})
|
||||
fetch(
|
||||
`${PB_ENDPOINT}/api/collections/completions/records?filter=famId='${famId}'&perPage=500`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${t}` }
|
||||
}
|
||||
),
|
||||
fetch(
|
||||
`${PB_ENDPOINT}/api/collections/weekly_history/records?filter=famId='${famId}'&perPage=500`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${t}` }
|
||||
}
|
||||
)
|
||||
]);
|
||||
const oldComps: any[] = (await oldCompsRes.json())?.items || [];
|
||||
const oldHistory: any[] = (await oldHistoryRes.json())?.items || [];
|
||||
@@ -1061,7 +1102,10 @@ async function seedDemoCompletions(): Promise<void> {
|
||||
|
||||
// Track per-member-per-week totals for weekly_history
|
||||
type WeekKey = string; // "YYYY-MM-DD" (Monday)
|
||||
const weekTotals: Record<string, Record<string, { points: number; money: number; count: number }>> = {};
|
||||
const weekTotals: Record<
|
||||
string,
|
||||
Record<string, { points: number; money: number; count: number }>
|
||||
> = {};
|
||||
|
||||
for (const member of members) {
|
||||
const profile = COMPLETION_PROFILES[member.name] || COMPLETION_PROFILES['Jalipo'];
|
||||
@@ -1092,10 +1136,7 @@ async function seedDemoCompletions(): Promise<void> {
|
||||
|
||||
const prob = dayProfile[chore.customName] || dayProfile.default;
|
||||
const rng = demoRng(
|
||||
famId.length * 1000 +
|
||||
member.id.length * 100 +
|
||||
d * 10 +
|
||||
(chore.id?.charCodeAt(0) || 0)
|
||||
famId.length * 1000 + member.id.length * 100 + d * 10 + (chore.id?.charCodeAt(0) || 0)
|
||||
);
|
||||
|
||||
if (rng() > prob) continue; // missed this day
|
||||
|
||||
Reference in New Issue
Block a user