# 🎮 Logic Spec 80: Gamification 2.0, Verseny és Önvédelmi Rendszer

**Verzió:** 1.0  
**Dátum:** 2026-03-15  
**Szerző:** Rendszer-Architect  
**Kapcsolódó mérföldkő:** [MILESTONE_8_GAMIFICATION_PRO.md](../MILESTONE_8_GAMIFICATION_PRO.md)

## 🎯 Modul célja és Masterbook 2 illeszkedés

### Cél
A Gamification 2.0 modul kiterjeszti a meglévő XP‑ és szintrendszert szezonális versenyekkel, önvédelmi mechanizmusokkal és egy robusztus moderációs keretrendszerrel. A modul biztosítja, hogy a felhasználók által beküldött szervizadatok biztonságosan, ellenőrzött módon kerüljenek a productionba, miközben a spam és rosszindulatú tevékenységeket automatikusan szűri.

### Masterbook 2 illeszkedés
- **Epic 7: Marketplace & API (A Külvilág felé)** – A szervizek publikálása és a marketplace minőségbiztosítása.
- **Epic 5: Robot Ecosystem** – A service robot pipeline (0–4) hibáinak kijavítása és kiegészítése.
- **Epic 3: Identity & Social** – Felhasználói reputáció, trust score és büntetési rendszer.

## 🗄️ Adatmodell

### 1. Season tábla (`system.seasons`)
Féléves versenyek tárolása. Minden szezonhoz tartozik egy ranglista, amely a szezonban szerzett XP alapján rangsorol.

| Mező | Típus | Leírás |
|------|-------|---------|
| `id` | `INTEGER` (PK) | Egyedi azonosító |
| `name` | `VARCHAR(100)` | Szezon neve (pl. "2026 Tavasz") |
| `start_date` | `DATE` | Szezon kezdete |
| `end_date` | `DATE` | Szezon vége |
| `is_active` | `BOOLEAN` | Aktív szezon? (egyidőben legfeljebb egy lehet) |
| `created_at` | `TIMESTAMPTZ` | Létrehozás időbélyege |

**Indexek:**
- `idx_seasons_active` (`is_active`) WHERE `is_active = TRUE`
- `idx_seasons_dates` (`start_date`, `end_date`)

**Alembic terv:**
```sql
CREATE TABLE system.seasons (
    id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    start_date DATE NOT NULL,
    end_date DATE NOT NULL,
    is_active BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE UNIQUE INDEX idx_seasons_active_unique 
ON system.seasons (is_active) WHERE is_active = TRUE;
```

### 2. UserContribution tábla (`gamification.user_contributions`)
Spam védelem: minden felhasználó csak 90 naponként kaphat XP‑t ugyanazon szerviz (fingerprint) beküldéséért.

| Mező | Típus | Leírás |
|------|-------|---------|
| `id` | `INTEGER` (PK) | Egyedi azonosító |
| `user_id` | `INTEGER` | `identity.users.id` hivatkozás |
| `service_fingerprint` | `VARCHAR(255)` | A beküldött szerviz hash‑je (MD5) |
| `action_type` | `VARCHAR(30)` | `submit_service`, `claim_business`, `review` |
| `earned_xp` | `INTEGER` | Az adott akcióért kapott XP |
| `cooldown_end` | `TIMESTAMPTZ` | Cooldown vége (90 nap a `submit_service` esetén) |
| `created_at` | `TIMESTAMPTZ` | Létrehozás időbélyege |

**Indexek:**
- `idx_user_contributions_user` (`user_id`, `service_fingerprint`, `action_type`)
- `idx_user_contributions_cooldown` (`cooldown_end`) WHERE `cooldown_end > NOW()`

**Alembic terv:**
```sql
CREATE TABLE gamification.user_contributions (
    id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    user_id INTEGER NOT NULL REFERENCES identity.users(id) ON DELETE CASCADE,
    service_fingerprint VARCHAR(255) NOT NULL,
    action_type VARCHAR(30) NOT NULL,
    earned_xp INTEGER NOT NULL DEFAULT 0,
    cooldown_end TIMESTAMPTZ NOT NULL,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

COMMENT ON TABLE gamification.user_contributions IS 
'Spam védelem: felhasználók csak 90 naponként kaphatnak XP‑t ugyanazon szerviz beküldéséért.';
```

### 3. UserStats bővítés (`system.user_stats`)
A meglévő táblához új mezők a restrikciós szintek és büntető kvóták kezeléséhez.

| Mező | Típus | Leírás | Alapérték |
|------|-------|--------|-----------|
| `restriction_level` | `INTEGER` | 0 (normál), -1 (figyelmeztetés), -2 (korlátozott), -3 (banned) | 0 |
| `penalty_quota_remaining` | `INTEGER` | Hátralévő büntető kvóta (pl. 3 strike) | 3 |
| `banned_until` | `TIMESTAMPTZ` | Kitiltás vége (ha restriction_level = -3) | NULL |

**Alembic terv (meglévő tábla módosítása):**
```sql
ALTER TABLE system.user_stats
ADD COLUMN restriction_level INTEGER NOT NULL DEFAULT 0,
ADD COLUMN penalty_quota_remaining INTEGER NOT NULL DEFAULT 3,
ADD COLUMN banned_until TIMESTAMPTZ;
```

### 4. ServiceStaging bővítés (`marketplace.service_staging`)
Hiányzó mezők hozzáadása a teljes adatátvitel érdekében.

| Mező | Típus | Leírás |
|------|-------|---------|
| `contact_phone` | `VARCHAR` | Telefonszám (Robot 4 vagy user által megadható) |
| `website` | `VARCHAR` | Weboldal URL |
| `external_id` | `VARCHAR` | Külső rendszer azonosító (pl. Google Place ID) |
| `contact_email` | `VARCHAR` | E‑mail cím |

**Alembic terv:**
```sql
ALTER TABLE marketplace.service_staging
ADD COLUMN contact_phone VARCHAR,
ADD COLUMN website VARCHAR,
ADD COLUMN external_id VARCHAR,
ADD COLUMN contact_email VARCHAR;
```

### 5. SystemParameter bővítés (`system.system_parameters`)
Dinamikus küszöbértékek a gamification és moderáció számára.

| Kulcs | Érték (JSON) | Leírás |
|-------|--------------|---------|
| `service_promotion_threshold` | `{"trust_score": 50}` | Minimális trust_score a staging → promotionhoz |
| `xp_reward_base` | `{"submit_service": 50, "claim_business": 200}` | Alap XP jutalmak |
| `penalty_multiplier` | `{"level_-1": 0.5, "level_-2": 0.2}` | XP szorzó restrikciós szint szerint |
| `strike_policy` | `{"max_strikes": 3, "cooldown_days": 90}` | Strike‑ok és cooldown beállítások |

**Megjegyzés:** A meglévő tábla módosítása nem szükséges, csak új rekordok beszúrása.

## 🛡️ Admin kontroll: Global/Country/Region/User szintű változók

A `system.system_parameters` tábla `scope` mezője (`global`, `country`, `region`, `user`) lehetővé teszi a különböző szintű beállításokat. A Gamification 2.0 paraméterei alapértelmezetten `global` scope‑kal rendelkeznek, de felülírhatók country vagy region szinten (pl. különböző országokban eltérő trust_score küszöb).

**Példa a hierarchiára:**
1. **Global:** `service_promotion_threshold = 50`
2. **Country (HU):** `service_promotion_threshold = 40` (lazább feltételek Magyarországon)
3. **Region (Budapest):** `service_promotion_threshold = 60` (szigorúbb Budapesten)

A prioritás: `user` > `region` > `country` > `global`.

## 🤖 Robot Refactoring Tervek

### 1. Robot 3 (Enricher) – Logika finomhangolása
**Jelenlegi állapot:** `enrich_ready` → `researched` (trust_score növelés).
**Új állapot:** `enrich_ready` → `auditor_ready` (trust_score növelés, de nem publikál).

**Módosítások:**
- A státusz neve `auditor_ready` legyen, jelezve, hogy az Auditor feldolgozhatja.
- A trust_score számítás változatlan marad.
- A robot továbbra is csak a `service_staging` táblát módosítja.

### 2. Robot 2 (Auditor) – Új implementáció
**Fájl:** `service_robot_5_auditor.py` (vagy `service_robot_2_auditor.py`)
**Feladat:** Atom módon feldolgozza az `auditor_ready` státuszú staging bejegyzéseket.

**Lépések:**
1. **Kiválasztás:** `FOR UPDATE SKIP LOCKED` egy `auditor_ready` rekordra.
2. **Küszöb ellenőrzés:** Lekéri a `service_promotion_threshold` értékét a `system_parameters`‑ből.
3. **Döntés:**
   - Ha `trust_score >= küszöb`:
     - Organization létrehozása (ha még nem létezik) a `fleet.organizations` táblában.
     - ServiceProfile létrehozása a `marketplace.service_profiles` táblában, a staging adatokkal.
     - Státusz beállítása `pending_validation` (vagy `active`, ha azonnal publikálható).
     - Audit log rögzítése (`audit.service_audit_log`).
   - Egyébként:
     - Státusz beállítása `needs_moderation`.
     - InternalNotification létrehozása a moderátorok számára.
4. **Staging frissítés:** Státusz `audited`, `audited_at` időbélyeg.

**Technikai részletek:**
- Tranzakció használata (minden lépés egy tranzakcióban).
- Hibakezelés: hiba esetén `status = 'error'` és logolás.
- Időzítés: folyamatos feldolgozás (pl. 30 másodperces ciklus).

### 3. Robot 4 (Validator) – Integráció
A Validator továbbra is a `service_profiles` táblán dolgozik, de ha a rekord `pending_validation` státuszú, a Validator frissítheti a hiányzó mezőket (contact_phone, website) a Google Places API‑ból, majd átállítja `active`‑ra.

## 🔧 SystemParameter integráció

A Gamification 2.0 minden dinamikus értékét a `system.system_parameters` táblából olvassa ki. Ez lehetővé teszi a rendszer finomhangolását anélkül, hogy kódot kellene módosítani.

**Példa lekérdezésre:**
```python
async def get_promotion_threshold(db):
    param = await db.scalar(
        select(SystemParameter)
        .where(SystemParameter.key == 'service_promotion_threshold')
        .where(SystemParameter.scope == 'global')
    )
    if param:
        return param.value.get('trust_score', 50)
    return 50
```

## 📝 Geo‑logika (Service Finder algoritmus)

A Service Finder alapvetően lokáció‑alapú keresést valósít meg. A Gamification 2.0 nem módosítja a keresési algoritmust, de befolyásolja a találatok minőségét:
1. **Trust Score súlyozás:** Magasabb trust_score‑ú szervizek magasabbra kerülnek a találati listában.
2. **Szezonális bónusz:** Aktív szezonban beküldött szervizek extra láthatóságot kaphatnak.
3. **Restrikciók:** `restriction_level < 0` esetén a felhasználó beküldései nem jelennek meg, amíg a korlátozás fennáll.

## 🚀 Migrációs lépések (Alembic)

1. **Új táblák létrehozása:**
   - `system.seasons`
   - `gamification.user_contributions`
2. **Meglévő táblák bővítése:**
   - `system.user_stats` (új mezők)
   - `marketplace.service_staging` (hiányzó mezők)
3. **Alapértelmezett paraméterek beszúrása:**
   - `service_promotion_threshold`, `xp_reward_base`, `penalty_multiplier`, `strike_policy`
4. **Robot kód frissítése:**
   - Robot 3 státusz átnevezése `auditor_ready`‑re.
   - Robot 5 (Auditor) implementálása.
   - Robot 4 integrációja a `pending_validation` státusszal.

## ✅ Jóváhagyási pont

Ez a logic specifikáció a Modell Fázis (Foundation) teljes tervét tartalmazza. A következő lépés a tervek implementálása a Code módban. **Állj meg és kérj jóváhagyást a felhasználótól, mielőtt továbblépsz.**

---
*Ez a dokumentum a `/plans` könyvtárban található, és a 8. mérföldkő technikai specifikációjaként szolgál.*