# Decision Log — Service Auto Prototype

**Prototype**: ROA2WEB `feat/service-auto`
**Owner**: Marius (ERP patron + sole dev)
**Timeline**: 24 săptămâni @ 2-4h/săpt
**Last updated**: 2026-04-11

Acest fișier urmărește verdictele pe cele 6 ipoteze din
`docs/service-auto/claude-main-design-20260411-rethink.md §"Things this prototype will probe"`.
Fiecare verdict e actualizat pe măsură ce testele rulează.
**Recomandarea finală** (merge/no-go pentru phase 2) se completează după săpt 24.

---

## Kill Criterion Status

Niciun kill criterion nu a fost declanșat până la data de mai sus.

Reminder: dacă orice ipoteză eșuează cu un răspuns clar → prototype încheiat cu succes
(learning obținut, decision point clar, zero cod irosit). Kill ≠ eșec.

---

## Ipoteza #1 — `python-oracledb` + OUT params

**Ipoteză**: `python-oracledb` apelează curat PL/SQL proc cu IN + OUT params (NUMBER + VARCHAR2).

**Status**: `CONFIRMED` ✅

**Dovezi**:
- Săpt 2 (`poc/async_out_param_probe.py`): `cursor.var(oracledb.NUMBER)` + `cursor.callproc`
  → `out_var.getvalue()` returnează `42.0` corect. Assert PASSED.
  Latență callproc: ~1ms după connect. Note: `.getvalue()` returnează `float`, necesită `int()` cast.
- Săpt 3 (test #1 + #2 `SP_CREEAZA_COMANDA_PROTOTIP`): SP cu 4 IN + 2 OUT (NUMBER + VARCHAR2)
  apelat via sync-facade în `oracle_pool.get_connection('mariusm_test')`.
  Test #1: 5.9ms, OUT p_id_ordl=412, p_nrord='P01-2'. Post-rollback: 0 rows ✅
- Pattern implementat în `backend/modules/service_auto/services/comanda_service.py`

**Decizie adoptată**: sync-facade (consistent cu `oracle_pool.py`), nu true-async
(`connect_async`). Motivat în `week1-notes.md §Gate Correction 9`.

**Implicație pentru template**: pattern `cursor.var(oracledb.NUMBER/STRING)` + `callproc`
+ `int(out.getvalue())` e reutilizabil direct pentru orice SP cu OUT params.

---

## Ipoteza #2 — `session_callback` nu leak-uiește între requests

**Ipoteză**: `session_callback` pentru `CURRENT_SCHEMA` switching nu produce state leak
între requests concurente pe același pool.

**Status**: `CONFIRMED` ✅

**Dovezi** (2026-04-12, `test_pool_concurrency.py` — 3/3 passed):
- `test_two_concurrent_connections_return_correct_results`: 2 asyncio tasks simultane pe
  același pool, bind values distincte (111, 222) → rezultate corecte fără cross-bleed.
- `test_session_callback_runs_per_connection`: `session_callback` înregistrat pe server config
  → confirmat că se apelează la prima conexiune din pool; nu leaked state inter-connection.
- `test_ten_concurrent_queries_no_errors`: 10 tasks concurente pe pool cu `max=5` →
  `POOL_GETMODE_WAIT` queue-uiește corect excesul; toate 10 completate fără erori.

**Nota bene**: pool `mariusm_test` nu folosește `session_callback` (ROA_WEB apelează SP cu
schemă explicită `MARIUSM_AUTO.SP_...`). Patch-ul `session_callback` în `oracle_pool.py`
e disponibil pentru modulele viitoare care au nevoie de `CURRENT_SCHEMA` switching.

---

## Ipoteza #3 — GRANTS model: EXECUTE ON SP, zero DML direct

**Ipoteză**: user `ROA_WEB` cu `GRANT EXECUTE ON SP` + zero `INSERT/UPDATE/DELETE` pe
tabele → INSERT direct returnează `ORA-00942`, SP call returnează succes.

**Status**: `CONFIRMED` ✅

**Dovezi** (2026-04-12):
- `ROA_WEB` creat de DBA cu `GRANT CREATE SESSION` + `GRANT EXECUTE ON SP` +
  `GRANT SELECT ON AUTO_VMASINICLIENTI` + `GRANT SELECT ON DEV_TIP_DEVIZ`.
- `test_grants_integration.py` — 3/3 passed (anterior 3 skipped — fișier lipsă parola):
  - `test_insert_direct_fails` → `ORA-00942` ✅ (INSERT blocat)
  - `test_select_direct_fails` → `ORA-00942` ✅ (SELECT pe tabel neautorizat blocat)
  - `test_exec_sp_succeeds` → SP apelat cu succes ✅
- Verificare live: `AUTO_VMASINICLIENTI` (266 rows) + `DEV_TIP_DEVIZ` (7 rows) accesibile;
  `NOM_LUCRARI` direct → `ORA-00942` (Oracle ascunde complet obiectul, nu returnează 0 rows).
- Pool `mariusm_test` switchat la `ROA_WEB` în `.env` / `.env.prod` / `.env.test`.

**Arhitectura multi-tenant documentată** (`grants-audit.md §4`):
- Oracle 21c: schema-level grants (23ai) nu există. Proxy auth respins — anulează boundary SP-only.
- Soluție: grants per-obiect incluse în deployment scripts. Firmă nouă = 1 script onboarding.
  Obiect nou în toate schemele = 1 script companion care loopează `V_NOM_FIRME`.

---

## Ipoteza #4 — Diacritice encoding end-to-end

**Ipoteză**: `RAISE_APPLICATION_ERROR(-20001, 'mesaj cu ă î ș ț â')` ajunge în Vue ca
eroare user-friendly, encoding corect prin tot stack-ul (Oracle → oracledb → FastAPI → Vue).

**Status**: `CONFIRMED` ✅ (Oracle→oracledb→FastAPI; Vue pending manual browser test)

**Dovezi** (2026-04-12, `test_diacritice_encoding.py` — 2/2 passed):
- L1 — Oracle→oracledb: `RAISE_APPLICATION_ERROR(-20001, 'Client invalid: ă î ș ț â Ă Î Ș Ț Â')`
  trimis via bind variable → `DatabaseError.args[0].message` conține toate diacriticele intact.
  Set complet testat: `ă î ș ț â Ă Î Ș Ț Â`. NLS chain funcționează fără configurare explicită.
- L2 — oracledb→FastAPI: `_handle_oracle_error(e)` → `HTTPException(422, detail)` conține
  diacriticele, prefix `ORA-20001:` stripped corect.
- Vue (manual pending): necesită browser + backend pornit; Toast PrimeVue afișează `detail`
  din 422 response. Probabilitate eșec mică (Vue nu modifică string-uri JSON).

---

## Ipoteza #5 — DX acceptabil (save→result < 10s)

**Ipoteză**: FastAPI hot-reload + Vite dev-server + SSH tunnel Oracle e un DX acceptabil
pentru side-work de 2-4h/săpt.

**Status**: `CONFIRMED` ✅

**Dovezi** (`week1-notes.md §Conectivitate`):

| Operație | Timp |
|----------|------|
| Sync connect | 33ms |
| Async connect | 22ms |
| Query | 0.2-3.3ms |
| SP callproc (săpt 3) | 5.9ms |

- Server Oracle e direct (10.0.20.121:1521) — fără SSH tunnel pe acest server.
- uvicorn `--reload` detectează schimbările și reîncarcă în < 1s.
- Total "save fișier → văd rezultatul" ≪ 10s. Gate trecut.

**Implicație**: ecosistemul nu necesită optimizare înainte de content. DX confirmat.

---

## Ipoteza #6 — Auth multi-server fără modificări shared code

**Ipoteză**: flux-ul de auth existent (login → JWT cu `server_id` → `AuthenticationMiddleware`)
suportă un server nou fără modificări la `shared/` code.

**Status**: `CONFIRMED` ✅

**Dovezi Oracle** (`week3-auth-audit.md`, 2026-04-11):
- `pack_drepturi.verificautilizator('MARIUS M', '123')` → `803` ✅
- `V_NOM_FIRME`: 3 firme cu `schema='MARIUSM_AUTO'` (id 110/167/169) ✅

**Dovezi HTTP** (2026-04-12):
```
POST /api/auth/login {"username":"VIZUALIZARE","password":"123","server_id":"mariusm_test"}
→ JWT companies: ["110","167","169"]  ✅
→ JWT server_id: "mariusm_test"       ✅
→ zero modificări în shared/auth/     ✅

GET /api/service-auto/ping (Bearer JWT)
→ {"result":1,"server":"mariusm_test","latency_ms":0.43}  ✅
```

Nota: MARIUS M are 2FA activat (email configurat) → testat cu VIZUALIZARE (no email,
aceleași 3 firme MARIUSM_AUTO). Același cod auth, același JWT structure.

---

## Decizii arhitecturale documentate

### D1 — Sync-facade în loc de true-async (Săpt 1)
**Decizie**: `oracle_pool.get_connection()` + `pool.acquire()` (sync) în `async def`.
**Motivare**: consistent cu pattern-ul deja proof-ed în `treasury_service.py` prod.
True-async (`connect_async`) nu aduce beneficii la latențele măsurate (22-33ms connect).

### D2 — SP_CREEAZA_COMANDA_PROTOTIP nou în loc de reuse pack_auto (Săpt 3)
**Decizie**: Opțiunea 3 din design doc — SP minimal cu 2 INSERT-uri (nom_lucrari → dev_ordl)
și `RETURNING id_lucrare`, zero dependency pe `pack_sesiune`.
**Motivare**: `pack_auto.dev_adauga_lucrare` v2 are 17 params + `pack_sesiune` coupling;
SP nou cu RETURNING e idiomul Oracle modern și mai ușor de testat.

### D3 — CONTAFIN_ORACLE în faza A, ROA_WEB în faza B (Săpt 3)
**Decizie**: Faza A (săpt 3+) folosește CONTAFIN_ORACLE (DBA role, zero grant work).
ROA_WEB creat în faza B când ipoteza #3 e pusă la test.
**Motivare**: faza A validează H1+H2+H5+H6 independent de H3.

### D4 — Pool `mariusm_test` separat de `central` (Săpt 3)
**Decizie**: ID distinct `mariusm_test` în ORACLE_SERVERS deși e același host/user ca `central`.
**Motivare**: pool sizing independent pentru module service_auto + swap atomic la ROA_WEB
în faza B (schimbă doar `.env`, zero modificări cod).

---

## Recomandare finală

**Decizie: MERGE** ✅ — prototype confirmă că arhitectura e viabilă pentru phase 2.

**Data**: 2026-04-12
**Toate 6 ipoteze**: CONFIRMED (H1, H2, H3, H4, H5, H6)

### Verdict pe ipoteze

| # | Ipoteză | Verdict | Implicație phase 2 |
|---|---|---|---|
| H1 | oracledb + OUT params | ✅ CONFIRMED | Pattern `cursor.var()` reutilizabil direct |
| H2 | session_callback concurență | ✅ CONFIRMED | Disponibil pentru module multi-schemă viitoare |
| H3 | ROA_WEB grants SP-only | ✅ CONFIRMED | Arhitectura grants documentată + automatizată |
| H4 | Diacritice encoding | ✅ CONFIRMED | NLS chain OK fără configurare explicită |
| H5 | DX < 10s | ✅ CONFIRMED | Ecosistem nu necesită optimizare |
| H6 | Auth multi-server zero shared code | ✅ CONFIRMED | Pattern reutilizabil pentru orice server Oracle nou |

### Ce a funcționat mai bine decât așteptat

- **Viteza SP**: 5.9ms callproc (față de estimat 50ms) — server local, zero latency Oracle
- **Diacritice**: zero configurare NLS necesară — oracledb + Oracle 21c funcționează out-of-box
- **Auth reuse**: zero linii modificate în `shared/` — `.env` + `register_server()` suficiente
- **ROA_WEB grants**: soluția cu `V_NOM_FIRME` loop e mai curată decât anticipat

### Precauții pentru phase 2

- **session_callback multi-schemă**: testul de concurență a confirmat pool-ul, dar izolarea
  CURRENT_SCHEMA între două scheme diferite pe același pool nu e testată — tagged connections
  necesare dacă apare cazul (vezi TODO-phase2.md)
- **SP production-grade**: `SP_CREEAZA_COMANDA_PROTOTIP` e minimal — nu setează `id_sucursala`,
  `id_inspector`, `proc_tvav`, `observatii`. Phase 2 decide: extinde SP-ul sau migrează la
  `pack_auto.dev_adauga_lucrare` (17 params, coupling cu pack_sesiune)
- **Vue manual browser test**: ComandaNoua.vue nu a fost testată în browser (H4 Vue layer)

### Deliverables prototype livrate

| Fișier | Ce conține |
|---|---|
| `docs/service-auto/template-modul-oracle.md` | Rețetă reutilizabilă: 11 secțiuni, de la `.env` la tests |
| `docs/service-auto/learnings.md` | 7 patterns consolidate din notele săptămânale |
| `docs/service-auto/grants-audit.md` | Arhitectura grants multi-tenant + scripts onboarding |
| `backend/modules/service_auto/` | Modul complet: router, service, schemas, tests (22/22) |
| `src/modules/service-auto/views/ComandaNoua.vue` | Formular cu date reale din Oracle |
| `poc/hello_oracle.py`, `poc/async_out_param_probe.py` | POC-urile de referință |
