Merge task/ASP-licenca-paket: preuzet radni paket ASP-Terminia licenciranje
This commit is contained in:
commit
da287c2aec
23
CLAUDE.md
23
CLAUDE.md
@ -736,6 +736,29 @@ DSN sadrži `multiStatements=true` — neophodno za izvršavanje migracija sa vi
|
||||
- Faza 8 (Light-Ticket): Integracija sa license serverom
|
||||
- ARV: Integracija sa license serverom
|
||||
- ESIR: Integracija sa license serverom
|
||||
- **ASP-Terminia (4. proizvod):** vidi `docs/asp-terminia/` — radni paket Z1–Z6
|
||||
|
||||
---
|
||||
|
||||
## Radni paket: ASP-Terminia (ESP32 terminal)
|
||||
|
||||
Četvrti proizvod na ovom serveru — **ASP-Terminia** (Autonomni Sistem Prolaza),
|
||||
ESP32-S3 terminal za kontrolu prolaza (bazeni/spa). Licenca je vezana za **MAC**
|
||||
čipa (eFuse) preko `machine_fingerprint`, a ne za računar.
|
||||
|
||||
**Klijentska strana je već gotova** — firmware modul `licenca.h/.cpp` (od FW
|
||||
0.10.0) radi aktivaciju, offline verifikaciju RSA potpisa i UI. Čeka samo da
|
||||
proizvod i ključ postoje ovde na serveru.
|
||||
|
||||
Kompletan paket (postojeće stanje, tačan API ugovor koji firmware očekuje,
|
||||
zadaci Z1–Z6, pravila rada na produkciji, enforcement pitanja za vlasnika):
|
||||
|
||||
**[`docs/asp-terminia/README.md`](docs/asp-terminia/README.md)** — čitati prvo.
|
||||
|
||||
Razlika u odnosu na ESIR/ARV/LIGHT_TICKET koja se mora poštovati:
|
||||
- fingerprint je MAC uređaja, ne hash računara;
|
||||
- uređaj radi **offline** — mrežna greška NIKAD ne sme da ga obori;
|
||||
- postojeći proizvodi su ŽIVI u produkciji (~140 licenci) — ništa se ne lomi.
|
||||
|
||||
---
|
||||
|
||||
|
||||
97
docs/asp-terminia/01-postojece-stanje.md
Normal file
97
docs/asp-terminia/01-postojece-stanje.md
Normal file
@ -0,0 +1,97 @@
|
||||
# Postojeće stanje (provereno na serveru 2026-07-24, read-only)
|
||||
|
||||
## 1. Server 151 — pristup i raspored
|
||||
|
||||
- **SSH:** `ssh root@157.180.119.151` (host se javlja kao `MCLaud`, Ubuntu; ključ
|
||||
`~/.ssh/id_ed25519` sa razvojne mašine; samo root). Hetzner, van LAN-a.
|
||||
- Na ISTOM serveru žive i drugi sistemi — **ne dirati**:
|
||||
- `terminia` SaaS platforma za klubove (portovi 8091/8092) — IME SLIČNO, ali
|
||||
NIJE naš proizvod;
|
||||
- Gitea;
|
||||
- ESIR backend (fiskalizacija).
|
||||
|
||||
## 2. `dal-license-server` (naš deo)
|
||||
|
||||
- **Kod:** `/root/projects/dal-license-server` — Go, bez frameworka, MySQL.
|
||||
- **Port:** 8090 lokalno; javno preko nginx sajta **`arv`**.
|
||||
- **Javni URL (ovo firmware već koristi):** `https://157.180.119.151/license/api/v1/`
|
||||
- HTTPS 443, cert `/etc/nginx/ssl/arv.crt`, `server_name` = IP → **self-signed**
|
||||
(zato firmware koristi `setInsecure()`; odluku štiti RSA potpis odgovora).
|
||||
- Na portu 80 je izložen samo validator API; ostalo redirect na 443.
|
||||
- **Produkcioni obim:** 3 proizvoda (ESIR, ARV, LIGHT_TICKET — seed u
|
||||
`migrations/002_seed_products.sql`), ~140 licenci, ~19 aktivacija. **ŽIVO.**
|
||||
|
||||
### Kripto
|
||||
|
||||
- **RSA-2048**, potpis **RSA-SHA256**.
|
||||
- Privatni ključ: na serveru (`crypto/` + `.env` konfiguracija) — **NE čitati, NE
|
||||
kopirati, NE logovati.**
|
||||
- Javni ključ: `crypto/public.pem` — VEĆ ugrađen u firmware (`licenca.cpp`,
|
||||
`LIC_PUBKEY`). Ako se ključ ikad rotira, MORA i novi firmware — to je krupna
|
||||
odluka, ne radi se usput.
|
||||
- Potpis stiže kao string: `"signature": "RSA-SHA256:<base64>"` uz `license` objekat.
|
||||
**Potpisuje se serijalizacija license objekta kakvu server pošalje** — klijent
|
||||
verifikuje SIROVE bajtove (ne re-serijalizuje). Svaka izmena serijalizacije na
|
||||
serveru lomi sve klijente u polju.
|
||||
|
||||
### Klijentski API (bez autentikacije, rate-limited)
|
||||
|
||||
| Ruta | Telo zahteva | Odgovor |
|
||||
|---|---|---|
|
||||
| `POST /api/v1/activate` | `{license_key, machine_fingerprint, app_version, os, hostname}` | `{license:{... expires_at, grace_days, limits, features, customer ...}, signature}` |
|
||||
| `POST /api/v1/validate` | `{license_key, machine_fingerprint}` | `{valid, expires_at, revoked}` |
|
||||
| `POST /api/v1/deactivate` | (transfer/oslobađanje) | — |
|
||||
|
||||
Greške (JSON `error` polje): `INVALID_KEY`, `ALREADY_ACTIVATED`, `KEY_EXPIRED`,
|
||||
`KEY_REVOKED`, `PRODUCT_MISMATCH`.
|
||||
|
||||
### Admin API
|
||||
|
||||
- Header `X-API-Key` (ključ u `.env` — od vlasnika se traži ključ ili da on sam
|
||||
klikne u dashboardu; agent NE vadi ključ iz `.env` bez izričite dozvole).
|
||||
- Kreira proizvode i licence. Postoji i htmx admin dashboard.
|
||||
|
||||
## 3. Firmware klijent — GOTOV (od FW 0.10.0)
|
||||
|
||||
Fajlovi u firmware repou (`firmware/10_terminia/`):
|
||||
|
||||
| Šta | Gde |
|
||||
|---|---|
|
||||
| Modul | `licenca.h` / `licenca.cpp` |
|
||||
| Ugrađen javni ključ | `licenca.cpp` → `LIC_PUBKEY` (PEM) |
|
||||
| NVS | namespace `lic`: `raw` (sirovi license JSON) + `sig`; ključ/URL u configu: `licKey`, `licUrl` (podrazumevano `https://157.180.119.151/license/api/v1`) |
|
||||
| Web API (SPA) | `/api/license` (status), `/api/license-save` (ključ/URL), `/api/license-activate`, `/api/license-check` — sve samo admin |
|
||||
| UI | SPA → Podešavanja → Uređaj → kartica „Licenca" (status, izdanje, korisnik, važi do, otisak uređaja, unos ključa, Aktiviraj, Proveri na serveru) |
|
||||
|
||||
### Kako klijent radi (bitno za server stranu)
|
||||
|
||||
1. **Otisak:** `machine_fingerprint = "sha256:" + sha256hex(MAC)` gde je MAC oblika
|
||||
`AA:BB:CC:DD:EE:FF` (velika slova, dvotačke). ⚠️ **PRETPOSTAVKA** — proveriti u
|
||||
Go kodu servera kako računa fingerprint za poređenje; ako se razlikuje, uskladiti
|
||||
NA SERVERU dokumentaciju/verifikaciju za ASP proizvod ILI javiti pa menjamo FW
|
||||
(zadatak Z2).
|
||||
2. **Aktivacija:** POST `/activate`; iz odgovora isecₐ SIROVE bajtove `license`
|
||||
objekta (brojanje zagrada, string-safe), verifikuje `signature` RSA‑SHA256
|
||||
javnim ključem, čuva sirovo+potpis u NVS.
|
||||
3. **Svaki start (offline):** ponovo verifikuje potpis iz NVS + poredi
|
||||
`machine_fingerprint` iz licence sa svojim + proverava `expires_at`
|
||||
(poređenje po datumu `YYYY-MM-DD`; prazno = trajna; nepouzdan sat → grejs,
|
||||
nikad pad).
|
||||
4. **Statusi na uređaju:** `nema / vazi / grejs / los-potpis / drugi-uredjaj / istekla`.
|
||||
5. **ENFORCEMENT NE POSTOJI** — uređaj samo prikazuje status. Gašenje funkcija bez
|
||||
licence je odluka vlasnika (zadatak Z4).
|
||||
|
||||
### Polja koja klijent čita iz `license` objekta
|
||||
|
||||
`edition`, `customer` (ili `customer_name`), `expires_at`, `license_id` (ili `key`),
|
||||
`grace_days`, `machine_fingerprint`. Nepoznata dodatna polja ne smetaju (parsira se
|
||||
ciljano). `limits`/`features` se JOŠ ne čitaju — planirano uz enforcement.
|
||||
|
||||
## 4. Šta NE postoji (i pripada zadacima)
|
||||
|
||||
- Proizvod **„ASP-Terminia"** na serveru — ne postoji (zadatak Z1).
|
||||
- Nijedan ASP ključ — ne postoji (Z1/Z2).
|
||||
- Domen `licenca.terminia.net` + Let's Encrypt — ne postoji (Z3; domen kupuje vlasnik).
|
||||
- Enforcement na uređaju + `features`/`limits` semantika za ASP (Z4/Z5).
|
||||
- FW potpisivanje `.bin` + katalog firmvera (Z6; preduslov za auto-OTA, vidi i
|
||||
ASP repo: `serviseri/03-provisioning-i-fw-katalog.md`).
|
||||
72
docs/asp-terminia/02-api-ugovor-firmware.md
Normal file
72
docs/asp-terminia/02-api-ugovor-firmware.md
Normal file
@ -0,0 +1,72 @@
|
||||
# API ugovor koji FIRMWARE očekuje (merodavno za server stranu)
|
||||
|
||||
> Ovo je ugovor kakav je VEĆ implementiran u firmveru (0.10.0+). Server strana se
|
||||
> usklađuje sa OVIM (ili se promena dogovara pa se menja i firmware — nikad tiho).
|
||||
|
||||
## 1. Aktivacija
|
||||
|
||||
```
|
||||
POST {licUrl}/activate
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"license_key": "ASP-XXXX-XXXX-XXXX",
|
||||
"machine_fingerprint": "sha256:<sha256hex od 'AA:BB:CC:DD:EE:FF'>",
|
||||
"app_version": "0.11.0",
|
||||
"os": "esp32s3",
|
||||
"hostname": "TERM-001"
|
||||
}
|
||||
```
|
||||
|
||||
Očekivan odgovor `200`:
|
||||
|
||||
```
|
||||
{
|
||||
"license": {
|
||||
... polja licence, među njima:
|
||||
"machine_fingerprint": "sha256:...", ← ako postoji, MORA biti otisak uređaja
|
||||
"expires_at": "2027-01-01T00:00:00Z", ← ili prazno/odsutno = trajna
|
||||
"grace_days": 14,
|
||||
"edition": "...", "customer": "...", "license_id": "..."
|
||||
},
|
||||
"signature": "RSA-SHA256:<base64 potpisa nad SIROVIM bajtovima license objekta>"
|
||||
}
|
||||
```
|
||||
|
||||
**Kritično:** potpis se računa nad TAČNIM bajtovima `license` objekta onako kako su
|
||||
poslati u HTTP telu (od `{` do para `}`). Firmware iseca taj isečak iz sirovog tela
|
||||
(string-safe brojanje zagrada) i verifikuje. **Nikakvo „lepše" formatiranje odgovora
|
||||
naknadno** — menja bajtove → lomi potpis.
|
||||
|
||||
## 2. Provera
|
||||
|
||||
```
|
||||
POST {licUrl}/validate
|
||||
{ "license_key": "...", "machine_fingerprint": "sha256:..." }
|
||||
```
|
||||
|
||||
Očekivano: `{"valid": true/false, "expires_at": "...", "revoked": true/false}`.
|
||||
Firmware tumači: `revoked` → poruka „licenca OPOZVANA na serveru"; `!valid` →
|
||||
„server kaže da licenca ne važi". Mrežna/HTTP greška NE dira lokalno stanje.
|
||||
|
||||
## 3. Greške
|
||||
|
||||
HTTP ≠ 200 → firmware čita JSON polje `"error"` i prikazuje ga korisniku uz HTTP kod
|
||||
(npr. `HTTP 403 (KEY_REVOKED)`). Poželjno je da server uvek vraća `{"error":"KOD"}`.
|
||||
|
||||
## 4. Ponašanje klijenta koje server sme da računa
|
||||
|
||||
- Klijent NIKAD ne šalje privatne podatke — samo gore navedena polja.
|
||||
- Klijent poštuje odgovor samo ako je potpis valjan; HTTP 200 bez valjanog potpisa
|
||||
se odbacuje (zaštita i od MITM na self-signed kanalu).
|
||||
- Nakon uspešne aktivacije klijent NE zove server pri svakom startu — offline
|
||||
verifikacija iz NVS. `validate` se zove ručno iz UI (kasnije: periodično uz sync).
|
||||
|
||||
## 5. Otvorena pitanja za usklađivanje (uneti odgovore ovde)
|
||||
|
||||
| # | Pitanje | Status |
|
||||
|---|---|---|
|
||||
| P1 | Tačna formula `machine_fingerprint` u Go kodu (ulazni string, velika/mala slova, dvotačke?) | ⬜ proveriti u kodu servera |
|
||||
| P2 | Da li `activate` na VEĆ aktiviran ključ + ISTI fingerprint vraća licencu ponovo (re-aktivacija posle brisanja NVS) ili `ALREADY_ACTIVATED`? Za teren nam treba: isti uređaj sme ponovo. | ⬜ proveriti/podesiti |
|
||||
| P3 | Tačan skup polja `license` objekta za ASP proizvod (limits/features imena) | ⬜ definisati uz Z1 |
|
||||
| P4 | `expires_at` format (ISO8601?) — firmware poredi prvih 10 znakova (`YYYY-MM-DD`) | ⬜ potvrditi |
|
||||
102
docs/asp-terminia/03-zadaci.md
Normal file
102
docs/asp-terminia/03-zadaci.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Zadaci (redom; svaki ima kriterijum prihvatanja)
|
||||
|
||||
> Redosled je namerno ovakav: prvo ono što odblokira kraj-do-kraja test sa pravim
|
||||
> uređajem, pa infrastruktura (domen), pa odluke, pa katalog firmvera.
|
||||
> **Pre svakog write-a na produkciju: backup + izričita dozvola vlasnika**
|
||||
> (vidi 04-pravila-rada.md).
|
||||
|
||||
## Z1 — Proizvod „ASP-Terminia" na serveru
|
||||
|
||||
**Šta:** kroz migraciju (SQL u `migrations/`, po uzoru na `002_seed_products.sql`)
|
||||
ili admin API/dashboard napraviti proizvod:
|
||||
|
||||
- `code`/`name`: **ASP-Terminia** (linija: ASP — Autonomni Sistem Prolaza)
|
||||
- `key_prefix`: **`ASP-`**
|
||||
- limiti (predlog, potvrditi sa vlasnikom): `max_citaca` (npr. basic 2 / pro 8),
|
||||
`max_kartica` (basic 2000 / pro 30000)
|
||||
- features (predlog bitova, uskladiti sa ASP repo docs/18 §6.3): provera karte, izdavanje,
|
||||
štampa, katalog-sa-servera, anti-passback, sync, OTA
|
||||
|
||||
**Kako:** pogledati kako su postojeći proizvodi definisani (tabela `products` +
|
||||
seed migracija) i uraditi ISTIM šablonom. Ne menjati postojeće redove.
|
||||
|
||||
**Prihvatanje:** proizvod vidljiv u dashboardu; postojeći proizvodi netaknuti
|
||||
(COUNT pre = posle za njihove licence/aktivacije); backup fajl postoji.
|
||||
|
||||
## Z2 — Test ključ + kraj-do-kraja aktivacija sa uređajem
|
||||
|
||||
**Šta:** izdati 1 test licencu ASP-Terminia (trajnu ili 90 dana) i proći ceo tok sa
|
||||
PRAVIM uređajem (MAC `1C:DB:D4:A6:A4:60`, dostupan vlasniku):
|
||||
|
||||
1. Odgovoriti na P1–P4 iz 02-api-ugovor-firmware.md (čitanjem Go koda).
|
||||
2. Ako se fingerprint formula razlikuje od FW pretpostavke → zapisati TAČNU formulu
|
||||
u 02 i javiti (menja se FW, jedna linija).
|
||||
3. Vlasnik unese ključ u SPA (Podešavanja → Uređaj → Licenca) → Aktiviraj.
|
||||
4. Proveriti: status „važi" na uređaju; restart uređaja → i dalje „važi" (offline);
|
||||
`Proveri na serveru` → potvrda.
|
||||
5. Negativni testovi: pogrešan ključ (INVALID_KEY prikazan), opozvan ključ
|
||||
(revoked prikazan), ključ aktiviran na drugom fingerprint-u (PRODUCT/ALREADY
|
||||
ponašanje po P2).
|
||||
|
||||
**Prihvatanje:** svih 5 koraka dokumentovano (šta je poslato/vraćeno, bez tajni).
|
||||
|
||||
## Z3 — Domen `licenca.terminia.net` + Let's Encrypt
|
||||
|
||||
**Preduslov:** vlasnik kupi/podesi `terminia.net` (A rekord → 157.180.119.151).
|
||||
Dok toga nema, zadatak stoji — NE blokira Z1/Z2 (ide se preko IP-a).
|
||||
|
||||
**Šta:**
|
||||
- nginx: novi `server_name licenca.terminia.net` blok koji proksira ISTI backend
|
||||
(port 8090) — **ne dirati postojeći `arv` sajt** (postojeći klijenti ostaju na IP).
|
||||
- certbot (Let's Encrypt) za taj domen; auto-obnova.
|
||||
- Provera da `https://licenca.terminia.net/api/v1/validate` radi sa validnim lancem.
|
||||
- U firmware repou: `cfg.licUrl` podrazumevana vrednost se menja na domen, a
|
||||
`setInsecure()` se zamenjuje validacijom lanca (ugraditi ISRG root CA) — to je
|
||||
FW izmena: pripremiti tačan diff/uputstvo, primenu radi firmware strana.
|
||||
|
||||
**Prihvatanje:** domen služi API sa validnim certom; stari IP pristup i dalje radi.
|
||||
|
||||
## Z4 — Odluke o enforcement-u (PRIPREMA, vlasnik odlučuje)
|
||||
|
||||
**Šta:** pripremiti kratak dokument sa predlogom (na bazi ASP repo docs/18 §5) i KONKRETNIM
|
||||
pitanjima za vlasnika:
|
||||
|
||||
1. Bez licence: potpuno odbijanje ILI ograničen rad (predlog: web/konfiguracija/ručno
|
||||
upravljanje rade; izdavanje+štampa+provera karata ne rade uz jasnu poruku)?
|
||||
2. Grejs: 14 dana posle isteka (podesivo)?
|
||||
3. Nepouzdan sat = grejs (nikad pad) — potvrda?
|
||||
4. Koje funkcije vezati za `features` bite, koje za `limits`?
|
||||
|
||||
**Prihvatanje:** dokument `05-enforcement-odluke.md` u ovom folderu sa odgovorima
|
||||
vlasnika upisanim (ne pretpostavkama). Implementacija enforcement-a u FW ide TEK
|
||||
posle toga (firmware strana).
|
||||
|
||||
## Z5 — Obnova/opoziv tok (sloj B)
|
||||
|
||||
**Šta:** definisati i (posle Z4) implementirati periodičnu proveru na uređaju:
|
||||
`validate` na N sati (podesivo), `revoked` → od kad važi ograničenje (posle grejsa),
|
||||
server može vratiti NOVU licencu (produženje) — proveriti da li postojeći server to
|
||||
podržava kroz `activate` re-poziv ili treba dorada (`check` endpoint po ASP repo docs/18 §4).
|
||||
|
||||
**Prihvatanje:** opisan tačan tok + potvrđeno na test ključu (produženje + opoziv).
|
||||
|
||||
## Z6 — Potpisivanje firmvera + veza sa katalogom
|
||||
|
||||
**Šta:** `.bin` slike se potpisuju RSA lancem (ODVOJEN ključ od licenci — preporuka
|
||||
ASP repo docs/18 §7.1; ako vlasnik odluči isti, dokumentovati). Server strana: skripta za
|
||||
potpis + čuvanje potpisa uz artefakt. Katalog (nginx `fw.terminia.net`) i
|
||||
kratkotrajni download URL su u paketu `ASP repo: serviseri/03` — ovde samo potpisni deo.
|
||||
|
||||
**Prihvatanje:** komanda za potpis + format potpisa dokumentovan + probni potpisan
|
||||
`.bin` verifikovan javnim ključem.
|
||||
|
||||
---
|
||||
|
||||
## Redosled i zavisnosti (sažetak)
|
||||
|
||||
```
|
||||
Z1 (proizvod) ──► Z2 (kraj-do-kraja) ──► Z4 (odluke) ──► [FW enforcement — firmware strana]
|
||||
└──► Z5 (obnova/opoziv)
|
||||
Z3 (domen) — čim vlasnik obezbedi DNS (nezavisno)
|
||||
Z6 (potpis .bin) — pre auto-OTA kataloga (koordinacija sa ASP repo: serviseri/)
|
||||
```
|
||||
41
docs/asp-terminia/04-pravila-rada.md
Normal file
41
docs/asp-terminia/04-pravila-rada.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Pravila rada — PROČITATI PRE PRVOG SSH-a
|
||||
|
||||
> Server 151 je **PRODUKCIJA** sa živim klijentima (fiskalizacija ESIR, ARV,
|
||||
> LIGHT_TICKET licence, terminia SaaS). Greška ovde košta prave korisnike.
|
||||
|
||||
## Tvrda pravila (bez izuzetka)
|
||||
|
||||
1. **Read-only dok se ne odobri write.** Istraživanje (čitanje koda, šeme,
|
||||
nginx konfiga) je slobodno. SVAKI write na produkciju (SQL, fajl, nginx reload,
|
||||
restart servisa) traži **izričito DA vlasnika za taj konkretan korak**.
|
||||
2. **Backup pre svake izmene.** Minimum:
|
||||
- baza: `mysqldump` ciljanih tabela (ili cele baze) u `/root/backup/` sa datumom;
|
||||
- fajl/konfig: kopija sa `.bak-YYYYMMDD` sufiksom pre izmene.
|
||||
U izveštaju navesti tačnu putanju backupa.
|
||||
3. **Migracije, ne ad-hoc SQL.** Izmene šeme/podataka idu kao numerisan fajl u
|
||||
`migrations/` (šablon = postojeće migracije), idempotentno gde je moguće.
|
||||
4. **Tajne se ne diraju:** `.env`, privatni ključevi (`crypto/` osim `public.pem`),
|
||||
lozinke — ne čitati sadržaj, ne ispisivati u logove/izveštaje. Ako je za posao
|
||||
potreban admin API ključ — **tražiti od vlasnika**, ne vaditi ga iz `.env`.
|
||||
5. **Ne dirati tuđe servise:** `terminia` SaaS (8091/8092), Gitea, ESIR — ni
|
||||
konfiguraciju, ni bazu, ni portove. Nginx: menjati SAMO dodavanjem novih
|
||||
server blokova; postojeći `arv` sajt ostaje kakav jeste.
|
||||
6. **Nikad destruktivno:** bez DROP/DELETE nad postojećim podacima; bez rotacije
|
||||
ključeva; bez gašenja servisa duže od reload-a.
|
||||
7. **Kompatibilnost klijenata u polju:** serijalizacija `license` objekta i format
|
||||
potpisa se NE menjaju (lome verifikaciju na uređajima). Nova polja se DODAJU,
|
||||
postojeća se ne preimenuju.
|
||||
|
||||
## Kako se testira bez rizika
|
||||
|
||||
- Novi proizvod (ASP-Terminia) i test ključevi su IZOLOVANI redovi — ne dodiruju
|
||||
postojeće. Test aktivacije gađaju samo ASP ključeve.
|
||||
- Za probe API-ja koristiti `curl` sa test ključem; nikad tuđe ključeve.
|
||||
- Ako postoji mogućnost lokalnog pokretanja (Go build + test MySQL šema) — poželjno
|
||||
prvo lokalno, pa migracija na produkciju.
|
||||
|
||||
## Izveštavanje
|
||||
|
||||
Posle svake sesije: šta je pročitano, šta je menjano (tačne putanje/tabele),
|
||||
gde je backup, šta je sledeće, otvorena pitanja za vlasnika. Odgovore na pitanja
|
||||
upisivati u `02-api-ugovor-firmware.md` §5 i `05-enforcement-odluke.md`.
|
||||
16
docs/asp-terminia/05-enforcement-odluke.md
Normal file
16
docs/asp-terminia/05-enforcement-odluke.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Enforcement — odluke vlasnika (popunjava se, NE pretpostavlja)
|
||||
|
||||
> Uređaj trenutno licencu samo PRIKAZUJE. Pre nego što ijedna funkcija sme da se
|
||||
> gasi bez licence, vlasnik odgovara na sledeće (predlozi iz ASP repo docs/18 §5 u zagradi):
|
||||
|
||||
| # | Pitanje | Predlog | ODLUKA VLASNIKA |
|
||||
|---|---|---|---|
|
||||
| E1 | Ponašanje bez važeće licence? | Ograničen rad: web/konfiguracija/ručno upravljanje izlazima RADE (bezbednost + mogućnost unosa licence); izdavanje karata, štampa i provera karata NE RADE uz jasnu poruku „Uređaj nije licenciran". Alternativa: potpuno odbijanje (rizik zaglavljene rampe). | ⬜ |
|
||||
| E2 | Grejs period posle isteka? | 14 dana, podesivo (`licGraceDays`); tokom grejsa pun rad + uporno upozorenje u UI i logu. | ⬜ |
|
||||
| E3 | Nepouzdan sat (RTC bez baterije)? | Tretirati kao grejs (radi + upozorava), NIKAD pad — inače nestanak struje bez NTP obara ispravan terminal. | ⬜ |
|
||||
| E4 | `features` biti — šta se licencira? | provera-karte / izdavanje / štampa / katalog-sa-servera / anti-passback / sync / OTA (servisni kanal, AP, web, prijava NIKAD ne zavise od licence). | ⬜ |
|
||||
| E5 | `limits` — šta se ograničava? | max_kartica u katalogu, max_citaca u registru; „basic" vs „pro" izdanje. | ⬜ |
|
||||
| E6 | Model prodaje? | Trajna (expires prazno) i pretplata (30/60/90 d uz obnovu kroz validate/check) — podržati oba. | ⬜ |
|
||||
|
||||
Kad su odluke upisane: implementacija ide u firmware (`licenca` modul + provere u
|
||||
`tickets/cards/printer` putanjama) — radi firmware strana, uz host testove.
|
||||
60
docs/asp-terminia/README.md
Normal file
60
docs/asp-terminia/README.md
Normal file
@ -0,0 +1,60 @@
|
||||
# ASP-Terminia — licenciranje (radni paket)
|
||||
|
||||
> **Misija:** dovesti licenciranje ASP‑Terminia terminala do produkcije na
|
||||
> postojećem `dal-license-server`-u (server 151), bez lomljenja ijednog
|
||||
> postojećeg klijenta (ESIR/ARV/LIGHT_TICKET su ŽIVI u produkciji).
|
||||
>
|
||||
> **Jezik projekta:** srpski (ekavica), latinica. Kod/komentari na serveru su Go —
|
||||
> komentari srpski ASCII.
|
||||
|
||||
> **Poreklo:** paket je nastao u firmverskom repou (`asp-terminia/licence/`) i
|
||||
> prebačen ovde 2026-07-24, jer je sav posao serverski. Firmverska strana je
|
||||
> gotova i ne dira se. „**ASP repo**" u tekstu znači
|
||||
> <https://git.terminia.net/djuka/asp-terminia>.
|
||||
|
||||
## Sadržaj foldera
|
||||
|
||||
| Fajl | Šta je unutra |
|
||||
|---|---|
|
||||
| [01-postojece-stanje.md](01-postojece-stanje.md) | šta VEĆ postoji: server (Go/MySQL/nginx/kripto) i firmware klijent (gotov!) |
|
||||
| [02-api-ugovor-firmware.md](02-api-ugovor-firmware.md) | tačan ugovor koji firmware očekuje — polja, potpis, greške |
|
||||
| [03-zadaci.md](03-zadaci.md) | šta treba uraditi, redom, sa kriterijumima prihvatanja |
|
||||
| [04-pravila-rada.md](04-pravila-rada.md) | **OBAVEZNO pročitati prvo** — produkcija, backup, tajne, granice |
|
||||
| [05-enforcement-odluke.md](05-enforcement-odluke.md) | pitanja E1–E6 za vlasnika: šta uređaj radi bez licence |
|
||||
|
||||
## Kontekst u 5 redova
|
||||
|
||||
1. **Šta se licencira:** ESP32‑S3 terminal za kontrolu prolaza (bazeni/spa), proizvod
|
||||
**„ASP‑Terminia"** (Autonomni Sistem Prolaza). Licenca je vezana za **MAC** čipa
|
||||
(eFuse, nepromenljiv) preko `machine_fingerprint`.
|
||||
2. **Server već postoji:** `dal-license-server` (Go, MySQL, RSA‑2048/SHA‑256) na
|
||||
`157.180.119.151`, u produkciji sa 3 proizvoda / ~140 licenci / ~19 aktivacija.
|
||||
3. **Firmware klijent je GOTOV** (modul `licenca.h/.cpp` u firmveru, od verzije 0.10.0):
|
||||
aktivacija, offline verifikacija potpisa javnim ključem, UI. Čeka samo proizvod
|
||||
i ključ na serveru.
|
||||
4. **Dva sloja:** potpisana lokalna licenca (radi offline) + serverska provera/obnova
|
||||
(opoziv). Mrežna greška NIKAD ne obara uređaj.
|
||||
5. **Domeni (kupuje vlasnik):** `licenca.terminia.net` → 157.180.119.151 (Let's
|
||||
Encrypt). Dok domena nema, uređaj radi preko IP‑a sa `setInsecure()` — odluku
|
||||
ionako štiti RSA potpis, ne TLS kanal.
|
||||
|
||||
## Šta agent NE radi
|
||||
|
||||
- Ne donosi odluku o **ponašanju uređaja bez licence** (gašenje funkcija) — to je
|
||||
odluka vlasnika (pitanja u 03-zadaci.md §Z4). Priprema se predlog, čeka se DA.
|
||||
- Ne dira postojeće proizvode (ESIR, ARV, LIGHT_TICKET) niti `terminia` SaaS
|
||||
(portovi 8091/8092 na istom serveru — TO NIJE OVAJ POSAO).
|
||||
- Ne čita niti loguje tajne (`.env`, privatni ključ) — vidi 04-pravila-rada.md.
|
||||
|
||||
## Veze ka ostatku projekta
|
||||
|
||||
- **Firmware repo (ASP repo):** <https://git.terminia.net/djuka/asp-terminia>
|
||||
(klijent: `firmware/10_terminia/licenca.h`, `licenca.cpp`; javni ključ ugrađen).
|
||||
Firmverska strana je GOTOVA od FW 0.10.0 — ovaj paket je ne dira.
|
||||
- Dizajn/istorijat: `ASP repo docs/18-licenciranje-po-mac.md` (pisan PRE nego što je pravi
|
||||
API poznat — gde se razlikuju, **ovaj folder je merodavan**), `ASP repo docs/21-platforma-i-provisioning.md`.
|
||||
- Serviserska strana (RBAC, uređaji, LoggerService): `ASP repo: serviseri/` —
|
||||
isti backend, drugi radni paket; koordinacija preko šeme baze (vidi tamo 01).
|
||||
*(Taj paket se seli u ovaj repo posebno — vidi dogovor od 2026-07-24.)*
|
||||
- Serverski kod i konvencije: [../../CLAUDE.md](../../CLAUDE.md),
|
||||
[../ARCHITECTURE.md](../ARCHITECTURE.md), [../../API.md](../../API.md).
|
||||
Loading…
Reference in New Issue
Block a user