migrate from hono
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import { todayInTz, resolveTz } from '@shared/timezone';
|
||||
import { famMeta } from './fam';
|
||||
|
||||
function resolveServerTz(tz?: string): string {
|
||||
return resolveTz(tz || 'auto');
|
||||
}
|
||||
|
||||
export function assertPaydayUnlocked(reward: any, tz?: string) {
|
||||
if (!reward || reward.claimable !== 'payday' || !reward.settleDate) return;
|
||||
const today = todayInTz(resolveServerTz(tz));
|
||||
if (today < reward.settleDate) {
|
||||
throw new Error(`This bonus pays out on payday (${reward.settleDate}) — hang tight!`);
|
||||
}
|
||||
}
|
||||
|
||||
// Member claim → status 'requested' (pending parent approval).
|
||||
export async function claim(pb: any, famId: string, id: string) {
|
||||
const now = new Date().toISOString();
|
||||
const { tz } = await famMeta(pb, famId);
|
||||
const found = await pb
|
||||
.collection('rewards')
|
||||
.getFullList({ filter: `famId = '${famId}' && id = '${id}'` });
|
||||
const reward = found?.[0];
|
||||
if (!reward) throw new Error('Reward not found');
|
||||
assertPaydayUnlocked(reward, tz);
|
||||
return pb.collection('rewards').update(id, { status: 'requested', requestedAt: now });
|
||||
}
|
||||
|
||||
// Admin approval → status 'claimed'.
|
||||
export async function approve(pb: any, famId: string, id: string) {
|
||||
return pb.collection('rewards').update(id, {
|
||||
status: 'claimed',
|
||||
claimedAt: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
|
||||
export async function requestAll(pb: any, famId: string, memberId: string) {
|
||||
const now = new Date().toISOString();
|
||||
const { tz } = await famMeta(pb, famId);
|
||||
const rewards = await pb.collection('rewards').getFullList({
|
||||
filter: `famId = '${famId}' && memberId = '${memberId}' && status = 'unclaimed'`
|
||||
});
|
||||
let count = 0;
|
||||
for (const r of rewards) {
|
||||
try {
|
||||
assertPaydayUnlocked(r, tz);
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
await pb.collection('rewards').update(r.id, { status: 'requested', requestedAt: now });
|
||||
count++;
|
||||
}
|
||||
return { count };
|
||||
}
|
||||
|
||||
export async function issueAll(pb: any, famId: string, memberId: string) {
|
||||
if (!memberId) throw new Error('memberId required');
|
||||
const now = new Date().toISOString();
|
||||
const rewards = await pb.collection('rewards').getFullList({
|
||||
filter: `famId = '${famId}' && memberId = '${memberId}' && rewardType = 'cash' && (status = 'unclaimed' || status = 'requested')`
|
||||
});
|
||||
let count = 0;
|
||||
for (const r of rewards) {
|
||||
await pb.collection('rewards').update(r.id, { status: 'claimed', claimedAt: now });
|
||||
count++;
|
||||
}
|
||||
return { count };
|
||||
}
|
||||
Reference in New Issue
Block a user