Files
famdone/frontend/src/lib/server/services/index.ts
T
2026-09-14 13:00:13 +01:00

114 lines
4.8 KiB
TypeScript

import * as famSvc from './fam';
import * as choresSvc from './chores';
import * as completionsSvc from './completions';
import * as rewardsSvc from './rewards';
import * as bonusesSvc from './bonuses';
import * as chatSvc from './chat';
import * as settingsSvc from './settings';
import * as crudSvc from './crud';
import * as debugSvc from './debug';
import * as statsSvc from './stats';
export * from './chat';
export { famMeta } from './fam';
export { assertPaydayUnlocked } from './rewards';
// Per-feature service binder. `pb` is the acting user's own PocketBase client
// (child or parent token), so PB collection rules enforce famId + role scoping;
// this layer is purely in-process logic grouped by app area for readability.
// `user` supplies the acting user's id/role so member-scoped ops default to it.
export function createServices(
pb: any,
user?: { id?: string; role?: string; name?: string; color?: string }
) {
const uid = user?.id || '';
return {
fam: {
meta: (famId: string) => famSvc.famMeta(pb, famId),
get: (famId: string) => famSvc.getFam(pb, famId),
update: (famId: string, body: Record<string, unknown>) => famSvc.patchFam(pb, famId, body),
rename: (famId: string, name: string) => famSvc.patchFam(pb, famId, { name }),
updatePayday: (famId: string, payday: number, paydayTime?: string, timezone?: string) =>
famSvc.patchFam(pb, famId, {
payday,
...(paydayTime !== undefined ? { paydayTime } : {}),
...(timezone !== undefined ? { timezone } : {})
}),
weeklySummary: (famId: string) => famSvc.weeklySummary(pb, famId),
payday: (famId: string) => famSvc.releaseWeek(pb, famId),
completeWeek: (famId: string) => famSvc.completeWeek(pb, famId),
getProfile: (famId: string) => famSvc.getProfile(pb, famId, uid),
updateProfile: (famId: string, data: Record<string, unknown>) =>
famSvc.updateProfile(pb, famId, uid, data)
},
crud: {
list: (resource: string, famId: string) => crudSvc.list(pb, resource, famId),
create: (resource: string, famId: string, data: Record<string, unknown>) =>
crudSvc.create(pb, resource, famId, data),
update: (resource: string, famId: string, id: string, data: Record<string, unknown>) =>
crudSvc.update(pb, resource, famId, id, data),
remove: (resource: string, famId: string, id: string) =>
crudSvc.remove(pb, resource, famId, id)
},
chores: {
myChores: (famId: string) => choresSvc.myChores(pb, famId, uid),
cleanupExpiredTodos: (famId: string) => choresSvc.cleanupExpiredTodos(pb, famId)
},
completions: {
toggle: (famId: string, body: { assignedChoreId: string; date: string }) =>
completionsSvc.toggle(pb, famId, uid, body),
revoke: (famId: string, completionId: string) =>
completionsSvc.revoke(pb, famId, completionId)
},
rewards: {
claim: (famId: string, id: string) => rewardsSvc.claim(pb, famId, id),
approve: (famId: string, id: string) => rewardsSvc.approve(pb, famId, id),
requestAll: (famId: string) => rewardsSvc.requestAll(pb, famId, uid),
issueAll: (famId: string, memberId: string) => rewardsSvc.issueAll(pb, famId, memberId)
},
bonuses: {
progress: (famId: string) => bonusesSvc.progress(pb, famId),
evaluate: (famId: string) => bonusesSvc.evaluateAll(pb, famId),
trigger: (famId: string, configId: string, memberId?: string) =>
bonusesSvc.trigger(pb, famId, configId, memberId),
assign: (famId: string, configId: string, data: Record<string, unknown>) => {
const updates: Record<string, unknown> = { status: 'active' };
if (data.target) updates.target = data.target;
if (data.memberId !== undefined) updates.memberId = data.memberId || null;
return pb.collection('bonus_configs').update(configId, updates);
},
complete: (famId: string, configId: string) =>
pb.collection('bonus_configs').update(configId, {
status: 'completed',
completedAt: new Date().toISOString().slice(0, 10),
completedBy: 'admin'
}),
destroy: (famId: string, configId: string) => pb.collection('bonus_configs').delete(configId)
},
settings: {
get: (famId: string) => settingsSvc.getSettings(pb, famId),
update: (famId: string, data: Record<string, unknown>) =>
settingsSvc.updateSettings(pb, famId, data)
},
chat: {
me: (famId: string, actor: chatSvc.ChatActor) => chatSvc.chatMe(pb, famId, actor),
send: (
famId: string,
actor: chatSvc.ChatActor,
body: { content?: string; clientId?: string; siteUrl?: string }
) => chatSvc.send(pb, famId, actor, body),
typing: (famId: string, actor: chatSvc.ChatActor, body: { typing?: boolean }) =>
chatSvc.typing(pb, famId, actor, body)
},
debug: {
generateData: (famId: string, days?: number) => debugSvc.generateData(pb, famId, days)
},
stats: {
family: (famId: string) => statsSvc.familyStats(pb, famId)
}
};
}
export type Services = ReturnType<typeof createServices>;