# Model ekonomii

Plik `Ekonomia_Projektu_2_0_model_bota_Discord.xlsx` opisuje znacznie większy
system niż zwykły sklep z losowym modyfikatorem ceny.

## Arkusze źródłowe

| Arkusz | Odpowiedzialność |
|---|---|
| `Konfiguracja` | Tydzień symulacji i parametry globalne |
| `Słowniki` | Wartości słownikowe i statusy |
| `Węzły` | Lokacje gospodarcze, ludność, bezpieczeństwo i infrastruktura |
| `Towary` | Towary, jednostki, ceny bazowe, psucie i legalność |
| `Wpływy` | Zdarzenia zmieniające podaż, popyt, transport i ceny |
| `Firmy` | Firmy graczy, frakcji, NPC i ich majątek |
| `Receptury` | Łańcuchy produkcji i wymagane zasoby |
| `Produkcja` | Tygodniowa produkcja i zużycie surowców |
| `Przepływy` | Transport, koszty, ryzyko, straty i dostawy |
| `Rynek` | Zapasy, konsumpcja, indeks cen i stan rynku |
| `Kontrakty` | Umowy handlowe, terminy, dostawy i kary |
| `Dashboard` | Raporty i metryki ekonomii |
| `Bot_Discord` | Docelowe komendy i raporty dla Discorda |

## Komendy modelu

Arkusz `Bot_Discord` przewiduje następującą powierzchnię komend:

```text
/rynek miejsce
/towar nazwa
/przeplyw towar
/firma nazwa
/kontrakty
/wplywy
/raport_gospodarczy
/produkcja ustaw
/transport zamow
```

Są one obecnie zarejestrowane jako komendy-wydmuszki. Ich uprawnienia i zakres
danych zostaną doprecyzowane po ustaleniu, które operacje są dostępne dla
graczy, właścicieli firm i administratorów.

## Mapowanie na bazę

Migracja `migrations/006_economy_model.sql` przygotowuje tabele:

- `economy_nodes`, `economy_goods`, `economy_influences`;
- `economy_companies`, `economy_recipes`, `economy_production_runs`;
- `economy_flows`, `economy_market_snapshots`, `economy_contracts`;
- `economy_ticks`.

Migracja nie uruchamia jeszcze symulacji. Formuły z Excela powinny zostać
przeniesione do testowalnych funkcji Economy Service, a nie kopiowane jako
nieprzejrzane formuły SQL.

## Aktualny stan

Economy Service ma już granicę HTTP, ledger zakupów, idempotencję, health check
i dashboard metryk. Endpoint zakupu jest przejściowym adapterem istniejącego
modelu postaci. Nie należy traktować obecnego wzoru ceny jako finalnego modelu
rynku z Excela.

Kolejny etap powinien zacząć się od implementacji tygodniowego ticka:

1. aktywacja wpływów dla tygodnia;
2. produkcja firm;
3. rozliczenie przepływów i strat;
4. konsumpcja i zapasy;
5. wyliczenie indeksów i cen;
6. zapis `economy_market_snapshots`;
7. publikacja raportu przez akcję dla Gatewaya.

## Implementacja v1: formuły referencyjne

Pierwsza implementacja znajduje się w:

```text
apps/economy/src/economy/models.py
apps/economy/src/economy/formulas.py
apps/economy/src/economy/reference_week_18.py
```

Formuły są czystymi funkcjami i używają `Decimal`, dzięki czemu nie zależą od
bazy, HTTP, Discorda ani aktualnego czasu. Wersja v1 nie wykonuje jeszcze
automatycznego ticka i nie zmienia danych produkcyjnych.

### Produkcja

```text
staffing = workers / max_workers
infrastructure = node.infrastructure / 100
security = node.security / 100
limiting_factor = min(staffing, resource_availability, tools,
                      infrastructure, security)
output = max(0, base_output * company_level * limiting_factor
                * (1 + active_supply_influence))
```

### Przepływ

```text
route_security = min(source.security, destination.security)
loss_rate = max(0, (100 - route_security) / 200
                   + max(0, transport_modifier))
lost = planned_quantity * loss_rate       # tylko dla statusu Dostarczony
delivered = max(0, planned_quantity - lost)
```

### Rynek i cena

```text
spoilage = (opening_stock + player_production + other_production + deliveries)
           * spoilage_per_week

closing_stock = max(0, opening_stock + player_production + other_production
                       + deliveries - population_consumption
                       - company_consumption - shipments - spoilage)

shortage = max(0.25, min(4, target_reserve / max(closing_stock, 1)))
risk = 1 + ((100 - node.security) / 100 * risk_sensitivity)
tax = 1 + node.tax_rate

price_index = clamp(
    100 * (1 + shortage_sensitivity * (shortage - 1))
        * risk * tax * (1 + active_price_influence),
    min_price_index,
    max_price_index,
)
current_price = base_price * price_index / 100
```

### Wynik referencyjny tygodnia 18

Uruchomienie:

```bash
python3 scripts/run_economy_reference.py
```

Dla danych `F_WOLF`, `FL_001` i `N_SAER/G_RATIONS` wynik powinien być zgodny
z Excelem:

```text
production F_WOLF/G_LUMBER: 8.40
flow FL_001 delivered: 6.200
market N_SAER/G_RATIONS index: 220.689409...
market N_SAER/G_RATIONS price: 48.551670...
market N_SAER/G_RATIONS state: Załamanie
```

Testy referencyjne są w `tests/test_economy_formulas.py`. Każda zmiana formuł
powinna najpierw przejść te testy, a dopiero potem zostać podłączona do
automatycznego ticka i danych administracyjnych.
