add toggle fix and possible log out issue
This commit is contained in:
@@ -10,6 +10,23 @@ import {
|
||||
} from '@shared/timezone';
|
||||
import { computeBonusProgress } from '@shared/bonus-progress';
|
||||
import { famMeta } from './fam';
|
||||
import { pbAdmin } from '$lib/server/pocketbase';
|
||||
|
||||
// `fams` reads via superuser: the acting token may predate RULE_OWN_FAM
|
||||
// (migrate only bootstraps fresh stores), which otherwise logs a 404 and
|
||||
// aborts evaluation. Fam-scoped by record id.
|
||||
async function famMetaSU(famId: string) {
|
||||
try {
|
||||
const fam: any = await pbAdmin.getOne('fams', famId);
|
||||
return {
|
||||
payday: fam.payday !== undefined && fam.payday !== null ? Number(fam.payday) : 1,
|
||||
paydayTime: fam.paydayTime || '18:00',
|
||||
tz: resolveTz(fam.timezone || 'auto')
|
||||
};
|
||||
} catch {
|
||||
return { payday: 1, paydayTime: '18:00', tz: resolveTz('auto') };
|
||||
}
|
||||
}
|
||||
|
||||
function resolveServerTz(tz?: string): string {
|
||||
return resolveTz(tz || 'auto');
|
||||
@@ -64,7 +81,7 @@ export async function evaluateFam(pb: any, famId: string) {
|
||||
try {
|
||||
allRewards = await pb.collection('rewards').getFullList({ filter: `famId = '${famId}'` });
|
||||
} catch {}
|
||||
const { payday: paydayEval, tz: tzEval } = await famMeta(pb, famId);
|
||||
const { payday: paydayEval, tz: tzEval } = await famMetaSU(famId);
|
||||
|
||||
// Chores "due" this week per member (daily = 7, otherwise 1). Used by the
|
||||
// `percent` threshold type to compute % of chores completed.
|
||||
|
||||
@@ -1,7 +1,27 @@
|
||||
import { periodWindow } from '@shared/timezone';
|
||||
import { famMeta } from './fam';
|
||||
import { pbAdmin } from '$lib/server/pocketbase';
|
||||
import { evaluateFam } from './bonuses';
|
||||
|
||||
// Reads/writes the acting user may not be permitted by PB rules:
|
||||
// - `fams` view (prod may predate RULE_OWN_FAM; migrate only bootstraps fresh)
|
||||
// - `assigned_chores` update (parent-only rule, but children claim shared chores)
|
||||
// Both stay fam-scoped: the fam record id and the chore's own famId are checked.
|
||||
async function famMetaSU(famId: string) {
|
||||
const fam: any = await pbAdmin.getOne('fams', famId);
|
||||
const { resolveTz } = await import('@shared/timezone');
|
||||
return {
|
||||
payday: fam.payday !== undefined && fam.payday !== null ? Number(fam.payday) : 1,
|
||||
paydayTime: fam.paydayTime || '18:00',
|
||||
tz: resolveTz(fam.timezone || 'auto')
|
||||
};
|
||||
}
|
||||
|
||||
async function claimChore(assignedChoreId: string, famId: string, memberId: string | '') {
|
||||
const chore: any = await pbAdmin.getOne('assigned_chores', assignedChoreId);
|
||||
if (!chore || chore.famId !== famId) throw new Error('Chore not found');
|
||||
await pbAdmin.update('assigned_chores', assignedChoreId, { memberId });
|
||||
}
|
||||
|
||||
export async function myChores(pb: any, famId: string, memberId: string) {
|
||||
const [templates, assigned, completions, rewards, bonusConfigs] = await Promise.all([
|
||||
pb.collection('chore_templates').getFullList({ filter: `famId = '${famId}'` }),
|
||||
@@ -12,7 +32,7 @@ export async function myChores(pb: any, famId: string, memberId: string) {
|
||||
pb.collection('rewards').getFullList({ filter: `famId = '${famId}' && memberId = '${memberId}'` }),
|
||||
pb.collection('bonus_configs').getFullList({ filter: `famId = '${famId}' && status = 'active'` })
|
||||
]);
|
||||
const { payday, paydayTime, tz } = await famMeta(pb, famId);
|
||||
const { payday, paydayTime, tz } = await famMetaSU(famId);
|
||||
return {
|
||||
templates,
|
||||
assigned,
|
||||
@@ -39,13 +59,13 @@ export async function toggle(pb: any, famId: string, memberId: string, body: { a
|
||||
let filter: string;
|
||||
if (isShared && !isTodo) {
|
||||
// Shared non-todo: any completion in the period = already claimed
|
||||
const { payday, tz } = await famMeta(pb, famId);
|
||||
const { payday, tz } = await famMetaSU(famId);
|
||||
const { from, to } = periodWindow(chore?.frequency, payday, tz);
|
||||
filter = `assignedChoreId = '${assignedChoreId}' && date >= '${from}' && date < '${to}'`;
|
||||
} else if (isTodo) {
|
||||
filter = `assignedChoreId = '${assignedChoreId}' && memberId = '${memberId}'`;
|
||||
} else {
|
||||
const { payday, tz } = await famMeta(pb, famId);
|
||||
const { payday, tz } = await famMetaSU(famId);
|
||||
const { from, to } = periodWindow(chore?.frequency, payday, tz);
|
||||
filter = `assignedChoreId = '${assignedChoreId}' && memberId = '${memberId}' && date >= '${from}' && date < '${to}'`;
|
||||
}
|
||||
@@ -60,7 +80,7 @@ export async function toggle(pb: any, famId: string, memberId: string, body: { a
|
||||
}
|
||||
// If this was a shared chore claimed by this member, un-share it
|
||||
if (isShared && existing[0].memberId === memberId) {
|
||||
await pb.collection('assigned_chores').update(assignedChoreId, { memberId: '' });
|
||||
await claimChore(assignedChoreId, famId, '');
|
||||
}
|
||||
evaluateFam(pb, famId).catch(() => {});
|
||||
return { completed: false };
|
||||
@@ -89,7 +109,7 @@ export async function toggle(pb: any, famId: string, memberId: string, body: { a
|
||||
});
|
||||
// Claim the shared chore by setting memberId
|
||||
if (isShared) {
|
||||
await pb.collection('assigned_chores').update(assignedChoreId, { memberId });
|
||||
await claimChore(assignedChoreId, famId, memberId);
|
||||
}
|
||||
evaluateFam(pb, famId).catch(() => {});
|
||||
return { completed: true, record };
|
||||
@@ -107,7 +127,7 @@ export async function revoke(pb: any, famId: string, completionId: string) {
|
||||
.getFullList({ filter: `famId = '${famId}' && id = '${completion.assignedChoreId}'` });
|
||||
const chore = choreList?.[0];
|
||||
if (chore?.shared === true) {
|
||||
await pb.collection('assigned_chores').update(chore.id, { memberId: '' });
|
||||
await claimChore(chore.id, famId, '');
|
||||
}
|
||||
evaluateFam(pb, famId).catch(() => {});
|
||||
return { revoked: true };
|
||||
|
||||
Reference in New Issue
Block a user