114 lines
4.8 KiB
TypeScript
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>;
|