Files
roa2web-service-auto/docs/service-auto/claude-main-design-20260411-rethink.md
Claude Agent f79a03062c docs(service-auto): add v2 design doc for learning prototype
CEO review output: rethink of scrapped 2026-04-10 product plan,
reframed as learning probe + talent-risk hedge. 24-week timeline,
1 screen + 1 SP + MARIUSM_AUTO test schema. Scope wall absolute:
zero touch on 4 existing VFP clients.

Document includes 8 review corrections vs first draft:
register_server over MarciusLabPool, SP targets dedicated orders
table not ACT ledger, explicit connection.commit(), Oracle error
code range classification, file handler logging, kill criterion,
integration checkpoints at weeks 6+12, template+decision-log as
week-24 deliverable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-05 09:37:09 +00:00

29 KiB
Raw Blame History

Design: Service Auto Web — Learning + Talent-Risk Hedge (rethink v2)

Generated by /plan-ceo-review on 2026-04-11 (pivot from the scrapped 2026-04-10 doc) Revised by /plan-ceo-review on 2026-04-11 (v2 after HOLD SCOPE review + outside voice) Branch: feat/service-auto Repo: romfast/roa2web Status: ACTIVE Owner: Marius (ERP patron + sole dev) Supersedes: claude-main-design-20260410-205024.md — premise invalidated (old doc was a product delivery plan; real intent is learning + capability hedge)

What this is (and what it is NOT)

This is: a side-exploration prototype. Part learning project (Vue 3 + FastAPI async + oracledb + PrimeVue), part strategic hedge against the "VFP is dead and I can't find programmers" problem. Target = 1 end-to-end screen with 1 SP write, on the existing test schema MARIUSM_AUTO at the office server 10.0.20.121/ROA. Budget ≈ 2-4 hrs/week, ≈48-96 hours total over 24 weeks (doubled from the original 12-week plan after sincere budget recalibration — see Review Corrections).

This is NOT: a product, an MVP, a migration plan, or a commitment to ship anything to any client. The 4 existing clients stay on VFP + Oracle XE local. Zero migration. Zero customer-facing delivery. Zero timeline pressure.

The deliverable is NOT a demo. The deliverable is a reusable template for future Oracle-backed modules + a decision log. See "Final deliverable" below.

Strategic driver (the one that matters)

Visual FoxPro is a dead language. Marius cannot hire programmers willing to learn it. Every year on VFP is another year of compounding talent risk on an ERP that powers 4 long-term clients and generates stable revenue. The only realistic path to "someone else can maintain this eventually" is moving incrementally to web stacks (Python/Vue) where the labor pool exists.

Constraint that makes this hard: Oracle coupling. The ERP has 25 years of PL/SQL, cross-schema synonyms, tenant-per-schema architecture. Postgres migration is not 1:1 — the PL/SQL and schema mechanics don't translate cleanly. Therefore the migration path is "stay on Oracle, switch UI + business logic layer to Python/Vue, keep PL/SQL as the durable layer." Service auto is the lowest-risk place to probe whether this path works.

Honest caveat on the hedge thesis: PL/SQL + Oracle domain knowledge is itself a scarce skill on the Romanian market. This prototype does NOT solve the hiring pipeline problem for PL/SQL maintainers. What it solves is the Python+Vue+integration layer — the UI/API half of the stack — where the labor pool is genuinely larger. The hedge is "replace the half of the stack where hiring is easier"; it is NOT "fix the hiring problem in one shot." This distinction matters for phase 2 scoping.

Success definition for this prototype: after 24 weeks (or sooner), Marius has direct evidence (working code, not hand-wavy) that the roa2web monolith can drive Oracle business logic end-to-end via PL/SQL stored procedures, AND a reusable template documenting exactly how. If that evidence is positive, the same pattern applies to the next module. If it's negative, Marius knows this before sinking years into it.

The prototype — minimum viable experiment

One screen, one SP, one test schema, one developer. Absolute scope wall.

Target feature

Screen: ComandaNoua.vue — formular creare comandă nouă service auto. Minimal fields: tip comandă (select 4 opțiuni), client (dropdown hardcoded în Vue — 2-3 clienți test cu 1-2 mașini fiecare), operații solicitate (textarea). Submit → backend → PL/SQL → insert row → return ID → display "Comanda X creată" via PrimeVue Toast.

SP: SP_CREEAZA_COMANDA(p_tip IN, p_client_id IN, p_masina_id IN, p_operatii IN, p_comanda_id OUT, p_numar OUT). Insert într-un tabel DEDICAT de comenzi (nume real în MARIUSM_AUTO — de verificat în VFP înainte de a scrie SP-ul, vezi pregătire săpt 3). NU inserează în ACT (registrul jurnal) — ACT se hit-uiește doar la facturare, care e NOT IN SCOPE pentru prototype. Validare minimă, return ID + număr.

Schema: MARIUSM_AUTO — schemă dedicată de test, deja existentă pe serverul de la biroul Marius (10.0.20.121/ROA), care nu e folosită de altcineva. Zero conexiune la schemele de producție ale celor 4 clienți. Zero copy / impdp necesar — schema există deja.

User Oracle tehnic: ROA_WEB — user nou dedicat app-ului FastAPI, cu grants explicite per SP (GRANT EXECUTE ON MARIUSM_AUTO.SP_CREEAZA_COMANDA TO ROA_WEB), fără acces direct la tabele. Pattern multi-tenant compatibil — același user va avea grants pe alte scheme în phase 2 dacă probează.

Things this prototype will probe (the real learning)

Fiecare din acestea e o ipoteză pe care prototype-ul trebuie să o confirme sau să o infirme:

# Ipoteză Cum o probez
1 python-oracledb async cleanly calls PL/SQL proc cu IN+OUT params Săpt 1 POC: poc/hello_async_out.py cu oracledb.connect_async() + cursor.var(oracledb.NUMBER) + await cursor.callproc('test_out', [out]). GATE: dacă merge curat, prototype-ul continuă pe true-async. Dacă NU merge, fallback la pattern-ul sync-facade din treasury_service.py (deja proof-ed în prod). Fallback e pre-aprobat, NU blochează săpt 2+.
2 session_callback pentru CURRENT_SCHEMA switching nu leak-uiește între requests concurente Săpt 4: 2 conexiuni paralele pe aceeași schemă MARIUSM_AUTO, ambele setează CURRENT_SCHEMA, rulează CALL-uri distincte, verific cu log-uri că nu se încurcă cursor tag reuse. Limitare acceptată conștient: testul pe 1 schemă nu dovedește 100% izolarea la multi-schemă — pentru asta ar trebui o a doua schemă test (ex: copie CLEVER), care e în afara budget-ului. Probă de primitive, nu de multi-schemă.
3 GRANTS de tip "EXECUTE ON SP, zero INSERT/UPDATE/DELETE pe tabele" țin în practică Săpt 3: user ROA_WEB încearcă INSERT INTO MARIUSM_AUTO.ACTORA-00942 sau ORA-01031; SELECT * FROM MARIUSM_AUTO.ACTORA-00942; EXEC MARIUSM_AUTO.SP_CREEAZA_COMANDA(...) → success. Un test automat pytest-marcat integration care rulează local.
4 RAISE_APPLICATION_ERROR(-20001, 'mesaj cu diacritice ă î ș ț â') ajunge în Vue ca eroare user-friendly, encoding corect Săpt 11-12: SP aruncă eroare (client inexistent, tip invalid, operatii gol), serviciul traduce oracledb.DatabaseError.code la HTTP status (20001-20999 → 422 business, 12541/12170 → 503 infra, rest → 500), Vue afișează PrimeVue Toast cu mesajul. Obligatoriu test pe un mesaj cu diacritice pentru a proba NLS_LANG / encoding chain end-to-end.
5 FastAPI hot-reload + Vite dev-server + SSH tunnel Oracle e un DX acceptabil pentru side-work de 2-4h/săpt Săpt 1: măsor timpul de la "save file" la "văd rezultatul" — dacă e > 10s, fix ecosistem înainte de content. Documentat în docs/service-auto/week1-notes.md cu numere concrete.

Dacă oricare din 1-4 eșuează cu un răspuns clar, prototype-ul s-a încheiat cu succes — learning obținut, decision point clar, zero cod irosit care trebuie să supraviețuiască.

Scope wall — what is explicitly NOT in this prototype

Toate aceste subiecte aparțin doc-ului scrapped sau sunt defer-uri la TODO-phase2. Niciunul nu intră aici:

  • Cei 4 clienți existenți, vreodată. Ei rămân pe VFP + XE local. Zero atingere.
  • Migrare scheme, SSH tunnel VFP→Oracle central, decomisionare XE local
  • eFactura / ANAF / SPV upload — irelevant fără producție
  • Feature flags per-tenant, FEATURE_FLAGS table
  • SP_BON_CONSUM (cross-schema synonyms), SP_VALIDEAZA_COMANDA, SP_EMITE_FACTURA — toate deferred
  • Insert în ACT la creare comandă — ACT e registrul jurnal, se hit-uiește la facturare, care e NOT IN SCOPE
  • reconcile.py, invariant checking, parallel testing cu VFP
  • Runbook rollback, monthly restore drill, uptime monitoring, Telegram alerts
  • 5 ecrane MVP (doar 1 — absolute wall)
  • Mobile, responsive, iPad, tablet — desktop-only, viewport-whatever-is-convenient
  • Playwright e2e, smoke parity pentru SPs
  • Endpoint /clienti sau /masini pentru populare dropdown — hardcoded în Vue
  • Onboarding client nou, referral pipeline, assignment cu telefoane
  • Phase 2, Phase 3, Phase 4 — menționate doar în decision-log.md la finalul prototype-ului
  • SLA, RPO, RTO, warm standby, backup discipline
  • X-Idempotency-Key, double-submit protection, retry policy
  • A doua schemă de test (ex: copie CLEVER) pentru probă multi-schemă — costă prea mult budget

Dacă în timpul construcției una dintre aceste tentații începe să pară "doar 30 min în plus", răspunsul e scriu o notă, nu scriu cod. Scope wall ține. Note de tipul "probabil o să am nevoie de X pentru phase 2" merg în docs/service-auto/TODO-phase2.md, nu în codul prototype-ului.

Review corrections (from /plan-ceo-review session, 2026-04-11)

Această secțiune documentează ce s-a corectat față de prima versiune a planului, pentru a fi transparent despre gândirea care a dus la planul final.

Correction 1 — Nu se creează MarciusLabPool nou

Prima versiune spunea: "modifică OracleMultiPool sau adaugă wrapper" și "creează NEW minimal helper MarciusLabPool". Realitate: OracleMultiPool la shared/database/oracle_pool.py are deja suport multi-server prin _pools: Dict[server_id, ConnectionPool]. MARIUSM_AUTO se adaugă ca server nou prin register_server('mariusm_test', host='10.0.20.121', port=1521, user='ROA_WEB', password='...', service_name='ROA') — zero pool nou, zero refactor.

Correction 2 — Pattern sync-in-async-facade e deja proof-ed în prod

Prima versiune trata ipoteza #1 ("oracledb async + OUT params") ca unknown. Realitate: backend/modules/reports/services/treasury_service.py deja apelează SPs cu OUT params de tip oracledb.CURSOR și oracledb.NUMBER în producție, folosind pattern-ul sync-in-async-facade (async with oracle_pool.get_connection(...), cursor sync, fără await pe execute/callproc). Consecință: ipoteza #1 e reîncadrată ca probă a pattern-ului oracledb.connect_async() true-async — nou, neprobeat în codebase. Săpt 1 e gate (vezi mai sus): dacă true-async merge → adoptă; dacă nu → fallback la sync-facade care e deja dovedit.

Correction 3 — SP nu inserează în ACT

Prima versiune spunea "Insert în ACT, validare minimă". Realitate: ACT e registrul jurnal contabil (double-entry bookkeeping, clasa 6/7 — vezi .claude/rules/financial-indicators.md). O comandă de service auto la CREARE aterizează într-un tabel dedicat (ex: COMENZI, COMD_SA, nume real de verificat în VFP), NU în ACT. ACT se hit-uiește la facturare, care e NOT IN SCOPE. SP-ul corect face INSERT în tabela dedicată de comenzi.

Task în săpt 3 (preparare): înainte de a scrie SP_CREEAZA_COMANDA, deschide VFP-ul producție (cu grijă, doar read), caută fluxul real de "creează comandă nouă service auto", identifică tabelele atinse, documentează în docs/service-auto/tabele-service-auto.md.

Correction 4 — connection.commit() e explicit în pattern

Prima versiune nu menționa commit. Realitate: oracledb driver are autocommit OFF default. Fără connection.commit() după cursor.callproc, SP-ul rulează dar datele NU se salvează — silent failure clasică. Pattern-ul corect e:

async with oracle_pool.get_connection('mariusm_test') as conn:
    with conn.cursor() as cursor:
        out_id = cursor.var(oracledb.NUMBER)
        out_numar = cursor.var(oracledb.STRING, size=50)
        cursor.callproc('SP_CREEAZA_COMANDA', [..., out_id, out_numar])
    conn.commit()  # <-- CRITICAL

Test obligatoriu în săpt 5-6: după callproc + commit, închide conexiunea, deschide alta, SELECT ... WHERE id = :id — confirmă că row-ul persistă. Dacă nu, commit-ul e problemă.

Correction 5 — Error code classification e explicită în plan

Prima versiune zicea doar "ORA-20001 → toast". Realitate: există multe categorii de erori Oracle, iar trducerea la HTTP trebuie să fie range-based:

Cod Oracle HTTP Ce vede user-ul
20001 — 20999 (RAISE_APPLICATION_ERROR) 422 Mesajul din SP, curat de prefix
12541, 12170, 12154 (connection / listener errors) 503 "Serviciul bazei de date e temporar indisponibil"
01017 (invalid credentials) 500 + critical log "Eroare de configurare. Contactați administratorul."
00942 (table or view not exist — grants leak) 500 + critical log "Eroare internă. Contactați administratorul."
Orice alt cod 500 + full log "Eroare internă neașteptată"

Săpt 11-12: scrie service-layer-ul cu try/except oracledb.DatabaseError + clasificare pe range. Test cu diacritice în mesaj.

Correction 6 — Logging persistent per-modul

Prima versiune nu menționa logging. Realitate: backend/main.py:57 folosește logging.basicConfig cu output doar în stdout. Dacă în săpt 5 vrei să recitești log-urile din săpt 2, nu ai unde. Fix local pentru service_auto:

# backend/modules/service_auto/__init__.py
import logging, os
os.makedirs('backend/logs', exist_ok=True)
logger = logging.getLogger('service_auto')
fh = logging.FileHandler('backend/logs/service_auto.log')
fh.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(name)s: %(message)s'))
logger.addHandler(fh)
logger.setLevel(logging.INFO)

Log structurat la fiecare call:

logger.info("service_auto.create_comanda START", extra={'user': user.username, 'tip': data.tip, 'client_id': data.client_id})
logger.info("service_auto.create_comanda OK", extra={'comanda_id': comanda_id, 'duration_ms': elapsed})
logger.warning("service_auto.create_comanda BUSINESS_ERROR", extra={'ora_code': code})
logger.error("service_auto.create_comanda INFRA_ERROR", extra={'ora_code': code}, exc_info=True)

La sfârșit de fiecare săptămână, grep în log pentru count-uri și duration p99.

Correction 7 — Timeline dublat: 12 → 24 săptămâni

Prima versiune aloca 12 săptămâni × 2-4 h/săpt = 24-48h. Realitate (outside voice): 10 tehnologii noi (Vue 3, Pinia, PrimeVue, Axios, FastAPI async, oracledb true-async, session_callback, PL/SQL OUT params, JWT reuse cu auth store, error mapping) ÷ 24h = ~2.4h per tehnologie, zero slack. Plus 2-3 săpt pierdute realist pe VFP urgențe din 12. Buget onest: 24 săptămâni × 2-4 h/săpt = 48-96h total. Scope-ul rămâne același, tempo-ul e mai onest.

Correction 8 — Week-12-style deliverable schimbă: template reutilizabil, nu demo

Prima versiune zicea săpt 12 = "cleanup + phase 2 notes". Realitate: un demo pe un branch throwaway nu e un hedge — e o demonstrație. Hedge-ul real e un template reutilizabil. Noul deliverable pentru săpt 24:

  • docs/service-auto/template-modul-oracle.md — rețetă de 1 pagină pentru "cum adaugi un modul nou peste Oracle în roa2web": register_server pattern, SP signature convention, grants model, error map range, session_callback snippet, JWT reuse via AuthenticationMiddleware, logging setup, file layout.
  • docs/service-auto/decision-log.md — go / no-go pentru phase 2: ce a funcționat, ce nu, sub ce condiții se justifică un al doilea modul, când să nu.
  • docs/service-auto/learnings.md — notele săptămânale consolidate în lesson patterns.

What to reuse from the scrapped doc

Nu tot efortul de pe doc-ul vechi e pierdut:

  • Manual ROAAUTO PDF (docs/service-auto/manual_ROAAUTO.pdf) — ground truth pentru fluxul real de service auto. Folosit ca input pentru ce câmpuri trebuie să aibă ComandaNoua.vue și ca referință pentru verificarea tabelelor atinse la creare comandă.
  • Legacy /workspace/roaauto/frontend/src/views/orders/OrderCreateView.vue — starting point pentru ComandaNoua.vue la ~125 linii, audit de 30 min în săptămâna 1.
  • Convenția de @cached + services din .claude/rules/backend-patterns.md — dar NU aplicat la endpoint-ul de INSERT (cache-ul e pentru reads).
  • Pattern-ul treasury_service.py ca golden example de apel PL/SQL cu OUT params.

Risks + mitigations

Risk 1: 2-4 hrs/week + learning curve = prototype drifts into 12+ months

Corecția de buget (24 săpt) ajută. Mitigare principală: stop-point discipline (milestone self-contained per săptămână) + kill criterion explicit (vezi mai jos). Săpt 1 goal e Hello World Oracle connection — nu SP, nu schema, nu UI.

Risk 2: oracledb async + PL/SQL OUT params sunt poorly documented

Săpt 1 POC e exact asta, pe o procedură trivială. Fallback pre-aprobat: dacă true-async nu merge, prototype-ul continuă cu sync-facade (pattern deja în prod). Zero timp pierdut.

Risk 3: CURRENT_SCHEMA switching conflictează cu OracleMultiPool

Corectat: nu conflictează. OracleMultiPool izolează per server_id. session_callback se aplică la create_pool call, nu la nivel de instance. Poți adăuga un argument session_callback= la pool creation pentru mariusm_test fără să atingi pool-urile altor servere.

Risk 4: Marius abandonează side project-ul după săpt 3 pentru că VFP-ul real cere atenție

Realitate acceptată (outside voice): 2-3 săpt pierdute în 12 e probabil. Mitigare: timeline dublat la 24, fiecare săptămână e stoppable milestone, plus kill criterion.

Risk 5 (NEW): Integration issues concentrate la final

Outside voice observă: fiecare layer e mock-uit până la săpt 11, apoi totul se integrează. Dacă Vue↔FastAPI↔oracledb are un CORS/proxy/JWT header issue, apare fără buffer. Mitigare: două integration checkpoints intermediare:

  • Săpt 6 checkpoint: un curl hit pe endpoint-ul fără UI, cu JWT real, care cheamă SP-ul și returnează JSON. Confirmă FastAPI↔oracledb chain.
  • Săpt 9 checkpoint: ComandaNoua.vue hit endpoint-ul cu JWT real, confirmă doar un drum happy path fără error handling. Confirmă Vue↔FastAPI chain.

Risk 6 (NEW): Grants inventory pe MARIUSM_AUTO nedocumentat

Outside voice observă: testul negativ săpt 3 presupune clean slate. Mitigare: săpt 3, înainte de testul negativ, rulează un SELECT * FROM DBA_TAB_PRIVS WHERE grantee = 'ROA_WEB'

  • SELECT * FROM DBA_SYS_PRIVS WHERE grantee = 'ROA_WEB' și documentează starting state în docs/service-auto/week3-grants-audit.md.

Kill criterion (NEW — from outside voice)

Prototype-ul se oprește definitiv (nu "pauză de o săptămână", ci "end of project, scrie decision-log și gata") dacă ORICARE din:

  1. Săpt 4 checkpoint: session_callback nu funcționează după 2 săpt de încercări (adică nu ai ajuns la o conexiune care schimbă CURRENT_SCHEMA curat, fără race). Decizia: scrie decision-log.md cu "session_callback nefezabil în acest oracledb/Python combo, multi-tenant necesită alt approach", apoi stop.
  2. Săpt 8 checkpoint: nu ai un SP SP_CREEAZA_COMANDA funcțional testat din SQL Developer + Python + grants OK. Decizia: decision-log.md cu "pattern SP-first prea greu pentru side-project budget", apoi stop.
  3. Săpt 14 checkpoint: nu ai un curl care apelează endpoint-ul + JWT real + SP + returnează JSON.
  4. Oricând: 3 săpt consecutive în care nu ai atins nici măcar 1 oră de work pe prototype. Side project-ul e mort, acceptă realitatea, decision-log.md cu "abandoned — VFP demands exceeded budget".

Stop NU înseamnă eșec. Stop înseamnă "am învățat ce trebuia, continuarea nu mai produce valoare marginală". Fiecare stop produce un decision-log.md citibil în 6 luni.

Timeline (ajustat pentru 2-4 hrs/week × 24 săptămâni)

Fiecare săptămână e self-contained + oprire curată. Ordering-ul original e păstrat, doar spațiat pe 24 săpt în loc de 12, cu checkpoints de integration intermediare.

Săpt Target Cum știu că e gata
1 Oracle central rulează + poc/hello_oracle.py (sync) + poc/hello_oracle_async.py (connect_async) conectează cu SELECT 1 FROM DUAL. Gate: decide sync-facade vs true-async. DX check (save → result < 10s?). File handler logging setup. Log arată rezultat, docs/service-auto/week1-notes.md scris
2 poc/async_out_param_probe.py — test SP trivial (CREATE PROCEDURE test_out(p OUT NUMBER) AS BEGIN p := 42; END;) + Python apel cu cursor.var(int) Script scris, primește 42
3 Preparare: audit grants curenți pe MARIUSM_AUTO (DBA_TAB_PRIVS, DBA_SYS_PRIVS). Verifică tabelele atinse de crearea comenzii în VFP, scrie tabele-service-auto.md. Creează user ROA_WEB + grants. week3-grants-audit.md + tabele-service-auto.md scrise
4 Test negativ ipoteza #3 (INSERT direct → ORA-00942; SELECT direct → ORA-00942; CALL SP → success). Pytest integration marker. Test automat rulează local, toate cele 3 asserts trec
5 session_callback pentru CURRENT_SCHEMA switching, test concurent pe 2 conexiuni paralele pe aceeași schemă Log-uri clare, niciun cursor tag leak
6 Checkpoint integration 1: endpoint FastAPI minimal (fără logic, hardcoded return) + JWT reuse din middleware + curl hit cu JWT real. Doar ca să confirm că chain-ul FastAPI + auth merge. curl cu JWT real returnează 200
7-8 Verify tabele în VFP (din săpt 3), scrie SP_CREEAZA_COMANDA în SQL Developer, test manual cu EXEC Row apare în tabela dedicată cu ID returnat prin OUT
9-10 Service-layer Python (comenzi_service.create_comanda) care apelează SP-ul prin pattern-ul ales în săpt 1 + connection.commit() + test persist după reconnect Test automat: callproc + commit + new connection + SELECT → row există
11 Endpoint FastAPI /api/service-auto/comenzi care primește Pydantic, apelează service, returnează JSON curl hit cu JWT real + body JSON → row inserted
12 Checkpoint integration 2: ComandaNoua.vue minimal (hardcoded dropdowns) + Pinia store + axios call → endpoint. Doar happy path, zero error handling. Submit în browser → row inserted → console log "OK"
13-16 Error handling end-to-end: ORA-20001 (diacritice!) → HTTP 422 → PrimeVue Toast în română. ORA-12541 → HTTP 503 → Toast generic. Spinner pe buton cât SP rulează. Reset form la success. Aruncă intenționat erori în SP, verifică fiecare drum
17-20 Buffer pentru VFP urgențe + lessons refactor (dacă săpt 1-16 au produs cod care trebuie curățat). Dacă nu e nevoie de buffer, rula ipoteza #2 mai adânc (2 conexiuni, concurență mai agresivă). N/A — buffer
21-22 Scrie template-modul-oracle.md — reteta reutilizabilă Doc scris, citibil de către un alt dev
23 Scrie decision-log.md — go/no-go phase 2, learnings consolidate Doc scris, decizie clară
24 Cleanup: ștergerea poc/ dacă e cazul, final commit pe branch, learnings.md consolidat Branch clean, commit final

Timeline-ul e intenționat conservativ. La 2-4 hrs/week, 24 săpt = 48-96 ore totale. Dacă merge mai repede, perfect — atingi mai devreme la sfârșit. Dacă merge mai încet, fiecare săptămână e încă un milestone self-contained.

What would make this prototype fail (and it would still be useful)

  • Ipoteza #1 eșuează pentru true-async: fallback la sync-facade, prototype continue. Zero învățare pierdută — sync-facade e deja în producție, știi că merge.
  • Ipoteza #1 eșuează pentru ambele (sync + true-async): dacă nici sync-facade-ul din treasury_service.py nu merge la MARIUSM_AUTO, e ceva radical prost cu oracledb instalat la tine. Stop și investighează.
  • Ipoteza #2 eșuează: session_callback fragil în practică → Marius știe că pool-per-tenant e necesar, nu pool-single-with-tag. Design major changed, decision-log documentează.
  • Ipoteza #3 eșuează: GRANTS model nu ține (SP cheamă alte SPs cu privilegii neașteptate) → Marius știe că "Regula de aur via GRANTS" e naivă și trebuie altceva (VPD? row-level security?). Design major changed.
  • Ipoteza #4 eșuează: error propagation urâtă (encoding, truncation) → Marius știe că trebuie protocol de eroare dedicat, nu RAISE_APPLICATION_ERROR.
  • Ipoteza #5 eșuează: DX pentru 2-4 hrs/week e unusable → Marius știe că side project pe acest stack nu e viabil și trebuie alt approach.

Orice din aceste failures e valoare mai mare decât "prototype care merge happy path fără să fi întâmpinat nicio problemă reală". Succesul real = învățare, nu cod.

Next actions (săpt 1, 2026-04-14 → 2026-04-18)

Cel mai concret lucru, o singură zi, 2-4 ore:

  1. Verifică SSH tunnel setup de la containerul de dev (sau workstation-ul de acasă) la 10.0.20.121/ROA. Există ssh-tunnel-manager.py în backend/shared/ — vezi dacă se refolosește.
  2. poc/hello_oracle.py (sync, la MARIUSM_AUTO user sau alt user Oracle existent) — oracledb.connect(...) + SELECT 1 FROM DUAL.
  3. poc/hello_oracle_async.py (true-async) — oracledb.connect_async(...) + același SELECT 1 FROM DUAL cu await cursor.execute(...).
  4. Setup logging file handler pentru modulul service_auto (nu exista încă, dar directory-ul backend/modules/service_auto/ se poate crea în săpt 1 just to house the logging setup).
  5. Raport săpt 1docs/service-auto/week1-notes.md, max 15 linii: ce a mers, ce a fost greu, DX latency măsurat (save → result în secunde), gate decision (sync vs true-async), buget rămas din săpt 1.

Zero SP-uri, zero Vue, zero auth, zero scheme noi. Doar "Python vorbește cu Oracle local" în ambele pattern-uri.

Non-negotiables

  1. Cei 4 clienți nu sunt atinși niciodată în acest prototype. MARIUSM_AUTO e dedicat, zero copy, zero conexiune la producție.
  2. Scope wall la 1 ecran + 1 SP. Tentațiile de scope creep merg la docs/service-auto/TODO-phase2.md, nu în cod.
  3. Stop points weekly. Fiecare săptămână e oprire curată. Nu se acceptă "oh, nu pot să mă opresc aici pentru că e jumătate făcut".
  4. Succesul se măsoară în învățare + template reutilizabil, nu în ecrane livrate. Un prototype care descoperă o problemă e mai valoros decât unul care evită toate problemele.
  5. Kill criterion trigger-ed → scrie decision-log → stop. Nu "mai dau 2 săpt să văd".

Final deliverable (săpt 24)

Nu e un ecran. Nu e un demo. E:

  1. docs/service-auto/template-modul-oracle.md — rețetă de 1 pagină citibilă de către un alt dev în 10 minute:
    • Cum înregistrezi un server nou în OracleMultiPool
    • Signature convention pentru SPs cu OUT params
    • Grants model (user tehnic + EXECUTE ON SP + ALTER SESSION SET CURRENT_SCHEMA)
    • Error code range classification (20xxx → 422, 12xxx → 503, else → 500)
    • session_callback snippet pentru CURRENT_SCHEMA switching
    • JWT reuse prin AuthenticationMiddleware
    • Logging file handler per-modul
    • File layout (routers/, services/, models/)
  2. docs/service-auto/decision-log.md — go / no-go pentru phase 2:
    • Ce ipoteze s-au confirmat, care nu
    • Evidența concretă (log-uri, teste, numere DX)
    • Condițiile sub care un al doilea modul e justificat
    • Condițiile sub care NU e justificat (kill criterion retroactiv)
  3. docs/service-auto/learnings.md — notele săptămânale consolidate, pattern-uri noi, surprize, workarounds descoperite, Oracle edge cases.
  4. Cod: tot sub branch feat/service-auto, NU merged în main. Branch = arhivă + referință.

Acest deliverable e valoros chiar dacă prototype-ul n-a ajuns la 100% din ipoteze.


END OF RETHINK DESIGN v2. ~9 pages. Budget 2-4 hrs/week × 24 weeks = 48-96 hrs total.


GSTACK REVIEW REPORT

Review Trigger Why Runs Status Findings
CEO Review /plan-ceo-review Scope & strategy 1 CLEAR (PLAN) HOLD SCOPE mode, 0 critical gaps post-fix, 10 items deferred to TODO-phase2, plan file rewritten v2 with 8 review corrections
Codex Review /codex review Independent 2nd opinion 0
Eng Review /plan-eng-review Architecture & tests (required) 0
Design Review /plan-design-review UI/UX gaps 0
DX Review /plan-devex-review Developer experience gaps 0

OUTSIDE VOICE: Claude subagent (Codex unavailable). 15 findings total. 3 load-bearing surfaced as cross-model tension (SP→ACT modeling error, budget ~2x under-scoped, demo vs template deliverable). All 3 accepted by user and integrated into plan v2.

UNRESOLVED: 0

VERDICT: CEO CLEARED — plan rewritten as v2 with 8 corrections, 0 critical gaps, 24-week timeline, template deliverable. Eng review recommended before writing any code (optional for learning prototype but helps catch architectural issues in service_auto module structure).