Files
roa2web-service-auto/docs/service-auto/deploy-schema-noua.md
2026-06-05 15:00:42 +00:00

9.9 KiB

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

  • <SCHEMA> — numele schemei noi (ex: ACME_AUTO, MARIUSM_AUTO).
  • <SERVER_KEY> — cheia logică pentru server în ORACLE_SERVERS (ex: acme_prod).
  • <ID_FIRMA>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.

# Exemplu minimal — adaptează directory_name, dumpfile, logfile la instanța ta.
impdp system/<pwd>@<tns> \
  SCHEMAS=TEMPLATE_AUTO \
  REMAP_SCHEMA=TEMPLATE_AUTO:<SCHEMA> \
  DIRECTORY=DATA_PUMP_DIR \
  DUMPFILE=template_auto.dmp \
  LOGFILE=impdp_<SCHEMA>.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:

SELECT COUNT(*) FROM DBA_OBJECTS WHERE OWNER = '<SCHEMA>';
SELECT OBJECT_TYPE, COUNT(*) FROM DBA_OBJECTS WHERE OWNER = '<SCHEMA>'
 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/<SERVER_KEY>.oracle_pass (gitignored).
  2. Deschide o copie locală a fișierului și înlocuiește <SCHEMA> 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:

-- 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 = '<SCHEMA>'
 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:

# 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:

./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ă:

# Autentifică-te în UI cu un user care are permisiuni pe schema nouă (sau via curl):
curl -H "Authorization: Bearer <JWT>" http://localhost:8000/api/auth/firme

Trebuie să apară <SCHEMA> cu noul id_firma. Notează <ID_FIRMA> — 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ă (<SCHEMA>), NU ca CONTAFIN_ORACLE, pentru că DDL-ul interior (ALTER TABLE, CREATE INDEX, CREATE OR REPLACE PROCEDURE) rulează pe obiectele proprii ale schemei.

# Înlocuiește schema name în fiecare fișier (sau folosește sqlplus ca <SCHEMA>).
sqlplus <SCHEMA>/<pwd>@<tns> @docs/service-auto/migrations/ff_2026_04_12_01_AUTO.sql
sqlplus <SCHEMA>/<pwd>@<tns> @docs/service-auto/migrations/ff_2026_04_13_01_AUTO.sql
sqlplus <SCHEMA>/<pwd>@<tns> @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:

-- Ar trebui să returneze cele 3 versiuni ff_2026_04_12_01_AUTO ... ff_2026_04_13_02_AUTO
SELECT VERSIUNE, DATA_APLICARE FROM <SCHEMA>.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 <ID_FIRMA>.

TOKEN="<JWT>"
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=<ID_FIRMA>"

# 6.3. Mașini — citește din AUTO_VMASINICLIENTI.
curl -H "Authorization: Bearer $TOKEN" "$BASE/masini?id_firma=<ID_FIRMA>"

# 6.4. Comenzi — JOIN DEV_ORDL + NOM_LUCRARI.
curl -H "Authorization: Bearer $TOKEN" "$BASE/comenzi?id_firma=<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ă <SERVER_KEY> 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)

-- Conectat ca CONTAFIN_ORACLE / DBA
REVOKE ALL ON <SCHEMA>.PACK_AUTO                 FROM ROA_WEB;
REVOKE ALL ON <SCHEMA>.AUTO_VMASINICLIENTI       FROM ROA_WEB;
REVOKE ALL ON <SCHEMA>.DEV_TIP_DEVIZ             FROM ROA_WEB;
REVOKE ALL ON <SCHEMA>.CALENDAR                  FROM ROA_WEB;
REVOKE ALL ON <SCHEMA>.DEV_ORDL                  FROM ROA_WEB;
REVOKE ALL ON <SCHEMA>.NOM_LUCRARI               FROM ROA_WEB;
REVOKE ALL ON <SCHEMA>.DEV_NOM_NORME             FROM ROA_WEB;
REVOKE ALL ON <SCHEMA>.DEV_NOM_INSPECTORI        FROM ROA_WEB;
REVOKE ALL ON <SCHEMA>.DEV_NOM_ASIGURATORI       FROM ROA_WEB;
REVOKE ALL ON <SCHEMA>.NOM_PARTENERI             FROM ROA_WEB;
REVOKE ALL ON <SCHEMA>.PACK_SERII_NUMERE         FROM ROA_WEB;

7.3. DROP schema

-- IRREVERSIBIL. Asigură-te că ai backup (expdp) înainte.
DROP USER <SCHEMA> CASCADE;

După DROP USER CASCADE, toate granturile acordate de <SCHEMA> 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):

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