dal-license-server/API.md
djuka dc0114e4b7 Inicijalni commit: kompletna implementacija + dokumentacija + testovi
- Kompletna Go implementacija licencnog servera (19 Go fajlova)
- Klijentski API: activate, deactivate, validate
- Admin API: CRUD licence, stats, audit log
- Admin dashboard: htmx + Go templates
- RSA-2048 potpisivanje licencnih podataka
- Rate limiting i API key autentifikacija
- MySQL migracije i seed podaci (ESIR, ARV, LIGHT_TICKET)
- Unit testovi: keygen, crypto, model, middleware (24 testa)
- Dokumentacija: SPEC.md, ARCHITECTURE.md, SETUP.md, API.md, TESTING.md, README.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 07:42:25 +00:00

273 lines
4.9 KiB
Markdown

# DAL License Server — API Dokumentacija
Bazni URL: `http://localhost:8090`
## Health
### GET /api/v1/health
Provera da li server radi.
**Response 200:**
```json
{"status": "ok"}
```
---
## Klijentski API
Endpointi za klijentske aplikacije (ESIR, ARV, Light-Ticket). Bez autentifikacije, zastiteni rate limiting-om.
### POST /api/v1/activate
Aktivacija licence na konkretnom racunaru.
**Request:**
```json
{
"license_key": "LT-K7M2-9P4N-R3W8-J6T1",
"machine_fingerprint": "sha256:a1b2c3d4e5f6...",
"app_version": "1.0.0",
"os": "windows",
"hostname": "FIRMA-PC"
}
```
**Response 200:**
```json
{
"license": {
"license_key": "LT-K7M2-9P4N-R3W8-J6T1",
"product": "LIGHT_TICKET",
"license_type": "MONTHLY",
"issued_at": "2026-03-01T00:00:00Z",
"expires_at": "2026-04-01T00:00:00Z",
"activated_at": "2026-03-03T10:00:00Z",
"machine_fingerprint": "sha256:a1b2c3d4e5f6...",
"grace_days": 30,
"limits": {
"max_operators": 3
},
"features": ["TICKET_VALIDATION", "REPORTS", "EXCEL_EXPORT", "LIVE_FEED"],
"customer": {
"name": "Firma DOO",
"email": "admin@firma.rs"
}
},
"signature": "RSA-SHA256:base64encodedSignature..."
}
```
**Error kodovi:**
| Kod | Opis |
|-----|------|
| INVALID_KEY | Licencni kljuc ne postoji |
| ALREADY_ACTIVATED | Licenca vec aktivirana na drugom racunaru |
| KEY_EXPIRED | Licenca istekla |
| KEY_REVOKED | Licenca opozvana |
| PRODUCT_MISMATCH | Proizvod ne odgovara |
**Error response 400:**
```json
{
"error": {
"code": "ALREADY_ACTIVATED",
"message": "Licenca je već aktivirana na drugom računaru",
"details": {
"activated_on": "DRUGA-PC",
"activated_at": "2026-02-15T08:00:00Z"
}
}
}
```
### POST /api/v1/deactivate
Deaktivacija licence (za transfer na drugi racunar).
**Request:**
```json
{
"license_key": "LT-K7M2-9P4N-R3W8-J6T1",
"machine_fingerprint": "sha256:a1b2c3d4e5f6..."
}
```
**Response 200:**
```json
{
"message": "Licenca uspešno deaktivirana",
"can_reactivate": true
}
```
### POST /api/v1/validate
Opciona online provera validnosti licence.
**Request:**
```json
{
"license_key": "LT-K7M2-9P4N-R3W8-J6T1",
"machine_fingerprint": "sha256:a1b2c3d4e5f6..."
}
```
**Response 200:**
```json
{
"valid": true,
"expires_at": "2026-04-01T00:00:00Z",
"revoked": false
}
```
---
## Admin API
Svi admin endpointi zahtevaju `X-API-Key` header.
```
X-API-Key: vas-api-kljuc
```
### GET /api/v1/admin/products
Lista svih proizvoda.
**Response 200:**
```json
[
{
"id": 1,
"code": "ESIR",
"name": "ESIR Fiskalizacija",
"key_prefix": "ESIR-",
"default_limits": {"max_installations": 1},
"available_features": ["FISCALIZATION", "REPORTS"],
"active": true
}
]
```
### GET /api/v1/admin/licenses
Lista licenci. Podrzava filter po proizvodu.
**Query parametri:**
- `product` — Filter po product code (ESIR, ARV, LIGHT_TICKET)
**Response 200:**
```json
[
{
"id": 1,
"product_code": "LIGHT_TICKET",
"license_key": "LT-K7M2-9P4N-R3W8-J6T1",
"license_type": "MONTHLY",
"customer_name": "Firma DOO",
"expires_at": "2026-04-01T00:00:00Z",
"active": true,
"revoked": false
}
]
```
### POST /api/v1/admin/licenses
Kreiranje nove licence.
**Request:**
```json
{
"product_code": "LIGHT_TICKET",
"license_type": "MONTHLY",
"customer_name": "Firma DOO",
"customer_pib": "123456789",
"customer_email": "admin@firma.rs",
"limits": {"max_operators": 10},
"features": ["TICKET_VALIDATION", "REPORTS", "EXCEL_EXPORT", "LIVE_FEED"],
"grace_days": 30,
"notes": "Pro paket"
}
```
**Response 201:**
```json
{
"id": 1,
"license_key": "LT-K7M2-9P4N-R3W8-J6T1",
"message": "Licenca kreirana"
}
```
### GET /api/v1/admin/licenses/{id}
Detalji jedne licence.
### PUT /api/v1/admin/licenses/{id}
Izmena licence.
### POST /api/v1/admin/licenses/{id}/revoke
Opozivanje licence.
**Request:**
```json
{
"reason": "Klijent nije platio"
}
```
### POST /api/v1/admin/licenses/{id}/release
Force release aktivacije (kada je racunar klijenta nedostupan).
### GET /api/v1/admin/licenses/{id}/activations
Lista aktivacija za licencu.
### GET /api/v1/admin/audit
Audit log. Lista svih akcija.
### GET /api/v1/admin/stats
Statistike po proizvodima.
---
## Dashboard rute (htmx)
| Metoda | Putanja | Opis |
|--------|---------|------|
| GET | /login | Login stranica |
| POST | /login | Login submit |
| POST | /logout | Logout |
| GET | /dashboard | Pocetna — statistike |
| GET | /licenses | Lista licenci |
| GET | /licenses/new | Forma za novu licencu |
| POST | /licenses | Kreiranje licence |
| GET | /licenses/{id} | Detalji licence |
| POST | /licenses/{id}/revoke | Opozivanje |
| POST | /licenses/{id}/release | Force release |
| GET | /audit | Audit log |
---
## Rate limiting
| Endpoint | Limit |
|----------|-------|
| POST /api/v1/activate | 10 req/min per IP |
| POST /api/v1/deactivate | 10 req/min per IP |
| POST /api/v1/validate | 60 req/min per IP |
---
*Mart 2026*