Pagina /integrare (tab autentificat, scoped pe cont): exemple cod multi-limbaj (curl/Python/PHP/C#/Node) + retetar Visual FoxPro (MSXML2 + WinHttp) pe ambele canale (prezentari JSON + import fisier), export Postman/OpenAPI/Swagger si buton "Testeaza conexiunea". - US-001: GET /v1/ping (readiness: account_id/mediu/autentificat_cu_cheie/ are_creds_rar/ts) + GET /v1/integrare/postman.json (v2.1.0, allowlist 3 rute) - US-002: app/web/integrare_examples.py pur (7 limbaje x 2 canale, drift-test is_required(), JSON compact pentru C#/VFP) - US-003: tab "Integrare" IA pe 2 niveluri (limbaj->canal, VFP cu dialecte), copy din <pre><code>, empty-state CTA, export .cardlink, script scoped - US-004: POST /integrare/test-cheie (account_for_key direct, scoped sesiune, no-echo cheie) Backend trimitere (worker/masina stari/idempotenta/mapping) si schema neatinse. 568 teste pass. VERIFY context curat + E2E browser (Playwright) + code-review high. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
24 KiB
PRD 5.1 — Hub de integrare (pagina /integrare cu exemple de cod + retetar VFP + ping + export)
Stare: inchis (2026-06-22 — VERIFY PASS + E2E browser PASS + /code-review high incorporat; 568 teste pass; writeback ROADMAP facut; asteapta poarta umana de commit)
Proces complet:
docs/ROADMAP.md§5. Contract RAR (sursa de adevar):docs/api-rar-contract.md. Starea trece:draft → aprobat → in-executie → verify-pass → inchis(actualizata de lead). Backend trimitere (worker, masina stari, idempotenta-logica, mapping-rezolvare) NU se atinge. Aceasta livrabila adauga DOAR suprafata de onboarding/integrare (citire) peste API-ul existent + stratul web. Schema neatinsa (zero coloane noi).
1. Obiectiv
Produsul e functional pe ambele canale (API + import web), dar un service nou care vine din Visual FoxPro
sau soft propriu nu are de unde sa inceapa integrarea: cheia API se creeaza/roteste din web (/cont), insa nu
exista nicio pagina cu cum chem API-ul, ce payload, ce header, in ce limbaj. Singurele referinte sunt
README.md (curl) si Swagger /docs — invizibile din aplicatie si fara exemple in limbajul integratorului.
Livram o pagina /integrare (tab nou, autentificat, scoped pe contul din sesiune) care:
- afiseaza exemple de cod pre-completate cu endpoint-ul real + account_id-ul utilizatorului pentru ambele
canale (
POST /v1/prezentariJSON siPOST /v1/importupload fisier), in curl, Python, PHP, C#, Node; - include un retetar Visual FoxPro (POST via
MSXML2.ServerXMLHTTP.6.0SIWinHttp.WinHttpRequest.5.1, plus upload CSV); - ofera export OpenAPI (
/openapi.jsondin FastAPI) + colectie Postman + link Swagger/docs; - are un buton "Testeaza conexiunea": utilizatorul lipeste cheia salvata, iar serverul confirma ca e valida si mapeaza pe contul lui (acelasi drum de auth ca API-ul real).
Constrangere de securitate (din app/auth.py): stocam DOAR SHA-256 al cheii API, deci nu putem reafisa cheia.
Exemplele folosesc placeholder rfak_...; cheia reala se obtine o singura data la creare/rotire din /cont.
2. Non-Goals (anti scope-creep)
- Nu reafisam cheia API — exemplele au placeholder, niciodata cheia in clar (SHA-256-only).
- Fara markdown versionat in
docs/(decis cu utilizatorul: doar pagina in-app dinamica). Daca apare nevoia de referinta indexabila, e o livrabila viitoare separata. - Fara generare automata de SDK-uri — OpenAPI + Postman sunt punctul de plecare; integratorul genereaza singur.
- Fara dry-run — validarea de payload fara enqueue e livrabila 5.2 (separata).
GET /v1/pingverifica DOAR autentificarea (cheie valida + cont activ), nu valideaza continut. - Fara editarea exemplelor de catre user — continut read-only generat din schema.
- Nu atinge backend-ul de trimitere (worker/masina stari/idempotenta-logica/mapping-rezolvare) si nici schema.
- Fara i18n — pagina e in romana, ca restul UI-ului.
3. Stories atomice
Backend + UI pentru acelasi comportament = stories separate. Toate rutele web noi sub
require_login+ scoped pe contul din sesiune. CSRF pe toate POST-urile web. Endpoint-urile/v1/*folosescresolve_account_id.
US-001: Backend — endpoint-uri de integrare (GET /v1/ping + export Postman)
Ca integrator extern vreau un endpoint care confirma ca cheia mea functioneaza si o colectie Postman gata de importat pentru ca sa-mi validez conexiunea inainte sa trimit prezentari reale.
- Depinde de: —
- Fisiere:
app/api/v1/integrare_router.py(NOU), montare inapp/main.py(app.include_router),tests/test_integrare_api.py(~3 fisiere) - Montare (decizie eng-review P1): router nou cu
prefix="/v1", inclus inapp/main.pycuapp.include_router(...)(consistent cuimport_v1_router). NU sub-include inapp/api/v1/router.py(acela are dejaprefix="/v1"→ ar dubla prefixul). - Test intai (RED):
tests/test_integrare_api.py—test_ping_cu_cheie_valida_200(raspuns:account_id,mediutest/prod,autentificat_cu_cheie=true,are_creds_rar,ts),test_ping_cu_bearer_valid_200(Authorization: Bearer rfak_...),test_ping_fara_cheie_dev_cont_implicit(flag off → cont 1,autentificat_cu_cheie=false),test_ping_x_api_key_gol_in_dev_cont_implicit(whitespace tratat ca lipsa),test_ping_are_creds_rar_reflecta_contul(cont cuaccounts.rar_creds_enc→true; fara →false),test_ping_cheie_invalida_401,test_ping_prod_fara_cheie_401(flag on),test_ruta_ping_inregistrata_o_singura_data(assert peapp.routes— fara dubla inregistrare),test_postman_export_json_valid(Content-Type JSON, parseaza, schema Postman v2.1.0),test_postman_contine_exact_trei_requesturi(prezentari, import, ping; headerX-API-Key: {{api_key}};{{base_url}}),test_postman_nu_deriva_din_app_routes(allowlist hardcodat — NU expune/v1/conturi/rar-credsetc.). - Acceptance criteria:
GET /v1/ping(dependintaresolve_account_id) = readiness check, nu doar auth-echo: cheie valida → 200{account_id, mediu, autentificat_cu_cheie, are_creds_rar, ts}; cheie invalida → 401; fara cheie curequire_api_key=true→ 401; fara cheie in dev → cont 1 cuautentificat_cu_cheie=false. (are_creds_rar= contul areaccounts.rar_creds_encsetate; citire-only, raspunde la "esti gata sa trimiti?", nu doar "cheia merge". CEO-review P1/P2.)- Suporta si
Authorization: Bearer rfak_...(al doilea header documentat in pagina). GET /v1/integrare/postman.json: colectie Postman v2.1.0 cu variabilebase_url+api_key, exact 3 requesturi (allowlist hardcodat, NU derivat dinapp.routes):POST /v1/prezentari,POST /v1/import,GET /v1/ping, fiecare cu headerX-API-Key: {{api_key}}si body exemplu (pt prezentari: payload din schema realaPrezentareRequest, inclusivprestatii)./openapi.jsonramane accesibil (FastAPI implicit) — niciun regres.- NU atinge
submissions, worker, schema.are_creds_rar= SELECT read-only peaccounts.
- Verificare E2E:
curl -H "X-API-Key: rfak_..." http://localhost:8010/v1/pingpe instanta locala → 200 cu contul corect +are_creds_rar; importpostman.jsonin Postman/Swagger.
US-002: Helper pur — generator de exemple de cod multi-limbaj
Ca dezvoltator al gateway-ului vreau un modul pur care produce snippet-urile de integrare dintr-un
(base_url, account_id) pentru ca pagina sa fie testabila si snippet-urile sa ramana langa schema reala.
- Depinde de: —
- Fisiere:
app/web/integrare_examples.py(NOU),tests/test_integrare_examples.py(~2 fisiere) - Test intai (RED):
tests/test_integrare_examples.py—test_snippet_curl_prezentari_contine_endpoint_si_header({base_url}/v1/prezentari,X-API-Key: rfak_...),test_snippet_python_import_upload_multipart(folosestefiles=/ multipart pe/v1/import),test_toate_limbajele_prezente(curl, python, php, csharp, node, vfp_msxml, vfp_winhttp),test_ambele_canale_per_limbaj(fiecare limbaj are si prezentari JSON, si upload fisier),test_vfp_msxml_si_winhttp_distincte(MSXML2.ServerXMLHTTP.6.0 vs WinHttp.WinHttpRequest.5.1),test_payload_acopera_campurile_obligatorii_din_model(snippet-ul prezentari contine TOATE campurile obligatorii derivate prinfield.is_required()dinPrezentareIn— INCLUSIVprestatiicu ≥1 item — siRarCredentials{email,password}; drift-test corect:{c for c,f in PrezentareIn.model_fields.items() if f.is_required()}⊆ campurile din snippet; campurile cu default —odometru_initial,obs,b64_image,sistem_reparat— NU dau drift fals),test_prestatii_in_snippet_are_cod(item-ulprestatiiarecod_prestatieSAUcod_op_service— veziPrestatieItem._require_one),test_placeholder_cheie_nu_e_valoare_reala(mereurfak_..., niciodata o cheie injectata). - Acceptance criteria:
- Functie pura
exemple(base_url: str, account_id: int) -> dictcare intoarce, per limbaj, snippet pt ambele canale. - Placeholder cheie =
rfak_...(constant), endpoint-ul derivat dinbase_url. - Payload-ul JSON reflecta schema reala (
PrezentareRequest):rar_credentials{email,password}+prezentari[]cu toate campurile obligatorii prinis_required(), inclusivprestatiicu cel putin un item valid (eng-review P1:prestatiie fara default → obligatoriu; un payload fara el ar fi nevalid, exact ce pagina trebuie sa previna). - Drift-test foloseste
field.is_required()(nu doar prezenta cheii), ca sa nu raporteze fals campurile cu default. - Fara I/O, fara DB, fara stare globala — pur (usor de testat).
- Functie pura
- Verificare E2E: acoperita de UI (US-003) + unit teste.
US-003: UI — tab "Integrare" cu exemple, retetar VFP si export
Ca utilizator vreau o pagina cu exemple gata de copiat in limbajul meu + linkuri de export pentru ca sa integrez gateway-ul fara sa caut prin README/Swagger.
- Depinde de: US-001, US-002, US-004
- Fisiere:
app/web/routes.py(_render_integrare+/_fragments/integrare+integrarein_TABS_VALIDE+ branch nou in_render_panel_for_tab— necesar pt deep-link server-side, altfel/?tab=integrarecade pe Acasa),app/web/templates/dashboard.html(tuplu nav nou + generalizarea scriptului ARIA tablist),app/web/templates/_integrare.html(NOU),tests/test_web_integrare.py(~4 fisiere) - Test intai (RED):
tests/test_web_integrare.py—test_tab_integrare_in_nav,test_deeplink_tab_integrare_randeaza_panou_server_side(/?tab=integrare→ panou randat, NU Acasa — prinde branch-ul lipsa din_render_panel_for_tab),test_fragment_integrare_necesita_login(require_login),test_pagina_contine_account_id_si_endpoint_real(dinrequest.base_url),test_pagina_are_tab_limbaje_si_vfp_cu_dialecte(limbaj = tablist primar; VFP = un tab cu sub-tablist MSXML2/WinHttp),test_canal_secundar_prezentari_si_import,test_export_card_openapi_postman_swagger,test_buton_copiaza_citeste_din_pre_code(markup copy citeste din<pre><code>, nu din atribut),test_empty_state_cta_cont_cand_fara_cheie_sau_creds,test_fara_culori_hardcodate_doar_tokens(snippet-ul template-ului nu contine#-hex; doarvar(--...)). - Acceptance criteria:
- Tab nou "Integrare" in nav (
dashboard.html),integrarein_TABS_VALIDE, branch nou in_render_panel_for_tab, deep-link/?tab=integrarerandat server-side, fragment lazy pe click (pattern identic cu Mapari/Cont). NU atinge_render_panel_import/coada. - IA pe doua niveluri (design-review P1): tab primar = LIMBAJ (curl/Python/PHP/C#/Node/VFP) — VFP e UN tab, nu sectiune separata; in panelul VFP, al doilea tablist = dialect (MSXML2 / WinHttp). Tab secundar (in fiecare panel de limbaj) = CANAL (Prezentari JSON / Import fisier). Se vede UN singur snippet o data (fara produs cartezian 14-snippet pe ecran).
- Refolosire ARIA (design-review P1): generalizeaza scriptul de keyboard-nav din
dashboard.html(sageti/Home/End, rovingtabindex, syncaria-selected+aria-controls) ca sa prinda ORICE[role=tablist], scoped pe containerul propriu (nu primulquerySelectorglobal) — altfel tab-urile imbricate (limbaj/canal/VFP-dialect) intra in conflict peArrowRight. - Copy-to-clipboard (design-review P2): buton per snippet care citeste textul din
<pre><code>asociat (NU dindata-*); feedback inaria-live="polite"+ label "Copiat" cu revenire la "Copiaza" dupa ~2s;navigator.clipboardcu.catch()+ fallback pt context ne-securizat (selecteaza textul + "Ctrl+C") — butonul nu ramane blocat fals pe "Copiat". - Empty-state onboarding (design-review P2 + CEO P1): cand sesiunea NU are cheie rotita sau NU are creds RAR, afiseaza
deasupra snippet-urilor un empty-state cu CTA direct
href="/?tab=cont"("Genereaza cheia din Cont; o vezi o singura data"). Snippet-urile raman vizibile (placeholder-based). Flux de onboarding continuu, nu doar o nota text. - Card separat "Export & referinta" (componenta
.cardlink): Swagger/docs,GET /openapi.json,GET /v1/integrare/postman.json(Postman =download; restultarget="_blank" rel="noopener"). - Integreaza formularul "Testeaza conexiunea" din US-004 (primul card al panoului; markup-ul tinteste ruta US-004).
- Tokens de tema (design-review P3, pregatire 5.3): template-ul foloseste DOAR variabilele din
:root(--bg/--card/--ink/--muted/--line/--accent), zero culori hex hardcodate; fara highlight de sintaxa colorat (ar introduce paleta noua). Cod copiabil pe--ink, nu--muted.
- Tab nou "Integrare" in nav (
- Verificare E2E: browser pe
/integrare— comuta limbaj (inclusiv VFP cu dialect), comuta canal, copiaza un snippet (vezi "Copiat" + revenire), vede account_id-ul + endpoint-ul reale, deschide/openapi.jsonsi importul Postman.
US-004: Backend web — "Testeaza conexiunea" (verifica cheia lipita, scoped pe sesiune)
Ca utilizator vreau sa lipesc cheia mea si sa primesc confirmare ca e valida pentru ca sa stiu ca integrarea va autentifica corect inainte sa scriu cod.
- Depinde de: —
- Fisiere:
app/web/routes.py(POST /integrare/test-cheie,require_login+ CSRF),app/web/templates/_integrare_test_rezultat.html(NOU — fragment de raspuns dedicat, NU inline in_integrare.htmlcare apartine US-003; eng-review P2: evita fisier partajat intre valuri),tests/test_integrare_test_cheie.py(~3 fisiere) - Test intai (RED):
tests/test_integrare_test_cheie.py—test_cheie_valida_a_contului_curent_ok(mesaj succes + account_id),test_cheie_a_altui_cont_respinsa(cheia mapeaza pe alt cont → mesaj "nu apartine contului tau", NU dezvaluie care),test_cheie_invalida_mesaj_clar,test_cheie_revocata_dupa_rotire_respinsa(eng-review P2: cel mai probabil caz de suport — lipesti cheia veche dupa rotire),test_cheie_goala_nu_da_fals_pozitiv_in_dev(eng-review P2: folosesteaccount_for_keydirect, NUresolve_account_idcu fallback cont 1),test_fara_login_redirect_sau_401,test_csrf_lipsa_respinsa,test_cheia_nu_apare_in_raspuns_sau_log(no echo). - Acceptance criteria:
POST /integrare/test-cheie(require_login, CSRF): valideaza cheia lipita prinaccount_for_keydirect (NUresolve_account_id— altfel in dev o cheie goala/gunoi ar cadea pe cont 1 si ar raporta fals "valida"); confirma DOAR daca mapeaza pe contul sesiunii; altfel mesaj neutru ("nu apartine contului tau", fara sa dezvaluie care cont).- Cheie revocata (dupa rotire) → tratata ca invalida (
account_for_keyfiltreazaactive=1). - Niciun echo al cheii in raspuns/log (regula 422-no-echo din
main.py). - Raspuns HTML fragment dedicat (
_integrare_test_rezultat.html), htmx swap intr-un containeraria-live="polite": succes pe.flash(border--ok, "Cheie valida — cont X"), eroare pe.banner(border--err). Label uman, fara emoji. - Input
type=password+autocomplete="off"; microcopy anti-confuzie langa camp: "Verificam doar daca cheia e valida. Nu o salvam si nu o memoram — cheia se gestioneaza in Cont." Buton "Testeaza conexiunea" (NU "Salveaza"). - NU creeaza/roteste chei (doar verifica) — fara efecte secundare.
- Verificare E2E: browser — lipeste cheia reala (din rotire
/cont) → "valida, cont X"; lipeste gunoi → eroare clara; lipeste cheia veche dupa rotire → respinsa.
4. Graful de valuri
- Val 1 (paralel, fisiere disjuncte): US-001 (
integrare_router.pyNOU) ‖ US-002 (integrare_examples.pyNOU) ‖ US-004 (routes.py+ test). US-001 si US-002 sunt fisiere noi; US-004 atingeroutes.py(ruta noua, fara suprapunere cu US-003 care vine in Val 2). Atentie: US-003 si US-004 ating ambeleroutes.py→ NU in acelasi val. - Val 2: US-003 (UI:
routes.py+dashboard.html+_integrare.html) — depinde de US-001/US-002/US-004. Nota (eng-review P2): US-004 isi pune raspunsul in_integrare_test_rezultat.html(fisier propriu), NU in_integrare.html(al US-003) — asa cele doua valuri nu impart un template.
Prioritate de descope (CEO-review P2/P3) — daca timpul se scurteaza, taie in aceasta ordine inversa de valoare:
- (pastreaza ultimul) US-002 + US-003 exemple + retetar VFP in pagina = wedge-ul de adoptie, ne-negociabil.
- US-004 (test cheie) — potentator.
- US-001 ping — potentator.
- (primul taiat) export Postman/OpenAPI — audienta moderna (Python/Node), public secundar fata de VFP. Retetarul VFP ramane prim-clas indiferent de descope.
5. Considerații tehnice
- Auth: header
X-API-Key: rfak_...(sauAuthorization: Bearer rfak_...), dependintaresolve_account_id(app/auth.py). In dev (require_api_key=false) lipsa cheii → cont 1;pingsemnaleaza asta cuautentificat_cu_cheie. - Schema request (din
app/models.py):PrezentareRequest{rar_credentials{email,password}, prezentari[PrezentareIn]};PrezentareIn{vin, nr_inmatriculare, data_prestatie(YYYY-MM-DD), odometru_final(str), odometru_initial?, sistem_reparat="null", obs?, b64_image?, prestatii?[{cod_prestatie|cod_op_service, denumire}]}. - Import:
POST /v1/import, multipart, campfile(app/api/v1/import_router.py). - base_url derivat din
request.base_url; documenteaza override in spatele proxy (X-Forwarded). Risc minor de base_url gresit in spatele reverse-proxy — mitigat prin nota in pagina. - Pattern UI: tab nou = tuplu in
dashboard.html+integrarein_TABS_VALIDE+_render_integrare+/_fragments/integrare(identic cu Mapari/Cont/Nomenclator). - OpenAPI/Postman:
/openapi.jsone gratuit din FastAPI; colectia Postman e construita o data din endpoint-urile cunoscute.
6. Riscuri
- Drift de schema intre snippet-uri si
PrezentareInreal → test care leaga snippet-ul demodel_fields(US-002). - base_url gresit in spatele proxy → nota + derivare din request.
- Confuzie dev "merge fara cheie" (cont 1) →
pingraporteazaautentificat_cu_cheie=false. - Scurgere cheie in test-cheie → no-echo enforce + test dedicat (US-004).
7. Intrebari deschise
Rezolvate cu utilizatorul (2026-06-22): test conexiune = GET /v1/ping nou (independent de 5.2); exemple pe ambele
canale (prezentari + import); continut doar in-app dinamic (fara markdown versionat); VFP = ambele dialecte (MSXML2 + WinHttp).
Niciuna ramasa deschisa.
8. Verificare (rezumat E2E per canal)
- API:
curl GET /v1/pingcu cheie reala pe instanta locala (8010) → 200 cont corect; importpostman.json. - Web: browser pe
/integrare— comuta limbaj, copiaza snippet, vede account_id+endpoint reale, testeaza cheia. - Regresia de aur (neatinsa, dar de confirmat ca nu s-a stricat):
POST /v1/prezentari(sau import → commit) → worker →FINALIZATAla RAR test.
Criteriu de succes al wedge-ului (CEO-review P3): un service nou (stil VFP) ajunge de la zero la o prezentare
FINALIZATA la RAR test folosind DOAR pagina /integrare (copiaza snippet → testeaza cheia → vede are_creds_rar →
trimite), fara suport uman si fara sa atinga README/Swagger separat.
Review-uri de plan (§5.3 — rulate 2026-06-22)
- CEO (valoare/scope) — APROB CU MODIFICARI. Aplicat: ping/test ca readiness-check (
are_creds_rar), CTA continuu spre/contin empty-state, VFP prim-clas + prioritate de descope (§4), criteriu de succes masurabil (§8). (P2 "ping redundant" rezolvat prin diferentierea payload-ului: ping poartaare_creds_rar+mediu, deci e readiness, nu auth-echo.) - Eng (fezabilitate/teste) — APROB CU MODIFICARI. Aplicat: montare router
prefix="/v1"inmain.pyfara dublare + test inregistrare unica; drift-test cuis_required()+prestatiiobligatoriu (US-002); template dedicat_integrare_test_rezultat.html(US-004, anti fisier-partajat intre valuri); teste Bearer/cheie-goala/cheie-revocata;account_for_keynuresolve_account_id; Postman allowlist exact 3 (nuapp.routes);_render_panel_for_tabin fisierele US-003. - Design (UI) — APROB CU MODIFICARI, claritate plan UI 6/10 → adresat. Aplicat: IA pe 2 niveluri (limbaj primar, canal
secundar, VFP cu sub-dialect); refolosire + generalizare script ARIA tablist (scoped per container); copy din
<pre><code>+aria-live+ fallback non-HTTPS; empty-state cu CTA/?tab=cont; card "Export & referinta" cu.cardlink; doar tokens de tema (pregatire 5.3); microcopy anti-confuzie +type=passwordla test-cheie.
Toate cele trei: APROB CU MODIFICARI, modificarile incorporate mai sus. Asteapta poarta umana de aprobare (§5.8) → aprobat.
Raport VERIFY (2026-06-22 — subagent context curat + E2E browser lead)
Rezultat: PASS (dupa o runda de fix pe 4 discrepante minore).
- Suita:
python3 -m pytest -q→ 564 passed, 0 failed (523 baseline + 41 noi: 11 API ping/postman, 8 examples, 10 web integrare initial + 4 lock-uri fix, 8 test-cheie). - US-001..US-004 (criterii de acceptare): toate PASS (verificator independent, dovezi in cod + teste +
curllive pe :8010 — ping cont 1autentificat_cu_cheie=false, cheie valida=true, Bearer ok, cheie invalida 401, postman.json 3 items allowlist fara/v1/conturi/rar-creds, openapi 200). - Fix dupa VERIFY r1 (4 discrepante PRD-vs-implementare, toate in
_integrare.html, lock-uite cu teste noi): cardul Export foloseste.cardlink; linkul Postman aredownload(faratarget=_blank); microcopy anti-confuzie la test-cheie ("Nu o salvam si nu o memoram…"); butonul Copiaza isi schimba label-ul in "Copiat" + revine la 2s. - E2E browser (Playwright, lead, dev
web_auth_required=false→cont 1): PASS pe/?tab=integrare— randare server-side, IA pe 2 niveluri (limbaj→canal), VFP cu al 3-lea nivel (dialect MSXML2↔WinHttp comuta corect, snippet WinHttp.WinHttpRequest.5.1), endpoint+account_id reale, empty-state CTA/?tab=cont, card Export, microcopy prezent, htmx test-cheie: cheie invalida → fragment eroare in containeraria-live("Cheie invalida sau revocata"). 0 erori in consola (clasa de bug-uri htmx care a muscat 3.6 — absenta aici). - Regresia de aur (enqueue):
POST /v1/prezentari→status: queued(live :8010). Backend trimitere NEATINS (doar rute noi de citire + UI; zero modificari worker/masina-stari/idempotenta/schema) — confirmat la diff. Live RAR test (postPrezentare→FINALIZATA) NEPROBAT in sesiune:AUTOPASS_CREDS_KEY/creds RAR test indisponibile in mediu. Risc minim (cod de trimitere neatins).
Toate PASS → CLOSE.
/code-review high (2026-06-22 — CLOSE)
8 unghiuri (3 correctness + cleanup/altitude/conventii), verificare 1-vot. 4 bug-uri reale reparate (toate in suprafata noua, backend trimitere neatins), lock-uite cu teste:
- C# snippet — payload JSON multi-linie (
json.dumps indent=2) intr-un string literal C# obisnuit → CS1010 (nu compileaza). Fix:_payload_json_compact(separators(",",":"), fara newline) pentru C#. - VFP snippet —
json.dumps(indent=0)PRODUCE TOTUSI newline-uri →cPayload = "..."rupt (VFP nu suporta string literal multi-linie) in ambele dialecte. Fix: acelasi helper compact. - Node import snippet —
await import("node:buffer")nu exportaFormData→new FormData()arunca TypeError pe orice Node; plus import mortreadFileSync/import("fs")duplicat. Fix:FormData/Blobglobale (Node 18+) +readFileSyncstatic folosit direct. - Script
_integrare.htmlne-scoped —document.querySelectorAll('[role=tablist]')ataseaza handlere si pe tab-bar-ul PRINCIPAL dindashboard.html, acumuland listeneri la fiecare swap htmx. Fix: scoping pe#integrare-section(root.querySelectorAll(...)), nu mai atinge tab-bar-ul principal.
Notat ca cleanup viitor (NEREPARAT, disciplina backend/altitudine — low value, fara risc): _render_integrare dubleaza SQL-ul are_creds/are_cheie din _get_acasa_context/_render_panel_cont (candidat de helper partajat); ping deschide 2 conexiuni DB + apeleaza account_for_key de 2 ori (derivabil din account_id != DEFAULT_ACCOUNT_ID); _campuri_obligatorii() necache-uit (apelat ~6×/render); cele 6 panouri de limbaj din _integrare.html copy-paste (candidat macro Jinja2); {{ mesaj }} fara | e explicit (salvat acum de autoescape, no-echo confirmat). Pre-existente (in afara 5.1): GET /v1/nomenclator + /_fragments/nomenclator neprotejate (deja notate in ROADMAP "de remediat").
568 teste pass.