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:
447
docs/FALUKANT_DEBTORS_PRISON_DAEMON_SPEC.md
Normal file
447
docs/FALUKANT_DEBTORS_PRISON_DAEMON_SPEC.md
Normal 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.
|
||||
Reference in New Issue
Block a user