added pocketmoney default droplet

This commit is contained in:
JCEEE
2026-08-25 14:30:26 +01:00
parent e904bb8210
commit 5302f86f3c
10 changed files with 423 additions and 83 deletions
+69
View File
@@ -327,7 +327,76 @@ export async function migrate(): Promise<void> {
// Runs even when the schema already exists (unlike ensureSchema's early
// return) so new platform collections/fields/seed land on existing installs.
await ensureFamFields();
await ensureBonusFields();
await ensureAccessCodes();
await ensurePlatform();
console.log("[migrate] Done");
}
// Add the pocket-money fields to bonus collections on existing installs, and
// backfill a default pocket-money droplet (£10 / 50% chores) for any child that
// doesn't yet have one. Idempotent.
async function ensureBonusFields(): Promise<void> {
for (const name of ["bonus_templates", "bonus_configs"]) {
const col = await getCollection(name);
if (!col) continue;
const has = (n: string) => col.fields.some((f: any) => f.name === n);
let changed = false;
const fields = [...col.fields];
if (!has("thresholdType")) {
fields.push({
name: "thresholdType", type: "select", required: false,
values: ["points", "percent"], maxSelect: 1,
});
changed = true;
}
if (!has("isPocketMoney")) {
fields.push({ name: "isPocketMoney", type: "bool", required: false });
changed = true;
}
// rewardValue must be optional so an unset pocket-money droplet can exist.
const rv = fields.find((f: any) => f.name === "rewardValue");
if (rv && rv.required) {
rv.required = false;
changed = true;
}
if (changed) await updateCollection(col.id, { ...col, fields });
}
await backfillPocketMoney();
}
async function backfillPocketMoney(): Promise<void> {
const t = await auth();
const childrenRes = await fetch(
`${PB_ENDPOINT}/api/collections/users/records?filter=role='child'&perPage=500`,
{ headers: { Authorization: `Bearer ${t}` } }
);
const children: any[] = (await childrenRes.json())?.items || [];
for (const c of children) {
const existingRes = await fetch(
`${PB_ENDPOINT}/api/collections/bonus_configs/records?filter=famId='${c.famId}' && memberId='${c.id}' && isPocketMoney=true`,
{ headers: { Authorization: `Bearer ${t}` } }
);
if ((await existingRes.json())?.items?.length) continue;
await fetch(`${PB_ENDPOINT}/api/collections/bonus_configs/records`, {
method: "POST",
headers: { "Content-Type": "application/json", Authorization: `Bearer ${t}` },
body: JSON.stringify({
famId: c.famId,
name: "Pocket Money",
target: "individual",
type: "threshold",
thresholdType: "percent",
occurrence: "recurring",
rewardType: "cash",
rewardValue: 10,
criteriaValue: 50,
memberId: c.id,
period: "weekly",
status: "active",
isPocketMoney: true,
}),
}).catch(() => {});
}
console.log("[migrate] Pocket-money droplets ensured.");
}