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 înORACLE_SERVERS(ex:acme_prod).<ID_FIRMA>—id_firmareturnat deV_NOM_FIRMEpentru 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
- 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). - Deschide o copie locală a fișierului și înlocuiește
<SCHEMA>cu schema reală (un singur search-and-replace — vezi header-ul fișierului). - 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
.envdirect pe serverele rulante în această procedură — doar documentează modificarea. Deployment-ul.envurmează 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 ADDwrap înPACK_MIGRARE.COLUMNEXISTCREATE INDEXwrap înPACK_MIGRARE.OBJECTEXISTCREATE OR REPLACE PROCEDURE— natural idempotentGRANT— 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
- Grants audit — raționament securitate ROA_WEB, attack surface, scalabilitate.
onboarding_roa_web.sql— scriptul de granturi per-schemă.migrations/— migrații AUTO idempotente, rulate per-schemă.backend/ENV-SETUP.md— structura.envșiORACLE_SERVERS.CLAUDE.md— regulistart.sh/start-backend.sh/status.sh.