Files
everythingbutwork/apps/api/src/lib/pflicht-minimum.ts
T
dejanandClaude Opus 4.8 22f79460b2
ci / quality (push) Failing after 38s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 53s
fix: Bug-Review-Fixes + README aktualisiert
Backend:
- Vortags-Feed (dashboard.overview + dayEntry.feed) sortierte aufsteigend
  mit limit(50) → zeigte die ÄLTESTEN statt neuesten Einträge. Jetzt desc.
- deal.updateStage: wonValueEur wurde beim Gewinnen mit der Wahrscheinlichkeit
  gewichtet → zu niedriger Won-Umsatz. Jetzt voller Auftragswert.
- Pflicht-Minimum „Status aktuell" wurde global (letzte Reflexion irgendwo)
  statt pro Projekt berechnet. Jetzt je Projekt aus dem jüngsten Statusbericht.
- time.listToday/teamToday nutzten fixen +02:00-Offset → im Winter (CET) um
  1h verschobene Tagesgrenze. Jetzt DST-sicher via AT TIME ZONE 'Europe/Berlin'.

Frontend:
- lead.tsx + projekt.tsx: Datumsanzeigen nutzten UTC (toISOString) → abends
  Off-by-one. Jetzt Berlin-lokal formatiert.
- reflexion.tsx: Submit mappte nur den initialen ToDo-Snapshot → mitten am Tag
  ergänzte ToDos verloren ihren Status. Jetzt über die aktuelle Liste.
- leads.tsx: CSV-Zeilenzähler konnte „-1" zeigen (Math.max).
- TimerPill: Label ohne Control (a11y-Lint-Error, war repo-weit rot) + unused
  clsx-Import behoben → pnpm lint jetzt 0 Errors.

DB: seed.ts unbedingten updatedAt-Bump aller User entfernt (Debug-Rest).

README: vollständig auf aktuellen Stand gebracht (Leads/CRM, CSV-Import,
PM-Tiefe, Phasen/Status/Risiken/Stakeholder/Änderungen, Tabellen bis 0011,
tRPC-Router, staleTime 0, Auto-Deploy-Runner + Startup-Migrationen).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 17:00:03 +02:00

39 lines
1.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Pflicht-Minimum-Berechnung (Leitfaden §9).
// Punkte 1–4 + 6 werden manuell in der App gepflegt; Punkt 5 (Status-Ampel aktuell)
// wird hier zeitabhängig berechnet und im Cron aktualisiert.
import { eq, desc } from 'drizzle-orm';
import { project, projectStatus } from '@cockpit/db';
import type { Db } from '@cockpit/db';
import { werktageBetween, todayIso, formatIsoDate } from './werktag.js';
const MAX_AGE_WERKTAGE = 7;
export async function recomputePflichtMinimumStatusActual(db: Db): Promise<{ updated: number }> {
const projects = await db.select().from(project).where(eq(project.archiviert, false));
const today = todayIso();
let updated = 0;
for (const p of projects) {
// Jüngsten Statusbericht DIESES Projekts heranziehen (statt global).
const last = (
await db
.select({ createdAt: projectStatus.createdAt })
.from(projectStatus)
.where(eq(projectStatus.projectId, p.id))
.orderBy(desc(projectStatus.createdAt))
.limit(1)
)[0];
const actual = last
? werktageBetween(formatIsoDate(last.createdAt), today) <= MAX_AGE_WERKTAGE
: false;
const newState = { ...p.pflichtMinimumState, status_aktuell: actual };
if (JSON.stringify(newState) !== JSON.stringify(p.pflichtMinimumState)) {
await db.update(project).set({ pflichtMinimumState: newState }).where(eq(project.id, p.id));
updated++;
}
}
return { updated };
}