# Jogosultság-modell és `authorization.json` — konszolidált referencia

**Dokumentum-típus:** konszolidált specifikációs referencia (fejlesztői, Claude Code-barát)
**Modul:** Szerver → jogosultság-érvényesítés
**Verzió:** v1.1
**Dátum:** 2026.05.20
**Cél olvasó:** senior fejlesztő + Claude Code
**Repó-hely (SD-33):** `urbino-docs` → `30_szerver/05_jogosultsag_es_authorization.md`

> **Mire való ez a fájl.** A `05_jogosultsagok_v2.md` akció-szintű funkcionális
> mátrixát egyetlen helyre vonja össze, `authorization.json`-szintű
> route→szerepkör leképezésként. Ez a **konszolidált referencia**: a Claude Code
> innen látja a teljes route→szerepkör képet egyetlen táblából, miközben minden
> route megtartja az egyetlen kanonikus forrását a feature-specjében.
>
> **Mi NEM ez.** Nem önálló feature-spec, és **nem a tényleges `authorization.json`
> fájl.** A jogosultság-érvényesítés *mechanikáját* (kétrétegű érvényesítés,
> prefix-konvenció, middleware-feloldás) az `01_kozos_mintak.md` 3.3–3.5 már
> teljesen rögzítette — ez a fájl arra **hivatkozik**, nem ismétli. A 23 lefedett
> route definíciója a forrás-feature-specekben él (`10` 3.8, `20_dup` 3.5,
> `20_felhasznalokezeles` 3.8); ez a fájl **összegzi és hivatkozza** őket, nem
> másolja át a `jsonc`-blokkjaikat.
>
> **Miért referencia, és nem feature-spec.** A felfedezési kör megállapította:
> a feature gerincét (a mechanika, a `TenantRole` enum, a `vezető`-reláció
> leképezési elve) az `01_kozos_mintak.md` 3.5 már lefedte; egy önálló
> feature-spec ezt csak ismételné. A kör valódi hézaga az volt, hogy nincs
> *egyetlen, teljes* route→szerepkör nézet — ezt adja ez a fájl.

---

## 0. Funkcionális alap

### 0.1 A feature-t fedő dokumentumok

| Dokumentum | Mit ad ehhez a referenciához |
|---|---|
| `05_jogosultsagok_v2.md` 1–7. | **A fő funkcionális bemenet.** Négy szerepkör (1.), akció-szintű mátrix kilenc csoportban (2.1–2.9), negatív leltár (3.), landing-logika (4.). |
| `01_kozos_mintak.md` 3.2–3.5 | **A platform-minta — kész.** SD-7 (kódbeli szerepkör-nevek), `authorization.json` prefix-konvenció (3.3), permission-kulcs elvetése (3.4), a kétrétegű érvényesítés platform-mintája (3.5). |
| `00_architektura_v4.md` 2.1–2.3, 3.2–3.3 | Szerepkör-viszonyok, a `vezető ⊇ diszpécser ÉS ⊇ tartalomkezelő` reláció, a teljes URL-fa. |
| `90_sitemap_v3.md` 3. | A nézet-szintű jogosultság-térkép — "melyik nézeten ki mit tehet". |
| `10_bejelentes_lista_es_adatlap.md` 3.8 | A bejelentés-gerinc 23-ból 15 route-jának kanonikus leképezése. |
| `20_duplikacio_es_osszevonas.md` 3.5 | A `similar`/`merge` route-ok leképezése (prefix-hibával — lásd VF-J1). |
| `20_felhasznalokezeles.md` 3.8 | A felhasználókezelés hat route-jának leképezése. |
| `CLAUDE.md` | A Claude Code hézag-feloldási és jogosultság-kezelési szabályai. |

### 0.2 Érintett kanonikus döntések

K-016 (a pilot durva szemcse — szerepkör-szintű jogosultság, nincs finomítás),
K-024 (a super-admin külön Urbino-admin felület), K-025 (implicit unió
szerepkör-modell), K-027 (szerepkör-érzékeny landing), K-038 (tartalomkezelő
mint harmadik pilot-szerepkör), K-039 (a GYIK Urbino-hatáskör).

### 0.3 Mit döntött már el a funkcionális és a specifikációs réteg

Röviden, hivatkozással — nem ismételve:

- **A teljes pilot-jogosultság-kép** — a `05_jogosultsagok_v2.md` 2. szakasza
  akció-szinten kész, mind a négy szerepkörre. A `05` 5. szerint ez
  *"a teljes pilot-jogosultság-kép"*.
- **A jogosultság-érvényesítés mechanikája** — az `01_kozos_mintak.md` 3.5
  rögzíti a kétrétegű érvényesítést, a prefix-konvenciót, a `TenantRole` enumot
  és a token-érvényesség kezelését.
- **A kódbeli szerepkör-nevek** — SD-7: `dispatcher`, `manager`,
  `content_manager`, `field_worker`.

### 0.4 Mit tölt ki EZ a referencia

- A `05` mind a kilenc akció-csoportjának egyetlen **traceability-mátrixba**
  vonása (4.2).
- A négy le nem fedett modul **szerepkör-szabályának** rögzítése, a
  route-stringre megtartott-hiány-jelöléssel (4.3).
- Négy **elhatárolás**, amit a route-szabály önmagában nem fejez ki (4.4).

---

## 1. Cél és hatókör

### 1.1 Cél

A platform jogosultság-érvényesítésének egyetlen összegző nézete. Üzleti
értéke közvetlen: a pilot indulásakor (T0) a fejlesztők egyetlen táblából
látják, mely API-végpontot mely tenant-szerepkör hívhat, és gépiesen
ellenőrizhetik, hogy a `vezető`-reláció sehol nem csorbult. A feature
T0-kritikus — a manager felület újraírása erre vár.

### 1.2 Hatókörön kívül (ennél a referenciánál)

- A jogosultság-érvényesítés **mechanikája** — az `01_kozos_mintak.md` 3.5
  dolga; ez a fájl arra hivatkozik.
- A 23 lefedett route **definíciója** — a forrás-feature-specekben él; ez a
  fájl összegzi, nem definiálja újra.
- A **polgári mobilapp** jogosultság-/auth-modellje — a polgár nem
  tenant-szerepkörrel lép be; külön kérdés, külön dokumentumban (NY-J1).
- A **tényleges, generált `authorization.json` fájl** — iterációs elem, lásd
  8.1; a pilotra a traceability-mátrix a konszolidáció hordozója.

---

## 2. Domain-modell

### 2.1 Új/módosított entitások

**Új entitás: nincs. Új mező: nincs. Új kapcsolat: nincs.**

Ez a referencia leképezési és összegző réteg — nem vezet be domain-elemet. A
jogosultsághoz tartozó összes domain-elem már létezik:

| Domain-elem | Hol él | Bevezette |
|---|---|---|
| `TenantRole` enum (`dispatcher`, `manager`, `content_manager`, `field_worker`) | `00_domain_model.md` | `01_kozos_mintak.md` 3.5 (SD-7) |
| `UserTenantRole` (`User ↔ Tenant` kötés szerepkörrel) | `00_domain_model.md` 3.3 | `20_felhasznalokezeles.md` |
| `TenantUser.roles[]` (szerepkör-replika a Tenant DB-ben) | `00_domain_model.md` | `01_kozos_mintak.md` 1.4, 3.2 (SD-2/SD-3) |

### 2.2 Állapotgép

**Nem releváns, mert** a jogosultság-érvényesítésnek nincs saját életciklusa —
egy route-szabálynak nincs "állapota". A jogosultság *bemenete* több
állapotgépnek (pl. a `02_globalis_allapotgep.md` `Ticket`-átmeneteinek), de
azokat a forrás-dokumentumok már formálisan rögzítették.

### 2.3 Lookup-ok, katalógus-érintettség

**Nem releváns, mert** a jogosultság szerepkör-szintű, a JWT-claimből dől el
(`01` 3.2). A `TenantRole` kódbeli enum, nem `ILookupProvider`-rel kiszolgált
lookup; nincs default-katalógus-érintettség.

### 2.4 A route-kiértékelés OR-szemantikája

Egyetlen modell-szintű elemet rögzíteni kell, mert a 4. szakasz erre épül:

> **A route-kiértékelés OR-szemantikája.** Az `authorization.json` egy
> route-szabálya egy `roles`-**listát** ad. A kiértékelés **OR**: a kérés
> *engedélyezett*, ha a kérő JWT-jének szerepkör-claimjei közül **legalább egy**
> szerepel a `roles`-listában. Nincs AND-feltétel, nincs szerepkör-prioritás.
>
> Ez **nem új döntés** — a meglévő `authorization.json`-minta viselkedése
> (`project_backend` CLAUDE.md, `01_kozos_mintak.md` 3.3). Azért kell mégis
> kimondani, mert ez teszi a **K-025 implicit unió-modellt route-szinten
> ingyenessé**: egy `dispatcher` + `content_manager` felhasználó mindkét
> szerepkört a JWT-ben hordozza, és az OR-kiértékelés miatt minden olyan
> route-ot elér, amelynek listájában *bármelyik* szerepköre szerepel —
> uniókezelő logika nélkül.

---

## 3. Szerver — API és logika

### 3.1 Mi standard, mi a referencia tárgya

**A jogosultság-érvényesítés mechanikája standard — eltérés nincs.** A
kétrétegű érvényesítés (route-szintű `authorization.json` + objektum-szintű
`(saját)`-szűrés), a `tenant_`-prefix-konvenció, a middleware-feloldás, a
`vezető`-reláció felsorolásos leképezésének *elve* — mind az
`01_kozos_mintak.md` 3.3–3.5-ben él. Ez a fájl azt nem írja újra.

A referencia tárgya három dolog: a traceability-mátrix (3.2), a hézagos
modulok szerepkör-szabálya (3.3), és négy elhatárolás (3.4).

### 3.2 Traceability-mátrix — a `05` akció-mátrix teljes route-leképezése

A mátrix a `05_jogosultsagok_v2.md` minden akció-sorát egy route-szabályra
vetíti. **Olvasata:** a "Route" a meglévő feature-spec definíciója (nem itt
születik); a "Szerepkörök" prefix-formában (`01` 3.3); a "Forrás" a route
kanonikus helye; a "Státusz" jelzi, lefedett-e vagy megtartott hiány.

A `manager` minden diszpécser- és tartalomkezelő-soron szerepel — ez a
`vezető ⊇ diszpécser ÉS ⊇ tartalomkezelő` reláció felsorolásos leképezése
(`01` 3.5). A mátrix a teljes route→szerepkör képet egy helyen adja, de minden
sor a forrás-dokumentumra mutat — leszármaztatott nézet, nem párhuzamos
igazság.

#### A — Bejelentés-gerinc (`05` 2.1–2.4) — LEFEDETT, forrás: `10` 3.8

| `05` akció | Route | Szerepkörök | Státusz |
|---|---|---|---|
| Lista, adatlap megtekintése (2.1) | `GET /v1/tickets`, `GET /v1/tickets/{id}` | `tenant_dispatcher`, `tenant_manager`, `tenant_field_worker` | ✓ — `field_worker` sor-szinten szűrt (3.4-#1) |
| Kategória / prioritás / határidő / felelős (2.2) | `PUT /v1/tickets/{id}/category` · `/priority` · `/due-date` · `/assignee` | `tenant_dispatcher`, `tenant_manager` | ✓ |
| "Triage kész — Kiosztás" (2.2) | `POST /v1/tickets/{id}/assign` | `tenant_dispatcher`, `tenant_manager` | ✓ |
| Munka megkezdése (2.3) | `POST /v1/tickets/{id}/start` | `tenant_dispatcher`, `tenant_manager`, `tenant_field_worker` | ✓ |
| Lezárás (2.3) | `POST /v1/tickets/{id}/resolve` | `tenant_dispatcher`, `tenant_manager`, `tenant_field_worker` | ✓ |
| Elutasítás (2.4) | `POST /v1/tickets/{id}/reject` | `tenant_dispatcher`, `tenant_manager` | ✓ |
| Korrekciós visszanyitás (2.4) | `POST /v1/tickets/{id}/reopen` | `tenant_dispatcher`, `tenant_manager` | ✓ |
| Felelős-váltás kiosztott ügyön (2.2) | `POST /v1/tickets/{id}/revert-to-assigned` | `tenant_dispatcher`, `tenant_manager` | ✓ |
| Belső jegyzet — olvasás (`05` 6.1) | `GET /v1/ticket-notes` | `tenant_dispatcher`, `tenant_manager`, `tenant_field_worker` | ✓ — `field_worker` olvas, nem ír |
| Belső jegyzet — írás (`05` 6.1) | `POST /v1/ticket-notes` · `PUT /v1/ticket-notes/{id}` · `DELETE /v1/ticket-notes/{id}` | `tenant_dispatcher`, `tenant_manager` | ✓ |

#### B — Duplikáció (`05` 2.5) — LEFEDETT, forrás: `20_dup` 3.5

| `05` akció | Route | Szerepkörök | Státusz |
|---|---|---|---|
| "Hasonló bejelentések" doboz (2.5) | `GET /v1/tickets/{id}/similar` | `tenant_dispatcher`, `tenant_manager` | ✓ — **prefix-hiba a forrásban, lásd VF-J1** |
| Összevonás megerősítése (2.5) | `POST /v1/tickets/{id}/merge` | `tenant_dispatcher`, `tenant_manager` | ✓ — **prefix-hiba a forrásban, lásd VF-J1** |
| Téves összevonás kézi korrekciója (`dup` 7.1) | — (a `reopen` route, lásd A-blokk) | `tenant_dispatcher`, `tenant_manager` | ✓ — nincs külön route, a `reopen`-nel azonos |

#### C — Bejelentés-létrehozás (`05` 2.6) — RÉSZBEN, megtartott hiány MH-3

| `05` akció | Route | Szerepkörök | Státusz |
|---|---|---|---|
| Manuális bejelentés-nyitás (2.6) | `POST /v1/tickets` | `tenant_dispatcher`, `tenant_manager` | **MH-3** — a route létezik, leképezése a manuális-nyitás feature-spec dolga (`10` 3.10) |

#### D — Felhasználókezelés (`05` 2.8 felhasználó-rész) — LEFEDETT, forrás: `20_felhasznalokezeles` 3.8

| `05` akció | Route | Szerepkörök | Státusz |
|---|---|---|---|
| Felhasználó-lista, -adatlap (2.8) | `GET /v1/users`, `GET /v1/users/{id}` | `tenant_manager` | ✓ |
| Meghívás-indítás (2.8) | `POST /v1/users/invite` | `tenant_manager` | ✓ |
| Felhasználó-módosítás (2.8) | `PUT /v1/users/{id}` | `tenant_manager` | ✓ |
| Deaktiválás / reaktiválás (2.8) | `POST /v1/users/{id}/deactivate` · `/reactivate` | `tenant_manager` | ✓ |
| Meghívó újraküldése (2.8) | `POST /v1/users/{id}/invitations/resend` | `tenant_manager` | ✓ |
| Meghívó beváltása | `POST /v1/users/invitations/accept` | **— (publikus)** | ✓ — token-alapú, lásd 3.4-#2 |

#### E — Dashboard és riport (`05` 2.7) — LEFEDETT, forrás: `40_riport` 3.1

A `40_riport.md` v1.0 (2026.05.20) hat új route-ot vezetett be a Dashboard
és heti riport köréhez, mind `tenant_manager`-only (Szabály-R1
érvényesítve, SD-66 az `authorization.json` 22 route-os fizetés-rendszere
a 30_beallitasok-tal együtt). A pontos route-leképezést a `40_riport`
3.1 nevezi meg.

| `05` akció | Route | Szerepkörök | Státusz |
|---|---|---|---|
| Dashboard megtekintése (2.7) | `GET /v1/dashboard` | `tenant_manager` | ✓ — forrás: `40_riport` 3.1 |
| Csapat-teljesítmény tábla, lefúrás (2.7) | `GET /v1/tickets?...` (a meglévő bejelentés-listából) | `tenant_manager`, `tenant_dispatcher` | ✓ — nem új route, szűrt nézet |
| Heti riport-lista | `GET /v1/weekly-reports` | `tenant_manager` | ✓ |
| Heti riport-adatlap | `GET /v1/weekly-reports/{id}` | `tenant_manager` | ✓ |
| Heti riport PDF-letöltése | `GET /v1/weekly-reports/{id}/pdf` | `tenant_manager` | ✓ |
| E-mail újraküldése | `POST /v1/weekly-reports/{id}/resend` | `tenant_manager` | ✓ |

#### F — Tenant-konfiguráció, nem-felhasználó rész (`05` 2.8) — LEFEDETT, forrás: `30_beallitasok` 3.5

A `30_beallitasok.md` v1.0 (2026.05.20) 22 új route-ot vezetett be a
kategória-, csoport-, tenant-alapadat-, logó- és heti riport-címzett-
kezeléshez, mind `tenant_manager`-only (Szabály-R2 érvényesítve, SD-66).

| `05` akció / route-csoport | Route | Szerepkörök | Státusz |
|---|---|---|---|
| Kategóriák kezelése | `GET/POST/PUT/DELETE /v1/categories(...)`, `POST /v1/categories/from-default`, `GET /v1/categories/available-default-roots`, `POST /v1/categories/reorder` | `tenant_manager` | ✓ — forrás: `30_beallitasok` 3.5 |
| Csoportok kezelése | `GET/POST/PUT/DELETE /v1/groups(...)`, `[ManyToManyConnection]` taglista | `tenant_manager` | ✓ |
| Tenant-alapadatok | `GET/PUT /v1/tenant-settings`, `POST/DELETE /v1/tenant-settings/logo` | `tenant_manager` | ✓ — SD-60/SD-61 minta, Core-mezőkre korlátozott írás |
| Heti riport-címzettek | `GET/POST/PUT/DELETE /v1/weekly-report-recipients(...)` | `tenant_manager` | ✓ — SD-66 közös forrás a riport-feature-nek (SD-57) |

#### G — Tartalomkezelés (`05` 2.9) — LEFEDETT, forrás: `60_tartalom` 3.1.1

A `60_tartalom.md` v1.0 (2026.05.20) **27 új route-ot** vezet be — mindegyik
`tenant_content_manager` + `tenant_manager` szerepkörrel (Szabály-R3
érvényesítve). A táblázat tematikus blokkban (News / Events / CityInfo):

| `05` akció / route-csoport | Route | Szerepkörök | Státusz |
|---|---|---|---|
| **Hír CRUD (News, 2.9)** | | | |
| Hír-lista | `GET /v1/news` | `tenant_content_manager`, `tenant_manager` | ✓ |
| Hír-adatlap | `GET /v1/news/{id}` | ua. | ✓ |
| Új hír (Draft) | `POST /v1/news` | ua. | ✓ |
| Hír szerkesztése | `PUT /v1/news/{id}` | ua. | ✓ |
| Hír törlése | `DELETE /v1/news/{id}` | ua. | ✓ — `Published`-re guard (`409 cannot_delete_published`) |
| Bulk törlés | `DELETE /v1/news/bulk` | ua. | ✓ — atomi guard |
| Borítókép feltöltése | `POST /v1/news/{id}/cover-image` | ua. | ✓ — SD-68 minta |
| Borítókép eltávolítása | `DELETE /v1/news/{id}/cover-image` | ua. | ✓ — idempotens |
| Állapot-átmenet (publikálás, visszavonás, archiválás, újrapublikálás) | `POST /v1/news/{id}/transition` | ua. | ✓ — SD-70 állapotgép |
| **Városi program CRUD (Event, 2.9)** | | | |
| Program-lista | `GET /v1/events` | ua. | ✓ |
| Program-adatlap | `GET /v1/events/{id}` | ua. | ✓ |
| Új program | `POST /v1/events` | ua. | ✓ |
| Program szerkesztése | `PUT /v1/events/{id}` | ua. | ✓ |
| Program törlése | `DELETE /v1/events/{id}` | ua. | ✓ — `Published`-re guard |
| Bulk törlés | `DELETE /v1/events/bulk` | ua. | ✓ — atomi guard |
| Borítókép feltöltése | `POST /v1/events/{id}/cover-image` | ua. | ✓ — SD-68 minta |
| Borítókép eltávolítása | `DELETE /v1/events/{id}/cover-image` | ua. | ✓ — idempotens |
| Állapot-átmenet | `POST /v1/events/{id}/transition` | ua. | ✓ — SD-70 állapotgép |
| **Városi információ CRUD (CityInfo, 2.9)** | | | |
| Lista | `GET /v1/city-infos` | ua. | ✓ |
| Adatlap | `GET /v1/city-infos/{id}` | ua. | ✓ |
| Új városi információ | `POST /v1/city-infos` | ua. | ✓ |
| Szerkesztés | `PUT /v1/city-infos/{id}` | ua. | ✓ |
| Törlés | `DELETE /v1/city-infos/{id}` | ua. | ✓ — `Published`-re guard |
| Bulk törlés | `DELETE /v1/city-infos/bulk` | ua. | ✓ — atomi guard |
| Állapot-átmenet | `POST /v1/city-infos/{id}/transition` | ua. | ✓ — SD-70 állapotgép |
| Sorrendezés | `POST /v1/city-infos/reorder` | ua. | ✓ — standard reorder-minta |
| `groupLabel` autocomplete | `GET /v1/city-info-groups` | ua. | ✓ — SD-71 distinct-lookup |

**A `manager` minden soron szerepel** a `vezető ⊇ tartalomkezelő` reláció
miatt (`01` 3.5, K-038). Az `authorization.json`-bejegyzés mind a 27
route-on pontosan ezt a `roles`-listát adja:
`["tenant_content_manager", "tenant_manager"]`.

#### Lefedettségi összegzés

A `05` kilenc csoportjából **nyolc teljesen lefedett** (2.1–2.5, 2.7, 2.8,
2.9 — 50 route, ebből 23 a bejelentés-gerinc, plusz 27 a `60_tartalom`), **egy
másik feature-re tartozik** (2.6 → MH-3 a manuális bejelentés-nyitás). **A
korábbi három hézag (2.7, 2.8 nem-felhasználó-rész, 2.9) mindegyike
lezárult** a `40_riport.md` (v1.0), `30_beallitasok.md` (v1.0) és
`60_tartalom.md` (v1.0) feature-specek megjelenésével. A
szerepkör-hozzárendelés mind a kilenc csoportra **kész és determinisztikus**;
az MH-1 megtartott hiány teljesen lezárult.

### 3.3 A hiányzó modulok szerepkör-szabálya — a determinisztikus rész

Bár a route-stringek MH-1 alatt nyitottak, a referencia **kötelező szabályt**
rögzít, amit a `40_riport`/`50_konfig`/`60_tartalom` feature-specnek követnie
kell, amikor a route-jait megírja:

> **Szabály-R1 (riport / Dashboard).** Minden `40_riport`-modul route
> `roles`-listája: `["tenant_manager"]`. A Dashboard és a riport `05` 2.7
> szerint vezető-only — a `dispatcher` és a `content_manager` nem fér hozzá.
>
> **Szabály-R2 (tenant-konfiguráció).** Minden `50_konfig`-modul route
> `roles`-listája: `["tenant_manager"]`. A kategória-, csoport- és
> tenant-alapadat-kezelés `05` 2.8 szerint vezető-only.
>
> **Szabály-R3 (tartalom).** Minden `60_tartalom`-modul route `roles`-listája:
> `["tenant_content_manager", "tenant_manager"]`. A `manager` a
> `vezető ⊇ tartalomkezelő` reláció miatt szerepel (`01` 3.5). A `dispatcher`
> és a `field_worker` nem fér a tartalmi route-okhoz.

Ezek a szabályok **gépiesen ellenőrizhetők**: amikor a három feature-spec
elkészül, a route-leképezésüknek pontosan ezt a `roles`-mintát kell adnia. Ha
eltérnek, az ütközés a `05` mátrixszal — megállást kíván.

### 3.4 Elhatárolások — amit a route-szabály önmagában nem fejez ki

Négy dolog, amit a Claude Code a route-szabályból félreolvasna, ha a
referencia nem mondja ki:

**#1 — A `field_worker` `(saját)`-korlátja sor-szintű, nem route-szintű.** A
`05` 2.1/2.3 `(saját)` jelölése: a terepi dolgozó a `GET /v1/tickets`-et
*hívhatja* (a route engedi), de csak a hozzá rendelt ügyeket kapja vissza, és
idegen ügy `id`-jára `404`. Ezt a **lekérdezés-predikátum** adja, nem az
`authorization.json` (`01` 3.5 második rétege). A `10` 3.8 ezt a `Ticket`-re
már rögzítette.

**#2 — Az `accept`-végpont publikus — explicit jelölés kötelező.** A
`POST /v1/users/invitations/accept` az egyetlen ismert admin-oldali route,
amely **autentikáció nélkül** elérhető: a meghívott felhasználónak még nincs
JWT-je, a token maga az azonosítás (`20_felhasznalokezeles` 3.8). Az
`authorization.json` default szabálya "auth kell" — ezért ezt a route-ot
**explicit publikus-jelöléssel** kell kivenni, különben a beváltás lehetetlen.

**#3 — A cross-tenant izoláció nem `authorization.json`-kérdés.** A rossz
`Tenant` headerrel érkező kérés a **middleware-ben** bukik el (`403`/`404`),
mielőtt a route-szabály egyáltalán kiértékelődne (`01` 3.5, SD-12). A
route-szabály a *szerepkört* ellenőrzi; a tenant-izolációt a
tenant-resolution middleware adja, a fizikai DB-szeparációval. A cross-tenant
kísérlet naplózott biztonsági esemény (SD-13).

**#4 — A `DELETE` és a bulk-műveletek: a route hiánya = `403`.** A
`BaseController` kínál `delete`/`bulk-delete`/`reorder` végpontot, de ahol egy
entitás nem törölhető, ott a route **egyszerűen nincs** az
`authorization.json`-ban → a default "auth kell, de nincs engedélyező szabály"
→ `403` (`10` 3.10). A `Ticket` és a `User` `DELETE`-je tiltott (`10` 3.10,
`20_felhasznalokezeles` SD-39). A hézagos moduloknál (kategória, csoport,
hír…) viszont nem tudható, mi törölhető és mi csak archiválható — megtartott
hiány MH-2.

### 3.5 Validáció

**Nem releváns, mert** ennek a referenciának nincs request body-ja, nincs
felhasználói beviteli mezeje. A jogosultsághoz tartozó egyetlen felhasználói
bevitel a meghívó-űrlap szerepkör-választója (`roles: TenantRole[]`), és annak
FluentValidation-szabályát a `20_felhasznalokezeles` 3.6 már rögzítette
(legalább egy elem, SD-38, duplikátummentes, érvényes enum-érték).

### 3.6 Multi-tenancy érvényesítés

**Standard — eltérés nincs.** A tenant-resolution a middleware-ben (`01` 2.1,
SD-6); a route-szabályok a `tenant_`-prefixet használják, a middleware fűzi
hozzá a `Tenant` header kódját futásidőben (`01` 3.3). A cross-tenant kísérlet
kezelése a 3.4-#3 szerint.

### 3.7 Audit és naplózás

**Részben standard.** A jogosultság-érvényesítés maga nem termel
feature-specifikus naplót. Egy elem nem standard, de már rögzített: a
cross-tenant hozzáférési kísérlet **naplózott biztonsági esemény** (SD-13,
`01` 7.3) — nem ennek a referenciának a teendője, csak elhatárolásként
említjük. A felhasználó-szintű szerepkör-változás audit-igénye a
`20_felhasznalokezeles` 3.9 megtartott hiánya (`UserAuditLog` iteráció).

---

## 4. Admin felület

### 4.1 Érintett képernyők

**Nem vezet be új nézetet.** A referencia szerver-oldali artefaktot ír le. A
jogosultság-modell minden admin-felületi nézetet érint, de a nézet-szintű
jogosultságot a `90_sitemap_v3.md` 3. és az egyes feature-specek már
rögzítették.

### 4.2 Lista-oldal, űrlap-oldal

**Nem releváns, mert** nincs lista és nincs űrlap. A jogosultsághoz tartozó
egyetlen admin-felületi űrlap a felhasználó-meghívó szerepkör-választója, amit
a `20_felhasznalokezeles.md` 4. szakasza már specifikált.

### 4.3 A kliens-oldali route-guard — már rögzített, csak elhatárolás

> **A kliens-oldali route-guard UX-réteg, nem biztonsági határ** (`10` 4.4). A
> `/bejelentesek*`, `/tartalom*`, `/beallitasok*`, `/fooldal`, `/riportok`
> route-okat az Angular route-guard a JWT szerepkör-claimje alapján szűri — egy
> `content_manager` a `/bejelentesek`-et meg sem nyitja. De ez **csak az
> élmény** kedvéért van: a valódi határ a szerver `authorization.json`-ja
> (3.2). Ha a guardot megkerülnék, a szerver `403`/`404`-gyel elutasít. A guard
> a `05` mátrixból és a landing-logikából (`05` 4., K-027) determinisztikus —
> új guard-konfiguráció nem születik ebben a referenciában.

### 4.4 Üres / betöltési / hibaállapot

**Nem releváns, mert** nincs adatot betöltő nézet. A jogosultság-megtagadás
hibaállapotát (route-guard megtagadás, illetve szerver `403`) az érintett
feature-specek kezelik a saját hibaállapot-szakaszukban.

### 4.5 i18n kulcsok

**Nem releváns ebben a referenciában** — nem jelenít meg felhasználói szöveget.
A `403`/`401` jogosultsági hibaüzenetek kulcsai az érintett feature-specek
i18n-szakaszában élnek (pl. `10` 4.6 `ticket.error.*`), a "szerver
kulcsot/kódot ad" elv szerint (`01` 5.5).

---

## 5. Polgári mobilapp adatigénye

**Nem releváns ehhez a referenciához, mert** ez a manager (admin) felület és a
szerver jogosultság-modelljét képezi le — a négy *tenant-szerepkör*
`authorization.json`-szabályait. A polgári mobilapp nem ezeket a szerepköröket
használja: a polgár nem tenant-szerepkörrel lép be, és a polgári auth-modell
maga is nyitott (`01` 3.1, NY-bej-1).

A polgári oldal jogosultság-vetülete külön kérdés, külön dokumentumban — nem
ennek a referenciának a hatóköre, és nem is megtartott hiánya (NY-J1).

---

## 6. Acceptance criteria

Számozva, gépiesen ellenőrizhetően — egy kritérium = egy tesztelhető állítás.

### 6.1 AC-A — A route-szintű érvényesülés

- **AC-A1** — *Given* egy kizárólag `tenant_content_manager` szerepkörű JWT;
  *When* a kérő `GET /v1/tickets`-et hív; *Then* a szerver `403`-at ad.
- **AC-A2** — *Given* egy `tenant_dispatcher` JWT; *When* a kérő
  `POST /v1/tickets/{id}/assign`-t hív; *Then* a route-szabály engedi, és a
  hívás nem jogosultsági okból bukik el.
- **AC-A3** — *Given* egy `tenant_field_worker` JWT; *When* a kérő
  `PUT /v1/tickets/{id}/category`-t hív; *Then* a szerver `403`-at ad.
- **AC-A4** — *Given* egy `tenant_field_worker` JWT; *When* a kérő
  `POST /v1/tickets/{id}/start`-ot hív; *Then* a route-szabály engedi.
- **AC-A5** — *Given* egy `tenant_dispatcher` JWT; *When* a kérő
  `GET /v1/users`-t hív; *Then* a szerver `403`-at ad.
- **AC-A6** — *Given* egy `tenant_field_worker` JWT; *When* a kérő
  `POST /v1/ticket-notes`-ot hív; *Then* a szerver `403`-at ad; *és When*
  `GET /v1/ticket-notes`-ot hív, *Then* a route-szabály engedi.

### 6.2 AC-B — A `vezető ⊇ diszpécser ÉS ⊇ tartalomkezelő` reláció

- **AC-B1** — *Given* a 3.2 traceability-mátrix; *When* végigvesszük az összes
  `tenant_dispatcher`-t tartalmazó route-szabályt; *Then* mindegyik
  `roles`-listájában a `tenant_manager` is szerepel. *(Statikus lint-szabály —
  az `authorization.json`-on azonnal futtatható.)*
- **AC-B2** — *Given* a 3.3 Szabály-R3; *When* végigvesszük az összes
  `tenant_content_manager`-t tartalmazó route-szabályt; *Then* mindegyik
  `roles`-listájában a `tenant_manager` is szerepel.
- **AC-B3** — *Given* egy `tenant_manager` JWT; *When* a kérő bármely
  diszpécser-akciót (pl. `POST /v1/tickets/{id}/reject`) vagy tartalmi akciót
  hív; *Then* a route-szabály engedi.
- **AC-B4** — *Given* a route-kiértékelés OR-szemantikája (2.4); *When* egy
  felhasználó JWT-je egyszerre hordoz `tenant_dispatcher`-t és
  `tenant_content_manager`-t (K-025); *Then* minden olyan route-ot elér,
  amelynek `roles`-listájában bármelyik szerepköre szerepel — külön
  uniókezelő logika nélkül.

### 6.3 AC-C — Az elhatárolások

- **AC-C1** — *Given* egy `tenant_field_worker` JWT és egy hozzá **nem**
  rendelt `Ticket` `id`-ja; *When* a kérő `GET /v1/tickets/{id}`-t hív; *Then*
  a szerver `404`-et ad — a route-szabály engedte, de a sor-szintű szűrés
  (3.4-#1) elrejti.
- **AC-C2** — *Given* a `POST /v1/users/invitations/accept` végpont; *When* a
  kérés **JWT nélkül** érkezik egy érvényes meghívó-tokennel; *Then* a végpont
  elérhető (nem `401`) — explicit publikus-jelölés (3.4-#2).
- **AC-C3** — *Given* egy `A` tenant JWT-je és a `Tenant: B` header; *When*
  bármely route-ot hív; *Then* a kérés a tenant-resolution middleware-ben
  bukik el (`403`/`404`, SD-12), a route-szabály kiértékelése előtt, és a
  kísérlet naplózott biztonsági esemény (SD-13).
- **AC-C4** — *Given* a `DELETE /v1/tickets/{id}` és a `DELETE /v1/users/{id}`
  route; *When* bármely szerepkör hívja; *Then* a szerver `403`-at ad — a route
  nincs az `authorization.json`-ban (3.4-#4).
- **AC-C5** — *Given* a kliens-oldali Angular route-guard; *When* egy
  `content_manager` a `/bejelentesek` URL-t nyitja; *Then* a guard megtagadja a
  betöltést — de a guard megkerülésekor a szerver `403`/`404`-gyel zár (4.3).

### 6.4 AC-D — A hézagos modulok szabálya (a feature-specek elkészültekor)

Ezek a `40_riport`/`50_konfig`/`60_tartalom` feature-spec implementálásakor
válnak ténylegesen tesztelhetővé — addig a szabály előírásként áll.

- **AC-D1** — *Given* a `40_riport` modul bármely elkészült route-ja; *When*
  megnézzük a `roles`-listáját; *Then* az pontosan `["tenant_manager"]`
  (Szabály-R1).
- **AC-D2** — *Given* a `50_konfig` modul bármely elkészült kategória-/csoport-
  /tenant-alapadat-route-ja; *When* megnézzük a `roles`-listáját; *Then* az
  pontosan `["tenant_manager"]` (Szabály-R2).
- **AC-D3** — *Given* a `60_tartalom` modul bármely elkészült route-ja; *When*
  megnézzük a `roles`-listáját; *Then* az pontosan
  `["tenant_content_manager", "tenant_manager"]` (Szabály-R3).
- **AC-D4** — *Given* egy `tenant_dispatcher` JWT; *When* a kérő bármely
  elkészült `60_tartalom`-route-ot hív; *Then* a szerver `403`-at ad (`05` 2.9,
  negatív leltár 3.).

---

## 7. Keresztmetszeti

- **Biztonság** — a kétrétegű érvényesítés (3.1), a publikus `accept`-végpont
  explicit jelölése (3.4-#2), a cross-tenant middleware-réteg és annak
  naplózása (3.4-#3, SD-13) a referencia biztonsági gerince. A
  route-szabály-hiány konzervatív default-ja (`403`) a "fail closed" elvet
  érvényesíti (3.4-#4).
- **i18n, időzóna, teljesítmény** — **Nem releváns, mert** a referencia nem
  jelenít meg szöveget, nem kezel időpontot, és a route-kiértékelés a meglévő
  middleware-minta — nincs új teljesítmény-szempont.

---

## 8. Lezárás

### 8.1 Első kiadás (MVP) vs. következő iterációk

**Első kiadás — a kör terméke:** ez a referencia-dokumentum — a 3.2
traceability-mátrix (a `05` mind a kilenc csoportja egy táblában), a 3.3 három
determinisztikus szabály, a 3.4 négy elhatárolás, a 2.4 OR-szemantika, és a 17
acceptance criterion (az AC-B1 statikus lint-szabályként a meglévő 23 route-on
azonnal futtatható).

**Következő iterációk (listázva, nem most specifikálva):**

- **CI-generált teljes `authorization.json`.** Amikor a `40_riport`,
  `50_konfig`, `60_tartalom` feature-spec mind elkészült, a
  traceability-mátrixból egy CI-script összeállíthatja a hiánytalan
  `authorization.json`-t. A pilotra korai — egy féllkész JSON félrevezetőbb,
  mint egy hézagot explicit jelölő mátrix.
- **Finomszemcsés permission-réteg** — a 6-12. hónapra; `01` 3.4 és K-016
  explicit elvetette a pilotra.
- **Aktív token-invalidálás** — a pilotra eventual consistency az elfogadott
  modell (`01` 3.5); az azonnali érvénytelenítés iterációs elem.
- **Új szerepkörök** (moderátor, polgármester, önálló tenant-admin) — egy új
  `TenantRole` enum-érték + új `authorization.json`-bejegyzések, architektúra-
  újratervezés nélkül (`05` 5.).

### 8.2 Feltételezések (explicit lista)

1. Az `01_kozos_mintak.md` 3.5 a kész platform-minta — a kétrétegű
   érvényesítés, a prefix-konvenció és a `vezető`-reláció leképezési *elve*
   érvényes; ez a referencia nem nyitja újra, csak alkalmazza.
2. A `TenantRole` enum a `00_domain_model.md`-ben kész és teljes (négy érték).
3. A meglévő `authorization.json`-minta route→szerepkör-listát ismer,
   **öröklődést nem** — ezért a `vezető`-reláció felsorolással képződik le.
4. A route-kiértékelés OR-szemantikájú (2.4) — a meglévő minta viselkedése.
5. A `05_jogosultsagok_v2.md` a teljes pilot-jogosultság-kép — szerepkör-szintű,
   finomítás nélkül (K-016).

### 8.3 Nyitott kérdések és megtartott hiányok

| # | Tárgy | Típus | Hatáskör |
|---|---|---|---|
| **MH-1** | ~~A `40_riport` (2.7), `50_konfig` nem-felhasználó-rész (2.8), `60_tartalom` (2.9) modulok pontos API-route-nevei.~~ **LEZÁRVA** (2026.05.20) — `40_riport.md` v1.0, `30_beallitasok.md` v1.0, `60_tartalom.md` v1.0 mind kanonikus route-stringeket adott. A 3.2 G-blokk a 27 tartalom-route-tal frissült; az E-blokk a `40_riport`-route-okkal; az F-blokk a `30_beallitasok`-route-okkal. **Már nincs hézagos modul.** | Lezárt hiány | — |
| **MH-2** | Mely hézagos-modul-entitások engednek `DELETE`-et (törölhető vs. archiválható). A `60_tartalom.md` v1.0 ezt **lezárta** a tartalmi entitásokra (`News`/`Event`/`CityInfo`): `Draft` és `Archived` törölhető; `Published` → `409 cannot_delete_published` (SD-70 guard). A `30_beallitasok.md` v1.0 a `Category` és `Group` törölhetőségét rendezte (SD-63 guard). **Az MH-2 a Specifikációs projekt aktuális hatókörében teljesen lezárult.** | Lezárt hiány | — |
| **MH-3** | A manuális bejelentés-nyitás (`POST /v1/tickets`) route-leképezése. A `10` 3.10 már külön feature-re utalta. **Nem blokkol:** a szerepkör (`dispatcher`/`manager`) ismert. | Megtartott hiány | Manuális-nyitás feature-spec |
| **NY-J1** | A polgári mobilapp jogosultság-/auth-modellje — nem ennek a referenciának a hatóköre, és nem is megtartott hiánya: a polgár nem tenant-szerepkörrel lép be, a polgári auth maga is nyitott (`01` 3.1, NY-bej-1). | Elhatárolás | Polgári adatigény-spec |

A megmaradt egyetlen megtartott hiány (MH-3) a feature **gerincét nem
érinti** — a referencia terméke (a traceability-mátrix és a három
szabály) önállóan teljes. **Minden Specifikációs projekten belüli modul
route-jai immár kanonikusan rögzítettek.**

### 8.4 Visszacsorgó jelzések a funkcionális/specifikációs projektnek

| # | Jelzés | Cél-dokumentum |
|---|---|---|
| **VF-J1** | A `20_duplikacio_es_osszevonas.md` 3.5 a `roles` tömbben csupasz `dispatcher`/`manager` formát használ, szemben az `01_kozos_mintak.md` 3.3 `tenant_`-prefixes mintájával és a `10` 3.8 / `20_felhasznalokezeles` 3.8 gyakorlatával. Vélhetően elírás (nincs "Eltérés a mintától:" jelölés) — javítandó `tenant_dispatcher`/`tenant_manager`-re. Ez a referencia mindenképp a helyes prefix-formát használja. | `20_duplikacio_es_osszevonas.md` |

### 8.5 Hivatkozott dokumentumok

- Funkcionális: `05_jogosultsagok_v2.md` (a fő bemenet), `00_architektura_v4.md`
  2–3., `90_sitemap_v3.md` 3., `manager_felulet_atadas.md`
- Alapdokumentumok: `01_kozos_mintak.md` 3.2–3.5 (a platform-minta),
  `00_domain_model.md` (`TenantRole`, `UserTenantRole`), `99_donesnaplo.md`,
  `CLAUDE.md`
- Meglévő feature-specek (a route-leképezések forrása):
  `10_bejelentes_lista_es_adatlap.md` 3.8, `20_duplikacio_es_osszevonas.md` 3.5,
  `20_felhasznalokezeles.md` 3.8
- Kanonikus: `kanonikus_donek.md` — K-016, K-024, K-025, K-027, K-038, K-039
- Meglévő minták: `project_backend` CLAUDE.md (`authorization.json`, Zitadel JWT)

---

## Verziónapló

- **v1.0 (2026.05.19)** — Első kiadás. A `05_jogosultsagok_v2.md` akció-mátrixának
  konszolidált `authorization.json`-leképezése: a 3.2 traceability-mátrix (a
  kilenc akció-csoport → route → szerepkör → forrás, 23 lefedett route + 3
  hézagos modul), a 3.3 három determinisztikus szabály (R1/R2/R3), a 3.4 négy
  elhatárolás, a 2.4 OR-kiértékelési szemantika, 17 acceptance criterion. A
  felfedezési kör megállapítása szerint ez **nem önálló feature-spec** — a
  jogosultság-érvényesítés mechanikáját az `01_kozos_mintak.md` 3.5 már lefedte
  —, hanem konszolidált referencia. Három megtartott hiány (MH-1 route-nevek,
  MH-2 `DELETE`-engedélyek, MH-3 manuális nyitás), egy elhatárolás (NY-J1
  polgári oldal), egy visszacsorgó jelzés (VF-J1 prefix-hiba a duplikáció-specben).
- **v1.1 (2026.05.20)** — A három hézagos modul feature-specjeinek átvezetése.
  **A 3.2 G-blokk (Tartalomkezelés) kitöltve** a `60_tartalom.md` v1.0 alapján:
  27 új konkrét route (News 9, Events 9, CityInfo 9) mind
  `tenant_content_manager` + `tenant_manager` szerepkörrel (Szabály-R3
  érvényesítve). **A 3.2 E-blokk (Dashboard és riport) frissítve** a
  `40_riport.md` v1.0 alapján: 6 konkrét route, mind `tenant_manager`-only
  (Szabály-R1 érvényesítve). **A 3.2 F-blokk (Tenant-konfiguráció, nem-
  felhasználó rész) frissítve** a `30_beallitasok.md` v1.0 alapján: kategória-,
  csoport-, tenant-alapadat- és heti riport-címzett-route-ok, mind
  `tenant_manager`-only (Szabály-R2 érvényesítve, SD-66 a 22 új route közös
  forrása). **A lefedettségi összegzés frissítve:** öt helyett **nyolc
  teljesen lefedett csoport**; a "három hézag" leírás helyett "minden modul
  lefedett". **A 8.3 megtartott hiányok táblája frissítve:** az MH-1
  **teljesen lezárva** (már nincs hézagos modul); az MH-2 is **lezárva** a
  Specifikációs projekt aktuális hatókörében (a `60_tartalom`-spec a tartalmi
  entitásokra rendezte az SD-70 állapot-érzékeny guarddal; a `30_beallitasok`-
  spec a `Category`/`Group`-ra rendezte az SD-63 guarddal). Egyetlen
  megtartott hiány marad (MH-3, manuális bejelentés-nyitás) — nem blokkol.
