dynamic chore counts
This commit is contained in:
@@ -438,6 +438,7 @@ async function ensureAssignedChoreFields(): Promise<void> {
|
||||
const col = await getCollection('assigned_chores');
|
||||
if (!col) return;
|
||||
const has = (n: string) => col.fields.some((f: any) => f.name === n);
|
||||
const fields = [...col.fields];
|
||||
const needed: any[] = [];
|
||||
if (!has('description')) needed.push({ name: 'description', type: 'text', required: false });
|
||||
if (!has('icon')) needed.push({ name: 'icon', type: 'text', required: false });
|
||||
@@ -445,27 +446,31 @@ async function ensureAssignedChoreFields(): Promise<void> {
|
||||
if (!has('emoji')) needed.push({ name: 'emoji', type: 'text', required: false });
|
||||
// Shared chores: memberId becomes optional, shared boolean tracks original mode
|
||||
if (!has('shared')) needed.push({ name: 'shared', type: 'bool', required: false });
|
||||
let changed = false;
|
||||
if (needed.length) {
|
||||
fields.push(...needed);
|
||||
changed = true;
|
||||
}
|
||||
// Todos can be celebration-only (emoji) as well as points/money.
|
||||
let changed = !!needed.length;
|
||||
const typeField = col.fields.find((f: any) => f.name === 'type');
|
||||
const typeField = fields.find((f: any) => f.name === 'type');
|
||||
if (typeField && Array.isArray(typeField.values) && !typeField.values.includes('emoji')) {
|
||||
typeField.values = [...typeField.values, 'emoji'];
|
||||
changed = true;
|
||||
}
|
||||
// Direct todos (created by a parent, not from a template) have no templateId.
|
||||
const tplField = col.fields.find((f: any) => f.name === 'templateId');
|
||||
const tplField = fields.find((f: any) => f.name === 'templateId');
|
||||
if (tplField && tplField.required) {
|
||||
tplField.required = false;
|
||||
changed = true;
|
||||
}
|
||||
// memberId must be optional for shared chores (null = shared with all members)
|
||||
const memberField = col.fields.find((f: any) => f.name === 'memberId');
|
||||
const memberField = fields.find((f: any) => f.name === 'memberId');
|
||||
if (memberField && memberField.required) {
|
||||
memberField.required = false;
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
await updateCollection(col.id, { ...col, fields: [...col.fields] });
|
||||
await updateCollection(col.id, { ...col, fields });
|
||||
}
|
||||
const comp = await getCollection('completions');
|
||||
if (comp && !comp.fields.some((f: any) => f.name === 'rewardId')) {
|
||||
@@ -526,6 +531,10 @@ async function ensureBonusFields(): Promise<void> {
|
||||
fields.push({ name: 'targetChoreId', type: 'text', required: false });
|
||||
changed = true;
|
||||
}
|
||||
if (name === 'bonus_configs' && !has('targetChoreIds')) {
|
||||
fields.push({ name: 'targetChoreIds', type: 'json', 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) {
|
||||
|
||||
Reference in New Issue
Block a user