From f115b5e35a0d65a39e72cdd4138db3cd4c174aea Mon Sep 17 00:00:00 2001 From: Claude Agent Date: Fri, 5 Jun 2026 15:00:42 +0000 Subject: [PATCH] modificari in curs nu stiu care este faza --- .gitignore | 1 - .../tests/test_comanda_persist.py | 10 + .../tests/test_grants_integration.py | 17 ++ docs/service-auto/PACK_SERII_NUMERE.pck | 267 +++++++++++++++++ docs/service-auto/decision-log.md | 31 ++ docs/service-auto/deploy-schema-noua.md | 277 ++++++++++++++++++ docs/service-auto/grants-audit.md | 14 + .../migrations/ff_2026_04_14_01_AUTO.sql | 98 +++++++ docs/service-auto/onboarding_roa_web.sql | 52 +++- docs/service-auto/pack-serii-verification.md | 149 ++++++++++ 10 files changed, 902 insertions(+), 14 deletions(-) create mode 100644 docs/service-auto/PACK_SERII_NUMERE.pck create mode 100644 docs/service-auto/deploy-schema-noua.md create mode 100644 docs/service-auto/migrations/ff_2026_04_14_01_AUTO.sql create mode 100644 docs/service-auto/pack-serii-verification.md diff --git a/.gitignore b/.gitignore index 6b3f625..6cf2119 100644 --- a/.gitignore +++ b/.gitignore @@ -543,4 +543,3 @@ scripts/ralph/usage.jsonl # Service-auto reference material (local only, not in repo) docs/service-auto/*.pdf -docs/service-auto/HANDOFF.md diff --git a/backend/modules/service_auto/tests/test_comanda_persist.py b/backend/modules/service_auto/tests/test_comanda_persist.py index a8bcf87..df4468e 100644 --- a/backend/modules/service_auto/tests/test_comanda_persist.py +++ b/backend/modules/service_auto/tests/test_comanda_persist.py @@ -45,6 +45,16 @@ def _connect() -> oracledb.Connection: @pytest.mark.integration +@pytest.mark.skip( + reason=( + "Obsolete target SP: commit 9cd7f35 migrated comanda creation to " + "PACK_AUTO (+PACK_SERII_NUMERE). SP_CREEAZA_COMANDA_PROTOTIP is no " + "longer the production path; callproc signature drift causes " + "PLS-00306. Persist/durability is now covered by live smoke tests " + "via /api/service-auto/comenzi — see docs/service-auto/" + "decision-log.md (2026-04-13)." + ) +) def test_comanda_persist_and_reconnect(): """ Full round-trip: callproc → commit → close → NEW connection → SELECT → assert exists. diff --git a/backend/modules/service_auto/tests/test_grants_integration.py b/backend/modules/service_auto/tests/test_grants_integration.py index 9cde648..2b15a2a 100644 --- a/backend/modules/service_auto/tests/test_grants_integration.py +++ b/backend/modules/service_auto/tests/test_grants_integration.py @@ -98,6 +98,14 @@ def test_insert_direct_fails(roa_web_connection): @pytest.mark.integration +@pytest.mark.skip( + reason=( + "Obsolete premise: ff_2026_04_13_01_AUTO.sql granted SELECT on " + "NOM_LUCRARI to ROA_WEB (needed by /api/service-auto/operatii). " + "Assertion ORA-00942 no longer holds. Rework or remove — see " + "docs/service-auto/decision-log.md (2026-04-13)." + ) +) def test_select_direct_fails(roa_web_connection): """ ROA_WEB has no SELECT privilege on NOM_LUCRARI. @@ -120,6 +128,15 @@ def test_select_direct_fails(roa_web_connection): # Positive test — SP execution must succeed (EXECUTE grant) # --------------------------------------------------------------------------- @pytest.mark.integration +@pytest.mark.skip( + reason=( + "Obsolete target SP: commit 9cd7f35 migrated comanda creation to " + "PACK_AUTO (+PACK_SERII_NUMERE). SP_CREEAZA_COMANDA_PROTOTIP is no " + "longer invoked by production code; signature drift causes " + "PLS-00306. Rewrite against PACK_AUTO.DEV_ADAUGA_LUCRARE or remove " + "— see docs/service-auto/decision-log.md (2026-04-13)." + ) +) def test_exec_sp_succeeds(roa_web_connection): """ ROA_WEB has EXECUTE on SP_CREEAZA_COMANDA_PROTOTIP. diff --git a/docs/service-auto/PACK_SERII_NUMERE.pck b/docs/service-auto/PACK_SERII_NUMERE.pck new file mode 100644 index 0000000..9118b38 --- /dev/null +++ b/docs/service-auto/PACK_SERII_NUMERE.pck @@ -0,0 +1,267 @@ +-- Reconstructed from ALL_SOURCE (GET_DDL unavailable for ROA_WEB) +-- ============ PACKAGE SPEC ============ +CREATE OR REPLACE PACKAGE MARIUSM_AUTO. +PACKAGE "PACK_SERII_NUMERE" is + + -- Author : MARIUS.ATANASIU + -- Created : 9/8/2006 14:00:56 + -- Purpose : + + -- 11.11.2009 + -- marius.mutu + -- aloca_numar - id_tip_entitate = 6 (tipuri imobilizari) + + -- 14.07.2016 + -- marius.mutu + -- am marit numarul de elemente din tabela_tipdoc si tabela_numere la 23 + -- dadea eroare la genereare de numere pentru PROFORMA tip=23 + + -- 17.08.2016 + -- marius.mutu + -- adauga_serie, modifica_serie: adaugat parametri ISAUTOFACTURA, ISBENEFICIARI, ISTERTI, ISFURNIZORI + + v_id_tipdoc PLAJE_NUMERE.ID_TIPDOC%TYPE; + v_id_tipentitate PLAJE_NUMERE.ID_TIPENTITATE%TYPE; + v_id_entitate PLAJE_NUMERE.ID_ENTITATE%TYPE; + v_id_serie PLAJE_NUMERE.ID_SERIE%TYPE; + v_id_sucursala PLAJE_NUMERE.ID_SUCURSALA%TYPE; + + nNumereMultiple NUMBER(1) := 0; -- 1 = in cadrul unei operatii se genereaza mai multe numere din tipul de document respectiv + + nTipNIR PLAJE_NUMERE.ID_TIPDOC%TYPE := 1; + nTipBonConsum PLAJE_NUMERE.ID_TIPDOC%TYPE := 2; + nTipBonFiscal PLAJE_NUMERE.ID_TIPDOC%TYPE := 3; + nTipNIRCMP PLAJE_NUMERE.ID_TIPDOC%TYPE := 4; + nTipFactura PLAJE_NUMERE.ID_TIPDOC%TYPE := 5; + nTipAvizExpeditie PLAJE_NUMERE.ID_TIPDOC%TYPE := 6; + nTipPVProductieVin PLAJE_NUMERE.ID_TIPDOC%TYPE := 7; + nTipPVProductie PLAJE_NUMERE.ID_TIPDOC%TYPE := 8; + nTipBonLivrare PLAJE_NUMERE.ID_TIPDOC%TYPE := 9; + nTipNumarRegistratura PLAJE_NUMERE.ID_TIPDOC%TYPE := 10; + nTipNumarInventar PLAJE_NUMERE.ID_TIPDOC%TYPE := 11; + nTipMonetar PLAJE_NUMERE.ID_TIPDOC%TYPE := 12; + nTipContract PLAJE_NUMERE.ID_TIPDOC%TYPE := 13; + nTipCodMaterial PLAJE_NUMERE.ID_TIPDOC%TYPE := 14; + nTipCodBare PLAJE_NUMERE.ID_TIPDOC%TYPE := 15; + nTipChitanta PLAJE_NUMERE.ID_TIPDOC%TYPE := 16; + nTipNotaPlata PLAJE_NUMERE.ID_TIPDOC%TYPE := 17; + nTipNrInventarImob PLAJE_NUMERE.ID_TIPDOC%TYPE := 18; + nTipNrDispPlata PLAJE_NUMERE.ID_TIPDOC%TYPE := 19; + nTipNrOrdinPlata PLAJE_NUMERE.ID_TIPDOC%TYPE := 21; + nTipBonImport PLAJE_NUMERE.ID_TIPDOC%TYPE := 22; + nTipProforma PLAJE_NUMERE.ID_TIPDOC%TYPE := 23; + nTipFactura394 PLAJE_NUMERE.ID_TIPDOC%TYPE := 24; + nTipBonPersoane PLAJE_NUMERE.ID_TIPDOC%TYPE := 25; + nTipPOSCard PLAJE_NUMERE.ID_TIPDOC%TYPE := 26; + + nCountTipDoc NUMBER(5) := 26; + + TYPE linie_numar IS RECORD( + v_id_numar SERII_NUMERE.ID_NUMAR%TYPE, + v_numar SERII_NUMERE.NUMAR%TYPE); + + TYPE tab_numere IS TABLE OF linie_numar; + TYPE tab_numere2d IS TABLE OF tab_numere; + TYPE cursor_plaje IS REF CURSOR; + TYPE tab_tipdoc_nrelem IS TABLE OF NUMBER(10); + + tabela_tipdoc tab_tipdoc_nrelem := tab_tipdoc_nrelem(1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1); + + linie_goala linie_numar := null; + -- trebuie atatea linie_goala cate tipuri de documente sunt + tabela_numere tab_numere2d := tab_numere2d(tab_numere(linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala, + linie_goala)); + + PROCEDURE verificari_serie(V_ID_SERIE IN NUMBER, + V_AN IN NUMBER, + V_LUNA IN NUMBER, + V_LUNGIME IN NUMBER); + + PROCEDURE adauga_serie(V_SERIE IN VARCHAR2, + V_AN IN NUMBER, + V_LUNA IN NUMBER, + V_LUNGIME IN NUMBER, + V_INACTIV IN NUMBER, + V_ID_UTIL IN NUMBER, + V_ISAUTOFACTURA IN SERII.ISAUTOFACTURA%TYPE DEFAULT 0, + V_ISBENEFICIARI IN SERII.ISBENEFICIARI%TYPE DEFAULT 0, + V_ISTERTI IN SERII.ISTERTI%TYPE DEFAULT 0, + V_ISFURNIZORI IN SERII.ISFURNIZORI%TYPE DEFAULT 0, + V_PREFIX IN SERII.PREFIX%TYPE DEFAULT NULL, + V_AN2CARACTERE IN SERII.AN2CARACTERE%TYPE DEFAULT 0); + + PROCEDURE modifica_serie(V_ID_SERIE IN NUMBER, + V_SERIE IN VARCHAR2, + V_AN IN NUMBER, + V_LUNA IN NUMBER, + V_LUNGIME IN NUMBER, + V_INACTIV IN NUMBER, + V_ID_UTIL IN NUMBER, + V_ISAUTOFACTURA IN SERII.ISAUTOFACTURA%TYPE DEFAULT 0, + V_ISBENEFICIARI IN SERII.ISBENEFICIARI%TYPE DEFAULT 0, + V_ISTERTI IN SERII.ISTERTI%TYPE DEFAULT 0, + V_ISFURNIZORI IN SERII.ISFURNIZORI%TYPE DEFAULT 0, + V_PREFIX IN SERII.PREFIX%TYPE DEFAULT NULL, + V_AN2CARACTERE IN SERII.AN2CARACTERE%TYPE DEFAULT 0); + + PROCEDURE sterge_serie(V_ID_SERIE IN NUMBER, V_ID_UTIL IN NUMBER); + + PROCEDURE verificari_plaja(V_ID_PLAJA IN NUMBER, + V_ID_TIPDOC IN NUMBER, + V_ID_TIPENTITATE IN NUMBER, + V_ID_ENTITATE IN NUMBER, + V_ID_SERIE IN NUMBER, + V_ID_SUCURSALA IN NUMBER, + V_PL_INF IN NUMBER, + V_PL_SUP IN NUMBER, + V_DATAI IN DATE, + V_DATAS IN DATE); + + PROCEDURE adauga_plaja(V_ID_TIPDOC IN NUMBER, + V_ID_TIPENTITATE IN NUMBER, + V_ID_SERIE IN NUMBER, + V_ID_ENTITATE IN NUMBER, + V_ID_SUCURSALA IN NUMBER, + V_PL_INF IN NUMBER, + V_PL_SUP IN NUMBER, + V_DATAI IN DATE, + V_DATAS IN DATE, + V_INACTIV IN NUMBER, + V_ID_UTIL IN NUMBER); + + PROCEDURE modifica_plaja(V_ID_PLAJA IN NUMBER, + V_ID_TIPDOC IN NUMBER, + V_ID_TIPENTITATE IN NUMBER, + V_ID_SERIE IN NUMBER, + V_ID_ENTITATE IN NUMBER, + V_ID_SUCURSALA IN NUMBER, + V_PL_INF IN NUMBER, + V_PL_SUP IN NUMBER, + V_DATAI IN DATE, + V_DATAS IN DATE, + V_INACTIV IN NUMBER, + V_ID_UTIL IN NUMBER); + + PROCEDURE sterge_plaja(V_ID_PLAJA IN NUMBER, V_ID_UTIL IN NUMBER); + + PROCEDURE modifica_tipdoc(V_ID_TIPDOC IN NUMBER, + V_ID_TIPENTITATE IN NUMBER, + V_CU_SERIE IN NUMBER, + V_CU_PLAJE IN NUMBER, + V_AN IN NUMBER, + V_LUNA IN NUMBER, + V_AN2CARACTERE IN NUMBER, + V_DEZACTIVEAZA_TOT IN NUMBER, + V_ID_UTIL IN NUMBER); + + PROCEDURE seteazaNumereMultiple(V_NUMERE_MULTIPLE IN NUMBER); + + PROCEDURE adauga_element(V_ID_TIPDOC IN NUMBER); + + PROCEDURE seteaza_numar(V_ID_PLAJA IN NUMBER, + V_ULTIMUL_NUMAR IN NUMBER, + V_URMATORUL_NUMAR IN NUMBER); + + PROCEDURE aloca_numar(V_ID_TIPDOC IN NUMBER, + V_ID_SERIE IN NUMBER, + V_ID_GESTIUNE IN NUMBER, + V_ID_UTIL IN NUMBER, + V_ID_SUCURSALA IN NUMBER, + V_NUMAR OUT NUMBER); + + PROCEDURE aloca_numar(V_ID_TIPDOC IN NUMBER, + V_ID_SERIE IN NUMBER, + V_ID_GESTIUNE IN NUMBER, + V_ID_UTIL IN NUMBER, + V_ID_SUCURSALA IN NUMBER, + V_NUMAR OUT NUMBER, + V_ID_NUMAR OUT SERII_NUMERE.ID_NUMAR%TYPE); + + PROCEDURE dezaloca_numere(V_ID_TIPDOC IN NUMBER, V_POZ_START IN NUMBER); + + PROCEDURE dezaloca_numar(V_ID_TIPDOC IN NUMBER); + + PROCEDURE dezaloca_id_numar(V_ID_NUMAR SERII_NUMERE.ID_NUMAR%TYPE); + + FUNCTION genereaza_urmval(V_ID_PLAJA IN NUMBER, + V_PL_INF IN NUMBER, + V_PL_SUP IN NUMBER, + V_MAXLEN IN NUMBER, + V_AN IN NUMBER, + V_LUNA IN NUMBER, + V_LUNGIME IN NUMBER) RETURN VARCHAR2; + + FUNCTION adauga_serie_numar(V_NUMAR IN NUMBER, + V_ID_PLAJA IN NUMBER, + V_ALOCAT IN NUMBER) RETURN NUMBER; + + FUNCTION citeste_serie(V_ID_SERIE IN NUMBER) RETURN VARCHAR2; + + PROCEDURE verifica_cursor_serii(V_ID_TIPDOC IN NUMBER, + V_ID_UTIL IN NUMBER, + V_ID_SUCURSALA IN NUMBER, + V_REZULTAT OUT NUMBER, + V_CURSOR OUT pack_serii_numere.cursor_plaje); + + PROCEDURE verifica_tipdoc(V_ID_TIPDOC IN NUMBER, V_REZULTAT OUT NUMBER); + + FUNCTION IdUtil2IdGrupUtil(V_ID_UTIL SYN_UTILIZATORI.ID_UTIL%TYPE, + V_ID_SUCURSALA NUMBER, + RAISE_APP_ERROR NUMBER) + RETURN GRUPURI_UTILIZATORI.ID_GRUP%TYPE; + +end PACK_SERII_NUMERE; +/ +-- ============ PACKAGE BODY ============ +CREATE OR REPLACE PACKAGE BODY MARIUSM_AUTO. + +/ diff --git a/docs/service-auto/decision-log.md b/docs/service-auto/decision-log.md index f892470..e816caf 100644 --- a/docs/service-auto/decision-log.md +++ b/docs/service-auto/decision-log.md @@ -229,3 +229,34 @@ ROA_WEB creat în faza B când ipoteza #3 e pusă la test. | `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ță | + +--- + +## 2026-04-13 — Skip 3 integration tests obsolete (post bc481da refactor) + +### Context +După commit `bc481da` (multi-tenant refactor) + `9cd7f35` (phase 3 PACK_AUTO) ++ migrația `ff_2026_04_13_01_AUTO.sql` (grants Tier 3), 3 integration tests +vechi din hypothesis-probing phase 1 au rămas pe un contract depășit. + +### Teste marcate cu `@pytest.mark.skip` + +| Test | Cauză | Acțiune viitoare | +|---|---|---| +| `test_grants_integration::test_select_direct_fails` | `ff_2026_04_13_01_AUTO.sql` acordă SELECT pe NOM_LUCRARI lui ROA_WEB (necesar pentru `/operatii`). Asserția ORA-00942 e inversă realității actuale. | Șterge sau rescrie cu altă tabelă la care ROA_WEB n-are acces (dacă mai există un astfel de caz). | +| `test_grants_integration::test_exec_sp_succeeds` | `SP_CREEAZA_COMANDA_PROTOTIP` nu mai e folosit în producție — `comanda_service.crea_comanda` invocă `PACK_SERII_NUMERE.NUMAR_AUTO_INI` + `PACK_AUTO.DEV_ADAUGA_LUCRARE`. Apelul cu 4 IN params cauzează PLS-00306. | Rescrie ca smoke live pe `PACK_AUTO.DEV_ADAUGA_LUCRARE` (17 params) SAU șterge — acoperit de `test_router_authorization` + live smoke tests. | +| `test_comanda_persist::test_comanda_persist_and_reconnect` | Același SP obsolete + durabilitate acum validată prin live smoke `POST /api/service-auto/comenzi` (vezi HANDOFF.md, 2026-04-13). | Rescrie ca e2e peste endpoint-ul HTTP dacă e nevoie, altfel șterge. | + +### Impact suite + +| Înainte | După | +|---|---| +| 62 passed, 3 failed (PLS-00306 + ORA-00942 inversat) | 62 passed, 3 skipped (0 failed) | + +### Ce NU s-a atins + +- Nu s-a modificat cod production (`services/`, `routers/`, `schemas/`) — nu + există regresie reală, doar teste care testau contractul vechi. +- `test_insert_direct_fails` rămâne activ și trece — ROA_WEB încă NU are INSERT pe NOM_LUCRARI, asertiunea e corectă. +- `test_pool_concurrency` (3/3 passed) și `test_diacritice_encoding` (2/2 passed) au ieșit din lista de "failing" — trec pe setup-ul curent; HANDOFF.md era puțin în urmă. + diff --git a/docs/service-auto/deploy-schema-noua.md b/docs/service-auto/deploy-schema-noua.md new file mode 100644 index 0000000..1002ad7 --- /dev/null +++ b/docs/service-auto/deploy-schema-noua.md @@ -0,0 +1,277 @@ +# Deploy — Onboarding schemă / server nou (Service Auto) + +**Scop**: Procedură completă pentru aducerea unei schem Oracle noi (firmă nouă) +sub umbrela modulului `service-auto`, inclusiv cazul în care schema trăiește pe +un server Oracle nou care nu e încă listat în `ORACLE_SERVERS`. + +**Audiență**: DBA + dev ops ROA2WEB. +**Prerechizite**: `CONTAFIN_ORACLE` (sau DBA) pe instanța Oracle destinație; +acces SSH la hostul backend pentru `.env` și restart. + +--- + +## 0. Convenții + +- `` — numele schemei noi (ex: `ACME_AUTO`, `MARIUSM_AUTO`). +- `` — cheia logică pentru server în `ORACLE_SERVERS` (ex: `acme_prod`). +- `` — `id_firma` returnat de `V_NOM_FIRME` pentru schema nouă. +- Toate exemplele folosesc placeholder-uri; **nu hardcoda** `MARIUSM_AUTO` în scripturi noi. + +--- + +## 1. `impdp` schema nouă + +Schema nouă se creează dintr-o schemă template (sau dintr-un dump al unei firme +existente) cu `impdp` + `REMAP_SCHEMA`. + +```bash +# Exemplu minimal — adaptează directory_name, dumpfile, logfile la instanța ta. +impdp system/@ \ + SCHEMAS=TEMPLATE_AUTO \ + REMAP_SCHEMA=TEMPLATE_AUTO: \ + DIRECTORY=DATA_PUMP_DIR \ + DUMPFILE=template_auto.dmp \ + LOGFILE=impdp_.log \ + TRANSFORM=OID:N +``` + +**Opțiuni utile**: + +| Caz | Flag | +|---|---| +| Sequences există deja pe instanță (ex: secvențe globale) | `EXCLUDE=SEQUENCE` | +| Doar DDL + date minimale (fără audit/log tables) | `EXCLUDE=TABLE:"IN('AUDIT_LOG','SESSION_LOG')"` | +| Paralel pe server cu resurse | `PARALLEL=4` | +| Reluare dacă a picat la jumătate | `TABLE_EXISTS_ACTION=SKIP` sau `REPLACE` | + +**Verificare post-impdp**: + +```sql +SELECT COUNT(*) FROM DBA_OBJECTS WHERE OWNER = ''; +SELECT OBJECT_TYPE, COUNT(*) FROM DBA_OBJECTS WHERE OWNER = '' + GROUP BY OBJECT_TYPE ORDER BY 2 DESC; +``` + +Obiectele critice pentru `service-auto` care **trebuie** să existe: +- `PACK_AUTO`, `PACK_MIGRARE`, `PACK_SERII_NUMERE` (PACKAGE) +- `AUTO_VMASINICLIENTI` (VIEW) +- `DEV_TIP_DEVIZ`, `DEV_ORDL`, `NOM_LUCRARI`, `NOM_PARTENERI`, `CALENDAR` (TABLE) +- `DEV_NOM_NORME`, `DEV_NOM_INSPECTORI`, `DEV_NOM_ASIGURATORI` (TABLE) + +--- + +## 2. Rulează `onboarding_roa_web.sql` (GRANT-uri) + +**Fișier**: `docs/service-auto/onboarding_roa_web.sql` + +1. Dacă e prima schemă pe instanță, rulează întâi §2 (CREATE USER ROA_WEB) + — O SINGURĂ DATĂ pe instanță. Parola se ia din vault și se salvează în + `backend/secrets/.oracle_pass` (gitignored). +2. Deschide o copie locală a fișierului și înlocuiește `` cu schema reală + (un singur search-and-replace — vezi header-ul fișierului). +3. Rulează secțiunea §1 conectat ca `CONTAFIN_ORACLE` (sau DBA cu privilegii de GRANT). + +**Verificare post-grants**: + +```sql +-- Ar trebui să returneze ≥ 11 rânduri (6 granturi inițiale + 5 din migrații 04_13). +SELECT TABLE_NAME, PRIVILEGE + FROM DBA_TAB_PRIVS + WHERE GRANTEE = 'ROA_WEB' AND OWNER = '' + ORDER BY TABLE_NAME, PRIVILEGE; +``` + +--- + +## 3. Update `.env` cu `ORACLE_SERVERS` (doar pentru server nou) + +Dacă schema nouă e pe un **server Oracle nou** (alt host decât cele existente), +trebuie adăugat un entry în `backend/.env`. + +> **NU atinge `.env` direct pe serverele rulante în această procedură** — doar +> documentează modificarea. Deployment-ul `.env` urmează procesul standard al +> ops-ului (secret manager / Ansible / copy manual). + +Pattern per `backend/ENV-SETUP.md`: + +```bash +# backend/.env (extras) +ORACLE_SERVERS=existing_key,acme_prod + +ORACLE_SERVER_ACME_PROD_DSN=oracle.acme.local:1521/ROA +ORACLE_SERVER_ACME_PROD_USER=ROA_WEB +ORACLE_SERVER_ACME_PROD_PASS_FILE=backend/secrets/acme_prod.oracle_pass +``` + +Dacă schema nouă trăiește pe un server **deja listat** în `ORACLE_SERVERS`, +pasul 3 se sare — nu trebuie modificat nimic în `.env`. + +--- + +## 4. Restart backend + verifică `V_NOM_FIRME` + +Per `CLAUDE.md`, serverele se pornesc/opresc **doar** cu scripturile dedicate: + +```bash +./start-backend.sh restart # doar backend +# sau +./start.sh prod # backend + frontend + tunnel (dacă e cazul) +./status.sh # verifică starea +``` + +**Verificare că schema nouă a fost descoperită**: + +```bash +# Autentifică-te în UI cu un user care are permisiuni pe schema nouă (sau via curl): +curl -H "Authorization: Bearer " http://localhost:8000/api/auth/firme +``` + +Trebuie să apară `` cu noul `id_firma`. Notează `` — e folosit +în pasul următor și în smoke tests. + +Dacă `V_NOM_FIRME` e cache-uit, forțează refresh conform `cache/decorators.py` +(TTL schema lookups = 24h; restart backend = invalidare completă). + +--- + +## 5. Rulează migrațiile service-auto în ordine cronologică + +Directorul `docs/service-auto/migrations/` conține migrațiile per-schemă care +completează schema template cu modificările recente. Rulează-le **în ordine +alfabetică a numelui fișierului** (convenția `ff_YYYY_MM_DD_NN_AUTO.sql` +garantează ordine cronologică). + +Migrații curente (aprilie 2026): + +| Ordine | Fișier | Rol | +|---|---|---| +| 1 | `ff_2026_04_12_01_AUTO.sql` | Adaugă `DEV_ORDL.id_sucursala` + rescrie `SP_CREEAZA_COMANDA_PROTOTIP` | +| 2 | `ff_2026_04_13_01_AUTO.sql` | GRANT-uri + index functional `IX_NOM_PARTENERI_DEN_UPPER` | +| 3 | `ff_2026_04_13_02_AUTO.sql` | `GRANT INSERT ON NOM_PARTENERI` | + +**Rulare**: conectat **ca schema țintă** (``), NU ca `CONTAFIN_ORACLE`, +pentru că DDL-ul interior (ALTER TABLE, CREATE INDEX, CREATE OR REPLACE PROCEDURE) +rulează pe obiectele proprii ale schemei. + +```bash +# Înlocuiește schema name în fiecare fișier (sau folosește sqlplus ca ). +sqlplus /@ @docs/service-auto/migrations/ff_2026_04_12_01_AUTO.sql +sqlplus /@ @docs/service-auto/migrations/ff_2026_04_13_01_AUTO.sql +sqlplus /@ @docs/service-auto/migrations/ff_2026_04_13_02_AUTO.sql +``` + +Toate migrațiile AUTO sunt **idempotente** (per `.claude/rules/oracle-migrations.md`): +- `ALTER TABLE ADD` wrap în `PACK_MIGRARE.COLUMNEXIST` +- `CREATE INDEX` wrap în `PACK_MIGRARE.OBJECTEXIST` +- `CREATE OR REPLACE PROCEDURE` — natural idempotent +- `GRANT` — no-op la re-rulare + +Re-rularea unei migrații = safe. Footer-ul `pack_migrare.UpdateVersiune(...)` e +ce scrie în tabelul de versiuni. + +**Verificare migrații**: + +```sql +-- Ar trebui să returneze cele 3 versiuni ff_2026_04_12_01_AUTO ... ff_2026_04_13_02_AUTO +SELECT VERSIUNE, DATA_APLICARE FROM .VERSIUNI_APLICATE + WHERE VERSIUNE LIKE 'ff_2026_04%_AUTO' + ORDER BY VERSIUNE; +``` + +(Numele tabelului de versiuni poate diferi — verifică în `PACK_MIGRARE` body.) + +--- + +## 6. Smoke tests + +Folosește un JWT valid pentru un user cu permisiuni pe ``. + +```bash +TOKEN="" +BASE="http://localhost:8000/api/service-auto" + +# 6.1. Ping — răspuns rapid, fără query Oracle. +curl -H "Authorization: Bearer $TOKEN" $BASE/ping + +# 6.2. Tip deviz — citește din DEV_TIP_DEVIZ; verifică GRANT SELECT. +curl -H "Authorization: Bearer $TOKEN" "$BASE/tip-deviz?id_firma=" + +# 6.3. Mașini — citește din AUTO_VMASINICLIENTI. +curl -H "Authorization: Bearer $TOKEN" "$BASE/masini?id_firma=" + +# 6.4. Comenzi — JOIN DEV_ORDL + NOM_LUCRARI. +curl -H "Authorization: Bearer $TOKEN" "$BASE/comenzi?id_firma=" +``` + +**Expectat**: 200 OK cu JSON (array-uri sau obiecte paginate). 401/403 = JWT +sau permisiuni greșite. 500 cu `ORA-00942` = GRANT lipsă (re-rulează §2). +500 cu `ORA-04063` = migrațiile §5 nu au rulat complet (verifică `SP_CREEAZA_...` +și `DEV_ORDL.id_sucursala`). + +--- + +## 7. Rollback + +Dacă onboarding-ul a eșuat ireversibil sau schema nouă trebuie eliminată: + +### 7.1. Oprește accesul din backend + +Elimină `` din `.env` `ORACLE_SERVERS` (dacă a fost adăugat la pasul 3) +și `./start-backend.sh restart`. `V_NOM_FIRME` nu va mai fi interogat pe hostul +respectiv. + +### 7.2. Revocă granturi (optional — vor dispărea cu DROP USER) + +```sql +-- Conectat ca CONTAFIN_ORACLE / DBA +REVOKE ALL ON .PACK_AUTO FROM ROA_WEB; +REVOKE ALL ON .AUTO_VMASINICLIENTI FROM ROA_WEB; +REVOKE ALL ON .DEV_TIP_DEVIZ FROM ROA_WEB; +REVOKE ALL ON .CALENDAR FROM ROA_WEB; +REVOKE ALL ON .DEV_ORDL FROM ROA_WEB; +REVOKE ALL ON .NOM_LUCRARI FROM ROA_WEB; +REVOKE ALL ON .DEV_NOM_NORME FROM ROA_WEB; +REVOKE ALL ON .DEV_NOM_INSPECTORI FROM ROA_WEB; +REVOKE ALL ON .DEV_NOM_ASIGURATORI FROM ROA_WEB; +REVOKE ALL ON .NOM_PARTENERI FROM ROA_WEB; +REVOKE ALL ON .PACK_SERII_NUMERE FROM ROA_WEB; +``` + +### 7.3. DROP schema + +```sql +-- IRREVERSIBIL. Asigură-te că ai backup (expdp) înainte. +DROP USER CASCADE; +``` + +După `DROP USER CASCADE`, toate granturile acordate de `` dispar automat +— §7.2 devine redundant, dar îl păstrăm pentru cazul în care vrei să dezactivezi +temporar accesul fără a pierde date. + +### 7.4. Rollback migrație specifică (selectiv) + +Migrațiile AUTO nu au script de `DOWN`. Pentru rollback de SP, redeployează +versiunea anterioară din `git log docs/service-auto/migrations/`. Pentru +rollback de coloană (`DEV_ORDL.id_sucursala`): + +```sql +BEGIN + IF PACK_MIGRARE.COLUMNEXIST('DEV_ORDL','ID_SUCURSALA')=1 THEN + EXECUTE IMMEDIATE 'ALTER TABLE DEV_ORDL DROP COLUMN id_sucursala'; + END IF; +END; +/ +``` + +Atenție — drop coloană **pierde date**. Folosește doar dacă schema e nouă +și nu are date reale. + +--- + +## Anexă — Legături utile + +- [Grants audit](grants-audit.md) — raționament securitate ROA_WEB, attack surface, scalabilitate. +- [`onboarding_roa_web.sql`](onboarding_roa_web.sql) — scriptul de granturi per-schemă. +- [`migrations/`](migrations/) — migrații AUTO idempotente, rulate per-schemă. +- [`backend/ENV-SETUP.md`](../../backend/ENV-SETUP.md) — structura `.env` și `ORACLE_SERVERS`. +- [`CLAUDE.md`](../../CLAUDE.md) — reguli `start.sh` / `start-backend.sh` / `status.sh`. diff --git a/docs/service-auto/grants-audit.md b/docs/service-auto/grants-audit.md index 1843d79..1c3d61b 100644 --- a/docs/service-auto/grants-audit.md +++ b/docs/service-auto/grants-audit.md @@ -205,6 +205,20 @@ ROLLBACK; --- +## 4.6. Deploy procedure + +Procedura completă de onboarding pentru o schemă/server nou (impdp → granturi → +`.env` → migrații → smoke tests → rollback) este documentată separat în: + +**[deploy-schema-noua.md](deploy-schema-noua.md)** + +Acest audit (§4.1–§4.5) stabilește *de ce* onboarding-ul arată așa; fișierul +`deploy-schema-noua.md` stabilește *cum* îl execuți pas-cu-pas. Scriptul +`onboarding_roa_web.sql` e referința canonică pentru GRANT-urile per-schemă, +cu header self-documenting și placeholder ``. + +--- + ## 5. Action items - [x] **Task #1** — Grants audit completat (2026-04-11) diff --git a/docs/service-auto/migrations/ff_2026_04_14_01_AUTO.sql b/docs/service-auto/migrations/ff_2026_04_14_01_AUTO.sql new file mode 100644 index 0000000..8844b85 --- /dev/null +++ b/docs/service-auto/migrations/ff_2026_04_14_01_AUTO.sql @@ -0,0 +1,98 @@ +-- configurare initiala serie + plaja numere pentru comenzi service auto (TIP_DOC=20) +-- +-- Context: happy-path POST /api/service-auto/comenzi esueaza cu +-- ORA-20000 "Nu exista plaje de serii comenzi auto pentru aceste configurari!" +-- (PACK_SERII_NUMERE line 1071) pentru ca schema MARIUSM_AUTO nu are nicio +-- intrare SERII + PLAJE_NUMERE pentru TIP_DOC=20. +-- +-- Verificare live 2026-04-14: AUTHID=DEFINER, verifica_tipdoc(20)=0 (OK), +-- verifica_cursor_serii(20, 1, 0)=ORA-20000. Vezi pack-serii-verification.md. +-- +-- IMPORTANT: Aceasta migratie TREBUIE rulata ca MARIUSM_AUTO (sau DBA) — ROA_WEB +-- are EXECUTE pe pachet dar nu are DML pe SERII/PLAJE_NUMERE (corect, DEFINER). +-- +-- IMPORTANT: Inainte de executie, inlocuieste placeholder-urile <...> cu valori +-- reale stabilite cu Marius M (administrator MARIUSM AUTO): +-- — denumire serie (ex: 'DEV01') +-- — lungime numerica (ex: 6 → 1..999999) +-- — ID util administrator (care creeaza seria); in runtime +-- fiecare user propriu va fi mapat la grup via IdUtil2IdGrupUtil +-- , — plaja (ex: 1..999999) +-- — 0 pentru toate sucursalele sau ID specific + +DECLARE + v_id_serie NUMBER; +BEGIN + -- pas 1: inregistreaza seria (idempotent: skip daca exista deja o serie cu acelasi nume) + BEGIN + SELECT ID_SERIE INTO v_id_serie + FROM MARIUSM_AUTO.SERII + WHERE SERIE = '' + AND ROWNUM = 1; + EXCEPTION WHEN NO_DATA_FOUND THEN + MARIUSM_AUTO.PACK_SERII_NUMERE.adauga_serie( + V_SERIE => '', + V_AN => EXTRACT(YEAR FROM SYSDATE), + V_LUNA => EXTRACT(MONTH FROM SYSDATE), + V_LUNGIME => , + V_INACTIV => 0, + V_ID_UTIL => , + V_ISAUTOFACTURA => 0, + V_ISBENEFICIARI => 0, + V_ISTERTI => 0, + V_ISFURNIZORI => 0, + V_PREFIX => NULL, + V_AN2CARACTERE => 0 + ); + SELECT ID_SERIE INTO v_id_serie + FROM MARIUSM_AUTO.SERII + WHERE SERIE = '' + AND ROWNUM = 1; + END; + + -- pas 2: inregistreaza plaja pentru TIP_DOC=20 (idempotent: skip daca exista) + DECLARE + v_count NUMBER; + BEGIN + SELECT COUNT(*) INTO v_count + FROM MARIUSM_AUTO.PLAJE_NUMERE + WHERE ID_TIPDOC = 20 + AND ID_SERIE = v_id_serie + AND NVL(ID_SUCURSALA, 0) = NVL(, 0); + IF v_count = 0 THEN + MARIUSM_AUTO.PACK_SERII_NUMERE.adauga_plaja( + V_ID_TIPDOC => 20, + V_ID_TIPENTITATE => NULL, + V_ID_SERIE => v_id_serie, + V_ID_ENTITATE => NULL, + V_ID_SUCURSALA => , + V_PL_INF => , + V_PL_SUP => , + V_DATAI => TO_DATE('01.01.' || EXTRACT(YEAR FROM SYSDATE), 'DD.MM.YYYY'), + V_DATAS => TO_DATE('31.12.' || EXTRACT(YEAR FROM SYSDATE), 'DD.MM.YYYY'), + V_INACTIV => 0, + V_ID_UTIL => + ); + END IF; + END; +END; +/ + +-- verificare post-migratie (nu afecteaza runtime; doar raporteaza status): +DECLARE + v_rez NUMBER; + v_cur SYS_REFCURSOR; +BEGIN + MARIUSM_AUTO.PACK_SERII_NUMERE.verifica_cursor_serii( + V_ID_TIPDOC => 20, + V_ID_UTIL => , + V_ID_SUCURSALA => , + V_REZULTAT => v_rez, + V_CURSOR => v_cur + ); + DBMS_OUTPUT.PUT_LINE('verifica_cursor_serii rezultat=' || v_rez); + IF v_cur IS NOT NULL THEN CLOSE v_cur; END IF; +END; +/ + +exec pack_migrare.UpdateVersiune('ff_2026_04_14_01_AUTO'); commit; diff --git a/docs/service-auto/onboarding_roa_web.sql b/docs/service-auto/onboarding_roa_web.sql index 99d7435..e067d49 100644 --- a/docs/service-auto/onboarding_roa_web.sql +++ b/docs/service-auto/onboarding_roa_web.sql @@ -1,23 +1,49 @@ -- ============================================================================= --- File purpose : Script de onboarding ROA_WEB pentru o schemă nouă --- When to run : Rulat ca CONTAFIN_ORACLE după impdp pentru fiecare firmă nouă --- Usage : Înlocuiește :SCHEMA_NAME cu schema reală (ex: MARIUSM_AUTO) +-- File purpose : Script de onboarding ROA_WEB pentru o schemă nouă (per-firmă) +-- When to run : Rulat ca CONTAFIN_ORACLE (sau DBA) DUPĂ `impdp` al schemei +-- Usage : Substituie `` (3 apariții pe linie sau per bloc) cu +-- numele schemei reale (ex: MARIUSM_AUTO, ACME_AUTO) înainte +-- de rulare. Un singur search-and-replace acoperă tot fișierul. -- Version : 2026-04-12 --- Prerequisite : ROA_WEB user creat (onboarding_roa_web_user.sql) +-- Prerequisite : ROA_WEB user creat O SINGURĂ DATĂ (vezi §2 de mai jos). +-- Full procedure : docs/service-auto/deploy-schema-noua.md -- ============================================================================= +-- +-- ORDINE OPERAȚII pentru o schemă nouă: +-- 1. impdp schema nouă (REMAP_SCHEMA, exclude sequences dacă există) +-- 2. RULEAZĂ SECȚIUNEA §1 a acestui fișier (GRANT-uri per-schemă) +-- 3. Adaugă `.env` → `ORACLE_SERVERS` dacă server nou + restart backend +-- 4. Rulează migrațiile service-auto în ordine cronologică +-- (docs/service-auto/migrations/ff_YYYY_MM_DD_NN_AUTO.sql) +-- 5. Smoke test: /ping, /tip-deviz, /masini, /comenzi +-- +-- ============================================================================= +-- §1. GRANT-uri per-schemă — RULAT PENTRU FIECARE FIRMĂ NOUĂ +-- ============================================================================= +-- Înlocuiește `` cu schema reală (ex: MARIUSM_AUTO) înainte de rulare. -GRANT EXECUTE ON :SCHEMA_NAME.PACK_AUTO TO ROA_WEB; -GRANT SELECT ON :SCHEMA_NAME.AUTO_VMASINICLIENTI TO ROA_WEB; -GRANT SELECT ON :SCHEMA_NAME.DEV_TIP_DEVIZ TO ROA_WEB; -GRANT SELECT ON :SCHEMA_NAME.CALENDAR TO ROA_WEB; -- period selector AppHeader -GRANT SELECT ON :SCHEMA_NAME.DEV_ORDL TO ROA_WEB; -- GET /api/service-auto/comenzi -GRANT SELECT ON :SCHEMA_NAME.NOM_LUCRARI TO ROA_WEB; -- JOIN cu DEV_ORDL pentru nrord +GRANT EXECUTE ON .PACK_AUTO TO ROA_WEB; +GRANT SELECT ON .AUTO_VMASINICLIENTI TO ROA_WEB; +GRANT SELECT ON .DEV_TIP_DEVIZ TO ROA_WEB; +GRANT SELECT ON .CALENDAR TO ROA_WEB; -- period selector AppHeader +GRANT SELECT ON .DEV_ORDL TO ROA_WEB; -- GET /api/service-auto/comenzi +GRANT SELECT ON .NOM_LUCRARI TO ROA_WEB; -- JOIN cu DEV_ORDL pentru nrord + +-- Granturi adăugate de migrațiile service-auto (ff_2026_04_13_01_AUTO.sql). +-- Dacă rulezi onboarding-ul INAINTE de migrații, aceste linii pot fi skipped +-- (migrația le va aplica). Dacă rulezi DUPĂ migrații, sunt idempotente (GRANT e no-op). +GRANT SELECT ON .DEV_NOM_NORME TO ROA_WEB; +GRANT SELECT ON .DEV_NOM_INSPECTORI TO ROA_WEB; +GRANT SELECT ON .DEV_NOM_ASIGURATORI TO ROA_WEB; +GRANT SELECT ON .NOM_PARTENERI TO ROA_WEB; +GRANT INSERT ON .NOM_PARTENERI TO ROA_WEB; +GRANT EXECUTE ON .PACK_SERII_NUMERE TO ROA_WEB; -- ============================================================================= --- ROA_WEB user creation (one-time, run as SYS or CONTAFIN_ORACLE) +-- §2. ROA_WEB user creation — O SINGURĂ DATĂ pe instanță Oracle -- ============================================================================= --- Rulat O SINGURĂ DATĂ la setup inițial, NU pentru fiecare firmă nouă. --- Pentru fiecare firmă nouă se rulează doar secțiunea de GRANT-uri de mai sus. +-- NU rula pentru fiecare firmă nouă. Rulează doar la setup inițial al instanței. +-- Parola reală se ia din vault și se salvează în `backend/secrets/.oracle_pass`. CREATE USER ROA_WEB IDENTIFIED BY ""; GRANT CREATE SESSION TO ROA_WEB; diff --git a/docs/service-auto/pack-serii-verification.md b/docs/service-auto/pack-serii-verification.md new file mode 100644 index 0000000..ce058a7 --- /dev/null +++ b/docs/service-auto/pack-serii-verification.md @@ -0,0 +1,149 @@ +# PACK_SERII_NUMERE — Verificare live + unblock serii tipDoc=20 + +**Data verificare**: 2026-04-14 +**Executat de**: teammate `pack-serii-verifier` (task #4, branch `feat/service-auto`) +**Mediu**: Oracle `10.0.20.121:1521/ROA`, schema `MARIUSM_AUTO`, user `ROA_WEB` + +--- + +## 1. AUTHID — DEFINER ✅ **verificat live** + +```sql +SELECT OBJECT_NAME, PROCEDURE_NAME, AUTHID + FROM ALL_PROCEDURES + WHERE OWNER = 'MARIUSM_AUTO' + AND OBJECT_NAME = 'PACK_SERII_NUMERE'; +``` + +Rezultat: + +| OBJECT_NAME | PROCEDURE_NAME | AUTHID | +|---|---|---| +| `PACK_SERII_NUMERE` | *(null, package-level)* | **`DEFINER`** | + +**Concluzie**: HANDOFF-ul era corect. Pachetul rulează cu privilegiile owner-ului +(`MARIUSM_AUTO`), deci `GRANT EXECUTE` pentru `ROA_WEB` este suficient. +Nu sunt necesare granturi suplimentare pe `SERII` / `PLAJE_NUMERE` / `SERII_NUMERE`. + +Status obiect: `VALID`, created `2025-09-30`, last DDL `2026-04-13 19:11`. + +--- + +## 2. DDL export + +`DBMS_METADATA.GET_DDL('PACKAGE', …)` → **ORA-31603**: ROA_WEB nu are +`SELECT_CATALOG_ROLE`. Fallback la `ALL_SOURCE` a reușit pentru **PACKAGE SPEC** +(12 825 caractere) dar nu și pentru **PACKAGE BODY** (0 caractere — ROA_WEB +nu are SELECT pe source-ul body-ului). + +- Spec salvat: [`PACK_SERII_NUMERE.pck`](./PACK_SERII_NUMERE.pck) +- Body-ul va trebui exportat manual de DBA (ex: de pe cont `MARIUSM_AUTO`) + dacă e nevoie pentru audit complet. + +### Tabele referite în spec (nume reale) + +Contrar denumirilor din HANDOFF (`SER_SERII`/`SER_PLAJE`), tabelele efective sunt: + +| Referit în spec ca | Rol | +|---|---| +| `SERII` | Master pentru serii (PREFIX, AN2CARACTERE, ISAUTOFACTURA, ISBENEFICIARI, ISTERTI, ISFURNIZORI) | +| `PLAJE_NUMERE` | Plaje numere (ID_TIPDOC, ID_TIPENTITATE, ID_ENTITATE, ID_SERIE, ID_SUCURSALA, PL_INF, PL_SUP, DATAI, DATAS, INACTIV) | +| `SERII_NUMERE` | Numere alocate (ID_NUMAR, NUMAR) — destinația lui `aloca_numar` | + +--- + +## 3. TIP_DOC=20 — valid, dar **fără configurare** + +Testarea indirectă, prin pachet (ROA_WEB nu are SELECT pe tabele, dar poate apela +procedurile pachetului via EXECUTE + DEFINER): + +``` +PACK_SERII_NUMERE.verifica_tipdoc(V_ID_TIPDOC=20, V_REZULTAT OUT) → 0 (OK) +``` + +→ TIP_DOC=20 este **acceptat** de pachet (deși nu apare ca named constant +`nTip…` în spec — există o „gaură" între `nTipNrDispPlata := 19` și +`nTipNrOrdinPlata := 21`, dar array-urile interne `tabela_tipdoc` / +`tabela_numere` au 26 elemente, deci indicele 20 e legal). + +``` +PACK_SERII_NUMERE.verifica_cursor_serii(V_ID_TIPDOC=20, V_ID_UTIL=1, V_ID_SUCURSALA=0, …) +→ ORA-20000: Nu exista plaje de serii comenzi auto pentru aceste configurari! + at PACK_SERII_NUMERE line 1071 +``` + +**Aceasta este exact eroarea care blochează happy-path `POST /api/service-auto/comenzi`** +(mapată la HTTP 422 „Nu s-au configurat valori…"). Cauza: nu există niciun rând în +`SERII` + `PLAJE_NUMERE` pentru TIP_DOC=20 care să matchuiască user-ul 1. + +--- + +## 4. Granturi efective ROA_WEB (live) + +```sql +SELECT TABLE_NAME, PRIVILEGE FROM USER_TAB_PRIVS + WHERE GRANTEE='ROA_WEB' AND OWNER='MARIUSM_AUTO'; +``` + +| TABLE_NAME | PRIVILEGE | +|---|---| +| `AUTO_VMASINICLIENTI` | SELECT | +| `CALENDAR` | SELECT | +| `DEV_NOM_ASIGURATORI` | SELECT | +| `DEV_NOM_INSPECTORI` | SELECT | +| `DEV_NOM_NORME` | SELECT | +| `DEV_ORDL` | SELECT | +| `DEV_TIP_DEVIZ` | SELECT | +| `NOM_LUCRARI` | SELECT | +| `NOM_PARTENERI` | SELECT, INSERT | +| `PACK_AUTO` | EXECUTE | +| `PACK_SERII_NUMERE` | EXECUTE | +| `SP_CREEAZA_COMANDA_PROTOTIP` | EXECUTE | + +Granturile sunt **aliniate** cu `docs/service-auto/onboarding_roa_web.sql`. +`SERII` / `PLAJE_NUMERE` / `SERII_NUMERE` NU sunt în listă — nici nu trebuie să fie, +deoarece pachetul e DEFINER. + +--- + +## 5. Unblock plan — 3 pași + +### Pasul 1 — DBA (MARIUSM_AUTO sau DBA) rulează migrația + +Fișierul [`migrations/ff_2026_04_14_01_AUTO.sql`](./migrations/ff_2026_04_14_01_AUTO.sql) +conține un template cu placeholders pentru: + +- nume serie (ex. `DEV01`) +- lungime numerică (ex. `6` → numere 1..999999) +- user/grup alocat (`` — tipic admin MARIUSM_AUTO; pachetul îl + transformă intern în grup via `IdUtil2IdGrupUtil`) +- plaja `PL_INF`/`PL_SUP` (ex. 1..999999) +- sucursală (`0` pentru toate sucursalele sau ID specific) + +Migrația folosește **procedurile publice ale pachetului** (`adauga_serie` + +`adauga_plaja`) pentru a respecta validările interne — NU face INSERT direct +în `SERII` / `PLAJE_NUMERE`. DBA-ul trebuie doar să înlocuiască placeholders +și să ruleze. + +### Pasul 2 — Verificare de regresie (re-rulare probe) + +După configurare, DBA sau teammate QA poate re-rula scriptul de probe și să +confirme că: + +``` +PACK_SERII_NUMERE.verifica_cursor_serii(20, 1, 0, …) → rezultat=0 (fără ORA-20000) +``` + +### Pasul 3 — Smoke test happy-path + +- `POST /api/service-auto/comenzi` cu payload valid (masina+tip deviz) pe + tenant `mariusm_test`, user `MARIUS M`/pass `123`, firma `MARIUSM AUTO` +- Așteptat: HTTP 200 + `pc_nr` generat (prefix + număr + `/` + nr. înmatriculare) + +--- + +## 6. Decizie pe AUTHID-related grants + +**NU este necesar** niciun grant suplimentar pe `SERII`/`PLAJE_NUMERE`/`SERII_NUMERE`. +DEFINER rights sunt suficiente. Dacă pe viitor observăm ORA-01031 la apel pachet, +atunci revedem (dar acum happy-path dă 422 nu 500, deci privilege ≠ cauza).