# Falukant: Produktions-Log und Zertifikatszählung (Abgleich Daemon ↔ Backend/UI) ## Ziel Die sichtbare Zertifikatsvorschau (Backend `buildCertificateProgress` / UI) soll dieselbe **abgeschlossene Produktionen**-Logik verwenden wie der Zertifikats-Daemon. Außerdem soll klar sein, wie Log-Zeilen aufbewahrt und bereinigt werden – **ohne** breites Löschen nur zum Zurücksetzen der Zählung. ## Spalte `certificate_productions_count_since` - Tabelle: `falukant_data.falukant_user` - Typ: `TIMESTAMPTZ`, nullable - **Semantik:** Nach einem **Zertifikatsaufstieg**, **Bankrott** oder **Erbfolge** (und gleichartigen Stufenänderungen im Daemon) wird der Zeitpunkt auf `NOW()` gesetzt. Alle Zählungen für Mindestanforderungen / Produktionspunkte berücksichtigen nur noch Log-Zeilen mit effektivem Zeitpunkt **≥** diesem Wert. - **`NULL`:** Wie bisher die gesamte relevante Historie zählen (Bestand bis zur ersten Stufenänderung nach Einführung der Spalte). Daemon-seitig typisch: `QUERY_UPDATE_FALUKANT_USER_CERTIFICATE` setzt bei jeder Stufenänderung `certificate_productions_count_since = NOW()`. ## Effektiver Zeitpunkt einer Log-Zeile Überall, wo der Daemon und das Backend dieselbe Bedeutung brauchen: ```sql COALESCE(pl.production_timestamp, pl.production_date::timestamp) ``` - `production_timestamp` fehlt oder ist unzuverlässig (z. B. ältere Upserts): Fallback auf Kalendertag `production_date`. - So wird **nicht** nur „Produktionen für den laufenden Kalendertag“ gewertet, sondern konsistent der gespeicherte Zeitbezug der Zeile – abgestimmt mit dem Daemon (`QUERY_GET_PRODUCTION_CERTIFICATE_INPUT_ROWS`). Backend-Implementierung: `getCertificateCompletedProductionCount` in `backend/services/falukantService.js` filtert bei gesetztem `certificateProductionsCountSince` mit derselben `COALESCE`-Bedingung. ## Log-Retention (30 Tage) `falukant_log.production` wird u. a. für Wissens-Updates, Preis-/Producer-Events und Zertifikatszählung genutzt. **Nicht** sinnvoll: alle Logs nach einem Aufstieg löschen, nur um neu zu zählen. Stattdessen: - Zähler-Reset über **`certificate_productions_count_since`** (siehe oben). - Alte Zeilen mit **Retention 30 Tage** bereinigen (z. B. im **YpDaemon** mit `QUERY_DELETE_OLD_PRODUCTIONS`), damit die Tabelle nicht unbegrenzt wächst: ```sql DELETE FROM falukant_log.production WHERE COALESCE(production_timestamp, production_date::timestamp) < NOW() - INTERVAL '30 days'; ``` Die C++-Worker unter **`src/`** sind **[obsolet](LEGACY_CPP_WORKERS.md)** und werden für Retention oder Zertifikatslogik **nicht** mehr als Bezug genutzt. ## Migrationen - **Sequelize (dieses Repo):** `backend/migrations-archive/20260402140000-add-certificate-productions-count-since.cjs` – fügt die Spalte und den DB-Kommentar hinzu. - **Externer Daemon / SQL-Pfad:** falls vorhanden z. B. `migrations/014_falukant_certificate_productions_count_since.sql` – inhaltlich dieselbe Spalte; nur eine Quelle der Wahrheit fürs Schema nötig. Weitere Hinweise: `backend/migrations/README.md`. ## Verwandte Spezifikation Ausführlicheres Fachkonzept (Stufen, Score, Events): [`FALUKANT_PRODUCTION_CERTIFICATE_SPEC.md`](./FALUKANT_PRODUCTION_CERTIFICATE_SPEC.md).