add fixes to claims and seasons
This commit is contained in:
@@ -553,5 +553,199 @@ export async function migrate(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
// ── 16. Add seasons json field to fams ──
|
||||
{
|
||||
const c = await getCollection("fams");
|
||||
if (c) {
|
||||
const hasField = c.fields.some((f: any) => f.name === "seasons");
|
||||
if (!hasField) {
|
||||
console.log("[migrate] Adding seasons to fams...");
|
||||
c.fields.push({ name: "seasons", type: "json" });
|
||||
await updateCollection(c.id, {
|
||||
name: "fams", type: "base",
|
||||
listRule: c.listRule, viewRule: c.viewRule,
|
||||
createRule: c.createRule, updateRule: c.updateRule,
|
||||
deleteRule: c.deleteRule, fields: c.fields,
|
||||
});
|
||||
} else {
|
||||
console.log(` ↳ fams.seasons already exists`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 17. Add seasonIds json field to assigned_chores ──
|
||||
{
|
||||
const c = await getCollection("assigned_chores");
|
||||
if (c) {
|
||||
const hasField = c.fields.some((f: any) => f.name === "seasonIds");
|
||||
if (!hasField) {
|
||||
console.log("[migrate] Adding seasonIds to assigned_chores...");
|
||||
c.fields.push({ name: "seasonIds", type: "json" });
|
||||
await updateCollection(c.id, {
|
||||
name: "assigned_chores", type: "base",
|
||||
listRule: c.listRule, viewRule: c.viewRule,
|
||||
createRule: c.createRule, updateRule: c.updateRule,
|
||||
deleteRule: c.deleteRule, fields: c.fields,
|
||||
});
|
||||
} else {
|
||||
console.log(` ↳ assigned_chores.seasonIds already exists`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 18. Create seasons collection if missing ──
|
||||
{
|
||||
const existing = await getCollection("seasons");
|
||||
if (!existing) {
|
||||
console.log("[migrate] Creating seasons collection...");
|
||||
const t = await auth();
|
||||
const famsCol = await getCollection("fams");
|
||||
const res = await fetch(`${PB_ENDPOINT}/api/collections`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${t}` },
|
||||
body: JSON.stringify({
|
||||
name: "seasons", type: "base",
|
||||
listRule: "", viewRule: "",
|
||||
createRule: null, updateRule: null, deleteRule: null,
|
||||
fields: [
|
||||
{ name: "famId", type: "relation", required: true, maxSelect: 1, collectionId: famsCol?.id || "" },
|
||||
{ name: "name", type: "text", required: true },
|
||||
{ name: "color", type: "text" },
|
||||
{ name: "active", type: "bool" },
|
||||
{ name: "autoDisable", type: "date" },
|
||||
{ name: "autoStart", type: "date" },
|
||||
],
|
||||
}),
|
||||
});
|
||||
if (res.ok) console.log(" ✓ Created seasons collection");
|
||||
else console.log(` ↳ seasons collection creation skipped or already exists`);
|
||||
} else {
|
||||
console.log(` ↳ seasons collection already exists`);
|
||||
}
|
||||
}
|
||||
|
||||
// ── 19. Add active bool to existing seasons collection ──
|
||||
{
|
||||
const c = await getCollection("seasons");
|
||||
if (c) {
|
||||
const hasActive = c.fields.some((f: any) => f.name === "active");
|
||||
if (!hasActive) {
|
||||
console.log("[migrate] Adding active bool to seasons...");
|
||||
c.fields.push({ name: "active", type: "bool" });
|
||||
await updateCollection(c.id, {
|
||||
name: "seasons", type: "base",
|
||||
listRule: c.listRule, viewRule: c.viewRule,
|
||||
createRule: c.createRule, updateRule: c.updateRule,
|
||||
deleteRule: c.deleteRule, fields: c.fields,
|
||||
});
|
||||
} else {
|
||||
console.log(` ↳ seasons.active already exists`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 20. Backfill active=true from fams.seasons array ──
|
||||
{
|
||||
const t = await auth();
|
||||
const fams = await getCollection("fams");
|
||||
if (fams) {
|
||||
const hasSeasonsField = fams.fields.some((f: any) => f.name === "seasons");
|
||||
if (hasSeasonsField) {
|
||||
console.log("[migrate] Backfilling season active flags from fams.seasons...");
|
||||
const allFams = await fetch(`${PB_ENDPOINT}/api/collections/fams/records?perPage=1000`, {
|
||||
headers: { Authorization: `Bearer ${t}` },
|
||||
});
|
||||
const famData = await allFams.json();
|
||||
for (const fam of famData.items || []) {
|
||||
const activeIds = fam.seasons || [];
|
||||
if (activeIds.length > 0) {
|
||||
for (const sid of activeIds) {
|
||||
await fetch(`${PB_ENDPOINT}/api/collections/seasons/records/${sid}`, {
|
||||
method: "PATCH",
|
||||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${t}` },
|
||||
body: JSON.stringify({ active: true }),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(` ↳ backfilled ${famData.items?.length || 0} fams`);
|
||||
} else {
|
||||
console.log(` ↳ fams.seasons already removed`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 21. Remove seasons field from fams ──
|
||||
{
|
||||
const c = await getCollection("fams");
|
||||
if (c) {
|
||||
const hasField = c.fields.some((f: any) => f.name === "seasons");
|
||||
if (hasField) {
|
||||
console.log("[migrate] Removing seasons field from fams...");
|
||||
c.fields = c.fields.filter((f: any) => f.name !== "seasons");
|
||||
await updateCollection(c.id, {
|
||||
name: "fams", type: "base",
|
||||
listRule: c.listRule, viewRule: c.viewRule,
|
||||
createRule: c.createRule, updateRule: c.updateRule,
|
||||
deleteRule: c.deleteRule, fields: c.fields,
|
||||
});
|
||||
} else {
|
||||
console.log(` ↳ fams.seasons already removed`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── 22. Convert rewards.claimed boolean to status select field ──
|
||||
{
|
||||
const c = await getCollection("rewards");
|
||||
if (c) {
|
||||
const hasClaimedField = c.fields.some((f: any) => f.name === "claimed");
|
||||
const hasStatusField = c.fields.some((f: any) => f.name === "status");
|
||||
if (hasClaimedField && !hasStatusField) {
|
||||
console.log("[migrate] Converting rewards.claimed to status field...");
|
||||
|
||||
// Fetch all rewards to backfill status
|
||||
const t = await auth();
|
||||
let page = 1;
|
||||
let total = 0;
|
||||
while (true) {
|
||||
const res = await fetch(`${PB_ENDPOINT}/api/collections/rewards/records?page=${page}&perPage=100`, {
|
||||
headers: { Authorization: `Bearer ${t}` },
|
||||
});
|
||||
const data = await res.json();
|
||||
for (const r of data.items || []) {
|
||||
const status = r.claimed ? "claimed" : "unclaimed";
|
||||
await fetch(`${PB_ENDPOINT}/api/collections/rewards/records/${r.id}`, {
|
||||
method: "PATCH",
|
||||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${t}` },
|
||||
body: JSON.stringify({ status }),
|
||||
});
|
||||
total++;
|
||||
}
|
||||
if (!data.items || data.items.length < 100) break;
|
||||
page++;
|
||||
}
|
||||
console.log(` ↳ backfilled ${total} rewards with status`);
|
||||
|
||||
// Remove claimed field and add status + requestedAt fields
|
||||
c.fields = c.fields.filter((f: any) => f.name !== "claimed");
|
||||
if (!c.fields.some((f: any) => f.name === "status")) {
|
||||
c.fields.push({ name: "status", type: "select", required: true, values: ["unclaimed", "requested", "claimed"], maxSelect: 1 });
|
||||
}
|
||||
if (!c.fields.some((f: any) => f.name === "requestedAt")) {
|
||||
c.fields.push({ name: "requestedAt", type: "date", required: false });
|
||||
}
|
||||
await updateCollection(c.id, {
|
||||
name: "rewards", type: "base",
|
||||
listRule: c.listRule, viewRule: c.viewRule,
|
||||
createRule: c.createRule, updateRule: c.updateRule,
|
||||
deleteRule: c.deleteRule, fields: c.fields,
|
||||
});
|
||||
} else if (!hasClaimedField) {
|
||||
console.log(` ↳ rewards.claimed already converted to status`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log("[migrate] Done");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user