Add balance adjustments (M8)

- New balance_adjustments table with CRUD store, sync logging, and service methods
- SQL migrations restructured: embed fs.FS from internal/store/migrations/, apply in order via user_version
- WeekService.Balance combines closed-weeks delta + adjustments delta; BalanceSummary breakdown
- Four REST routes: GET/POST /api/balance/adjustments, PUT/DELETE /api/balance/adjustments/{id}
- Dexie schema v2 + sync apply cases for balance_adjustments
- API client: BalanceAdjustment type, balance namespace (list/create/update/delete)
- utils: composeDeltaMs / decomposeDeltaMs helpers + 8 new Vitest tests (19 total, all passing)
- History page: balance card breakdown line + full adjustments section with inline add/edit/delete
This commit is contained in:
2026-04-30 21:50:57 +02:00
parent 8ca838fa6e
commit 3214f48a6f
19 changed files with 1014 additions and 86 deletions

View File

@@ -81,6 +81,23 @@ export interface Settings {
created_at: number;
}
export interface BalanceAdjustment {
id: string;
delta_ms: number;
note: string;
effective_at: number; // unix ms
created_at: number;
updated_at: number;
}
export interface BalanceSummary {
total_delta_ms: number;
weeks_delta_ms: number;
adjustments_delta_ms: number;
closed_week_count: number;
adjustment_count: number;
}
// ─── Entries ─────────────────────────────────────────────────────────────────
export const entries = {
@@ -125,7 +142,18 @@ export const weeks = {
},
close: (weekKey: string) => request<ClosedWeek>('POST', `/weeks/${weekKey}/close`),
reopen: (weekKey: string) => request<void>('DELETE', `/weeks/${weekKey}/close`),
balance: () => request<{ total_delta_ms: number; closed_week_count: number }>('GET', '/weeks/balance')
balance: () => request<BalanceSummary>('GET', '/weeks/balance')
};
// ─── Balance adjustments ─────────────────────────────────────────────────────
export const balance = {
list: () => request<BalanceAdjustment[]>('GET', '/balance/adjustments'),
create: (body: { delta_ms: number; note?: string; effective_at?: number }) =>
request<BalanceAdjustment>('POST', '/balance/adjustments', body),
update: (id: string, body: { delta_ms: number; note?: string; effective_at?: number }) =>
request<BalanceAdjustment>('PUT', `/balance/adjustments/${id}`, body),
delete: (id: string) => request<void>('DELETE', `/balance/adjustments/${id}`)
};
// ─── Settings ────────────────────────────────────────────────────────────────