# RBAC model — ZAKLJUČENO sa vlasnikom 2026-07-24 > Ovo NIJE predlog za raspravu — model je dogovoren. Slobodne su implementacione > odluke (imena kolona, indeksi, Go slojevi), ne semantika. ## 1. Stablo organizacija Hijerarhijsko stablo proizvoljne dubine; **koren = Terminia (vendor)**. Primer: ``` Terminia (vendor, koren) ├─ DAL (kupac) ← DAL je KUPAC, ne vendor! │ ├─ Bazen Gradski (objekat/pod-firma) │ └─ Spa Centar X ├─ Distributer Jug │ └─ Firma Y │ └─ Bazen Z └─ ServisPlus (org tipa "serviser") ← eksterni serviseri kao zaseban org ``` ### Tabele (dogovorene; tipove/indekse odrediti po MySQL praksi projekta) ```sql orgs(id, parent_id NULL za koren, tip ENUM('vendor','distributer','firma','objekat','serviser',...), naziv, status) users(id, org_id, rola ENUM('owner','admin','operator','viewer'), ime, email, auth...) devices(id, org_id, mac UNIQUE, product_code, fw_verzija, status, license_id NULL, naziv, poslednji_heartbeat, ip) entitlements(id, org_id, product_code, max_uredjaja, fw_kanal, vazi_do) service_grants(id, serviser_org_id, ciljni_org_id NULL / ciljni_device_id NULL, dozvole SET('registruj','flesuj_fw','odrzavanje'), vazi_do) sale_grants(id, prodavac_user_id ili org_id, plan/proizvod opseg, vazi_do) ``` ## 2. Role (iste na SVAKOM čvoru stabla) | Rola | Prava | |---|---| | **Owner** | pun vlasnik org-a i CELOG podstabla | | **Admin** | upravljanje unutar org-a | | **Operator** | operativni rad (kasir na terminalu / interni serviser) | | **Viewer** | samo pregled | ## 3. Invarijante (moraju biti sprovedene u kodu, ne samo dogovoru) 1. **Delegacija sa podskupom:** dete-org dobija PODSKUP prava roditelja; zbir entitlements dece ≤ roditeljev max (`max_uredjaja` itd.). 2. **Vidljivost (row-level):** org vidi SEBE + celo svoje PODSTABLO. Ništa iznad, ništa bočno. Svaki upit ide kroz filter podstabla (CTE po `parent_id` ili materijalizovana putanja — implementaciona odluka). 3. **Serviser ≠ vlasnik:** service_grant daje PRISTUP (registruj/flešuj/održavaj) nad tuđim org-om/uređajima, sa rokom — NE daje vlasništvo ni uvid u naplatu. 4. **Prodavac ne kreira** zone/cenovnik (to su entiteti objekta na uređaju) — `sale_grants` samo kaže KOJE planove sme da prodaje. ## 4. Odnos sa licencama - `devices.license_id` → licenca iz postojećeg licencnog sistema ([`docs/asp-terminia/`](../asp-terminia/README.md)). - `entitlements` je „koliko čega sme org" — licencni server pri izdavanju ključa proverava entitlement (npr. max_uredjaja). - **Kill-switch lanac:** opoziv licence (revoked) + istek + offline grejs na uređaju + sigurno stanje — mehanika na uređaju, okidač na serveru. ## 5. Dva lica, jedan mozak - **Terminia lice** (`terminia.net`): vendor pogled — proizvodi, licence, katalog FW. - **LoggerService lice** (`loggerservice.com`): serviserski pogled — moji grantovi, uređaji do kojih smem, registracija/flešovanje/održavanje, nalozi servisera. - Tehnički: isti Go backend + baza; lice se bira po hostu (nginx `server_name`) i/ili po tipu org-a prijavljenog korisnika. Brendiranje (logo/boje/naziv) po licu. ## 6. Pristup „sve odmah / UI inkrementalno" Dogovor: **pun MODEL/šema odmah** (migracije za sve tabele iznad), a **UI dashboard inkrementalno** (prvo orgs+devices+users, pa grantovi). Uređaji teku paralelno — heartbeat prijem (02) može i pre punog UI-ja.