feat(04-01): multi-project schema migration — projects, settings, FK pivot

- schema.ts: add projects table, settings kv table, slug on clients;
  migrate 6 FK from client_id to project_id (phases, payments, documents, notes,
  time_entries, quote_items); update all relations and TypeScript types
- admin-queries.ts: fix getAllClientsWithPayments + getClientFullDetail to aggregate
  through projects; add getAllProjectsWithPayments, getProjectFullDetail,
  getClientWithProjects, ClientWithProjects type
- settings.ts: new file — getSetting, updateSetting, getTargetHourlyRate, SETTINGS_KEYS
- Fix all downstream files: actions.ts, quote-actions.ts, new/actions.ts,
  timer-actions.ts, approve/route.ts, comment/route.ts, TimerCell.tsx,
  analytics-queries.ts, client-view.ts, seed.ts
- DB migration applied to Coolify Postgres (all test data cleared, schema rebuilt)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-21 21:58:15 +02:00
parent 44d4fde0a5
commit 63c9f750df
14 changed files with 673 additions and 156 deletions
+2 -2
View File
@@ -2,7 +2,7 @@
import { useState, useEffect, useTransition } from "react";
import { useRouter } from "next/navigation";
import { startTimer, stopTimer } from "@/app/admin/timer-actions";
import { startTimerForClient, stopTimer } from "@/app/admin/timer-actions";
function formatDuration(seconds: number): string {
const h = Math.floor(seconds / 3600);
@@ -47,7 +47,7 @@ export function TimerCell({
if (isRunning && activeEntryId) {
await stopTimer(activeEntryId);
} else {
await startTimer(clientId);
await startTimerForClient(clientId);
}
router.refresh();
});