24 August 2026 · Draft v1 (strawman pentru sesiunea de shaping cu Prodi + Cristi) · BONO × SOLO · Confidențial Autor: BGN + Claude · Răspunde concluziei review-ului de arhitectură („v1 e formă — lipsesc tipurile"). Din acest model derivă: contractele Tenant-in/Tenant-out, porturile motoarelor, schema DB, tipurile C# și fixtures-urile de test.
xml_efactura | pdf | imagine | json) care alege pipeline-ul de extracție, nu structura datelor. eFactura = o factură sosită ca XML; factura „externă" = factura cu extensia de valută populată.raw JSONB). Câmpurile noi se promovează aditiv din raw, cu backfill.IMatching): corelarea operațiunilor bancare cu documentele justificative, many-to-many cu sume, manual-first cu sugestii deterministe. Nota de decontare atârnă de corelare, nu de document.operator | istoric | larry@vX | adam@vX | match@vX) · schimbări doar aditive · sume DECIMAL, niciodată float · cota TVA e per linie, dată din document (21% azi, 19% pe documente vechi — nu constantă globală).
Tenant ─┬─ ProfilClient ──(înghețat la procesare)── ContextSnapshot
│
└─ Document (nucleu comun + extensie per tip + raw)
├── LinieDocument ─┐ (unități interpretabile)
├── OperațiuneBancară ─┤
│ └─ Interpretare (categorie · folosință · verdict · sursă · confidence)
├── Tranzacție (emergentă) ── DecizieContabilă ── NotaContabilă (SRL | PFA)
├── Corelare (operațiune ↔ document/tranzacție, sume alocate) ── NotaDecontare
└── Dubiu (junior → senior)
Eveniment (jurnal append-only — sursa adevărului pentru toate de mai sus)
MemoryIndex (proiecție: istoricul per furnizor → precompletare)
| Câmp | Tip | Note |
|---|---|---|
iris_document_id | UUIDv7 | PK intern (Guid.CreateVersion7()) |
display_id | text | BN-2026-00003 — secvență per (tenant, an-ingest), NU gapless |
tenant_id | UUID | din claim-ul JWT validat (iam); RLS pe el |
client_id | UUID | firma clientului final (ref ProfilClient) |
source_document_id | text | ID-ul în sistemul tenantului (Nucleu/Jedi) |
tip | enum | factura · bon · extras · factura_emisa |
format_sursa | enum | xml_efactura · pdf · imagine · json |
status | enum | primit · in_lucru · in_asteptare · finalizat · respins (+ motiv la respins) |
hash_fisier | bytea | dedup identic per tenant |
fisier | {r2_key, mime, size} | originalul, prefix per tenant |
numar_doc, data_doc | text, date | de pe document (extras: n/a — vezi extensia) |
moneda | char(3) | per document; RON implicit |
curs_bnr, data_curs | decimal, date | doar valută ≠ RON (sursa: forex.bono.ro) |
total_net, total_tva, total | decimal(14,2) | totalurile de pe document — verificarea încrucișată cu unitățile e obligatorie la finalizare |
mentiuni | text | mențiuni la nivel de document |
context_snapshot_id | UUID | contextul imutabil folosit |
dedup_semantic_ref | UUID? | posibil duplicat (nr+dată+CUI+sumă) → flag, nu respingere |
raw | JSONB | parsarea brută completă (D5) — XML-ul UBL descompus, JSON-ul primit etc. |
trace_id, timestamps, operator_id | — | transversale |
ext_factura| Câmp | Note |
|---|---|
partener | snapshot: {nume, cui_sau_vat_id, tara, adresa, tip: PJ/PF} — furnizorul |
verificare_partener | rezultat directory.bono.ro: {anaf_activ, platitor_tva, vies_valid, verificat_la}; nullable dacă serviciul e jos (flag neverificat) |
scadenta, mod_plata | date, enum (OP/card/cash/—) |
taxare_inversa_mentiuni | bool + text — mențiunile reverse-charge de pe document |
rol_client | fix beneficiar |
*Factura „externă" nu e tip separat*: moneda ≠ RON și/sau partener.tara ≠ RO activează câmpurile de valută din nucleu + regulile de scenariu TVA (TVA-SERV / TVA-AIC / TVA-IMP).
ext_bon| Câmp | Note |
|---|---|
partener | ca la factură (emitentul bonului) |
cui_pe_bon | bool — CUI-ul firmei clientului apare pe bon (relevanță fiscală) |
mod_plata | enum |
Fără serie/scadență. Liniile agregate (D6) sunt tipice aici.
ext_factura_emisa| Câmp | Note |
|---|---|
beneficiar | snapshot partener — clientul firmei (rolurile inversate) |
serie_numar_fiscal | numerotarea fiscală a tenantului (nu a noastră) |
sursa_emitere | facturare_bono · oblio · smartbill · alt (via SPV toate ajung oricum) |
rol_client | fix furnizor |
Interpretarea: categorie de venit (grupa V), fără folosință/deductibilitate (N/A). Nota: ramura de venit (ex. 4111 = 704).
ext_extras| Câmp | Note |
|---|---|
iban, banca | contul |
perioada | {de_la, pana_la} |
sold_initial, sold_final | decimal — verificare încrucișată: sold_initial + Σ(operațiuni semnate) = sold_final (echivalentul „liniile bat cu totalurile") |
moneda_cont | poate diferi de RON |
numar_doc/data_doc din nucleu: n/a — identitatea extrasului e (iban, perioadă).
unit_id (UUIDv7) · document_id · ordinal (poziția în sursă) · descriere · interpretare (secțiunea 5) · tranzactie_id (derivat — secțiunea 6) · status (de_interpretat · interpretata · in_dubiu)
| Câmp | Note |
|---|---|
cantitate, um, pret_unitar | um: buc/ore/kg/luni… (ajută bun vs. serviciu) |
valoare_neta, cota_tva, valoare_tva, valoare_totala | cota per linie (21/19/11/9/5/0), din document |
reducere | discount pe linie |
mentiune_tva_linie | „scutit", „taxare inversă" per linie |
agregata | bool + nr_articole? — linia agregată (D6); permisă doar cu tratament omogen |
alocare | bool — linie de livrare/transport/discount distribuită proporțional cu neta pe celelalte tranzacții; nu primește interpretare proprie; breakdown-ul alocării se stochează pe tranzacții (audit) |
| Câmp | Note |
|---|---|
data_operatiunii, data_valutei | date |
sens | debit · credit (plată/încasare) |
suma | decimal, pozitivă; semnul îl dă sensul |
sold_dupa | decimal — pentru verificarea lanțului |
contrapartida | {nume?, iban?, cui?} — ce se poate extrage |
referinta | textul brut (detaliile plății) — inputul principal al interpretării și al matching-ului |
tip_operatiune | sugerat: transfer · pos · comision · atm · fx · sepa … (listă de închis la shaping) |
| Câmp | Note |
|---|---|
categorie | cod din taxonomia globală versionată (~58 categorii, 8 grupe + grupa V venituri) |
folosinta_firma | DA · NU — doar la cheltuieli; NU → R1 → 0% |
verdict_operatiune | doar operațiuni (D3): directa (cheltuială/venit propriu → notă) · de_corelat (plată/încasare cu document justificativ → Corelare sau export marcat) · transfer_intern (între conturile proprii / neutru → fără notă) |
confidence_categorie, confidence_folosinta | 0–100, nullable (Faza 1: gol) |
explicatie | raționamentul (română) — de la om la corecții, de la Larry în Faza 2 |
sursa | operator · istoric · larry@vX + operator_id/versiuni |
| corecțiile | nu se suprascriu — eveniment interpretare.corectata cu valoarea veche/nouă/motiv |
Tranzacție: tranzactie_id ({doc}-T{n}) · cheia de tratament (categorie, folosinta, cota_tva) · unitati[] · suma_alocata_primita (partea din liniile de alocare, cu breakdown per linie-sursă) · status (draft · interpretata · nota_generata · exportata).
DecizieContabilă (per tranzacție — precompletată determinist, confirmată de om în Faza 1):
| Câmp | Note |
|---|---|
scenariu_tva | NO-TVA · TVA-SERV · TVA-AIC_BUNURI · TVA-IMP_BUNURI (+ validările G1–G3 ca flags) |
ded_ch_pct, ded_tva_pct | din reguli (anexa Adam): fix / R1 / R3(regim auto) / R4(sediu) / N/A |
baza_ch, baza_tva | formulele per scenariu (NO-TVA la neplătitor: TVA intră în cost; IMP: editabil pe DVI) |
val_ded_ch, val_neded_ch, tva_ded, tva_neded | aritmetică, needitabile direct |
amortizare | {da/nu, luni} — doar marcaj; calculul lunar = Engine Contabil (tenant) |
tac, tac_tva | codurile de tratament |
flags[] | G1_vies_invalid · G2_extern_peste_prag · G3_bun_extern_special · prag_mf_reclasificare · prag_mf_verificare · divergenta_tratament · neverificat_anaf … |
reguli_aplicate[] | id-urile regulilor + ruleset_version — trasabilitate completă |
Comun: nota_id · tip_nota (nota_document — din tranzacție · nota_decontare — din corelare) · sursa (tranzactie_id | corelare_id) · ruleset_version · context_snapshot_id · versiuni motoare (nullable) · autor · timestamps.
Ramura SRL (partidă dublă): linii_nota[] = {cont_debit, cont_credit, suma, eticheta} — ex: [{603, 401, 2.979,10}], la taxare inversă + {635, 4423, …}; decontare: {401, 5121, …} / încasare {5121, 4111, …}.
Ramura PFA (fără partidă dublă): inregistrari[] = {categorie_generala, suma, deductibilitate_pct, sens: cheltuiala|venit}. *Schema există de acum; maparea categorie→înregistrare PFA se populează la sosirea tabelului de la Cristi (gap cunoscut).*
| Câmp | Note |
|---|---|
corelare_id | UUIDv7 |
operatiune_id | operațiunea bancară |
tinta | {document_id sau tranzactie_id, tip: factura_primita · factura_emisa} |
suma_alocata | many-to-many cu sume: o plată poate stinge N facturi; o factură poate fi plătită în N tranșe; Σ alocărilor ≤ suma operațiunii și ≤ restul de plată al țintei |
status | sugerata · confirmata · respinsa |
confidence | nullable; sugestiile deterministe: sumă ± toleranță, fereastră de zile, CUI/nume contrapartidă, numărul facturii în referință |
sursa | operator · match@vX |
nota_decontare_id | nota generată la confirmare |
Operațiunile de_corelat fără țintă în Iris (salarii, taxe, rate) → export cu marcaj de_corelat_la_tenant.
ProfilClient (starea curentă per (tenant, client), actualizată prin API-ul de ingest — sursă: Nucleu/Vertigo; de aliniat cu modelul Vertigo al lui Cristi): identitate {nume, cui} · tip_entitate (SRL · PFA) · regim_impozitare (micro · profit · pfa_real · pfa_norma) · TVA {platitor, cod_activ, vies_valid} · asociati[], administratori[] (nume — detectarea facturilor pe persoană fizică) · regim_auto (fara · mixt · 100%) · activitate_la_sediu (bool) · mijloace_fixe[] · caen_principal, caen_secundare[] · nr_salariati · versiune_profil · goluri[] (câmpurile lipsă — raportate asincron tenantului).
ContextSnapshot (imutabil, per document): copia profilului la momentul procesării + rezultatele interogărilor externe pe partener + versiune_profil referită. Orice decizie contabilă se leagă de snapshot, nu de profilul curent.
tenant_id · nume (BONO, SOLO) · iam_client_ref (identitatea la iam — Iris nu ține secrete de auth) · webhook {url, hmac_secret_ref} (secretul în Railway secrets) · tipuri_acceptate[] · feature_flags{} (per categorie — mecanismul shadow→precompletare→Zero-Touch) · prefix_display (BN, SL).
(tenant_id, client_id, partener_cui, descriere_normalizata) → {categorie, folosinta, tratament, count, ultima_data} — construită din evenimentele de interpretare confirmată; alimentează precompletarea (nivelul 0 al piramidei) și typeahead-ul de furnizori. Reconstruibilă oricând prin replay.
| Tabel | Note |
|---|---|
documents | nucleul + extensia în coloane tipizate unde e financiar + ext JSONB pentru rarități + raw JSONB; partiționat lunar; RLS pe tenant_id |
document_lines / bank_operations | două tabele (nu unul cu NULL-uri); interpretarea inline (coloanele §5) |
transactions | + decizia contabilă inline (coloanele §6) + breakdown alocări JSONB |
notes | cu linii_nota/inregistrari JSONB (forme diferite SRL/PFA) |
correlations | §8 |
client_profiles, context_snapshots | §9 |
tenants | §10 |
events | append-only, partiționat lunar — sursa adevărului |
outbox | livrări webhook |
display_sequences | (tenant_id, an) → next — mecanica Prodi |
memory_index | proiecția §11 |
dubii | întrebare/răspuns junior↔senior, ref unitate/tranzacție |
Toate tabelele multi-tenant: tenant_id NOT NULL + politică RLS + scoping aplicativ (dublu strat).
6232 = 4016022 = 401 + valori ded/neded628 = 401 + 635 = 44234111 = 704 (ramura venit)directa, G2 Comisioane → 627 = 5121de_corelat → Corelare cu factura IKB-78421 (sumă integrală) → notă decontare 401 = 5121Fiecare fixture = JSON complet pe tot lanțul (document → unități → interpretări → tranzacții → decizii → note) — devine test de contract în CI și, ulterior, eval pentru Larry.
tip_operatiune bancară de închis + sursele de parsare extras (PDF per bancă? MT940/camt.053 unde există?) — formatul extraselor per bancă e cel mai variabil terensource_document_id + cine trimite interim