Files
solduri2roa/docs/handoff_etapa2_convertor.md
Marius Mutu 15bb26ac15 Etapa 2: plan v3, rapoarte de cercetare si etalonul de regresie
Cercetare: ambele formate SAGA (VFP xls/xlsx si Firebird .FDB), cu dovezi
fisier:linie in docs/raport_sursa_saga_xlsx.md si raport_exporturi_saga_noua.md.

Plan v3 dupa review de strategie si arhitectura: contract intern + trei
cititoare, mapare in doua fisiere cu proprietari diferiti, lane-uri.

Etalon de regresie anonimizat in tests/golden/ (sume si structura neatinse,
zero IBAN si zero cod fiscal real). Tabela de corespondenta ramane ignorata.

Iesirile de productie ies din git (raman pe disc); .gitignore acopera si
copiile de baze de client si iesirile intermediare ale convertorului.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYeAtVxeS8m4oXekjX8Am2
2026-09-21 15:44:57 +03:00

9.2 KiB
Raw Blame History

Handoff - etapa 2, convertorul reutilizabil SAGA -> ROA

Scris 21.09.2026. Sesiunea urmatoare este orchestrator, nu executant: imparte pe lane-uri, trimite sarcinile la agenti opencode, verifica portile. Nu scrie ea codul.

Stare: planul e gata si aprobat pe decizii; nu s-a scris nicio linie de cod pentru etapa 2. Marius nu a dat inca "porneste" pe lane-uri. Intreaba-l inainte sa lansezi primul lane.


1. Ce sa citesti, in ordine, si de ce

fisier de ce
docs/plan_etapa2_convertor.md contractul de lucru, v3. Tot ce urmeaza se masoara fata de el
docs/raport_sursa_saga_xlsx.md SAGA veche (VFP); conventiile conturi_roa.dbf (.TOATE, .RESTUL)
docs/raport_exporturi_saga_noua.md SAGA noua (Firebird); structura exporturilor si a bazei
docs/decizii_import.md regulile de mapare, validate in productie - nu se redeschid
docs/review_ceo_etapa2.md, docs/review_eng_etapa2.md de unde vin corectiile din v3; reciteste doar daca vrei sa redeschizi o decizie

Nu reface cercetarea. Cele doua rapoarte au costat doua lane-uri si contin dovezi cu fisier si linie.

2. Ce e gata

  • Etapele 1-6 din docs/plan_solduri2roa.md: cele doua xlsx au fost importate in ROACONT si au trecut; scripturile sql/update_cod_fiscal_*.sql au fost executate de Marius.

  • Cercetarea pe ambele formate SAGA + conectarea la Firebird, verificata live.

  • Planul v3, dupa review de strategie si de arhitectura.

  • .gitignore + git rm --cached pe iesirile de productie (fisierele raman pe disc).

  • Etalonul de regresie este facut si pus in git (21.09.2026): tests/golden/ cu golden_FUNDATIA_2025_12.xlsx si golden_MASTER_2025_12.xlsx, produse de tests/anonimizeaza_etalon.py. Verificat: structura, numarul de randuri si sumele sunt identice cu originalele (SUM(totdeb) = SUM(totcred) neatins), au fost schimbate doar coloanele 10-14 pe randurile FACTURA plus IBAN-urile; zero IBAN si zero cod fiscal real ramase. Tabela de corespondenta (tests/_corespondenta_anonimizare.json) e ignorata de git - nu o comite, cu ea anonimizarea se desface.

3. Ce NU e facut

Tot ce e in tabelul de lane-uri din plan, mai putin etalonul. Niciun fisier de cod nou pentru conversie, niciun test, niciun config/conturi_parteneri.csv.

4. Deciziile deja luate - nu le redeschide

  1. Conturile cu parteneri: setul validat din genereaza_xlsx.py:46-50 este autoritatea, tinut in config/conturi_parteneri.csv. CONFIG_CONT_IREG e consultativ; unealta raporteaza divergentele, nu le aplica. Motivul, cu dovada, e in plan - Oracle nu listeaza 5121/5124/5311.
  2. acont pentru conturi cu parteneri ramane decis de genereaza_xlsx.py; maparea doar suprascrie explicit. Randurile de diferenta raman calculate in cod.
  3. Maparea = doua fisiere: mapare_<FIRMA>.xlsx scris doar de unealta (regenerat complet), corectii_<FIRMA>.xlsx scris doar de Marius.
  4. Cititorul FDB se face acum, marcat explicit "verificat doar pe cazul sintetic".
  5. Etalonul de regresie: xlsx-uri intregi, anonimizate (sume si structura neatinse), in tests/golden/. Tabela de corespondenta nume real -> nume fals nu se comite.
  6. Teste: unittest din stdlib. Fara dependinte noi de test.
  7. Sursa: PDF, foaie de calcul SAGA si Firebird, toate trei, egale.

5. Ordinea lane-urilor

contract singur, primul -> apoi citire-xlsx si mapare in paralel -> citire-fdb -> integrare -> regresie. Criteriile de terminare sunt in plan, in tabelul de lane-uri si in cel de testare. Etalonul din tests/golden/ a fost fixat inainte sa se schimbe vreo linie de cod - asta e tot rostul ordinii. Daca vreun lane modifica genereaza_xlsx.py si regresia incepe sa pice, etalonul are dreptate, nu codul nou.

6. Cum lansezi un lane (verificat azi, functioneaza)

Ghidul complet: D:\ROA\ROACONT\COMUN\docs\opencode_agenti_orchestrare.md.

  • Port pentru acest proiect: 4296. Nu-l folosi pe 4196 (ROACONT) sau 4096 (ROAFACTURARE) - oprirea serverului dintr-un proiect omoara lane-urile celuilalt. Portul 4296 nu e inca trecut in tabelul din ghid - adauga-l acolo (COMUN are nevoie de aprobare inainte de commit).
  • Pornire, din directorul proiectului: opencode serve --port 4296
  • Model: {"providerID":"opencode-go","modelID":"deepseek-v4.1-flash"}
  • Promptul de sistem, obligatoriu la fiecare sesiune, in campul system: D:\ROA\ROACONT\COMUN\docs\opencode_prompt_initial.md
  • Sesiune noua: POST /session {title} -> id; sarcina: POST /session/:id/prompt_async?directory=D:\ROA\IMPORT2ROA\solduri2roa
  • Stare: GET /session/status - sesiunea lipseste cand e libera, {} = toate libere.
  • Oprire la final: Stop-Process -Id (Get-NetTCPConnection -LocalPort 4296 -State Listen).OwningProcess

Sablon PowerShell pentru trimitere (JSON pe UTF-8, altfel se strica diacriticele si ghilimelele):

$u='http://127.0.0.1:4296'
$sys = [IO.File]::ReadAllText('D:\ROA\ROACONT\COMUN\docs\opencode_prompt_initial.md')
$m = @{providerID='opencode-go'; modelID='deepseek-v4.1-flash'}
$sid = (Invoke-RestMethod -Method Post "$u/session" -ContentType 'application/json' -Body '{"title":"lane-X"}').id
$b = @{model=$m; system=$sys; parts=@(@{type='text';text=$task})} | ConvertTo-Json -Depth 5
Invoke-RestMethod -Method Post "$u/session/$sid/prompt_async?directory=D:\ROA\IMPORT2ROA\solduri2roa" `
  -ContentType 'application/json; charset=utf-8' -Body ([Text.Encoding]::UTF8.GetBytes($b))

Asteptarea: nu face Start-Sleep lung in foreground (harness-ul il blocheaza). Foloseste Bash in fundal: until curl -s http://127.0.0.1:4296/session/status | grep -qv busy; do sleep 20; done.

Ce trebuie sa contina fiecare sarcina de lane: numele lane-ului, fisierele exacte de atins, criteriul de terminare luat din plan, interdictiile (fara commit, fara sed -i, fara modificari in D:\ROA\ROACONT, D:\SAGA250909, saga2roa*), unde scrie raportul, si ultimul mesaj GATA <lane> / BLOCAT <lane>: motiv. Agentii respecta asta; doi lane-uri au mers azi asa.

7. Capcane deja platite - nu le redescoperi

  • openpyxl nu citeste .xls (BIFF). Pentru .xls: xlrd (instalat, 2.0.2) sau conversie soffice --headless --convert-to xlsx. Ambele verificate.
  • Firebird: numai embedded. firebird-driver (instalat, 2.0.3) + fdb.load_api catre C:\Program Files\Firebird\Firebird30_Saga\fbclient.dll, SYSDBA/masterkey, charset WIN1250, access_mode=READ, no_gc=True. Pe TCP 3060 parola implicita nu merge.
  • In CONTURI soldurile stocate sunt 0; balanta se obtine agregand REGISTRU. Cine citeste CONTURI.DEB_PREC scoate o balanta goala fara nicio eroare.
  • Coloanele _1 din export (S..AF) seamana cu cele principale. Potrivirea numelor de coloana se face exact, niciodata pe substring: TOTAL_DEB vs TOTAL_DEB_1.
  • Numele foii difera intre surse (balanta / xl / Sheet1) - ia prima foaie, nu cauta dupa nume.
  • CONT se citeste ca text. 401.00002 citit ca numar se strica.
  • Heredoc-urile lungi in Bash au esuat pe fisierele mari de documentatie; scrie-le cu tool-ul de scriere de fisiere.
  • python direct din Bash e stub Windows Store si nu scrie nimic (iese 0 si fisierul ramane neatins). Foloseste py, sau PowerShell.

8. Starea pe disc - nimic periculos, dar necomis

git status la predare (HEAD = ceab089, branch main):

M  .gitignore
D  balanta_FUNDATIA.csv
D  balanta_MASTERJOB.csv
 M docs/parteneri_cui_gasite.md
 M docs/plan_solduri2roa.md
D  export_balanta_fundatia_12_2025.xlsx
D  init_FUNDATIA_2025_12.xlsx
D  init_MASTER_2025_12.xlsx
 M sql/update_cod_fiscal_FUNDATIA.sql
 M sql/update_cod_fiscal_MASTER.sql
A  tests/anonimizeaza_etalon.py
A  tests/golden/golden_FUNDATIA_2025_12.xlsx
A  tests/golden/golden_MASTER_2025_12.xlsx
?? docs/handoff_etapa2_convertor.md
?? docs/plan_etapa2_convertor.md
?? docs/raport_exporturi_saga_noua.md
?? docs/raport_sursa_saga_xlsx.md
?? docs/review_ceo_etapa2.md
?? docs/review_eng_etapa2.md
?? exemple/

Verificari inainte de orice altceva:

  • init_FUNDATIA_2025_12.xlsx si init_MASTER_2025_12.xlsx sunt pe disc dar nu mai sunt in git. Etalonul anonimizat e deja generat din ele si comis, deci poarta de regresie nu mai depinde de ele. Sunt necesare doar daca vrei sa regenerezi etalonul (py testsnonimizeaza_etalon.py).
  • Nu se da commit fara ca Marius sa vada diff-ul (regula proiectului).
  • Niciun proces ramas viu: serverul opencode de pe 4296 a fost oprit la predare. Il pornesti tu, cu comanda din sectiunea 6.
  • D:\ROA\ROACONT, D:\SAGA250909 si saga2roa* nu au fost modificate si nu se modifica.

9. Primul lucru de facut in sesiunea noua

  1. Citeste planul v3.
  2. Intreaba-l pe Marius daca pornesti (nu a dat inca "da" pe lansarea lane-urilor).
  3. La "da": lanseaza doar lane-ul contract. Etalonul exista deja, deci lane-ul are de facut config/conturi_parteneri.csv + scriptul de divergenta Oracle, si de scris testul de regresie care compara iesirea codului de azi cu tests/golden/, pe valori de celula (nu pe hash: un xlsx rescris de alta versiune de openpyxl are alti octeti cu acelasi continut). Testul trebuie sa treaca cu codul de conversie neschimbat. Daca nu trece, e bug in test sau in etalon, nu in cod, si restul lane-urilor nu au voie sa porneasca.