Implement debtors prison features across the application: Enhance FalukantController to include debtors prison logic in various service methods. Update FalukantService to manage debtors prison state and integrate it into user data retrieval. Modify frontend components, including DashboardWidget, StatusBar, and BankView, to display debtors prison status and warnings. Add localization for debtors prison messages in English, German, and Spanish, ensuring clarity in user notifications and actions.

This commit is contained in:
Torsten Schulz (local)
2026-03-23 11:59:59 +01:00
parent f2343098d2
commit 9b88a98a20
19 changed files with 1643 additions and 102 deletions

View File

@@ -0,0 +1,447 @@
# Falukant: Schuldturm und Pfändung - Daemon-Spezifikation
Dieses Dokument beschreibt die Umsetzung des **Schuldturm-Systems** im externen Daemon.
Wichtig:
- Die projektseitigen DB-Felder, API-Erweiterungen, UI-Warnungen und Aktionssperren sind bereits umgesetzt.
- Der Daemon ist die führende Quelle für:
- Verzugstage
- Eintritt in den Schuldturm
- Pfändung und Verwertung
- soziale Folgen
- Freilassung
## 1. Bereits vorhandene Datenbasis
Bereits im Projekt vorhanden:
- `falukant_data.credit`
- `falukant_data.debtors_prism`
- `falukant_data.user_house`
- inkl. `household_tension_score`
- inkl. `household_tension_reasons_json`
- Familien-/Liebschaftsdaten in:
- `falukant_data.relationship`
- `falukant_data.relationship_state`
- `falukant_data.child_relation`
Bereits erweitert:
- `debtors_prism.status`
- `debtors_prism.entered_at`
- `debtors_prism.released_at`
- `debtors_prism.debt_at_entry`
- `debtors_prism.remaining_debt`
- `debtors_prism.days_overdue`
- `debtors_prism.reason`
- `debtors_prism.creditworthiness_penalty`
- `debtors_prism.next_forced_action`
- `debtors_prism.assets_seized_json`
- `debtors_prism.public_known`
Es sind für den Daemon derzeit keine weiteren DB-Änderungen nötig.
## 2. Grundregel
Ein Charakter kommt in den Schuldturm, wenn:
- mindestens ein aktiver Kredit offen ist
- fällige Kreditbedienung ausbleibt
- und `days_overdue >= 3`
Der Daemon prüft dies im Daily-Tick.
## 3. Zustände
`debtors_prism.status` verwendet mindestens:
- `delinquent`
- `imprisoned`
- `released`
Bedeutung:
- `delinquent`: Kreditverzug, aber noch nicht im Schuldturm
- `imprisoned`: im Schuldturm, Verwertung läuft
- `released`: historischer abgeschlossener Fall
## 4. Daily-Tick
Der Daily-Tick prüft pro Falukant-Nutzer:
1. aktive Kredite
2. verbleibende Schuld
3. geleistete Bedienung seit letztem Tick
4. neue Verzugstage
5. Schuldturm-Eintritt
6. laufende soziale Folgen
7. Verwertungsschritt
### 4.1 Verzugstage
Regel:
- wenn offene Schuld vorhanden und fällige Bedienung ausbleibt:
- `days_overdue += 1`
- wenn Kreditpflicht erfüllt wurde:
- `days_overdue = 0`
- falls nicht im Schuldturm
Wenn noch kein aktiver `debtors_prism`-Eintrag existiert:
- bei erstem Verzug `debtors_prism` anlegen mit
- `status = 'delinquent'`
- `days_overdue = 1`
- `remaining_debt = aktuelle offene Schuld`
- `next_forced_action = 'reminder'`
### 4.2 Warnstufen
Bei Verzug:
- Tag 1:
- `next_forced_action = 'reminder'`
- Event `falukantUpdateDebt` mit `reason: 'delinquency'`
- Tag 2:
- `next_forced_action = 'final_warning'`
- Event `falukantUpdateDebt` mit `reason: 'delinquency'`
- Tag 3:
- Schuldturm-Eintritt
Für Warnstufen senden:
- `falukantUpdateDebt`
- zusätzlich `falukantUpdateStatus`
## 5. Eintritt in den Schuldturm
Bei `days_overdue >= 3`:
- `status = 'imprisoned'`
- `entered_at = now()`
- `released_at = null`
- `debt_at_entry = aktuelle offene Schuld`
- `remaining_debt = aktuelle offene Schuld`
- `reason = 'credit_default'`
- `creditworthiness_penalty += 45`
- `next_forced_action = 'asset_seizure'`
- `public_known = true`
### 5.1 Sofortfolgen bei Eintritt
Einmalig anwenden:
- Reputation deutlich senken
- Empfehlung: `-12`
- `marriage_satisfaction` senken
- Empfehlung: `-10`
- `household_tension_score` erhöhen
- Empfehlung: `+15`
- `household_tension_reasons_json` um `debtorsPrison` ergänzen
Zusätzlich:
- aktive Liebhaber/Mätressen sichtbar destabilisieren
- mindestens `affection -= 4`
- Kreditaufnahme und aktive Falukant-Aktionen bleiben projektseitig bereits gesperrt
Bei Eintritt senden:
- `falukantUpdateDebt`
- `reason: 'debtors_prison_entered'`
- `falukantUpdateStatus`
- `falukantUpdateFamily`
- `reason: 'daily'`
- `falukantHouseUpdate`
- `falukantBranchUpdate`
## 6. Verwertung / Pfändung
Die Verwertung läuft nicht alles auf einmal, sondern schrittweise pro Tick.
Reihenfolge:
1. freies Geld
2. Fahrzeuge
3. Waren / Lagerbestände
4. Haus
5. Niederlassungen
Ziel:
- `remaining_debt` schrittweise senken
- Fortschritt im UI sichtbar machen
### 6.1 Geld
Wenn `falukant_user.money > 0`:
- direkt zur Schuld tilgen
- `remaining_debt -= eingezogener_betrag`
Events:
- `falukantUpdateDebt`
- `reason: 'asset_seizure'`
- `falukantUpdateStatus`
### 6.2 Fahrzeuge
Verkaufe zuerst:
- freie Fahrzeuge
- dann weniger wertvolle Typen
- keine Fahrzeuge in aktiven Transporten im selben Tick anfassen, falls technisch problematisch
Erlös:
- Empfehlung: `vehicle_type.cost * condition_factor * 0.55`
Zusätzlich in `assets_seized_json` protokollieren:
- Typ
- Anzahl
- Erlös
Events:
- `falukantUpdateDebt`
- `reason: 'vehicle_liquidation'`
- `falukantUpdateStatus`
### 6.3 Waren / Lager
Verwertbare Güter:
- Lagerbestände
- Inventar
- handelbare Waren
Erlös:
- Empfehlung: Marktwert mit Abschlag von `35% bis 50%`
Events:
- `falukantUpdateDebt`
- `reason: 'asset_seizure'`
- `falukantUpdateStatus`
- `falukantBranchUpdate`
### 6.4 Haus
Wenn Restschuld nach Geld/Fahrzeugen/Waren weiter hoch ist:
- Haus pfänden
- Spieler auf niedrigeres Haus oder Minimalhaus zurücksetzen
- Dienerschaft reduzieren
- `household_order` senken
Events:
- `falukantUpdateDebt`
- `reason: 'house_seizure'`
- `falukantHouseUpdate`
- `falukantUpdateStatus`
- `falukantUpdateFamily`
- `reason: 'daily'`
### 6.5 Niederlassungen
Wenn weiter nicht gedeckt:
- Niederlassungen schließen
- zuerst niedrige Stufe / niedriger Wert
- Hauptniederlassung nur als letzter Schritt
Events:
- `falukantUpdateDebt`
- `reason: 'branch_closure'`
- `falukantBranchUpdate`
- `falukantUpdateStatus`
## 7. Laufende soziale Folgen im Schuldturm
Solange `status = 'imprisoned'`:
- täglicher Reputationsmalus
- Empfehlung: `-2`
- zusätzliche `creditworthiness_penalty += 1` pro Tag
- `marriage_satisfaction -= 1`
- `household_tension_score += 2`
Wenn aktive Liebschaften bestehen:
- `affection -= 2`
- bei niedriger Zuneigung oder hoher Sichtbarkeit kann Beziehung enden
Empfohlene Absprungregel:
- wenn `affection <= 30` oder `months_underfunded >= 2`
- Chance auf Beziehungsende prüfen
- bei repräsentativen Beziehungen zusätzlich höhere Absprungchance, wenn `public_known = true`
Events bei sozialen Folgewirkungen:
- `falukantUpdateFamily`
- `reason: 'daily'`
- zusätzlich `falukantUpdateStatus`
## 8. Kreditwürdigkeit
Die UI rechnet bereits aus `creditworthiness_penalty` und Status einen sichtbaren Wert.
Der Daemon muss pflegen:
- `creditworthiness_penalty`
- `status`
- `days_overdue`
Empfehlung:
- Eintritt Schuldturm: `+45`
- pro weiterem Hafttag: `+1`
- Hauspfändung: zusätzlich `+10`
- Niederlassungsschließung: zusätzlich `+8`
## 9. Freilassung
Freilassung, wenn:
- keine relevante Restschuld mehr offen ist
oder
- ein definierter Restwert unterschritten wird, falls ihr einen Bagatellgrenzwert wollt
Dann:
- `status = 'released'`
- `released_at = now()`
- `next_forced_action = null`
- `days_overdue = 0`
- `remaining_debt = 0`
Events:
- `falukantUpdateDebt`
- `reason: 'debtors_prison_released'`
- `falukantUpdateStatus`
- `falukantUpdateFamily`
- `reason: 'daily'`
- `falukantHouseUpdate`
- `falukantBranchUpdate`
Keine automatische vollständige soziale Heilung:
- Reputation bleibt reduziert
- Kreditwürdigkeit bleibt reduziert
- Familie/Haus bleiben in Folgezuständen
## 10. Event-Kommunikation zur UI
Der Daemon sendet als Primärevent:
```json
{
"event": "falukantUpdateDebt",
"user_id": 123,
"reason": "delinquency"
}
```
Mögliche `reason`:
- `delinquency`
- `debtors_prison_entered`
- `asset_seizure`
- `vehicle_liquidation`
- `house_seizure`
- `branch_closure`
- `debtors_prison_released`
### 10.1 Begleitevents
Je nach Folge zusätzlich:
- `falukantUpdateStatus`
- `falukantHouseUpdate`
- `falukantBranchUpdate`
- `falukantUpdateFamily`
### 10.2 Empfohlene Minimalregeln
- `delinquency`:
- `falukantUpdateDebt`
- `falukantUpdateStatus`
- `debtors_prison_entered`:
- `falukantUpdateDebt`
- `falukantUpdateStatus`
- `falukantUpdateFamily`
- `falukantHouseUpdate`
- `falukantBranchUpdate`
- `asset_seizure`:
- `falukantUpdateDebt`
- `falukantUpdateStatus`
- optional `falukantBranchUpdate`
- `vehicle_liquidation`:
- `falukantUpdateDebt`
- `falukantUpdateStatus`
- `house_seizure`:
- `falukantUpdateDebt`
- `falukantUpdateStatus`
- `falukantHouseUpdate`
- `falukantUpdateFamily`
- `branch_closure`:
- `falukantUpdateDebt`
- `falukantUpdateStatus`
- `falukantBranchUpdate`
- `debtors_prison_released`:
- `falukantUpdateDebt`
- `falukantUpdateStatus`
- `falukantUpdateFamily`
- `falukantHouseUpdate`
- `falukantBranchUpdate`
## 11. Idempotenz
Der Worker muss idempotent arbeiten.
Wichtig:
- Eintritt in den Schuldturm nicht mehrfach für denselben aktiven Fall auslösen
- Verwertungsschritte nur einmal je Asset anwenden
- `released` nicht erneut freisetzen
Empfehlung:
- pro Tick Transaktion
- pro Nutzer eine klare Reihenfolge
- Änderungen in `assets_seized_json` protokollieren
## 12. Mindestumsetzung für Version 1
Pflicht:
1. Verzugstage pflegen
2. Eintritt nach 3 Tagen
3. Status und Penalty schreiben
4. Geld zuerst einziehen
5. danach Fahrzeuge
6. Events senden
Danach:
7. Hauspfändung
8. Niederlassungsschließung
9. volle Familienfolgen
## 13. Hinweis an den Daemon
Die projektseitigen Grundlagen sind bereits umgesetzt:
- `debtors_prism` ist erweitert
- Bank-/Haus-/Familien-/Übersichts-UI reagiert auf den Status
- aktive Falukant-Aktionen werden im Backend bereits gesperrt, sobald `inDebtorsPrison = true`
Der Daemon muss daher vor allem die Zustände und Folgen zuverlässig schreiben und die dokumentierten Events senden.