Dublin — PRD funcțional
Ce e documentul ăsta: specificația funcțională a Dublin — ce informații afișăm, din ce sisteme le preluăm, ce acțiuni sunt disponibile, plus regulile de business și stările. Fără detalii de interfață: pixelii trăiesc în prototip (dublin.bgn.ro) + design system (edge-33), iar istoria deciziilor în tabul Jurnal.
Actualizat: 6 august 2026 · Autori: BGN + Claude (la cererea Prodi)
0. Cum se citește + harta sistemelor
Fiecare informație afișată poartă tag-ul sursei; fiecare acțiune poartă motorul în care se termină. Dublin e un shell: nu calculează, nu clasifică, nu stochează — inițiază acțiuni și afișează informații.
| Tag | Sistem | Ce stăpânește | Relația cu Dublin |
|---|---|---|---|
| [NUCLEU] | System of record + hub (prezent de la lansare; numele final de ales) | documentele + fișierele lor (10 ani), cu statusul canonic: neprocesat · primit · în lucru · respins+motiv · finalizat · notele contabile · facturile emise (baza de date a facturilor — 25.aug) · situațiile închise + taxele · registrul firmelor (CUI) · jurnalul de evenimente · taskurile · agregatele KPI. Lângă el: modulul de RECONCILIERE (plăți ↔ facturi/taxe/salarii) + mini-registrul de solduri taxe (Σ obligații SAGA − Σ plăți din extrase) | singurul API pe care îl consumă Dublin; scrie și citește tot prin el |
| [F] | Facturare (modulith, există) | motorul emiterii: seriile + numerotarea (mini-serviciul de serii) · trimiterea e-Factura (SPV) | emite la cererea Dublin și scrie factura în [NUCLEU] — arhiva se citește din nucleu |
| [S] | SalarEasy (există) | angajați, state de plată, taxe salariale, fluturași, auto-angajare | citire directă interim (F5); execuția angajării |
| [IRIS] | Procesorul de documente (PRD: iris.bgn.ro/prd · /atribute · /modele-date) | documente → note contabile complete · motive de eșec · parsarea extraselor → plățile identificate (potrivirea o face reconcilierea de lângă nucleu) | Dublin NU vorbește direct cu Iris — totul prin nucleu |
| [SAGA] | Motorul de calcul contabil (operat de echipă, via saga-automation) | taxe, situații, închideri, declarații | livrează în nucleu la închiderea lunii + evenimente |
| [ID] | cont.bono.ro (identitate; PRD propriu există) | login (email-first, OTP, passkeys, Google) · sesiuni · user↔firme · SSO .bono.ro | fiecare request; claim-ul firmei curente |
| [BILL] | Subscription & Billing (NOU, mic) | planul + plățile recurente (procesator extern, de ales) · facturile Bono către client | pagina Contul tău; starea abonamentului → acces |
| [V] | Vertigo (shell-ul echipei) | inputul echipei: taskuri „De făcut", mesaje, completări la note, cereri rezolvate | echipa scrie în nucleu; cererile clientului ajung la ea |
1. Shell — pe toate paginile
Afișăm: firma curentă + CUI [ID+NUCLEU] · starea „Live" = ultima sincronizare reușită [NUCLEU] · rail „De făcut" — sarcinile clientului, cu actor și scadență [V→NUCLEU] · ticker „Live · din motorul Bono" — jurnalul a tot ce a făcut Bono + „Ce urmează" (calendarul fiscal din ciclul SAGA) [NUCLEU] · stiva de mesaje — alerte și insight-uri de la Bono, închizabile, cu amânare [NUCLEU/IRIS] · badge-uri pe navigație (facturi neplătite, documente în procesare) [F/NUCLEU].
Acțiuni: căutare globală în documente/facturi/cheltuieli → [NUCLEU] · chatul client↔Bono — MVP: aplicație de CS existentă (ex. Helpscout); Vox = V2 (decizie 25.aug) · acțiunile din „De făcut" (fiecare CTA duce la fluxul paginii potrivite) · închide/amână un mesaj · ieși din cont [ID].
Reguli & stări: max ~6 iteme în „De făcut", ordonate după urgență: scadente azi → termene/avertismente → confirmări → insight-uri · sarcinile rezolvate rămân bifate câteva ore (dovada zilei; badge-ul numără doar activele) · „live" = polling 30–60s + evenimente, nu WebSocket · mesajul amânat revine a doua zi. Scope (25.aug): feed-ul live, chatul Vox și rail-ul „De făcut" = candidate V2 — primesc PRD separat, apoi se decide ce intră în MVP.
2. Acasă — /
Afișăm: starea de ansamblu („totul e ok" = zero sarcini urgente + zero erori) [NUCLEU] · 3 KPI: venituri facturate [F] / cheltuieli deductibile / nedeductibile [NUCLEU], pe perioade · a treia familie de cifre, „Poți scoate · net" (31.aug/8.sep — permanent; rândul de cifre = 3 familii: Venituri · Cheltuieli · Poți scoate, fiecare cu cifra mare + două sub-cifre; cardul e link spre pagina Banii tăi): dividende = suma totală distribuibilă contabil (tot profitul acumulat nedistribuit, fără estimări pe viitor; vine de la contabilitate) cu NET-ul + impozitul aferent [SAGA→NUCLEU] · împrumuturi = împrumuturile date firmei + ce a plătit acționarul personal pentru firmă (deconturile sunt tot un fel de împrumuturi — 8.sep), restituibile fără impozit [NUCLEU] · cardul „taxe și impozite de plată" — cifra curentă [SAGA→NUCLEU] · contorul documentelor în curs de procesare [NUCLEU] · ultimele 10 facturi emise [F] · ultimele 10 cheltuieli procesate [NUCLEU].
Acțiuni: emite factură — cardul (client + sumă + valută) deschide modalul de emitere în pagină, identic cu cel din Facturi (dată, scadență, conturi de încasare, descriere) → [F], cu seria+numărul de la mini-serviciul de serii · încarcă documente (picker + tragere oriunde pe pagină) → [NUCLEU] · scurtături către liste („Vezi documentele/toate").
Reguli & stări: upload-ul confirmă DOAR primirea — procesarea nu se simulează; rândurile apar când Iris întoarce documentul complet · KPI-urile de adaptat la regimul Micro (deschis) · „Banii tăi" = dreptul teoretic din contabilitate, NU soldul bancar (v0 nu e legat live de bancă — „dacă ai banii în cont") · scoaterea banilor: clientul își face transferul din bancă → îl vedem în extras (sau ne anunță) → confirmă → Bono pregătește actele (decizia de distribuire, situațiile cerute) → impozitul intră în De plată; fără plăți din Dublin · metoda de calcul a impozitului (inclusiv CASS pe praguri) = a motorului, de definit — Dublin doar afișează net + impozit.
3. Facturi — /facturi
Afișăm: arhiva facturilor emise — serie·nr, dată, client + CUI, descriere, sumă, valută [NUCLEU] (baza facturilor stă în nucleu; [F] doar le emite) — inclusiv facturile externe (ex. Smartbill), urcate ca documente și identificate de Iris drept venit · status Încasată/Neîncasată [NUCLEU] (potrivirea = modulul de reconciliere de lângă nucleu; vocabular: „Încasată" = facturile EMISE — „Plătită" se folosește doar la facturile PRIMITE și obligații) · starea e-Factura per factură (trimisă/se trimite — nu primim index ANAF, UI-ul nu îl promite) [F↔SPV] · KPI Emise / Încasate / Neîncasate, pe perioade [NUCLEU]. Definiție: „Încasată" = plata potrivită cu extrasul de cont.
Acțiuni: emite rapid (client + sumă + valută, apoi: data emiterii, scadența, conturile de încasare, descriere) → [F] — seria+numărul cerute mini-serviciului de serii al [F], alocate atomic la emitere · cazurile ne-rapide (persoană fizică, firmă străină, stornare) → modulul Facturare [F+ID], precompletat · descarcă PDF · trimite pe email · caută/filtrează (status, dată, valută, text).
Reguli & stări: data emiterii = azi sau max. 5 zile lucrătoare în urmă; peste — doar cu asumare explicită de risc (amendă ANAF) · scadența default 10 zile · minim un cont de încasare · Dublin nu numerotează niciodată · înregistrarea contabilă a facturii — pe sursa descrierii: preset → automat (fără interpretare); descriere scrisă de mână → [IRIS] (interpretare) · „Plătită" apare abia când reconcilierea potrivește plata (până la extrase: doar status document + e-Factura) · valutele cu curs BNR, total afișat în lei.
4. Cheltuieli — /cheltuieli
Afișăm: KPI pe perioade — pe Profit: Cheltuieli / Deductibile / Nedeductibile; pe Micro: Cheltuieli / Documente procesate / Fără documente [NUCLEU] · coada documentelor neprocesate (fișier, tip Poză/PDF/e-Factura, încărcat, stare) [NUCLEU] · tabelul cheltuielilor procesate (furnizor, dată, tip bon/factură, sumă, valută, deductibilitate 100 / 50 / Parțial / Nu, cu motivul în clar — „Parțial" = deductibilă în limita unui plafon de categorie: protocol, asigurări; vizual: mini-plăcinta cu fracția dedusă, verde/portocaliu/roșu, starea plății) [IRIS→NUCLEU] · banda + lista plăților fără documente — plăți văzute în extrase, fără document justificativ (furnizor, dată, sumă, valută; filtrabilă) [IRIS→NUCLEU] · insight-uri („Iris a observat…") [IRIS] · banda de confirmare a eFacturilor primite de la furnizori noi/neplătite [NUCLEU+IRIS] · în detaliu: documentul original + cine l-a procesat și în cât timp [NUCLEU].
Acțiuni: încarcă documente (bonuri, facturi, extrase — un singur mecanism) → [NUCLEU] · dă context / întreabă pe un document → reprocesare la [IRIS] · confirmă/infirmă o eFactură primită („E a noastră" / „Nu o recunosc") → [NUCLEU→IRIS] · încarcă documentul unei plăți fără documente → [NUCLEU→IRIS], care îl potrivește cu plata (alegerea dintr-un document deja încărcat = retrasă — dacă documentul era conspectat, alocarea o face Bono, nu clientul).
Reguli & stări: documentele se procesează identic pe Micro și Profit — regimul (citit din vectorul fiscal) schimbă doar prezentarea · „incomplet nu se întoarce" — documentul stă în coadă până e conspectat complet · eșecurile vin pe motive, în 2 clase: ale clientului (duplicat, incompatibil — afișate cu acțiune) și interne (nu ajung la client) · stările canonice ale documentului (25.aug): neprocesat · primit · în lucru · respins + motiv · finalizat — aceleași în Dublin și Vertigo.
5. Extrase — /extrase
Afișăm: matricea conturi × luni cu starea fiecărui extras: încărcat / se procesează / lipsește / „din Mmm.yy" [NUCLEU] · conturile bancare (bancă, valută, IBAN) — citite din sursa canonică (Firma ta) [NUCLEU].
Acțiuni: încarcă extrasul unei luni (PDF/CSV/MT940) → [NUCLEU→IRIS] — parsare + reconciliere plăți↔facturi↔documente · adaugă cont/IBAN → cerere către echipă [V].
Reguli & stări: extrasul lunii se încarcă luna următoare — din el se potrivesc plățile și se închide luna · oricine primul, egal: clientul (Dublin) sau echipa (Vertigo) · post-MVP, dacă se semnează OpenBanking: sincronizare automată, uploadul manual rămâne opțiune.
6. De plată — /de-plata
Afișăm: KPI: Plătite (pe perioadă) / De plată acum / Următoarea scadență [SAGA→NUCLEU] · obligațiile pe 5 categorii — TVA, taxe salarii, impozit micro, impozit dividende, impozite locale — fiecare cu starea ei: sumă + scadență / „la zi" + ultima plată / „așteptăm decizia" [SAGA→NUCLEU] (baza micro [F], salariile [S]) · detaliile complete de plată per obligație: beneficiar, IBAN Trezorerie, sumă, detalii [SAGA→NUCLEU] · istoricul plăților, potrivite cu extrasul [IRIS→NUCLEU].
Acțiuni: copiază detaliile de plată — per câmp, valori „bancabile" (IBAN fără spații, suma fără separatori) · încarcă decizia de impunere (impozite locale) → [NUCLEU] · vezi istoricul complet al unei categorii.
Reguli & stări: Dublin nu calculează nimic fiscal — obligațiile vin din SAGA, iar soldul per taxă = mini-registrul de lângă nucleu: Σ(obligații SAGA) − Σ(plăți din extrase); verificare periodică vs. SAGA · „Plătit" se bifează automat la potrivirea cu extrasul (reconcilierea de lângă nucleu; salariile per angajat după IBAN, contribuțiile urmărite agregat) · scadențele legale alunecă peste weekend (25 → luni 27) · butonul „Plătește taxele" direct din Dublin (card → ANAF) = în analiză (legal + tehnic, 25.aug).
7. Banii tăi — /banii (drill-down-ul familiei „Poți scoate")
Afișăm — pe trei niveluri (8.sep, structură BGN): (1) totalul — cât poți scoate din firmă, net: dividende nete (decise + partea netă din profitul nedistribuit) + deconturi + împrumuturi [SAGA→NUCLEU + NUCLEU] · (2) componentele, fiecare cu cifra ei: Dividende — cu două informații: dividende nete decise prin AGA, de ridicat (impozitul reținut) și profitul nedistribuit (cu descompunerea: net + impozit dividende) [SAGA→NUCLEU]; Deconturi — ce a plătit acționarul personal pentru firmă (n documente, fără impozit) [NUCLEU]; Împrumuturi — cu starea contractului (de semnat / semnat) [NUCLEU] · (3) lista componentei deschise (o singură listă odată): distribuirile (brut, impozit, net, stare: nedistribuit / decise · de ridicat / ridicate · impozit plătit; decizia; click → viața distribuirii) · documentele plătite personal · împrumuturile cu contractul și rambursările potrivite din extras.
Acțiuni: semnează contractul de împrumut — generat de Bono, semnat electronic prin Rex (singura inițiere a paginii) → [Rex] · deschide/închide lista unei componente · vezi decizia unei distribuiri · „Cum îți scoți banii?" (explainer).
Reguli & stări: totalul include și dividendele nete nedistribuite (profit nedistribuit − impozit) — decizie BGN · sumele = dreptul teoretic din contabilitate, nu soldul bancar · fluxul e același ca pe Home: îți transferi banii singur → îi vedem în extras (sau ne anunți) → confirmi → formalizăm (dividende: decizie + situații; împrumut nou: contract de semnat) · împrumuturile și deconturile se recuperează fără impozit; impozitul pe dividende intră în De plată · contractul se generează la detectarea transferului, nu înainte · MVP: citire + semnarea contractului; confirmările se aprind odată cu modulul de reconciliere.
8. Angajați — /angajati
Afișăm: KPI pe luni: Cost total / Salariu net / Taxe la stat (cu % din cost) [S] · fișă per angajat: nume, rol, contract (CIM, normă), data angajării, stare contract + Revisal [S] · istoricul lunar per angajat: net, taxe, salariul total, datele plăților cu starea lor, fluturașul [S] (starea plății: [IRIS→NUCLEU]).
Acțiuni: angajează → SalarEasy [S] (MVP: auto-angajare — administratorul se angajează pe sine; fără angajați, pagina e poarta de intrare) · descarcă fluturașul [S] · aprobarea lunară a statului de plată = item în „De făcut" (push, nu pull).
Reguli & stări: Salariul total = Net + Taxe · datele și execuția = SalarEasy prin API — Dublin doar afișează și lansează · înregistrarea Revisal durează 3–5 zile.
9. Contabilitate — /contabilitate
Afișăm: bara de stare: „contabilitatea e la zi · ultima lună închisă · verificată de {contabil}" [SAGA→NUCLEU + V] · doar documentele importante — lista canonică, aliniată cu Vertigo (25.aug): Balanța de verificare · Registrul inventar · D112 · D311 · D100 (lunar + trimestrial) · D301 (CUI · VIES) · D390 · D406 SAF-T · Bilanț (S1120 + anual) · D101 · SAF-T anual · D205 — cu istoricul fiecărui tip: perioada, generat/depusă, marcajul „Depusă la ANAF" cu recipisă, starea „se pregătește" [SAGA→NUCLEU]. Pachetul complet (fișe de cont, documente intermediare) = V2, când le generează motorul contabil propriu; fișa mijlocului fix = V2 (trăiește în SAGA).
Acțiuni: descarcă orice instanță (fișele de cont = pachet ZIP pe lună) · trimite un document — Vezi · Email · WhatsApp, per instanță (jobul real: documentul ajunge la cineva, nu doar pe disc) · „Cere un document" → Vox/echipa [V] — inclusiv pentru dosarele de bancă (fiecare bancă cere alt set; nu există pachet predefinit — clientul ne dă lista) · caută în arhivă.
Reguli & stări: aici e arhiva („nimic nu se pierde" — retenție 10 ani); obligațiile de plată stau pe De plată · declarațiile apar cu recipisele lor · documentele în curs sunt marcate, fără download până sunt gata.
10. Firma ta — /firma
Afișăm: datele firmei — denumire, CUI, Reg. Com., sediu, administrator, capital, stare (verificată ONRC + ANAF zilnic) — cu istoric per atribut [NUCLEU] · vectorul fiscal pe limba clientului: TVA, impozit micro/profit, angajator, cod VIES — sincronizat zilnic cu ANAF [NUCLEU] · asociații și procentele · conturile bancare = sursa canonică a IBAN-urilor [NUCLEU] · documentele firmei (ONRC, ANAF, AGA, administrative, înființare), cu sursă și dată [NUCLEU] (semnate prin Rex).
Acțiuni: copiază orice valoare (CUI, IBAN…) · trimite datele de facturare — pachetul Denumire + CUI + Nr. Reg. Com. + Sediu (obligatoriile despre cumpărător pe factură, art. 319 CF), cu previzualizare + Copiază/Email/WhatsApp · cere un document / „Cere codul VIES" → echipa [V] · adaugă IBAN (aceeași cerere ca pe Extrase) · vezi istoricul unui atribut. Certificatul constatator și specimenul de semnătură nu se mai stochează — constatatorul se cere proaspăt la nevoie (ONRC îl emite la cerere).
Reguli & stări: clientul nu editează nimic — modificările se fac prin Bono, cu act justificativ · vectorul fiscal alimentează regimul Micro/Profit din Cheltuieli · certificatele constatatoare vechi primesc avertisment + „cere unul proaspăt".
11. Contul tău & abonament — /cont (intrarea: avatarul, nu un tab)
Afișăm: profil & securitate: nume, email, telefon, parolă, passkey, sesiunile active [ID] · firma contului [ID+NUCLEU] · planul și abonamentul: preț, următoarea plată, metoda de plată [BILL] · facturile de la Bono [BILL].
Acțiuni: schimbă cardul → [BILL → procesator extern] · anulare — cu reținere pe vocea Bono („vorbește cu noi întâi"); cererea merge la echipă; arhiva contabilă se predă integral clientului · ieși din cont.
Reguli & stări: MVP: un cont = O firmă (25.aug) — fără multi-firmă și fără useri/roluri per firmă; „Firmele mele"/switcher + „adaugă altă firmă" = V2, la primul client cu cerința · starea abonamentului guvernează accesul (activ / suspendat la neplată → entitlements) · meniul principal = FIRMA; relația cu Bono trăiește sub avatar.
12. Reguli globale de produs
- Dublin are două funcții + un strat: clientul inițiază acțiuni (fiecare se termină într-un motor extern) și vede informații (read-only) + stratul cont & abonament. Testul oricărui feature: inițiere sau afișare? dacă e motor — nu e Dublin.
- Regimul fiscal (Micro/Profit) = comutator de prezentare — pipeline-ul de procesare e identic.
- „Incomplet nu se întoarce" — clientului nu i se arată niciodată un document pe jumătate procesat.
- Read-heavy, action-light. MVP fără: OpenBanking, stocuri, pontaj. (Plata taxelor din Dublin: era post-OpenBanking; din 25.aug e ÎN ANALIZĂ — card → ANAF. Facturile externe intră prin upload → Iris, nu prin import SPV multi-source.)
- Scope MVP (25.aug, BGN & Prodi): fără useri/roluri per firmă · un cont = o firmă (fără multi-firmă) · chat prin aplicație de CS existentă (Vox = V2) · feed-ul live + rail-ul „De făcut" = candidate V2 — PRD separat, apoi se decide ce intră în MVP.
- Retenție legală 10 ani — nimic nu se șterge.
- Zonele = module condiționale (personalizarea pe comportament = north-star, nu MVP).
- Mobil = Model B adaptiv — aceleași capabilități și API-uri, altă prezentare.
Referințe
- PRD Dublin (acest document, 3 tab-uri): dublin.bgn.ro/prd · PRD IRIS: iris.bgn.ro/prd + /atribute + /modele-date · PRD Vertigo V2 (intern)
- Analiza Vertigo–Dublin–IRIS — Concluzii finale (25.aug.2026): repo
bono-ro/vertigo-product/arhiva— sursa deciziilor marcate „25.aug" de mai sus.
Dublin — Analiza de implementare
Data: 3 august 2026 · Actualizat: 4 august 2026 — decizia NUCLEULUI central (BGN + Prodi) · 6 august — sincronizare cu prototipul (quick-emit Facturi + mini-serviciul de SERII al [F], Contabilitate v3 acordeon, banda de confirmare eFacturi primite) · 31 august — concluziile echipei (doc „Analiza Vertigo–Dublin–IRIS — Concluzii finale", 25.aug, A1–A3 + minutele dev + BGN & Prodi): modelul nucleu+procesoare+shell-uri CONFIRMAT; schimbări: facturile emise = în NUCLEU · reconcilierea = modul LÂNGĂ nucleu, nu în Iris · statusuri documente canonice · scope MVP tăiat (fără multi-firmă/roluri; chat = CS extern; feed live + „De făcut" → V2) · Autori: BGN + Claude
Scop: de la prototipul validat (dublin.bgn.ro) la sistemul real — inventar de componente, harta surselor de date, arhitectură, dimensionare, faze.
Context: stack standard BONO (.NET/ASP.NET Core + NHibernate/CQRS + Quartz · React 19 + Vite + TanStack Query, pattern BFF din bono-skills-website) · hosting on-prem RO · țintă: zeci de mii de clienți · ~20–40 documente/client/lună.
Status: COMPLET (v2). §1–2 din prototip + PRD; §3 din explorarea de cod cu agenți pe repo-urile bono-ro relevante (invoicing-services, salareasy-api, tenant-auth-service, dublin-web + bono-skills-website, open-banking-services); §4–6 = sinteza. v2 (4 aug): decizia NUCLEULUI central (BGN + Prodi) — system of record + hub; Dublin și Vertigo = shell-uri; Iris și SAGA = procesoare. Modelul + argumentele + regulile de perimetru: §4.0.c; harta și fluxurile actualizate: §7. Marcajele „transport DIRECT Dublin→Iris" din v1 sunt depășite și notate ca atare. Următorul pas natural: contractul API al nucleului, apoi task breakdown pe F0–F2.
1. Inventarul componentelor (din prototipul live)
REVIZUIRE DE PERIMETRU (BGN, 3 aug seara): Dublin NU construiește motoarele — presupune două API-uri externe cu contracte de definit: [IRIS-API] (Dublin trimite documentele — upload client, e-Factura, OpenBanking — și primește înapoi DOAR documente complet conspectate, ca note contabile; rutarea pe confidence, motivele de eșec, parsarea extraselor și reconcilierea = TOATE în perimetrul Iris) și [CONT-API] (taxe, profit, situații — calculate în SAGA, expuse via Vertigo). În consecință: „[ED]" din tabele = doar Document Gateway (transmitere/preluare/storage), „[REC]"/„[ST]" dispar din scope-ul Dublin (sunt în Iris), taxele vin din [CONT-API].
REVIZUIRE 2 — NUCLEUL central (BGN + Prodi, 4 aug): se construiește un modul nou — system of record + hub („nucleul"; numele final de ales) — care stochează toate informațiile și documentele firmelor. Dublin devine SHELL. Cheia de citire a tabelelor de mai jos rămâne valabilă, dar toate săgețile converg acum în nucleu: [ED]/Document Gateway = absorbit în nucleu · [IRIS-API] și [CONT-API] devin contractele nucleu↔procesoare (nu mai sunt ale lui Dublin) · Dublin consumă UN singur API — al nucleului. Modelul complet + reguli de perimetru: §4.0.c; fluxurile actualizate: §7.
Legendă sursă: [F] invoicing-services (Facturare) · [ED] Expenses & Documents — serviciu NOU (cheltuieli+documente+conspectare) · [REC] Reconciliation — serviciu NOU (extrase↔facturi↔documente) · [S] salareasy-api · [ID] serviciul de identitate — NOU · [V] Vertigo (prototip!) · [OB] open-banking-services (cod exploratoriu în repo — NEimplementat, stand-by comercial) · [Vox] canal chat · [?] de decis
1.1 Shell (pe toate paginile)
| # | Componentă | Ce face | Sursa datelor | Note implementare |
|---|---|---|---|---|
| S1 | Sidebar navigație (deschis pe Acasă / colapsat pe secțiuni) | nav + badge-uri count (Facturi 7, Cheltuieli 3) | counts: [F] + [ED] | badge-urile = agregări ieftine, cache per tenant |
| S2 | Topbar: firmă + CUI + badge „LIVE · joi 24.apr.26" | identitatea firmei; LIVE = sistemul e sincron | [ID] (firma) + heartbeat intern | LIVE = ultima sincronizare reușită (SPV/procesări), nu ceas |
| S3 | Rail „DE FĂCUT" (max ~6 iteme cu actori Vox/Iris/Alina/Mihai) | sarcinile clientului, atribuite | [V] — motorul de taskuri operat de echipă + reguli automate | entitate Task(tenant, tip, actor, scadență, CTA-link, stare); Vertigo e doar prototip → dependență critică |
| S4 | Rail „LIVE · din motorul Bono" (ticker trecut + „Ce urmează") | dovada muncii invizibile | event stream din TOATE sistemele ([F],[ED],[V],[S]) | cere un jurnal de evenimente per tenant (event log) cu copy pe vocea Bono; „Ce urmează" = joburi programate |
| S5 | Căutare globală („Caută orice…") | găsește documente/facturi/cheltuieli | index peste [F]+[ED] | search per tenant (Postgres FTS la început; nu Elastic din prima) |
| S6 | Chat „Întreabă Vox" (fab) | canalul client↔BONO | [Vox] | MVP = Intercom/Vox Lite embed; câmpul din modal (vezi C8) scrie în același canal |
| S7 | Stiva de mesaje (alertă warn + insight „Iris a observat", închizabile, snooze) | comunicare push de la Bono | [V] (sarcini) + motor insight [ED] | entitate Message(tenant, tip, severitate, CTA, snooze-until, dismissed); insight-urile = reguli pe datele contabile (ex. comodat) |
1.2 Dashboard (Acasă)
| # | Componentă | Sursa datelor | Note |
|---|---|---|---|
| D1 | Hero „Salut, Eduard. Totul e ok azi." | agregat: există alerte? [V]+[ED] | „ok" = zero taskuri urgente + zero erori |
| D2 | 3 KPI (Venituri facturate / Chelt. deductibile / Chelt. nedeductibile) cu selector perioadă în card | [F] (venituri) + [ED] (cheltuieli) | agregări pe perioade — vezi §arhitectură: tabele de agregate per tenant×lună |
| D3 | Card „Emite o factură nouă" (CUI lookup + sumă + valută) | [F] + registru CUI (geo-registry-api / ANAF lookup) | acțiunea reală se termină în modulul Facturare |
| D4 | Card dark „Taxe și impozite de plată" (sumă + Vezi detalii) | [ED]/[V] — obligațiile fiscale calculate | MVP: citire; sursa = închiderile lunare făcute de echipă |
| D5 | Card upload (dropzone + „Adaugă document") | → coada de procesare [ED] | upload direct în object storage + înregistrare document |
| D6 | Card „27 documente în curs de procesare… Vezi documentele ›" | [ED] — coada conspectare | link către Cheltuieli#documente |
| D7 | Mini-tabele „Ultimele facturi emise / Ultimele cheltuieli procesate" + Vezi toate | [F] / [ED] | primele 10, aceleași API-uri ca listele mari |
| D8 | Rândul „Banii tăi în firmă" (31.aug, mini-Bruce BGN): De distribuit · dividende (cu net + impozit) · De recuperat · deconturi · Împrumuturile tale + explainer „Cum îi scoți?" | dividendele = suma totală distribuibilă contabil (profit acumulat nedistribuit, fără estimări) [SAGA→NUCLEU] · deconturile + împrumuturile = soldurile față de acționar din notele contabile [NUCLEU] · impozitul aferent = calculat la motor (metoda, incl. CASS pe praguri = de definit) | sume = dreptul teoretic din contabilitate, NU soldul bancar (v0 fără bancă live); Dublin doar afișează — nu calculează, nu plătește |
1.3 Facturi emise
| # | Componentă | Sursa datelor | Note |
|---|---|---|---|
| F1 | KPI Facturate/Plătite/Neplătite cu perioadă în card | [F] | statusul „plătită" vine din corelarea plăți↔facturi (extrase [REC]/[OB]) |
| F2 | Filtre (status, calendar pe emisă, valută) + căutare (nume/CUI/sumă) | [F] | server-side query + paginare |
| F3 | Tabel 8 coloane: Seria·nr, Emisă, Client(+CUI hover), Descriere, Sumă, Valută, Status, e-Factura (bulină) | [F] | bulina e-Factura = statusul trimiterii SPV per factură (pending/confirmat) |
| F4 | Paginare „‹ pagina 1 din N ›" | [F] | limit/offset sau cursor |
| F5 | Kebab ⋮: Vezi factura · Descarcă PDF · Trimite · Stornează | [F] (+DocGen pentru PDF) | storno = operație reală în Facturare; Trimite = email (infrastructure-mandrill) |
| F6 | Modal detaliu (sumă cu valută, CUI, emisă, status cu note, linia SPV dinamică) | [F] | notele oneste („plata potrivită cu extrasul") cer motivele corelării |
| F7 | Quick-invoice bar (header) + modal „Emite factura" (5–6 aug — înlocuiește CTA-ul link-out): client (căutare + clienți recenți) + sumă + valută în bară; data emiterii (fereastra legală 5 zile lucrătoare + asumare risc), scadența, conturi de încasare multi-select, descriere/mențiuni în modal; succes cu share (PDF/email/WhatsApp) | [F] — emiterea rămâne a modulith-ului; Dublin = client al API-ului lui. Seria+numărul: mini-serviciul de SERII al [F] (✅ decizie BGN 6.aug) — registru de serii per firmă, UN singur scriitor al numerotării, alocare atomică la commit (modalele abandonate nu ard numere; numărul din eyebrow = preview) | cazurile ne-rapide (PF, firme străine, storno) → modulul Facturare (SSO din [ID]), precompletat; consecința contabilă a facturii se publică în nucleu (F4) |
1.4 Cheltuieli
| # | Componentă | Sursa datelor | Note |
|---|---|---|---|
| C1 | KPI Cheltuieli/Deductibile/Nedeductibile cu perioadă | [ED] | agregate pe clasificarea Iris |
| C2 | Card coadă „27 documente… Vezi documentele ⌄" | [ED] — documente stare=neprocesat | contorul sincron cu D6 |
| C3 | Tabelul neprocesatelor (Nume fișier mono, Tip Poză/PDF/e-Factura, Încărcat, Status Se procesează/Neprocesat; filtre Tip+Dată presete; paginare) | [ED] — registrul documentelor + starea pipeline | sursa „e-Factura" = XML-uri furnizor din SPV (intrare automată!) |
| C4 | Tabel procesate (Furnizor, Dată, Tip BON/FACTURĂ, Sumă, Valută, Deductibilă 100/50/Nu+motiv ⓘ, Plată ✓data/Neplătită; paginare) | [ED] — cheltuieli conspectate | deductibilitatea cu MOTIV pe vocea Bono = câmp din clasificare |
| C5 | „Se procesează" pe Deductibilă (procesat parțial) | [ED] pipeline (extras→clasificare) | cele 3 stări din model: neprocesat→parțial→complet |
| C6 | Modal 2 coloane: stânga documentul (imagine reală, lightbox), dreapta detaliile | [ED] + object storage (imaginea originală!) | prototipul desenează bonul; realul afișează fișierul (thumbnail + original) |
| C7 | Badge „Nu" roșu + motive per stare | [ED] | |
| C8 | Cardul de chat Vox (întrebare SAU context, chips contextuale, „Iris reanalizează") | [Vox] + feedback loop către [ED] | mesajul cu context → reprocesare document (coadă) |
| C9 | Alerta „2 plăți fără documente — 4.580 lei" | [ED] — plăți din extrase fără document atașat | matching engine extrase↔documente |
| C10 | Insight „Iris a observat — comodat" | motor de reguli [ED] | prima „regulă de insight"; CTA → [V] (task la echipă) |
| C11 | Banda de confirmare eFacturi primite (5 aug): „eFactură primită acum 30 de zile, încă neplătită — furnizor nou. E a firmei tale?" cu „E a noastră" / „Nu o recunosc" + badge „De confirmat" pe rând + item în De făcut | eFactura primită (SPV pull, în nucleu) + heuristica „furnizor nou" (perimetrul Iris) | răspunsul clientului = input înapoi în nucleu → Iris (confirmare/respingere); praguri (30 zile vs scadență) = deschise în contract |
1.5 Extrase de cont
| # | Componentă | Sursa datelor | Note |
|---|---|---|---|
| E1 | Matricea conturi×luni (badge download success / upload warn / „din mmm.yy") | [ED] — registrul extraselor per cont bancar×lună | entitate BankAccount + StatementMonth(stare) |
| E2 | Antete: bancă+steag valută+IBAN scurtat+copy | [ED] conturi bancare | |
| E3 | Paginare pe perioade (trio + dots + „din mar.23") | derivat | |
| E4 | Upload extras (CTA + per-celulă) | → parser extrase [ED] | formate: PDF/CSV/MT940 per bancă — efort real de parsere! |
| E5 | „+ Adaugă cont/IBAN" → du-modal | [ED] + verificare echipă [V] | |
| E6 | (post-MVP) sincronizare automată | [OB] — cod exploratoriu în repo, NEimplementat (stand-by până la deal-ul comercial, la BGN) | dacă se activează: AIS zilnic → dispare uploadul manual |
1.6 Restul paginilor (TOATE construite în prototip — actualizat 4 aug)
| Pagină | Componente (din prototip) | Sursa | Note |
|---|---|---|---|
| De plată ✅ | KPI Plătite/„De plată acum" (DARK)/Următoarea scadență · 5 carduri-categorie expandabile (TVA, taxe salarii, micro, dividende, impozite locale) cu istoric + modal „toate plățile" · detalii de plată copiabile per câmp (beneficiar, IBAN Trezorerie, sumă, detalii) · upload decizie de impunere | [CONT-API] (obligațiile din SAGA via Vertigo) + [F] (baza micro 1%) + [S] (taxele salariale) + [IRIS-API] (bifarea „Plătit" din extrase; decizia de impunere → Document Gateway) | consumatorul principal al [CONT-API]; „Plătit" (generic) ≠ „Plătită" (factura) — decizie de limbaj |
| Banii tăi ✅ (8 sep — drill-down-ul familiei „Poți scoate") | 3 niveluri: totalul net (ancoră) → 3 componente (Dividende cu nete decise + profit nedistribuit = net + impozit · Deconturi · Împrumuturi cu starea contractului) → lista componentei deschise (distribuiri cu viața lor · documente plătite personal · împrumuturi cu contract + „Semnează") · explainer | dividendele = suma distribuibilă [SAGA→NUCLEU] · soldurile 455/deconturi + contractele [NUCLEU] · semnarea = Rex · confirmările transferurilor = modulul de reconciliere (Prodi) | singura inițiere = semnarea contractului; fără plăți din Dublin; contractul se generează la detectarea transferului |
| Angajați ✅ | KPI Cost total/Net/Taxe cu perioade · fișă angajat (nu tabel-de-un-rând) cu istoric 6 luni + fluturași · mod 3 angajați (carduri) · empty state cu auto-angajare · CTA „Angajează" → SalarEasy | [S] salareasy-api (TotalEmployerCost, PayrollResult, PDF fluturaș) + Revisal (badge) | simulare 0/1/3 angajați (provizoriu) |
| Contabilitate ✅ (v3 acordeon, 5 aug) | bară de stare „la zi · ultima lună închisă · verificată de Alina" · acordeon de bare bej per TIP de document (15 tipuri, listă plată, toate cu istoric — 45 instanțe): registre, jurnale TVA, declarații (D300/D100/D112), bilanț, fișe MF; istoricul per instanță cu „generat/depusă" + tag „Depusă la ANAF" + download; doar căutare (fără filtre/kebab) · „Cere un document" (→ Vox) — | documentele generate în SAGA → nucleu → afișate; recipise ANAF; cererile de documente = task către echipă [V]/Vox | „arhiva completă — nimic nu se pierde" = retenția din §5 |
| Firma ta ✅ | Datele firmei (9 atribute cu copy + istoric per atribut, „modificările prin Bono — cu act justificativ") · Vector fiscal sincronizat cu ANAF (zilnic 06:00; TVA/impozit/angajator/VIES + „Cere codul") · conturi bancare (sursa canonică IBAN) · Documentele firmei (14, în 5 grupe: ONRC/ANAF/AGA/administrative/înființare) + „Cere un document" | ONRC + ANAF (sincronizări noi de definit — intră natural în [CONT-API]/Vertigo) + [V] (cererile către echipă) + Rex (acte semnate) | vectorul fiscal alimentează și regimul Micro/Profit din Cheltuieli |
| Contul tău ✅ — intrarea: avatarul din sidebar, NU tab | profil & securitate (passkey „Activ" — starea din PRD Bono Auth) · firmele mele · plan & abonament (299 lei/lună placeholder, Visa ··4412) · facturile de la Bono · anulare cu reținere pe vocea Bono | [ID] cont.bono.ro + [BILL] | meniul = firma; relația cu Bono = sub avatar |
| tab-ul din nav duce acum la /prd (documentul cu 2 tab-uri: Arhitectura + Specificații); dublin-plan.html = orfan | — |
Regimul fiscal Micro/Profit (decizie 3 aug — afectează afișarea, nu pipeline-ul): clientul MVP tipic = MICRO neplătitor de TVA → UI-ul Cheltuieli NU afișează deductibilitatea (coloana/filtrul/rândul din modal dispar; KPI devin „Documente procesate / Fără documente"); pe PROFIT apare tot, inclusiv linia „economisiți la taxe". Documentele se procesează IDENTIC în ambele regimuri ([IRIS-API] întoarce aceeași notă contabilă) — regimul e doar un comutator de prezentare, citit din vectorul fiscal (Firma ta / [CONT-API]).
1.7 Fluxuri transversale (nu au UI propriu, dar sunt sisteme)
| Flux | Ce presupune | Sursa |
|---|---|---|
| Pipeline conspectare (Iris) | upload → storage → OCR/extracție (Castor/Larry) → clasificare+deductibilitate (Adam) → cheltuială în [ED]; stările neprocesat/parțial/complet; eșecuri (ilizibil/duplicat — nedefinit încă în UI!) | prototipul Iris (Castor→Larry→Adam) |
| Intrare e-Factura furnizori | pull XML-uri din SPV (facturi PRIMITE) → intră direct în coadă | anaf-api-simulator la dev; integrarea ANAF reală |
| Corelare plăți↔facturi | tranzacții din extrase ↔ facturi emise → status Plătită + „note oneste" | [ED] matching engine |
| Jurnalul de evenimente | tot ce fac sistemele, pe vocea Bono → ticker S4 + „Ce urmează" | event log nou |
| Agregate KPI | venituri/cheltuieli pe perioade (2026/2025/Q/luni) per tenant | job-uri de agregare [ED]+[F] |
2. Cerințe nefuncționale (din deciziile de produs)
- Scară: zeci de mii de clienți (calibrez la 30.000 activi în §5), ~20–40 doc/client/lună.
- Retenție documente: legislație contabilă RO → 10 ani arhivă (documente justificative). Nimic nu se șterge.
- Hosting: on-prem RO — atenție: codul existent folosește AWS (S3 etc.) + Railway; analiza tratează explicit ce înlocuim (S3→MinIO, RDS→Postgres propriu etc.) și ce rămâne cloud dacă se decide hibrid.
- Real-time percieput: ticker/LIVE/coadă — suficient polling la 30–60s + push la evenimente cheie; nu cere WebSocket peste tot.
- Mobil: Model B adaptiv (aceleași API-uri; alt layout) — API-urile se proiectează o singură dată.
- Personalizare (north-star): zonele = module condiționale → feature flags per tenant încă din MVP.
3. Ce există deja în ecosistemul bono-ro
3.1 salareasy-api — sursa paginii „Angajați" ✅ explorat
Stack: .NET 9 · NHibernate + MariaDB 10.11 · Quartz worker · QuestPDF · pattern-ul Bono 4-layer (9 proiecte) · CI + deploy staging/producție pe registry.bono:5000.
Maturitate: MVP funcțional, deployat, dar NU expozabil clientului final.
Ce oferă Dublin-ului (≈80% din datele paginii Angajați):
- Model complet:
Tenant → Company → EmploymentPeriod (contractul, pivotul) → Employee;PayrollRun(draft→calculated→finalized→sent) +PayrollResultcu 44 câmpuri/angajat/lună — inclusivTotalEmployerCost(exact cifra-erou din Dublin). - Endpoints: employees list/detaliu/contracte · payroll-runs list/results · PDF fluturaș/stat de plată/pontaj (QuestPDF).
Blocante și gap-uri:
- 🔴 Auth = cheie API partajată + tenant AUTO-DECLARAT prin header (
X-Bono-TenantId) — nu poate fi expus browserului; doar prin BFF care injectează el tenantul. - 🔴 Tenant-scoping LIPSĂ exact pe
employees/listșipayroll-runs/{id}/results(returnează cross-tenant — IDOR). De remediat înainte de orice expunere. - Nu există endpoint agregat „situația angajaților" — Dublin compune 4-5 apeluri sau cerem un endpoint nou.
- Auto-angajarea = ~10%: există doar
GET /self-employment/config(prefill); persistare, documente HR (CIM/fișă post), semnare, REGES = neimplementate.POST /employeespoate încheia fluxul. - Nu există „firmele mele" (user→companii) — vezi 3.2.
3.2 tenant-auth-service — NU e contul de client ✅ explorat
Stack: .NET 10 · NHibernate + MariaDB (bono_iam) · RS256 prin Azure Key Vault · Windows Service on-prem · Azure Pipelines. Documentație excelentă, zero teste, zero consumatori azi (invoicing folosește propriul API-key handler).
Ce E: OAuth2 client_credentials mașină-la-mașină — tenant = organizație-client API (slug+nume+credențiale+entitlements pe servicii). JWT validat local prin JWKS. Pachet NuGet consumator gata (AddTenantTokenClient / AddTenantJwtBearer).
Ce NU e (răspuns definitiv): ❌ user uman · ❌ parole/sesiuni/cookie · ❌ user↔firmă („firmele mele") · ❌ roluri/RBAC · ❌ SSO browser cross-subdomeniu · ❌ 2FA · ❌ onboarding (provisioning manual prin SQL/PowerShell).
Consecință majoră pentru Dublin: serviciul de identitate pentru PERSOANE nu există nicăieri în ecosistem — trebuie construit (sau adoptat un IdP) ca fundație: login client, sesiune, legătura user↔firmă, switch firme, 2FA, SSO către Facturare/SalarEasy. Auth-ul actual din dublin-web e demo (parola = literal "bono", per BFF-ARCHITECTURE.md §9.1).
Notă de integrare: nepotrivire de identificatori — tenant-auth folosește tenant_code (string opac), salareasy tenant_id (int); maparea nu există încă.
3.3 dublin-web — Dublin SE CONSTRUIEȘTE DEJA ✅ explorat
⚠️ Corecție față de prima impresie („creat azi"): clona shallow ascundea istoricul. Realitatea: repo activ din iunie 2026, ~230 PR-uri, 22.674 LOC TS + 3.548 LOC C#, QA activ (ultimul PR azi: polish pe view-ul de storno). Echipa: Adrian Rusan (FE), Vlad (backend invoicing), Prodi (PO/arhitectură).
Ce e construit: copie a template-ului canonic bono-skills-website (BFF ASP.NET Core net10 + React 19/Vite/Tailwind 4/TanStack Query 5) — modulul Facturare complet: rute /facturare (listă, editor wizard, view, storno, client nou), ~99 componente, ~50 fișiere de teste, CI. Navigația are DOAR „Acasă" + „Facturi" (nimic pre-seedat).
Arhitectura BFF (pattern-ul obligatoriu pentru tot Dublin): cookie HttpOnly SameSite=Strict 7 zile, default-deny (FallbackPolicy), RPC-style (business failures = HTTP 200 cu OperationResult; 401 doar „sesiune moartă"), reverse proxy /api/core/{**path} cu strip de Cookie/Authorization + injectare X-Bono-SecretKey + X-Bono-UserContext, guard anti-SSRF, rate-limit login, un singur deployable (SPA în wwwroot).
Directiva de arhitectură activă (Prodi, 27–30 iul): UI nu ia decizii de business · fără proxy-uri per-feature (cele 14 controllere BFF de facturare, 2.501 LOC, sunt în curs de retragere spre passthrough /api/core) · componente mai puține · editor simplificat. Orice modul nou Dublin = features/<modul>/ + intrare în navigation.ts, pe passthrough — NU controllere noi.
Gap-uri semnalate chiar de repo: HomePage pe date demo („NONE of these numbers come from a backend… invoicing-services exposes no aggregation at all") · auth demo (parola literal "bono"; CUI-ul firmei = config stopgap, „becomes a session claim when real auth lands") · InfiniteTable șters la curățenie (de readus din template pentru liste lungi).
3.4 open-banking-services — cod exploratoriu, NU implementat (corecție BGN)
Stare reală (corecție BGN, 3 aug): NEimplementat operațional. În repo există cod exploratoriu de calitate (schelet AIS cu teste), dar: zero deployment, zero consumatori, zero integrare, provideri doar pe sandbox, deal-ul comercial cu vendorul ne-semnat („OB on stand-by until commercial deal" — decizia la BGN). Se tratează ca INEXISTENT pentru planificare; post-MVP oricum. Ce e în repo, ca fundație viitoare: ~3.100 LOC producție + 4.137 LOC teste (164 metode), migrații, pipelines, 5 joburi de fundal (sync 6h = plafonul PSD2, outbox 30s, expirare consimțăminte), AES-GCM pe secrete, mTLS Smart Fintech.
- Providere: Smart Fintech (implementat) + Finqware (implementat) + Fake (dev); Salt Edge = proiect GOL (0 LOC). PIS (inițiere plăți) = inexistent — nici măcar schițat.
- Model: BankConnection (consimțământ Berlin Group, refresh-token criptat) · BankAccount (cheiat pe IBAN+firmă, supraviețuiește re-consimțământului) · BankTransaction (DedupKey propriu SHA-256 cu unicitate în DB;
RemittanceInformation= unde stă nr. facturii; bani ca string decimal + valută). - API (dacă s-ar activa):
POST /v1/connections(→ redirect SCA) ·GET /v1/banks·GET /v1/companies/{CUI}/accounts|balances|transactions(cursor, max 500) + evenimente pe Azure Service Busbono.banking(transactions.imported= semnal, produsul trage datele;consent.expiringT-7). Auth consumator =X-Consumer-Key(cheie simplă). - Integrarea cu invoicing: ZERO azi. Seam-ul există în invoicing (
InvoicePayment.Source+ExternalReference), necablat. ⚠️ Contradicție de ownership în docs: cine face reconcilierea plăți↔facturi — invoicing (README vechi) sau IRIS (specs noi, iun 2026)? De decis explicit. - Blocaj comercial documentat: vendorul final ne-ales („OB on stand-by until commercial deal" — discuția e la BGN).
3.5 invoicing-services (Facturare) ✅ explorat — cel mai matur sistem
Stack: .NET 10 · NHibernate/hbm + MariaDB 11.4 · Quartz worker (Windows Service ne-containerizat) · QuestPDF (PDF on-demand, fără storage!) · Typesense (căutare firme) · forex.bono.ro · Mandrill · API pe Cloud Run europe-west1 (⚠️ realitatea de azi e CLOUD — Cloud Run + Azure Pipelines — de reconciliat cu decizia on-prem, vezi §4).
Modelul facturii — excelent pentru Dublin: fin_invoice cu 3 vocabulare de status în tabele de referință: status (draft/issued/cancelled/storno/partially-stornoed) · e-Factura (not-eligible/queued/sending/sent/skipped/error/voided + coadă cu delay configurabil, default 2 zile, + jurnal fin_einvoice_events) · payment (unpaid/partially-paid/paid). Snapshot legal al părților (fin_invoice_parties, cu CUI). Multi-valută cu echivalent RON (CIUS-RO). Tenant→Company(CUI)←UserCompanyAssociation→User există în model!
e-Factura: prin serviciu separat ElectronicInvoiceApi (enqueue/status; UBL-ul se face downstream). ⚠️ AnafReferenceNumber = mereu null (clientul SPV de citire lipsește); „sent" = trimis, nu acceptat ANAF.
API azi: POST /invoice/list (paginat, per CompanyUniqueCode) · detaliu cu bloc e-Factura · PDF stream · fluxul complet de emitere. HTTP 200 + Status în body (stil RPC, ca BFF-template).
Gap-uri pentru Dublin (ordonate):
- 🔴 Plătită/Neplătită IMPOSIBIL azi —
InvoicePaymentmodel gata dar nimic nu-l scrie;PaidAmount=0hardcodat; sursa reconcilierii (extrase/IRIS/OB) = proiect separat. Blocantul real al paginii Facturi. - CUI client lipsește de pe wire (fix mic: proiecție în
FindInvoicePageQuery+ câmp în model). - Fără filtre/căutare/sortare (parametrii acceptați dar IGNORAȚI tăcut; sort fix IssueDate DESC; TotalRecords nefiltrat) + lista include drafts/cancelled.
- Zero evenimente/webhooks → ticker doar prin polling; jurnalele interne (
fin_einvoice_events,fin_invoice_status_h,AuditEvent) există dar nu-s expuse. - Fără CORS + cheie API globală + zero autorizare per-user (
?userUniqueCode=e[TemporaryApi]) → BFF-ul face autorizarea. - Capcane: suma din detaliu = NET fără valută (lista = TOTAL cu TVA); storno negativ + valute mixte pe pagină (nu se însumează coloana); email
Ok:truedar jobul de trimitere e COMENTAT în JobRegistry; migrareavoidedobligatorie per mediu; port 9301 vs 9210 inconsistent.
Quick-win recomandat de explorare: 1 PR mic pe query+model rezolvă CUI+filtre+doar-emise.
4. Arhitectura propusă (ancorată în ce există)
4.0.a Principiul ordonator: Dublin are DOUĂ funcții (BGN, 3 aug)
1. Clientul INIȚIAZĂ acțiuni · 2. Noi îi AFIȘĂM informații utile. Atât. Regăsirea la nivel de arhitectură a deciziei de produs „read-heavy, action-light" din PRD.
Calea acțiunilor (write — inventar COMPLET, scurt): emite factură / storno / trimite pe email (→ Facturare) · încarcă documente + extrase (→ nucleu → Iris) · adaugă cont/IBAN (cerere către echipă) · întreabă / dă context (→ Vox, cu re-procesare la Iris) · acțiunile din „De făcut" (aprobă/confirmă — CTA-uri către fluxurile de mai sus sau către echipă) · închide/amână mesaje. Fiecare acțiune se termină într-un motor extern — Dublin doar o transportă corect (cu identitatea potrivită).
Calea afișării (read — tot restul): KPI-uri, liste (facturi/cheltuieli/extrase), statusuri, taxe și situații, De făcut, ticker, mesaje — toate read-only, din API-ul nucleului (+ citiri directe interim din [F]/[S] până publică în nucleu). Dublin nu calculează, nu clasifică, nu reconciliază.
+ Stratul de CONT & ABONAMENT (completare BGN): pe lângă cele două funcții pe datele FIRMEI, există relația client↔Bono: contul (profil, securitate/2FA, firmele mele) și abonamentul (planul, metoda de plată, plata — inclusiv recuperarea plăților eșuate, facturile emise DE Bono către client, upgrade/downgrade, anularea). Același principiu: acțiunile se termină într-un motor extern (procesatorul de plăți), afișarea e read-only (status abonament, istoric facturi Bono). Starea abonamentului guvernează accesul (tenant-auth are deja active/suspended/deactivated — se leagă de entitlements).
Testul de perimetru pentru orice feature viitor: e o inițiere de acțiune sau o afișare utilă? Dacă e „motor" (calcul, clasificare, matching, procesare plăți) — nu e Dublin.
4.0.b Constatarea centrală (v2 — 4 aug)
dublin-web e fața unică a produsului, iar granițele s-au limpezit definitiv (BGN + Prodi, 4 aug): Dublin = SHELL — fereastra clientului + identitatea. Atât. Nici gateway-ul de documente nu mai e al lui: stocarea și rutarea trăiesc în NUCLEU (§4.0.c). Motoarele nu sunt ale Dublin-ului: Iris procesează documentele, SAGA calculează contabilitatea — ambele ca procesoare atașate nucleului. Dublin consumă UN singur API — al nucleului — și poate fi construit pe mock-ul lui până se maturizează restul sistemului. (v1, 3 aug: „Dublin = fereastră + gateway de documente + identitate", cu două API-uri presupuse [IRIS-API]+[CONT-API] consumate direct — depășită de decizia nucleului.)
4.0.c NUCLEUL: system of record + hub (decizia din 4 aug — BGN + Prodi)
Decizia. Construim un modul nou — „engine-ul contabil" — baza de date pentru toate informațiile unei firme. Clientul urcă un document în Dublin → documentul se salvează în nucleu → nucleul îl trimite la Iris → Iris întoarce nota contabilă → nucleul o stochează → de acolo o preiau Vertigo, Dublin, SAGA. La fel cu SAGA: din nucleu pleacă înregistrările, înapoi vin situațiile și rapoartele. Dublin și Vertigo = shell-uri simetrice: prin Dublin clientul are input (documente, acțiuni) și își vede firma; prin Vertigo contabilul are input (documente, completări la note) și vede toate firmele.
Modelul: NUCLEU + PROCESOARE + SHELL-URI.
- Nucleul — un serviciu cu bază PRIVATĂ (expune API + evenimente/cozi): stochează, rutează, ține istoricul. Nu calculează, nu clasifică, nu decide — niciodată, nici în v5. E registru + oficiu poștal, nu creier.
- Procesoarele — se atașează la nucleu, toate în aceeași priză: iau date → prelucrează → livrează înapoi rezultate. Din ziua 1 există două: Iris (documente → note contabile) și SAGA via saga-automation (înregistrări → situații/taxe/închideri). Serviciile proprii viitoare intră în aceeași priză.
- Shell-urile — Dublin (clientul: firma lui) și Vertigo (echipa: toate firmele): input + afișare, prin API-ul nucleului, cu permisiuni diferite.
De ce e decizia corectă (pros):
- Rezolvă clasa de probleme, nu instanța. Întrebarea de ieri („nota vine direct de la Iris sau via Vertigo?") era simptomul lipsei unui stăpân al datelor. Fără nucleu, fiecare pereche de sisteme cere contract propriu (mesh care crește pătratic: Dublin↔Iris, SAGA↔Vertigo, Iris↔Facturare…); cu nucleu, fiecare sistem se integrează O dată. Orice modul viitor (Rex, Vox, OpenBanking) are deja priză în perete.
- SAGA devine înlocuibilă — câștigul strategic. Datele stau la noi; SAGA e doar un procesor atașat. Înlocuirea se face calcul cu calcul (strangler): serviciul propriu pentru un calcul (ex. impozit micro) rulează în paralel cu SAGA pe aceleași date, ieșirile se compară (shadow mode), apoi se comută consumatorii; repetat pentru TVA, salarii, închideri. Fără nucleu, gravitația datelor ne leagă de SAGA definitiv — iar la 30k de clienți operarea SAGA era deja semn de întrebare (§4.4).
- Dublin și Vertigo cu adevărat simetrice: un singur registru de documente, un singur jurnal de evenimente, un singur read-model — două skin-uri cu permisiuni diferite. Dispare exportul asimetric Vertigo→Dublin din v1.
- Construcția Dublin se simplifică: UN contract de definit + mock-uit (API-ul nucleului), în loc de două API-uri presupuse + Document Gateway propriu.
- Buffer natural de disponibilitate: Iris picat → documentele se acceptă și așteaptă în coadă; SAGA lentă → clientul vede „ultima situație închisă". Store-and-forward pentru tot, nu doar pentru documente.
- Retenția legală de 10 ani, criptarea, backup-ul, perimetrul de securitate — se fac bine O dată, într-un singur loc. Se potrivește natural cu decizia full on-prem.
- Nu e U-turn: v1 conținea deja embrionul (Document Gateway + Read-Model + registrul canonic, ca trei bucăți nedenumite). Decizia le unește, le dă nume și ownership și le extinde peste informația contabilă.
Regulile de perimetru (condițiile ca să nu ne muște):
- Serviciu cu bază privată, NU „bază partajată". Nimeni — Iris, saga-automation, Vertigo, Dublin — nu intră direct în baza nucleului; totul prin API + evenimente. Formularea „va fi baza de date" e exact fraza cu care începe anti-patternul clasic (integration database): în 6 luni schema nu mai poate fi schimbată fără să spargi patru sisteme.
- Testul de perimetru al nucleului, scris (perechea testului Dublin): nucleul stochează / rutează / istoricizează. Nu calculează, nu clasifică, nu decide. Calculul = procesoare; interpretarea = Iris; prezentarea = shell-uri. Orice feature care „ar merge în nucleu" trece întâi testul — altfel nucleul devine magnet de monolit.
- Stăpânit vs. publicat, per domeniu + UN singur scriitor per tip de dată. Stăpânite de nucleu: documentele, notele contabile, situațiile închise, registrul firmelor, jurnalul de evenimente și — (31.aug, concluziile echipei) — FACTURILE EMISE: baza de date a facturilor stă în NUCLEU, nu în modulul de facturare; [F] rămâne motorul emiterii (seriile+numerotarea prin mini-serviciul de serii, transportul e-Factura) și scrie factura în nucleu la emitere. Facturile externe (ex. Smartbill) intră ca documente urcate în Dublin → Iris le identifică drept facturi de venit → nucleu. Stăpânite de modulele operaționale și publicate în nucleu: statele de plată ([S]) (
facturile emise ([F])— depășit 31.aug). Toți ceilalți sunt abonați. Fără regula asta: dual-write și două „adevăruri" pentru aceeași informație. - v1 mic — nucleul NU intră pe drumul critic al tuturor. Nucleul v1 = documente + note contabile + registrul canonic de firme (exact fluxul care a născut decizia). Facturi (F1) și Angajați (F5) rămân pe citiri directe prin BFF și migrează în spatele nucleului ulterior. Nu construim 6 luni de infrastructură fără nimic livrat.
- Numele. „SAGA = motorul contabil" (v1) + „engine contabil" (nou) = confuzie garantată în fiecare discuție. Nucleul = system of record / registrul central (numele final = decizie deschisă); SAGA rămâne motorul de CALCUL până e înlocuită.
- Igiena de hub, din prima: idempotență + deduplicare la intrare (același bon urcat de două ori, duplicate din SPV pull) · versionarea API-ului din ziua 1 (e contractul tuturor) · izolare de tenant impecabilă (toate firmele într-un singur loc = blast radius maxim la o scăpare — lecția IDOR din salareasy, la puterea a doua) · tier-0: singurul serviciu cu HA obligatoriu de la început (DB primary+replica, ≥2 noduri aplicație, cozile persistente pe RabbitMQ — deja decis).
- Contractul de procesor = generic. Interfața nucleu↔SAGA se proiectează ca și cum ar fi pentru serviciul nostru viitor („cum arată un procesor contabil"), nu mulată pe ciudățeniile SAGA — SAGA e doar primul care joacă rolul. Așa înlocuitorii se montează în aceeași priză fără să schimbăm nimic altundeva.
Unde pot apărea probleme (de urmărit activ):
- Anti-patternul bazei partajate (regula 1) — cel mai probabil mod de eșec al ideii.
- Magnetul de monolit (regula 2): fiecare feature viitor va tinde să aterizeze „în nucleu" — întâi stocarea, apoi o agregare, apoi o regulă de business — până devine creierul de care totul se blochează.
- Drumul critic (regula 4): „totul trece prin nucleu" aplicat dogmatic = luni de construcție fără livrare vizibilă.
- Destabilizarea sistemelor mature (regula 3): „toate informațiile" luat literal = migrarea invoicing + salareasy — singurele sisteme care funcționează azi.
- Single point of failure (regula 6): nucleu picat = Dublin orb, Vertigo orb, documente blocate. Tehnic (HA) și organizațional: e cea mai senioră bucată de inginerie din sistem — cine o deține = decizie deschisă; dacă „toată lumea" scrie în el, revine riscul de monolit.
- Fragmentarea de tenant NU se rezolvă de la sine — devine mai urgentă: registrul canonic Company/CUI intră în nucleu de la prima zi (§4.2).
4.1 Straturile
- dublin-web (SPA React/Vite + Dublin.Server BFF) — singura suprafață expusă browserului. Sesiune cookie httpOnly; BFF-ul face autorizarea user→companie (niciun backend n-o face azi); passthrough
/api/core/*per mandatul anti-proxy; chei per serviciu injectate server-side (X-Invoicing-SecretKey,X-Bono-SecretKey,X-Consumer-Key…), niciodată în browser. - Serviciul de identitate = cont.bono.ro — SPEC-UL EXISTĂ DEJA (PRD „Bono Auth — Register & Login", 30 iun 2026, + prototip; repo
cont-bono-ro-prd): email-first, flux unic register/login (serverul decidenext: otp | password | passkey), OTP 6 cifre pe email (10 min, 3 încercări→blocare 5 min, cooldown 30s), parola OPȚIONALĂ (bcrypt-12 + verificare HaveIBeenPwned, fără reguli artificiale — NIST), Google OAuth (PKCE), passkeys/WebAuthn ca metodă principală în timp (biometria = al doilea factor încorporat — deci FĂRĂ TOTP separat), fără SMS, fără CAPTCHA (rate limiting Redis per email+IP), anti-enumeration strict (UI-ul nu confirmă niciodată existența unui email). Sesiuni: JWT + refresh rotit, HttpOnly + SameSite=Strict, „Rămâi autentificat" = 30 zile. Endpoint-urile sunt definite în PRD. Ce adaugă analiza Dublin peste PRD-ul de auth: legătura user↔FIRME (User ← UserCompanyAssociation → Company(CUI)— schema există în invoicing) + roluri + claim-ul CUI în sesiune + registrul de mapare a identificatorilor + SSO-ul explicit pe.bono.ro(implicit deja prin cookie + passkey legat de domeniu). Notă de implementare: notele tehnice din PRD sunt pe stack Node — pe stack-ul Bono .NET se adaptează bibliotecile (ex. fido2-net-lib), deciziile de produs rămân identice. - Serviciile de domeniu (există): invoicing-services · salareasy-api · ElectronicInvoiceApi · forex · CompanyDirectory. (open-banking = doar cod exploratoriu în repo, neimplementat — nu contăm pe el.) Pe termen scurt rămân pe API-keys, dar cu tenant-scoping reparat obligatoriu (salareasy IDOR, invoicing per-user); pe termen mediu devin consumatori tenant-auth (JWT M2M — primul consumator real).
- Servicii NOI de construit (v2 — reorganizate în jurul NUCLEULUI, §4.0.c):
- NUCLEUL (NOU — system of record + hub; tier-0): absoarbe Document Gateway-ul din v1 și îl extinde: inbox-ul documentelor (upload client din Dublin, upload echipă din Vertigo, SPV pull e-Factura, extrase manuale, post-MVP OpenBanking/email-in) → MinIO + registru + statusul canonic per document (31.aug): neprocesat · primit · în lucru · respins + motiv · finalizat (când nota s-a întors; afișat identic în Dublin și Vertigo — B1) · notele contabile (primite de la Iris, completate de echipă din Vertigo) · situațiile închise + taxele (primite de la SAGA) · registrul canonic de firme (Company/CUI) · jurnalul de evenimente per tenant + agregate KPI (read-model-ul din v1 = o față a nucleului, nu serviciu separat) · cozile persistente spre/dinspre procesoare (RabbitMQ). Bază PRIVATĂ, API versionat + evenimente. Nu interpretează conținut, nu calculează nimic — testul de perimetru din §4.0.c. (✅ v1 „transport DIRECT Dublin→Iris" = depășit: transportul e Dublin→nucleu→Iris; spiritul deciziei rămâne — Vertigo NU e broker, e shell.)
- Contractul nucleu↔Iris (fost [IRIS-API] — procesor, de definit): tot ce e prelucrare — extracție, clasificare+deductibilitate cu motiv, rutarea internă pe confidence (Q1 trăiește AICI), motivele de eșec + comunicarea lor (Q2 — maparea în contractul Iris), fluxul documentelor „în așteptare"/golurilor de context — se propune ÎN Iris (31.aug, BGN; include comunicarea cu ambele shell-uri, prin nucleu), triajul universal: ORICE document primit de la client ajunge în Iris pentru triaj (31.aug, BGN — inclusiv contracte, PV-uri; soarta documentelor speciale post-triaj = decizia Iris), parsarea extraselor (plățile identificate).
Reconcilierea plăți↔facturi e a lui Iris— depășit (31.aug, concluziile echipei): RECONCILIEREA = modul LÂNGĂ NUCLEU (facturile pot fi anulate/modificate — potrivirea are nevoie de starea curentă din nucleu; Iris doar livrează plățile din extrase; fezabilitate de confirmat până la 1 octombrie, MVP). Consumă documente din nucleu; produce în nucleu: note contabile + statusuri + motive + plățile din extrase. Regula rămâne: incomplet nu se întoarce. (PRD-urile Iris există: iris.bgn.ro/prd + /atribute + /modele-date.) - Reconcilierea + soldurile (NOU — modul LÂNGĂ nucleu; 31.aug) · OWNER: PRODI (accountable — decizie BGN, 31.aug): potrivirea plăților cu facturile (venituri/cheltuieli), cu taxele și cu salariile (per angajat, după IBAN; contribuțiile urmărite bulk — „rest de plată agregat"). Soldul taxelor = mini-registru finit de conturi: sold = Σ(obligații din SAGA) − Σ(plăți din extrase, via Iris); Bono NU calculează taxa — verificare periodică vs. SAGA. Idee în analiză (legal + tehnic, la Cristi): buton „Plătește taxele" în Dublin (card → ANAF). + (31.aug) transferurile către acționar: clientul își ia banii singur din bancă → reconcilierea identifică transferul în extras (sau clientul îl anunță) → task de confirmare în De făcut („dividende / decont / restituire împrumut?") → la confirmare: actele (decizia de distribuire + situațiile cerute) pregătite de echipă [V], impozitul pe dividende intră în De plată, soldurile 455/deconturi se actualizează în nucleu. Fără plăți din Dublin.
- Contractul nucleu↔SAGA (fost [CONT-API] — procesor, via saga-automation, de definit): taxe de plată, profit, situații, calendarul închiderilor — calculate în SAGA din înregistrările luate din nucleu, livrate înapoi în nucleu; shell-urile (Dublin, Vertigo) citesc nucleul. ✅ Cadența decisă: la ÎNCHIDEREA LUNII + evenimente (depunere declarație, plată confirmată) — clientul vede mereu „ultima situație închisă", cu ora ultimei actualizări afișată. Se proiectează GENERIC („cum arată un procesor contabil" — §4.0.c regula 7): aceeași priză va fi folosită de serviciile proprii care înlocuiesc SAGA calcul cu calcul.
- Subscription & Billing [BILL] (NOU, mic, al Bono): starea abonamentului per client (plan, status, istoricul facturilor Bono) + integrarea cu un procesator de plăți extern (de ales) pentru card, plăți recurente, retry la eșec, anulare. Legat de entitlements (tenant-auth: active/suspended) → suspendare la neplată. Facturile Bono către client se pot emite prin propriul invoicing-services (dogfooding).
Dublin Read-Model(v2: absorbit în nucleu) — jurnalul de evenimente per tenant (ticker „Live"), mesaje/insights (stiva), taskurile „De făcut" (scrise de Vertigo/echipă + reguli automate ÎN nucleu; Dublin le citește), agregate KPI pe perioade — toate = fețe ale nucleului, servite din același API. Alimentare: întâi polling adapters de la modulele operaționale, apoi outbox-uri (banking are deja).
- Storage documente: MinIO on-prem (S3-compatible; integrare standard în .NET), erasure coding, criptare, thumbnails, retenție legală 10 ani (WORM/object-lock pe arhivă).
- DB: MariaDB e standardul de facto (TOATE serviciile) — rămâne; câte o bază per serviciu; HA (primary+replica; Galera doar dacă e nevoie de multi-master).
4.4 SAGA — motorul de CALCUL, ca procesor al nucleului (Q5, revizuit 4 aug)
Toată contabilitatea „adevărată" (taxe, situații, închideri, declarații) se calculează în SAGA, operat de echipă. Consecințe arhitecturale (v2):
- Dublin/Vertigo NU implementează motor contabil — ambele sunt shell-uri care citesc nucleul; SAGA e procesor atașat nucleului: ia înregistrările din nucleu, întoarce situațiile + taxele ÎN nucleu (v1 „export SAGA → Vertigo → Read-Model → Dublin" = depășit).
- Se construiește pipeline-ul de automatizare SAGA (există deja repo
saga-automation-web— de explorat): (intrări, din nucleu) înregistrarea cheltuielilor conspectate + extraselor + consecința contabilă a facturilor emise; (ieșiri, în nucleu) situațiile + taxele per companie. - La zeci de mii de clienți, operarea SAGA per firmă devine ea însăși un subiect de scalare (licențe, instanțe, automatizare robotizată?) — de dimensionat separat cu echipa contabilă.
- Orizontul (deblocat de nucleu): SAGA se înlocuiește treptat cu procesoare proprii, calcul cu calcul, în aceeași priză (strangler + shadow mode — §4.0.c pro #2). Vocabular: SAGA = motorul de calcul · nucleul = system of record — nu le amestecăm.
4.2 Problema tăcută: FRAGMENTAREA identității de tenant
Patru identificatori diferiți azi: invoicing Tenant+CompanyUniqueCode · salareasy tenant_id (int) · banking companyRef (=CUI) · tenant-auth tenant_code (string opac). Cheia de unificare naturală = Company/CUI. (v2, 4 aug): registrul canonic al firmelor + maparea identificatorilor istorici trăiesc în NUCLEU (lângă datele firmei, de la prima zi); serviciul de identitate ține user↔firmă + sesiunile. Nucleul nu rezolvă fragmentarea de la sine — o face mai urgentă. Fără asta, orice integrare cross-serviciu se împotmolește.
4.3 Hosting: FULL ON-PREM înainte de lansare (✅ decis BGN, 3 aug)
Decizie fermă: totul on-prem RO de la început — nu hibrid. Consecința: repatrierea devine workstream propriu, PRE-lansare, în paralel cu F0–F1: invoicing-services de pe Cloud Run → on-prem (registry registry.bono:5000 există) · Azure Service Bus → RabbitMQ · Azure Key Vault → Vault/OpenBao · pipelines reconfigurate · workers Windows Service rămân on-prem (sunt deja). Serviciile noi (identitate/cont.bono.ro, NUCLEUL cu MinIO + cozile lui) se nasc direct on-prem. Câștig: suveranitate completă pe datele fiscale + documente și un singur model operațional; cost: efortul de migrare se plătește înainte de primul client, nu după.
5. Dimensionare (30.000 clienți activi · 30 doc/client/lună)
| Dimensiune | Calcul | Rezultat |
|---|---|---|
| Documente | 30k × 30/lună | ~900k/lună · ~11M/an |
| Storage nou (avg ~1,2MB: poze bonuri domină) | 900k × 1,2MB | ~1TB/lună · ~13TB/an |
| Arhiva la 10 ani (cu creștere) | ~80–150TB → MinIO 4–8 noduri, start ~100TB raw, tiering hot(90 zile)/cold | |
| Debit OCR | ~30k doc/zi, vârf seara ~4–5k/oră | Conspectare: 10–20 workers paraleli; coada persistentă = obligatorie |
| Facturi emise | ~5/client/lună | ~150k/lună · 1,8M/an — banal pentru MariaDB |
| Rânduri cheltuieli | ~11M/an + linii | partiționare pe (tenant, dată); agregate precalculate pentru KPI |
| Trafic API | 30k clienți, sesiuni scurte | zeci de RPS la vârf — 2–3 noduri/serviciu ajung |
| Infra on-prem (ordin de mărime) | ~8–12 VM-uri app + DB HA 3 noduri + MinIO 4–8 + RabbitMQ 3 + monitoring; redundanță N+1 | |
| Real-time | polling 30–60s + evenimente la acțiuni | fără WebSocket în MVP |
(v2, 4 aug: storage-ul documentelor, cozile și registrul de mai sus = ale NUCLEULUI — singurul serviciu tier-0, cu HA obligatoriu de la început: DB primary+replica, ≥2 noduri aplicație, RabbitMQ persistent. Restul dimensionării nu se schimbă — aceleași date, alt stăpân.)
6. Faze de implementare + dependențe critice
F0 — Fundația identității (deblochează tot): serviciul de identitate (construit de la zero) + user↔companie + claim CUI în sesiune + registrul de mapare tenant-ids + fix tenant-scoping în salareasy și invoicing (IDOR) + SSO cookie .bono.ro.
F1 — Facturi emise REAL în dublin-web (cel mai ieftin modul end-to-end): PR-ul quick-win în invoicing (CUI pe wire + filtre + doar-emise) + portarea designului validat din prototip în features/facturi/; KPI-uri prin endpoint de agregare nou. Fără „Plătită" încă (onest: doar status document + e-Factura).
F2 — NUCLEUL v1 + pagina Cheltuieli (revizuit 4 aug): nucleul v1 = documente + note contabile + registrul canonic de firme (inbox + MinIO + registru + cozi procesoare + jurnal evenimente), construit pe contractul nucleu↔Iris cu MOCK (Dublin nu așteaptă Iris-ul real) + SPV pull furnizori + pagina Cheltuieli în dublin-web (coada + tabelul + modalul cu documentul real, citite din nucleu). Perimetrul v1 = strict cele trei domenii — regula 4 din §4.0.c: nucleul nu blochează F1.
F3 — Extrase: pagina Extrase + extrasele curg prin nucleu → Iris; „Plătită" pe Facturi + „plăți fără documente" apar când Iris livrează efectele reconcilierii în nucleu (dependență externă, urmărită prin contract — nu construcție Dublin).
F4 — Taxe, De făcut, Live: contractul nucleu↔SAGA (mock întâi; explorare saga-automation-web + prototip-vertigo; proiectat GENERIC — regula 7) + situațiile/taxele intră în nucleu + taskurile „De făcut" scrise în nucleu de Vertigo/echipă + stiva de mesaje + ticker + „Ce urmează" din ciclul SAGA. Tot aici: [F] începe să publice în nucleu consecința contabilă a facturilor emise (stăpânit vs. publicat — regula 3).
F5 — Angajați: endpoint agregat în salareasy + pagina + finalizarea auto-angajării (persistare+documente HR+semnare Rex+REGES).
F6 — Cont & Abonament: pagina Contul tău completă + [BILL] cu procesatorul ales (până atunci: planul afișat static + facturare manuală; anularea = cerere către echipă). Urcă mai devreme dacă lansarea comercială o cere.
Post-MVP: OpenBanking on (după deal-ul comercial — la BGN) · PIS · email-in documente · personalizare pe comportament.
Dependențele critice (drumul care doare): F0 blochează tot → nucleul v1 (F2) blochează Cheltuieli → reconcilierea (F3, în Iris) blochează „Plătită" și jumătate din wow-ul Dublin → contractul nucleu↔SAGA (F4) blochează „De făcut"/ticker (pilonul 3 al produsului).
SCOPE MVP (31.aug — deciziile BGN & Prodi din concluziile echipei, 25.aug): fără useri/roluri per firmă în MVP · fără multi-firmă — un cont = o firmă (switcher-ul se face la primul client cu cerința; [ID] păstrează user↔firmă 1:1) · chat-ul din Dublin = aplicație de CS existentă (ex. Helpscout), NU Vox · V2 cu PRD separat: feed-ul live, Vox/chat, rail-ul „De făcut" — apoi se decide ce intră în MVP. Consecință pe faze: F0 se subțiază (fără roluri/multi-firmă), F4 (taskuri/ticker) devine condiționat de PRD-ul V2.
Decizii deschise (de luat cu echipa):
Ownership reconciliere: în perimetrul Iris (3 aug)→ redecis 31.aug: modul LÂNGĂ nucleu · OWNER: PRODI (accountable) — el îl construiește sau răspunde de el (decizie BGN, 31.aug); rămâne de confirmat doar fezabilitatea reconcilierii de facturi până la 1 octombrie (MVP).Identitate✅ decis: cont.bono.ro ca serviciu separat, pe PRD-ul existent (30 iun); de adăugat doar stratul user↔firme + claim CUI (registrul firmelor = în nucleu).- Broker: cu decizia full on-prem, RabbitMQ intră oricum (înlocuiește Azure Service Bus) → cozile nucleului pornesc direct pe el (elimină dilema tabel-coadă).
- (în perimetrul Iris) Conspectarea: productizare internă vs OCR extern ca accelerator — decizia echipei Iris, nu blochează Dublin.
4b. (31.aug, din concluziile echipei): documentele „în așteptare" la Iris + golurile de context — cum se deblochează? ✅ decis (BGN, 31.aug): fluxul de deblocare se propune ÎN IRIS (documentele pe care nu știe să le interpreteze = perimetrul lor); va include comunicarea cu Dublin și Vertigo (prin nucleu) — Dublin afișează și colectează răspunsul clientului, Vertigo = rezolvarea echipei; probabil pe clasele din Q2. De așteptat propunerea echipei Iris. · un document cu mai multe tranzacții → o singură notă contabilă vizuală agregată (propunere Cristi) · ce facem cu documentele non-factură/bon/extras (contracte, PV-uri)? ✅ decis (BGN, 31.aug): ORICE document primit de la client ajunge în Iris pentru TRIAJ; ce se întâmplă după triaj cu documentele speciale = de decis în Iris · Regim_Auto: Vertigo îi dă lui Iris deductibilitatea PER VEHICUL (propunere Cristi) · facturile emise prin Iris vs. TAC automat ✅ regulă (BGN, 31.aug): HIBRID, pe sursa descrierii — descriere aleasă din PRESETURI → TAC automat, fără Iris (presetul cară interpretarea); descriere scrisă DE MÂNĂ → Iris, pentru interpretarea prin Larry. De înțeles cu echipa: se înregistrează veniturile diferit după criterii (produse vs. servicii, avans etc.)? — răspunsul dimensionează cât e de interpretat și leagă preseturile de CAEN (item-ul Otilia/Raluca devine condiție pentru ruta TAC) · butonul „Plătește taxele" (legal ConsAudit + tehnic) · preseturile de descriere factură vs. CAEN (Otilia/Raluca — acum condiție pentru TAC automat).
- (4 aug) NUMELE nucleului — „engine contabil" se bate cu „SAGA = motorul contabil"; de ales un nume care spune „system of record" (registrul central, cartea firmei…).
- (4 aug) OWNERSHIP-ul nucleului — cine îl construiește și cine aprobă schimbările de contract (e cea mai senioră bucată; nu poate fi „al tuturor").
- (4 aug) Stăpânit vs. publicat per domeniu — calendarul: când încep [F] (facturile emise) și [S] (statele) să publice în nucleu (F4 propus pentru [F]; [S] la F5?); până atunci shell-urile citesc direct prin BFF.
7. Schema logică de funcționare a ecosistemului
Fluxurile numerotate pas cu pas, cu sursa fiecărei săgeți. Întrebările Q1–Q5 au fost tranșate cu BGN pe 3 aug; pe 4 aug (BGN + Prodi) a venit decizia NUCLEULUI (§4.0.c) — harta și fluxurile de mai jos sunt pe modelul v2: toate săgețile trec prin nucleu; ce s-a schimbat față de v1 e marcat. Vocabular: nucleul = system of record · SAGA = motorul de calcul · Iris = procesorul de documente · Dublin/Vertigo = shell-uri.
7.0 Harta serviciilor
flowchart LR
subgraph SHELLS["Shell-uri (input + afișare)"]
UI["dublin-web SPA + BFF<br/>clientul: firma lui<br/>cookie httpOnly · authz user→firmă"]
V["Vertigo — shell-ul echipei<br/>toate firmele · completări note · taskuri"]
end
ID["Identitate cont.bono.ro<br/>user ↔ firmă · sesiuni · passkeys"]
subgraph NUC["NUCLEUL — system of record + hub (NOU, tier-0)"]
NAPI["API versionat + evenimente<br/>(bază PRIVATĂ — nimeni nu intră direct)"]
REG[("registru firme CUI · documente<br/>note contabile · situații închise<br/>jurnal evenimente · taskuri · agregate")]
MIO[("MinIO on-prem<br/>fișiere, 10 ani, WORM")]
end
subgraph PROC["Procesoare (toate în aceeași priză)"]
IRIS["IRIS — documente → note<br/>conspectare · motive eșec ·<br/>parsare extrase (plăți identificate)"]
REC["Reconciliere (modul LÂNGĂ nucleu, 31.aug)<br/>plăți ↔ facturi · taxe · salarii<br/>+ mini-registru solduri taxe"]
SAGA["SAGA via saga-automation<br/>înregistrări → situații · taxe · închideri<br/>(motorul de CALCUL, operat de echipă)"]
FUT["procesoare proprii (viitor)<br/>înlocuiesc SAGA calcul cu calcul<br/>(strangler + shadow mode)"]
end
subgraph OPER["Module operaționale (stăpâne pe datele lor)"]
F["invoicing-services<br/>+ ElectronicInvoiceApi → SPV/ANAF"]
S["salareasy-api"]
OB["open-banking<br/>(stand-by comercial)"]
end
UI --> ID
V --> ID
UI --> NAPI
V --> NAPI
UI -.->|citiri directe interim F1 · F5| F & S
NAPI <--> REC
NAPI <-->|documente → note| IRIS
NAPI <-->|înregistrări → situații| SAGA
NAPI <-.->|aceeași priză| FUT
F -.->|publică consecința contabilă F4| NAPI
S -.->|publică statele F5| NAPI
OB -.->|post-MVP| NAPI
Flux A — Documentul de cheltuială (inima produsului) (v2 — prin NUCLEU)
- Intrare în NUCLEU: (a) clientul urcă bon/factură în Dublin; (b) echipa urcă din Vertigo (shell-urile sunt simetrice); (c) SPV pull — XML-urile facturilor PRIMITE; (d) extrase manuale (Flux C); (e) post-MVP: OpenBanking, email-in. Idempotență + deduplicare la intrare (același bon de două ori, duplicate SPV).
- Nucleul: fișierul → MinIO,
Documentîn registru (stare neprocesat — coada „27 documente" din UI), mesaj în coada spre Iris. - Transmitere nucleu → Iris — ✅ v2 (4 aug): traseul e Dublin → nucleu → Iris (decizia v1 „DIRECT Dublin→Iris" = depășită; spiritul ei rămâne: Vertigo NU e broker — brokerul e nucleul, Vertigo e shell). Din acest punct, documentul e „la Iris".
- Iris prelucrează intern (extracție → clasificare → deductibilitate cu motiv; rutarea pe confidence + review-ul uman = treaba lui Iris — shell-urile nu văd scoruri). Regula contractului: ce nu e complet conspectat NU se întoarce.
- Întoarcere: Iris livrează nota contabilă completă în NUCLEU → de acolo o preiau TOȚI consumatorii: Dublin (rândul apare în tabelul Cheltuieli, cu deductibilitatea + motivul gata puse), Vertigo (completări/verificări ale echipei), SAGA (înregistrarea contabilă) → agregatele + ticker-ul se actualizează. (Consecință UI: starea „Se procesează" pe Deductibilă din prototip devine inutilă sau doar cosmetic-informativă — documentul stă în coadă până e gata de tot.)
- Eșecuri: vin tot de la Iris, pe motive, în nucleu; cele care privesc clientul (duplicat, incompatibil) → Dublin le afișează cu acțiune; cele interne (interpretare) nici nu ajung la client. Contextul dat de client (câmpul Vox) → nucleul îl retransmite lui Iris (reprocesare).
Flux B — Factura emisă
- Clientul emite — două căi (5–6 aug): (a) emiterea rapidă ÎN Dublin — quick-invoice bar + modal → apel API către [F]; la commit, [F] alocă seria+numărul din mini-serviciul lui de SERII (✅ BGN 6.aug: registru per firmă, un singur scriitor, alocare atomică — nimic numerotat în Dublin); (b) cazurile ne-rapide (PF, firme străine, storno) → modulul Facturare (SSO prin [ID], shell comun), precompletat cu clientul+suma.
- [F]: factura
issued+ snapshot legal al părților + intră în coada e-Factura (delay configurabil, azi default 2 zile). - Jobul SPV ([F]→EF):
queued → sending → sent/error, cu jurnal de evenimente. ✅ Q3 DECIS: F1 = doar „trimisă" (starea internă existentă); citirea confirmării ANAF cu nr. de referință intră în F2+. - (v3, 31.aug) Arhiva facturilor: Dublin citește din NUCLEU — baza facturilor stă acolo de la lansare; [F] = motorul emiterii, scrie factura în nucleu la emitere. (v2 „citire directă interim din [F] + publicare la F4" = depășită de concluziile echipei.)
- Facturile externe (client pe Smartbill etc.): urcate ca documente în Dublin → Iris le identifică drept facturi de venit → nucleu (arhiva le afișează la fel).
5b. Înregistrarea contabilă a facturii emise — HIBRID pe sursa descrierii (✅ BGN, 31.aug): descriere din preseturi → TAC automat, fără Iris; descriere scrisă de mână → Iris (Larry) pentru interpretare. De înțeles: dacă veniturile se înregistrează diferit pe criterii (produse/servicii/avans) — condiționează preseturile (legătura cu CAEN, la Otilia/Raluca).
- Plătită apare abia când modulul de reconciliere de lângă nucleu scrie potrivirea plată↔factură (v3, 31.aug — Iris livrează doar plățile din extrase; un singur scriitor al potrivirii: reconcilierea) — până atunci, pagina arată onest doar status document + e-Factura.
Flux C — Extrasul de cont
- Intrare: ✅ oricine primul, egal — clientul (Dublin) sau echipa (Vertigo); post-MVP, DACĂ se semnează deal-ul OpenBanking, sync automat. Toate intră tot în NUCLEU (extrasul = un tip de document — exact decizia veche de produs).
- Nucleu → Iris: Iris parsează extrasul și livrează plățile identificate în nucleu; modulul de reconciliere de lângă nucleu (v3, 31.aug) face potrivirile și scrie efectele: facturile devin Încasate, plățile fără documente (alerta din Cheltuieli), taxele/salariile bifate, transferurile către acționar (→ task de confirmare: dividende / decont / împrumut — 31.aug), note contabile (le ia SAGA).
- Shell-urile doar reflectă: matricea de extrase (stările pe lună×cont din registrul nucleului) + statusurile de plată + alertele primite.
Flux D — Identitatea și fiecare request
- Login (magic link / parolă / Google) în [ID] → sesiune cookie httpOnly pe
.bono.ro(SSO către modulele randate în shell). - Fiecare request: BFF validează sesiunea → claim-uri user + Company/CUI → autorizarea user↔firmă se face în BFF (serviciile n-o fac azi).
- BFF traduce identitatea către fiecare serviciu (maparea CUI ↔ identificatorii istorici: CompanyUniqueCode, tenant_id, companyRef) și injectează cheile de serviciu — nimic sensibil în browser.
Flux E — Taxe, „De făcut", „Live" (Q5 + v2: SAGA = motorul de CALCUL, procesor al nucleului)
- SAGA (operat de echipă) calculează TOT ce e contabil: taxele de plată, situațiile, închiderile de lună, declarațiile — din înregistrările luate din nucleu. Shell-urile NU calculează nimic contabil.
- SAGA → NUCLEU (v1 „export SAGA → Vertigo" = depășit): situația fiecărei companii abonate (taxe scadente, situații, statusuri) se livrează din SAGA în nucleu, prin stratul
saga-automation(repo existent, de explorat). ✅ Cadența: la închiderea lunii + evenimente (nu zilnic, nu on-demand) — clientul vede „ultima situație închisă". - Nucleul → shell-uri: taxele + situațiile se afișează în Dublin (cardul „Taxe și impozite", pagina De plată, Contabilitate) și în Vertigo (situația per firmă, pentru echipă). Soldul per taxă (31.aug) = mini-registrul finit de lângă nucleu: Σ(obligații SAGA) − Σ(plăți din extrase) — Bono nu calculează taxa, doar ține evidența; verificare periodică vs. SAGA. Taskurile „De făcut" = scrise în nucleu de Vertigo/echipă + reguli automate; Dublin le citește din același loc (rail-ul „De făcut" + feed-ul live = candidate V2 — v. scope MVP, §6).
- Restul surselor alimentează jurnalul de evenimente al nucleului ([F] e-Factura, documente, potriviri Iris, [S] payroll) — polling la început, evenimente/outbox apoi.
- Dublin randează: rail De făcut · ticker pe vocea Bono · stiva de mesaje · „Ce urmează" (calendarul fiscal derivat din ciclul SAGA: închidere lună, D394, D300…).
Deciziile de pe schemă (BGN, 3–4 aug 2026)
| # | Decizia | Consecința |
|---|---|---|
| Q1 ✅ | Hibrid pe încredere — dar în perimetrul Iris (revizuit): shell-urile nu văd scoruri; primesc doar documente complete | contractul nucleu↔Iris: „incomplet nu se întoarce" |
| Q2 ✅ | Rutare pe motiv, 2 clase — maparea completă motive→rezolvare intră în contractul nucleu↔Iris, nu în Dublin | Dublin doar afișează motivele destinate clientului |
| Q3 ✅ | F1 = doar „trimisă" la SPV; confirmarea ANAF în F2+ | pagina Facturi se deblochează rapid |
| Q4 ✅ | Extrase: oricine primul, egal (client din Dublin + echipă din Vertigo) | matricea = oglindă; remindere către ambii |
| Q5 ✅ | SAGA = motorul de CALCUL (nu system of record): taxe + situații se calculează în SAGA | vezi §4.4; Vertigo NU calculează; Dublin e read-only pe contabilitate |
| 4 aug ✅ | NUCLEUL central (BGN + Prodi): system of record + hub pentru toate informațiile firmelor; Dublin + Vertigo = shell-uri; Iris + SAGA = procesoare în aceeași priză | înlocuiește „transport DIRECT Dublin→Iris" (A.3) și „export SAGA→Vertigo→Dublin" (E.2); Dublin consumă UN API; SAGA devine înlocuibilă (strangler). Modelul + pros/cons + reguli: §4.0.c |
| 31 aug ✅ | Concluziile echipei (25.aug, A1–A3 + minutele dev + BGN & Prodi): modelul confirmat; facturile emise = în NUCLEU ([F] = doar motorul emiterii) · reconcilierea = modul LÂNGĂ nucleu, nu în Iris · statusuri canonice per document · scope MVP: fără multi-firmă/roluri, chat = CS extern, feed live + „De făcut" → V2 | actualizează Flux B (4–6), Flux C.2, Flux E.3, §4.0.c regula 3, §4.1, §6; fezabilitatea reconcilierii de facturi = până la 1 oct |
Rămase deschise (revizuit 4 aug)
- Contractul API al NUCLEULUI (livrabilul următor natural — îl pot drafta ca spec): suprafața pentru shell-uri (documente in/out, note, situații, taxe, evenimente, taskuri) + cele două contracte de procesor: nucleu↔Iris (documente → note + statusuri/motive + efectele reconcilierii) și nucleu↔SAGA (înregistrări → situații/taxe; generic — de explorat
saga-automation-web+prototip-vertigo). - Numele nucleului (§6.5) · ownership-ul (§6.6) · calendarul stăpânit-vs-publicat pentru [F]/[S] (§6.7).
- În interiorul Iris (nu blochează Dublin): maparea motivelor de eșec, pragul de confidence.
- Billing: alegerea procesatorului de plăți (Netopia/euplatesc vs Stripe) + momentul automatizării (primii clienți pot fi pe facturare manuală; politica de suspendare la neplată = de definit).
Dublin — PRD v1
Produs: Dublin · interfața client a BONO Conta
Owner: Bogdan (BGN) · Co-autor: Claude
Data: 3 iunie 2026 · Status: Draft v1 — Nevoia închisă, Produs în curs (home definit + prototip v1)
Cum citești acest document: Partea 1–3 = Nevoia (de ce existăm, pentru cine, ce facem). Partea 4–6 = Produsul (cum arată, ce intră în MVP). Partea 7–8 = principii + ipoteze. Partea 9 = unde suntem și ce mai e de făcut (citește asta dacă revii după o pauză). Partea 10 = cum rulezi prototipul.
0. Rezumat
Dublin este partea din BONO pe care o vede clientul — "casa" lui (numele vine de la U2). Clientul (freelancer / mic antreprenor) nu vrea să facă contabilitate; vrea să știe că firma lui e în regulă și să facă rapid câteva lucruri (factură, încărcat cheltuieli, văzut taxe). Viziunea: "nu trebuie să ceri, îți dăm exact ce vrei" — BONO face (aproape) tot ce ține de administrativ, iar Dublin îi arată clientului exact ce contează, fără jargon și fără să caute.
Arhitectura aleasă: home curat + drill-down (Model B), cu un home construit pe 3 piloni (cifrele / ce ai de făcut / ce face BONO pentru tine) + un strat subțire de acțiuni. Avem prototipuri funcționale (desktop + mobil) în design system-ul Edge-33.
1. Nevoia
Ce e Dublin
Interfața client-facing a BONO. Locul unic unde clientul își vede situația firmei și face acțiunile principale. Nu există încă — BONO Conta nu e lansat. Azi, clientul depinde complet de contabil (telefon/WhatsApp/email) pentru orice informație despre propria firmă.
Job statement
Când un client BONO vrea să-și vadă situația firmei sau să facă ceva legat de ea (emite factură, încarcă o cheltuială, vede ce are de plată), intră în Dublin și găsește exact ce-i trebuie — fără căutare, fără jargon contabil, fără să sune contabilul pentru lucruri simple.
Clientul
MVP (primii 2–3 ani): freelancer / antreprenor mic, 25–45 ani, SRL micro, ~30% plătitori TVA. Lucrează singur sau cu 1–2 angajați. De multe ori firma e doar instrumentul legal de a încasa bani (medic, ITist, designer). Nu-i pasă de contabilitate — vrea să știe că e totul OK.
Post-MVP: mici întreprinzători cu afaceri reale (cafenea, frizerie, magazin online), 3–10 angajați. Produs diferit — nu ne ocupăm acum.
Ce vrea clientul de la BONO
Să factureze ușor · să încarce ușor documente de cheltuieli · să știe cât are de plată la stat · să acceseze ușor orice document al firmei (când i-l cere banca/o instituție) · să nu fie nevoit să rezolve el partea admin (ANAF, ONRC, semnătură electronică).
Viziunea (north star)
"Nu trebuie să ceri, îți dăm exact ce vrei." Nu o aplicație clasică de contabilitate cu totul la grămadă. Simplitate maximă, claritate. BONO face pentru client tot ce e nevoie administrativ.
Paradoxul care justifică designul
Dacă BONO face tot, invizibil, clientul ajunge să se întrebe "ce plătesc?". Munca perfectă și tăcută e indistinctă de munca neexecutată. De aceea Dublin trebuie să facă vizibilă munca invizibilă (vezi Pilonul 3) — e și dovadă de valoare, și motor de retenție.
2. Dublin în sistemul BONO
| Componentă | Rol |
|---|---|
| Dublin | Interfața clientului (acest document) |
| Vertigo | ERP/CRM intern BONO — echipa vede tot ce face clientul și intervine. Operațiile BONO trăiesc aici, NU în Dublin |
Module satelit și cum se leagă de Dublin:
- Facturare — modulith (UI randat în shell; subdomeniu cu design identic → clientul nu simte că a plecat)
- SalarEasy — salarizare simplă (administrator/acționar unic), serviciu prin API. Modul extern ca Facturare, dar cu pagină dedicată în Dublin („Angajați"): situația angajaților + lansarea angajării (acțiunile #10–11 din §3)
- Vox — chat AI, suport nivel 1 (contabilul din Vertigo escaladează)
- Rex — semnături electronice (backend, la onboarding)
- IRIS — procesare documente (backend invizibil). Fluxul (aliniat cu decizia Nucleului, 4 aug): Dublin NU vorbește cu Iris — clientul încarcă în Dublin → documentul intră în Nucleu (system of record) → Nucleul trimite
ProcessingRequestla Iris → Iris întoarce notele contabile tot Nucleului → Dublin/Vertigo afișează statusuri și rezultate citind din Nucleu. Interim, până e gata Nucleul: backend-ul Vertigo joacă rolul de expeditor, pe același contract. Contractele și arhitectura Iris: iris.bgn.ro/arhitectura
Facturi multi-sursă: Dublin arată toate facturile clientului, indiferent de unde sunt emise (BONO, Oblio, SmartBill). Sursa universală: import din SPV (e-Factura e obligatorie → SPV le are pe toate). În MVP, practic doar clienți pe facturarea BONO (vezi §6).
3. Ce face clientul în Dublin
| # | Acțiune | Note |
|---|---|---|
| 1 | Emite o factură | via modul Facturare |
| 2 | Încarcă cheltuială (bon / factură furnizor străin) | upload + OCR (Iris) |
| 3 | Încarcă extras de cont | parte din upload general; manual în MVP, OpenBanking post-MVP |
| 4 | Verifică ce taxe are de plată | citire în MVP; plata directă post-MVP |
| 5 | Distribuie dividende | BONO arată cât poate; pregătește AGA; client semnează (Rex) |
| 6 | Caută un document al firmei | search; "banca mi-a cerut ceva" |
| 7 | Întreabă (chat Vox) | suport AI nivel 1 → contabil |
| 8 | Vede cum i-au fost procesate cheltuielile + taxe salvate | pasiv — i-l arătăm noi |
| 9 | Găsește plăți fără documente | la cererea BONO (reminder) |
| 10 | Vede situația angajaților | state de plată, taxe salariale, cost total — datele vin din SalarEasy (API) |
| 11 | Angajează un om nou | Dublin lansează fluxul, SalarEasy îl execută; MVP: auto-angajare (administratorul se angajează pe sine) |
Ce face BONO în spate (operat în Vertigo, surfacat în Dublin): onboarding (F150, conectare SPV) · push facturi în SPV · corelează plăți↔facturi · semnalează lipsuri · situații financiare + depunere ANAF · AGA & dividende.
4. Arhitectura de produs (IA)
Model B modern (decis)
Home curat + drill-down în secțiuni. NU single-rich-page (A = capcana "totul la grămadă" Keez), NU widget customizabil de user (C = trăsătură de incumbent). Validat prin research pe 12 platforme: 10/12 sunt B; toți liderii de UX (Mercury, Puzzle, Digits, FreeAgent) sunt B cu home minimal. "Exact ce vrei" = curat (B), nu tot (A).
Două zone
- Bară de meniu / navigație — secțiunile reale (v. §5/§5b): Acasă · Facturi · Cheltuieli · Extrase · De plată · Angajați · Contabilitate · Firma ta (+ PRD); căutarea în sidebar, chatul Vox în shell (nomenclatura veche „Banii/Documente/Taxe" = abandonată)
- Pagina principală
Home = 3 piloni + strat de acțiuni
| Pilon | Răspunde la | Ton |
|---|---|---|
| 1. Cifrele | "Unde stau?" (Venituri facturate · Cheltuieli deductibile · Nedeductibile — v. §5; Profitul a ieșit) | factual |
| 2. DE FĂCUT | "Ce trebuie eu să fac?" (puține, acționabile, atribuite actorilor BONO) | activ |
| 3. Motorul BONO | "Ce face BONO pentru mine?" (trecut = dovadă + valoare cuantificată; viitor = liniștire) | pasiv, relaxant |
Acțiunile sunt țesute, nu un al 4-lea pilon: frecvente pe home (emite factură, adaugă document), reactive în DE FĂCUT, rare aduse contextual de BONO (ex: dividende), căutare + chat în shell.
Mobil ≠ desktop (Model B adaptiv)
Aceleași capabilități pe ambele; prezentarea se adaptează (tabel lat desktop → search/filtru+detaliu pe mobil). SOLO are uz ~50/50. Mobilul se proiectează primul — constrângerea forțează prioritizarea și dezvăluie ce contează cu adevărat.
5. Home — SPECIFICAȚIE FINALĂ (desktop · finalizat 9 iulie 2026)
Sursa de adevăr vizuală = prototipul
Dublin/prototype/dublin-acasa.html. Secțiunea asta e decision-log-ul; pixelii sunt în prototip.
Nav stânga — deschis (nu icon-only), 212px, bej-1
- Logo B + wordmark „Dublin"
- Secțiuni cu etichete vizibile: Acasă (activ: pink-tint) · Facturi (badge = neplătitele, 6) · Cheltuieli (badge) · Extrase · De plată · Angajați (10 iul) · Contabilitate · Firma ta · PRD (3.aug.2026 — tabul afișează UN document cu 2 tab-uri: Arhitectura (din
dublin-analiza-implementare-3aug2026.md— analiza de implementare) + Specificații (acest document); ambele randate debuild-prd.py; a înlocuit „Plan" — harta veche rămâne pe/plan, în afara meniului) - Căutarea în meniu, jos („Caută orice…", pill alb) — scoasă din topbar ca să respire pagina
- Profil jos: avatar + nume + firmă
Topbar + hero
- Topbar minimal: firma + CUI (stânga) · badge „LIVE · data" (dreapta). Fără search.
- Filtru de perioadă: (istoric: 15 iul — dropdown sus-dreapta cu presete verbale „Anul acesta/Luna trecută…"; 31 iul — mutat ÎN eticheta primului KPI, ca pe secțiuni, cu formatele compacte 2026·2025·Q2-26·Q1-26·12 luni·apr.26·mar.26 — v. §5b „Dashboard — rundă de finisaje".) Cifrele KPI se schimbă cu perioada; din 3.aug valorile pe perioade sunt reconciliate transversal (venituri = cifrele Facturi; deductibile/nedeductibile = cifrele Cheltuieli, calculate din tabel).
- Hero: „Salut, [nume]. Totul e ok azi." — reasigurarea e prima propoziție.
Cifrele (Pilon 1)
- 3 KPI stil DS: Venituri facturate · Cheltuieli deductibile · Cheltuieli nedeductibile (redenumite/înlocuite 15 iul, edit BGN pe prototip — Profitul a ieșit de pe Acasă; nedeductibilele = 5.790 lei, dot warn). Fără rândul de evoluție („vs 2025"), carduri slim: etichetă + cifră (10 iul). Pe secțiuni, liniile de sub cifre rămân — informație, nu evoluție.
Rândul de acțiuni — 3 carduri (cutii identice 240px; titluri 14px/500 pe aceeași linie; butoane 40px full-width pe aceeași linie de bază)
- „Emite o factură nouă" (bej): câmp „Caută după CUI sau numele firmei" · câmp „Introdu suma" cu selector de valută (pill steag SVG + nume; Lei/EUR/USD/GBP; dropdown funcțional) · CTA roz plin „Emite factura →" — singurul roz plin de pe ecran (primarul). v2 (BGN 6.aug): cardul are ACELAȘI comportament cu widgetul de factură nouă din Facturi (
link-out către modul): la click/focus în câmpul de client se deschide „Clienți facturați recent" — ultimele firme către care s-a facturat (buline cu inițiale, CUI, footer PF/firmă străină; pe Acasă lista e constantă-demo, oglinda arhivei din Facturi — nu există tabel-sursă pe pagină) · CTA inactiv până sunt completate clientul și suma · click → modalul de emitere (pașii Detalii + Revizuire, portat identic) · la emitere: rând nou în capul mini-tabelului „Ultimele facturi emise" (flash roz, „Neplătită") + KPI „Venituri facturate" crește pe an/Q/lună/12 luni (daKpiBumpexpus din IIFE-ul KPI) + widgetul se golește. Regulă de produs (notată la cererea BGN): la click în câmpul de căutare a firmei, dropdown-ul arată ÎNTOTDEAUNA ultimele companii către care clientul a emis facturi — pe orice suprafață de emitere (Acasă, Facturi). - „Taxe și impozite de plată" (dark + glow roz): badge chip 14px, sentence case, fără dată de scadență (scadențele diferă → în detaliu) · suma 32px (= mărimea KPI), centrată vertical · buton alb „Vezi detalii →" (doar citire — plata directă e post-OpenBanking).
- „Încarcă un document" (v2, 31 iul — era „Încarcă bon, factură sau extras" pe bej): card ALB (border
--c-rule-input) cu dropzone roz pal dashed, copy „Încarcă un document" + „sau trage un document aici", un singur buton „Adaugă document ↑" — alb cu outline roz (hover: se umple roz). Fără butoane Foto/Fișier, fără hints, fără badge AI.
Cele 2 mini-tabele (side-by-side, NU toggle — vezi ambele fluxuri dintr-o privire)
- Ultimele facturi emise: Client (+descriere sub) · Sumă · Status (Plătită=verde / Neplătită=bej neutru — aliniat la limbajul Facturi v3, 22 iul; Încasată/Emisă/Restantă = istorie)
- Ultimele cheltuieli procesate (redenumit 15 iul — subliniază munca făcută de Bono): Furnizor (+descriere) · Sumă · Deductibilă (100/50/Nu)
- Ultimele 10 rânduri fiecare; coloane-esență: cine + cât + statusul care contează (Tip și Dată → în secțiune)
- Banda bej-1 la final (ca în DS): doar „Vezi toate →", aliniat dreapta (cifrele-sumar scoase 15 iul — tabelele arată strict „ultimele"; totalurile trăiesc în cifrele de sus și pe secțiuni). Filtrul de perioadă = STRICT pentru cele 3 carduri de cifre; tabelele nu-l urmează.
- Transparența deductibilității: badge-urile ≠100% au ⓘ + tooltip dark la hover cu motivul, pe vocea BONO („Mesele de protocol sunt deductibile limitat.") — poziționat în stânga badge-ului (nu se taie de marginile cardului). Educă fără să aglomereze.
Chat client↔BONO — mereu prezent în shell
- FAB dark „Întreabă Vox" + meta „răspundem în câteva minute", colț dreapta-jos (componenta
.vox-fabdin DS). (Evoluție consemnată 3.aug: identitatea Vox e expusă în buton pe toate paginile — copy-ul inițial „Întreabă-ne" a fost depășit.) - Canalul din spate (Vox / Intercom / WhatsApp) = detaliu de implementare; produsul = un canal de comunicare, mereu la un click.
Rail dreapta — full-height sticky, 40/60
- DE FĂCUT = 40% din înălțime (scroll intern discret) — itemi MVP: aprobă declarația, confirmă cheltuieli, încarcă extrasul (manual = MVP), răspunde ANAF, dividende surfacate contextual („poți distribui până la X"), documente lipsă la plăți. Actori atribuiți (Vox/Iris/Alina/Mihai).
- LIVE · din motorul Bono = restul (~60%), ticker rolling cu fade + hover-pause: „Rezolvat" (cu valoare cuantificată: „ți-a găsit 240 lei deduceri") + „Ce urmează" (liniștire).
Alinierea la MVP (diferențe față de sketch-ul DS)
- ❌ „Plătește" pe cardul dark → ✅ „Vezi detalii" (plata directă = post-OpenBanking)
- ❌ „Vox a sincronizat BCR" (=OpenBanking) → ✅ „Vox a procesat extrasul BCR încărcat"
- ❌ jargon („reconciliat", „balanța de verificare") → ✅ „a potrivit 14 plăți", „a închis luna martie"
- ❌ pastila L·D·B·S (cross-nav DS) → scoasă
Lecții de design capturate (pentru restul secțiunilor)
- Egalitatea percepută ≠ egalitatea geometrică — alb-pe-negru înflorește, alb-pe-bej se estompează. Butoanele identice pot părea inegale; se rezolvă prin greutate vizuală (fill/outline puternic), nu prin geometrie. Dovada rapidă: outline temporar pe cutii.
- Tooltip-urile în tabele se poziționează lateral (nu sus/jos) ca să nu fie tăiate de
overflow: hiddenal cardului.
Mobil — PARCAT (decizie: desktop-first)
Prototipul vechi mobil (dublin-home-mobile.html) = depășit, are banner. Prioritizarea mobil se reia după secțiunile desktop.
5b. Secțiunile — decision-log per pagină (toate cele 9 pagini; pornit 10 iul cu Cheltuieli & Facturi)
Sursa de adevăr vizuală = prototipurile
dublin-*.html(unul per pagină). Acesta e decision-log-ul.
Pattern-ul de secțiune (șablonul pentru toate drill-down-urile viitoare — actualizat 10 iul)
- Rail-ul dreapta pe TOATE paginile Dublin (DE FĂCUT sus + Live·motorul Bono jos, identic cu Acasă); conținut pe grila 1fr + 290px.
- Meniul colapsat pe secțiuni — deschis DOAR pe Acasă (v2, 15 iul): 84px, icon + eticheta tab-ului dedesubt (10px · 400w — 4 aug: era 9px/600; iconurile la stroke 1.25; și meniul DESCHIS de pe Acasă a trecut pe 400w — activ 500 — cu iconuri 1.25): Dashboard · Facturi · Cheltuieli · Extrase · De plată · Angajați · Contabilitate · Firma ta (+ PRD — din 3.aug, în locul „Plan"); activ = pill pink-tint; badge-urile pe colțul iconului; căutarea = buton-icon; jos: avatar + „Contul tău" + buton Logout (icon, tooltip „Ieși din cont" — adăugat și pe meniul deschis de pe Acasă). Uneltele de review = rotița ⚙ deasupra profilului. Notă naming de decis: colapsat zice „Dashboard", meniul deschis de pe Acasă zice „Acasă". IA cont & abonament (decizie BGN, 3 aug — analiza de implementare): meniul principal = FIRMA clientului; relația cu Bono (cont + abonament: profil, securitate, plan, metoda de plată, facturile de la Bono, anulare) trăiește sub AVATARUL din zona de jos („Contul tău") — nu ca tab; tab-ul „Plan" din prototip e provizoriu și dispare din navul produsului final. → Contul tău v1 ÎN PROTOTIP (3 aug, noaptea): pagina
/contconstruită — avatarul de pe TOATE paginile e acum link (hover: inel roz; pe pagină: inel roz permanent + label pink-deep = „ești aici"); fără rail (zona e „a ta", nu „a firmei"; conținut centrat 780px); secțiuni: Profil & securitate (nume/email/telefon + Parolă setată + Passkey·Face ID „Activ" — starea din PRD-ul Bono Auth + Sesiuni) · Firmele mele (Youngblood cu badge „Curentă" + „+ Adaugă altă firmă") · Plan & abonament (Bono Conta·Start, 299,00 lei/lună — PREȚ PLACEHOLDER, pricing-ul nu e decis; următoarea plată; Visa ··4412 + Schimbă cardul) · Facturile de la Bono (3 rânduri, Plătită, Descarcă) · Anulare jos, discret (link warn) → du-modal pe vocea Bono: „Chiar vrei să pleci?" cu „Vorbește cu noi întâi" (dark, primar) + „Continuă anularea" (link) → confirmare „Am primit cererea — un coleg te sună azi; arhiva contabilă e a ta și ți-o predăm întreagă." - Topbar firmă+LIVE, vox-fab — identice cu Acasă.
- Anatomie (actualizată 3.aug — versiunea reală a paginilor): h1 T40, fără subtitlu (aerisit; 34px + subtitlu = varianta din 10 iul, depășită) → CTA-ul principal în linia titlului → 3 KPI Card bej cu selectorul de perioadă în eticheta primului card (ancorate la cifrele de pe Acasă) → rând de filtre → tabel complet → bandă = doar paginare, la dreapta („‹ pagina 1 din 3 ›"; banda cu totaluri live = depășită, v4 22 iul).
- Filtre funcționale (client-side): dropdown-uri de tip/status (chips-urile cu count = varianta veche, depășită 10 iul) + calendar pe dată + căutare text 360px cu clear ×; perioada KPI trăiește în eticheta primului card. Zero rezultate → empty state cu „Șterge filtrele".
- Click pe rând → modal detaliu (pattern du-modal, read-only): rânduri-pill albe cu datele, strip-ul documentului original, atribuirea muncii BONO (Pilonul 3 dus în detaliu) + link „Întreabă-ne".
- Max 1 CTA roz per pagină: pe Cheltuieli = „Încarcă document" (în banda dropzone), pe Facturi = „Emite factura ↗" din quick-invoice bar (header; din 5.aug).
Cheltuieli — specific
- Bandă dropzone orizontală sub header (pink-ultra, chenar dashed): „Trage aici un bon, o factură sau un extras".
- KPI: Cheltuieli 2026 (148.670 = 142.880 deductibile + 5.790 nedeductibile) / Deductibile / Nedeductibile.
- Tabel: Furnizor (+descriere) · Dată · Tip (Bon/Factură) · Sumă · Deductibilă (badge 100/50/Nu + ⓘ tooltip cu motivul, poziționat stânga).
Chips + bandă de totaluri— fosile din 10 iul, înlocuite (filtre pe dropdown-uri; banda de jos = doar paginare — v. finisajele din 22 iul).- Modalul de detaliu: sumă/dată/tip + deductibilitatea cu motivul în clar + documentul original + „Procesată de Iris în N secunde".
Facturi — specific (v3, 22 iul: corecția de nevoie — pagina e ARHIVA facturilor emise)
- Titlul paginii = „Facturi emise" (22 iul, cerere BGN) — h1-ul spune exact ce conține arhiva; tab-ul din meniu rămâne scurt, „Facturi".
Nevoia reală (corecție owner, 22 iul): clientul vine aici ca să vadă facturile emise anterior — arhivă de consultare, nu dashboard de încasări. Verificarea plăților se face în internet banking; abia după OpenBanking (extrase zilnice) s-ar putea forma obiceiul în Dublin. Emiterea se face în modulul de Facturare — pagina are doar butonul care duce acolo (superseded 5.aug: emiterea rapidă trăiește ÎN Dublin — bara + modalul de mai jos; modulul de facturare rămâne motorul și destinația pentru cazurile ne-rapide: PF, firme străine, stornări). Analiza Bruce s-a oprit la pasul Nevoie: direcția de la owner a făcut research-ul inutil.
- Quick-invoice bar în locul CTA-ului (5.aug, idee BGN — „widget în care clientul să treacă pe cine facturează și suma, cam cum e în Dashboard, doar că pe orizontală"): butonul „Emite factură" e înlocuit de cardul „Emite o factură nouă" de pe Acasă, comprimat pe orizontală, în dreapta titlului — capsulă bej-1 pill (padding 6px, h 56) cu: câmp client alb pill 264px (placeholder „Caută după CUI sau numele firmei" — același text ca pe cardul din Acasă, corecție BGN 5.aug) → la focus/tastare, card „Clienți facturați recent" (label corectat de BGN din „Clienți recenți") construit din rândurile tabelului: bulină 26px cu primele 2 litere din PRIMUL cuvânt al firmei (CO, TE, BR…), 6 nuanțe tonale calde (roz-CTA/chihlimbar/salvie/albastru prăfuit/violet/verde-marin — pastel + text închis din aceeași familie, à la Notion/Linear) atribuite pe index la construirea listei (primii 6 garantat diferiți; hash-ul pe nume a fost încercat și retras — coliziona) · nume cu ellipsis · CUI în mist pe dreapta; max 5, filtrare fără diacritice, alegerea sare focusul pe Suma; card lățit 330–390px. Footer-ul cardului (decizie de plasare 5.aug — jos, nu deasupra label-ului: lista servește cazul de 90%, ruta de scăpare stă la subsol, pattern Stripe/Linear): link fog „Facturezi o persoană fizică sau o firmă din străinătate? ↗" → direct modulul de facturare; afordanță și fără hover (feedback BGN 5.aug „nu e evident că e link"): bandă bej-0 pe toată lățimea de jos a cardului (colțuri rotunjite 13px) + text subliniat cu decoration mist (pattern-ul linkurilor „Mai târziu"/„Cum funcționează?") — NU roz din prima (rozul rămâne al CTA-ului unic și al actorilor); hover roz-deep pe text și subliniere; afișat și când căutarea nu găsește nimic (cardul rămâne deschis doar cu footer-ul — exact momentul PF/firmă străină). Bug 5.aug (catch BGN): closer-ul global de meniuri (
document click → închide .per-menu) prindea și acest card imediat după deschiderea pe focus — click-ul care dădea focus bubla la document; cardul e acum exclus din closer (are ciclu propriu focus/blur) · câmp Sumă 230px (BGN 5.aug: să încapă lejer 12-13 caractere; placeholder „Suma"; tabular-nums, grupare cu puncte la blur, Enter = Emite) cu anatomia sumelor și în câmp (BGN 5.aug): la blur, un overlay.qi-fmtscrie suma formatată cu zecimalele 11px fog peste input-ul făcut transparent (un<input>nu poate stiliza substring-uri); la focus revine editarea simplă; „,00" se omite · selectorul de valută din Dashboard (steag + Lei/EUR/USD/GBP, pill bej-1 în câmp — corecție BGN 5.aug, hover bej-0) · CTA roz „Emite factura ↗" (label complet, ca pe Acasă — corecție BGN 5.aug) — inactiv (opacity .45) până sunt completate clientul și suma (rămâne singurul CTA roz al paginii).
Modalul „Emite factura" (5.aug, cerere BGN: „un modal cu un formular cu toate info din factura — vezi conținut și design în modulul de facturare"): research pe repo bono-ro/facturare-prd (PRD v2 + prototip responsive — sursa de adevăr): modulul e un wizard în 4 pași (Client → Sumă → Detalii → Revizuire), filozofia „emiterea se simte ca o plată prin Revolut" — fără linii de articole, fără TVA (MVP = neplătitori), single-line, numerotare automată ne-editabilă, scadență default 30 zile, valute RON/EUR/USD/GBP cu curs BNR editabil. Maparea în Dublin: bara din header E pașii 1–2 (client + sumă + valută), iar modalul = pașii 3–4 comprimați, pe du-modal (bej-1, radius 24, outline alb): eyebrow „● Factură nouă · YB-0144" (nr. auto, muted) · h2 „Factură către {client}" (Fraunces roz) · rânduri albe (v2, punch-list BGN 5.aug — fără subtitlu/lead; toate câmpurile editabile): Client — nume cu CUI dedesubt, ambele pe dreapta, ambele ink (bulina cu inițiale scoasă; „client nou" dacă nu e în arhivă) · Sumă editabilă în rând (17px/700 tabular; golirea dezactivează CTA) · la valută: formula stă ÎN câmpul Sumă (v6, BGN 6.aug — rând separat de curs; „am cerut un singur câmp pt sumă"): pe rândul cu label-ul „Sumă" — inputul editabil (345) urmat de „Euro × 4,89 = 1.687<small>,05</small> Lei" — multiplicatorul în fog 14/400, rezultatul 16/700 ink cu zecimalele 11px fog (anatomia sumelor) și „Lei" în mist; badge-ul de valută din câmp dispare (e redundant — valuta e în formulă); se recalculează live la tastare (demo: EUR 4,89 / USD 4,55 / GBP 5,80) · Data emiterii = badge-dropdown cu mini-calendarul DS („azi ·" scos; aprilie 2026; v3, BGN 6.aug: selectabile DOAR azi + max. 5 zile lucrătoare în urmă (17–24.apr; 1–16 și viitorul blocate — backdatarea peste fereastră = risc amendă ANAF), iar sub calendar linkul de asumare „Vrei o dată cu mai mult de 5 zile în trecut? Apasă aici →" — în modul deschide dialogul de asumare a riscului; schimbarea datei recalculează scadența păstrând termenul și data cursului BNR) · Scadența = badge-dropdown cu zilele, așezat LÂNGĂ label (v3, BGN 6.aug — nu înainte de dată; data calculată rămâne valoarea rândului, pe dreapta; meniul se deschide pe stânga): default 10 zile, listă în ordinea BGN 10 · 30 · 20 · 15 · 5 zile · Cont încasare (mutat DUPĂ scadență) = badge-dropdown cu selecție MULTIPLĂ (checkbox-uri roz; min. 1 bifat; badge cu primele 4+4 caractere — „RO49 BTRL … 8021 · BT" (v3, BGN 6.aug), „+1" la mai multe; demo: BT Lei default / BCR Lei / UniCredit EUR) cu „+ Adaugă un IBAN nou" ca footer al listei (hairline deasupra); v4 (BGN 6.aug): conturile multiple se afișează UNUL SUB CELĂLALT în badge (pill-ul crește pe verticală, câte un rând per cont — „+N" retras) · Descriere = lfield (label roz caps ÎN câmp — pattern-ul modulului) default „Servicii conform contract", un singur rând (chips-urile cu sugestii din istoric scoase — v4, BGN 6.aug) · Mențiuni · opțional (un rând) · footer: „Renunță" (link) + CTA „Emite factura". Lățimea modalului (istoric 6.aug): 560 → −20% = 448 (cerere BGN, aplicată în sesiunea paralelă) → +10% = 493px (cerere BGN, ambele pagini — emitere și succes). Selectorul de scadență (BGN 6.aug): outline --c-rule-input 18% pe transparent, fără fundal bej-1 (celelalte badge-uri — dată, IBAN — rămân bej-1). Titlul modalului (v4, BGN 6.aug): centrat VERTICAL între eyebrow și formular — măsurat pe glife (cutia h2 are aer deasupra): eb margin 0 + h2 margin 16/16 → 21,3px deasupra capitalelor / 21,4px sub baseline; cu chips-urile scoase și câmpurile pe un rând, modalul încape fără scroll. La emitere: starea de succes în modal (check verde, „Factura a fost emisă cu succes"; v2, BGN 6.aug: recapul — Factura · Client · Sumă · Data emiterii (v3, BGN 6.aug — Scadența) · + Descriere — stă într-un SINGUR card alb cu rânduri despărțite de hairline (nu carduri separate); cardul e-Factura cu countdown ANAF scos; share-ul cu iconuri SVG: ochi „Vezi PDF-ul" · plic „Trimite pe email" · glyph „WhatsApp" — centrate, colorate (roz-deep / chihlimbar / verde-success), v3 BGN 7.aug: font 14,5px + iconuri 18px (la 12,5/16 erau prea discrete); butonul „Gata" scos — închide X-ul din dreapta sus) și, REAL în pagină: rândul nou intră în capul arhivei (flash roz 2,4s, „{descriere} · emisă acum o clipă", bulina e-Factura pending care pulsează, kebab funcțional — rebind pe clonă) + KPI-urile cresc (Emise și Neîncasate pe 2026/Q2/apr/12 luni; valutele se convertesc în lei la cursul demo) + bara se golește. SERIA ȘI NUMĂRUL (decizie BGN, 6.aug): vin din mini-serviciul de SERII al modulului de facturare. Modulith-ul de facturare își ține registrul de serii per firmă și e singurul scriitor al numerotării (regulă legală: unică și secvențială per serie) — la emiterea din Dublin, bara+modalul apelează modulul și cer seria+numărul; Dublin nu generează niciodată numere local. Notă de implementare: alocarea = atomică la commit (click pe „Emite factura"), nu la deschiderea modalului — modalele abandonate nu ard numere din serie; eyebrow-ul „Factură nouă · YB-0144" = preview informativ al următorului număr, cel real vine în răspunsul serviciului. Numerotarea demo YB-0144, 0145… și formatul modulului NE-47/26 se unifică la legarea reală (formatul = al modulului). Emiterea rămâne deci a modulith-ului (Dublin = client al API-ului lui — pașii 1–2 în bară, 3–4 în modal); cazurile ne-rapide (PF, firme străine, stornări) pleacă în continuare în modul, cu clientul și suma precompletate. Fișier-sursă research: facturare-prd/visual-design-responsive/index.html + PRD_Modul_Facturare_MVP.md. Sub ~1500px bara se înfășoară sub titlu (flex-wrap). Borduri: câmpuri albe pe bej-1 = --c-rule-card 12%, conform regulii. CTA simplu „Emite factură" · modalul „Către cine emitem factura?" — ambele istorie.
- Tabel-arhivă, 8 coloane (spec BGN 22 iul): Seria · nr (mono 12px fog — standardul din 22 iul; 11px = istorie) · Emisă · Client (nume; CUI pe tooltip dark la hover + căutabil prin
data-cui— v. standardele de tabel) · Descriere (fog, ellipsis + tooltip) · Sumă (DOAR cifra — fără „lei/€", v2 22 iul: valuta are coloana ei imediat după; în modalul de detaliu suma își recapătă valuta, acolo nu există coloană separată) · Valută (steag 14×10.5 + Lei/Euro) · Status (doar Plătită tonal success / Neplătită bej+fog — neutru, nu alarmă) · e-FACTURA (label corectat de 2× pe 22 iul: „SPV" → „eFactura" → „e-FACTURA" — e mic + cratimă, singurul cap de tabel fără text-transform uppercase; bulină doar-icon 21px: check pe success tint = „Trimisă în e-Factura (SPV) în ziua emiterii" pe tooltip; dot AI pulsând = se trimite chiar acum). Coloana Descriere: 210px pe ecrane ≥1420px, 96px sub (tabelul trebuie să încapă la 1280 fără scroll orizontal). - Selector de perioadă ÎN eticheta primului KPI (22 iul, idee BGN): pe Facturi și Cheltuieli, perioada KPI-urilor nu e un dropdown separat sus-dreapta (ar fi concurat cu CTA-ul roz „Emite factură") — anul din prima etichetă e chiar selectorul, aliniat la DREAPTA pe rândul etichetei (v2, 22 iul: „● FACTURATE … 🗓 2026 ⌄" — trigger-ul la capătul drept al rândului, fără „·"; font 12px ca eticheta — varianta +2px a fost încercată și retrasă de BGN în aceeași zi; meniul se deschide sub trigger, aliniat pe dreapta lui, cu specificitate
.kper-wrap .kper-menuca să bată.per-menu{left:0}) — cu icon de calendar 11px înaintea anului (feedback BGN: trigger-ul trebuie să se lege evident de dată/perioadă; e același calendar ca pe filtrul „Oricând") + chevron 9px, hover ink, fără outline de browser pe focus. Fix z-index: hover-transformul cardului crea stacking context și prindea meniul sub rândul de filtre →.da-kpi:hover, .da-kpi:focus-within { z-index: 30 }. Dropdown pe pattern-ul per-menu, ancorat de trigger (corectat 22 iul — inițial era ancorat de card și părea decuplat): wrap poziționat pe buton, meniul se deschide fix sub „🗓 2026 ⌄", aliniat pe dreapta trigger-ului (right 0, gap 8px — trigger-ul e la capătul drept al rândului). Opțiunile în formate compacte (v3, 22 iul — cerere BGN): 2026 · 2025 · Q2-26 · Q1-26 · 12 luni · apr.26 · mar.26 (YYYY / Qn-YY / „12 luni" / mmm.yy); eticheta selectată = același format (meniu 128px) și toate cele 3 valori (+ numărul de facturi) se schimbă — cifrele pe T1/T2/lună sunt reconciliate cu tabelul (T1: neplătite 8.900 = StartUp+Pixel; 2025: Neplătite „0 lei · toate plătite"). Perioada afectează DOAR cardurile, nu tabelul (care are calendarul lui). Pe Acasă rămâne dropdown-ul de sus-dreapta (acolo nu concurează cu nimic). - KPI pe Card bej = REGULĂ pe secțiuni; pe Dashboard = ALB (amendată 31 iul): pe paginile de secțiune (Facturi, Cheltuieli…) cardurile KPI sunt Card bej (bej-1 cald, fără border). Pe Acasă/Dashboard KPI-urile sunt ALBE (border
--c-rule-input18%) — acolo rândul 2 e din carduri de acțiune bej, iar albul diferențiază cifrele de acțiuni; pe secțiuni e invers (tabelele-s albe, KPI bej). Principiul real: KPI-urile contrastează cu vecinii lor. Regulă pentru TOATE paginile viitoare (De plată, Angajați, Contabilitate, Firma ta…): KPI = card bej slim — etichetă T12 cu dot colorat + cifra mare cu unit mic, fără rând sub cifră; contextul scurt („n facturi") stă inline, aliniat dreapta pe baseline-ul cifrei, 13px fog. Albul rămâne al datelor (tabele) și al controalelor (inputuri, dropdown-carduri). - FĂRĂ umbre statice — site plat (5.aug, regulă BGN „nu vreau umbre în site"): auditul a găsit umbre reale doar pe plutitoare — dropdown-urile (perioadă/calendar/kebab/valută/clienți,
0 10px 28px), tooltip-urile dark (0 8px 24px), tooltip-ul mono de CUI și „hârtia" decorativă din cardul de procesare (Cheltuieli). Toate scoase, pe toate cele 9 pagini (inclusiv /cont). Compensarea flat: dropdown-urile plutitoare trec pe border--c-rule-input18% (era 12% + umbră); tooltip-urile dark se separă singure prin contrast; „hârtia" primește border 12%. Rămân (nu sunt umbre): ringurile fără blur0 0 0 Npx— focusul roz, inelele de avatar, pulsul bulinelor live, inset-borders — și adâncimea de hover (--sh-pinkpe lift-ul CTA-urilor, hover-lifts), singura exceptată explicit de BGN. Regula e și în skill (secțiunea Shadows rescrisă). - Aliniamente în tabel (22 iul): bulina e-FACTURA centrată în coloană (header + celule,
text-align: center); kebab-ul ⋮ împins spre marginea dreaptă a tabelului (padding-right 10px pe act-col). Amendament BGN 5.aug: celulele coloanelor Client și Descriere = STÂNGA (text lung, se citește de la stânga) — labels din cap rămân centrate (tbody td:nth-child(3/4), thead neatins). - Kebab de acțiuni pe rând (22 iul, cerere BGN): coloană finală cu ⋮ (26px, fog → cerc ink 8% pe hover) care deschide un meniu pe pattern-ul dropdown existent, aliniat dreapta: Vezi factura · Descarcă PDF · Trimite · ─ · Stornează (ordinea = frecvență; Stornează ultimul, după separator — e acțiunea delicată, cu tooltip „o anulează legal"; cerute de BGN ca „View/Share", traduse per regula copy-ului RO). „Vezi factura" deschide modalul de detaliu; restul inerte în prototip. Meniul rândurilor de jos se deschide în sus (< 240px până la marginea ferestrei). Click-ul pe ⋮ nu declanșează click-ul de rând (stopPropagation); guard
.act-colîn uneltele de review (overlay v9). Compensare lățime la 1280: paddings 10px + descriere 96px pe ecrane mici. - Acasă aliniat la limbajul v3 (22 iul): mini-tabelul „Ultimele facturi emise" folosește Plătită/Neplătită (Restantă a dispărut și de acolo — fostele restante = Neplătită pe bej neutru), iar BrightWorks apare în € (3.750), ca pe Facturi.
- Dispar: coloana Scadență · statusurile Încasată/Emisă/Restantă · nota „depășită cu N zile" · statusul „Se trimite" din coloana Status (devine starea pending a bulinei SPV).
- Filtre: Status (Toate/Plătite/Neplătite) · calendar pe data emiterii (zi/interval) · Valută (Toate valutele/Lei/Euro) · căutare „Caută după nume sau CUI firmă sau sumă…".
- KPI (v3.1, 22 iul — regulă globală: cardurile KPI slim pe TOATE paginile, ca pe Dashboard: fără rândul de sub cifră):
Facturate/Plătite/Neplătite(v3.2, redenumite de BGN): „Emise · 🗓 2026" / „Încasate" / „Neîncasate" — la nivel de KPI facturile vorbesc limba banilor care INTRĂ (încasat), în timp ce statusurile din tabel rămân Plătită/Neplătită (starea facturii); (v3.3) materiale ca pe De plată: Emise = ALB (border 18%) · Încasate = DARK cu glow roz · Neîncasate = bej-1 — pe Facturi eroul dark e banul intrat (dovada), pe De plată e datoria curentă; numărul de facturi („42 de facturi" / „36 de facturi" / „6 facturi") stă în linie cu suma, aliniat la dreapta, 13px fog pe baseline (un punct peste delta de 12px care a dispărut). Pe Cheltuieli rândurile delta au fost scoase de tot — inclusiv „≈ 22.860 lei economisiți la taxe" (⚠ superseded: scos la slim-ificarea KPI; decizia de audit #9 = linia de economii există DOAR pe regim de PROFIT — demo-ul Youngblood (micro) rămâne fără ea) (⚠️ informația-wow rămâne de replasat, poate inline ca la Facturi sau în insight). Tabelul ține feb–apr, restul în arhivă; KPI-urile acoperă tot anul. Footer cu totaluri + text arhivă→ Banda de jos = DOAR paginare, la DREAPTA (v4, 22 iul; „centrată" din prima formulare = greșit — ambele pagini o aliniază flex-end): „‹ pagina 1 din 3 ›" (10 facturi/pagină, pattern-ul chevrons-cerc de la neprocesate; capete disabled; schimbarea oricărui filtru resetează pagina — detectat prin hash pe flState). Meta-ul cu totaluri și „restul anului e în arhivă" au fost scoase.- Modal detaliu: fără Scadență, + rând „CUI client"; note: Plătită „Plata a fost potrivită cu extrasul tău de cont. Nimic de făcut." / Neplătită „Când plata apare în extrasul tău de cont, o marcăm plătită automat." / SPV-pending „O trimitem chiar acum în e-Factura (SPV)…"; linia de jos dinamică („Trimisă în e-Factura de Bono în ziua emiterii" ↔ „Bono o trimite chiar acum").
- Demo: 2 facturi în EUR (BrightWorks GmbH · DE812470335, Baker & Co · IE6388047V) pentru cazul multi-valută; badge-ul Facturi din sidebar = 6 (neplătitele).
- Istoric v2 (10 iul): aliniere la tratamentul Cheltuieli — fără subtitlu, dropdown-uri + calendar, „Se trimite" AI pe factura proaspătă, KPI reconciliate. Depășit de v3 acolo unde se contrazic.
Firma ta — pagină nouă (v1, 23 iul, analiza light + input Vertigo/Cristi)
Jobul paginii: referința firmei — „banca/instituția mi-a cerut ceva" + „dă-mi repede CUI-ul/IBAN-ul". Live la /firma. Analiza: draft de componente Claude → feedback BGN → cross-check cu analiza Vertigo a lui Cristi (minutele 12 iun + 13 iul, Drive/folder Vertigo: pagina companiei = nucleul Vertigo; paritate explicită Cont Vertigo ↔ Dublin; istoric per-atribut în modelul de date: valoare + interval de valabilitate; stare = ANAF + ONRC; VIES ca atribut care „se obține"; schimbări majore doar cu document justificativ). Research extern: skip — nevoia limpede din §3 #6.
- Fără CTA roz (decizie BGN) — singura pagină fără; acțiunile sunt cereri discrete către contabil.
- 4 carduri albe (albul = date; eyebrow T12 cu dot colorat): (1) Datele firmei — Denumire/CUI/Nr.Reg.Com./Sediu/Administrator/Capital/Înființată/Stare (badge „Activă" cu tooltip „Activă la ONRC · Cod TVA valid la ANAF · verificată zilnic de Bono"); valori cu copy (icon → check verde 1,4s) și istoric (icon ⏱, pe hover). (2) Vector fiscal — pe limba ta: TVA „Plătitor · trimestrial (D300 până pe 25)" / Impozit „Micro · 1%" / TVA la încasare / Angajator „Da · D112 lunar" / Cod VIES „Nu ai — îți trebuie doar dacă lucrezi cu firme din UE" + acțiune „Cere codul"; footer „● Sincronizat cu ANAF de Bono · azi 06:00". (3) Administrator & asociați (nume ales ca să nu se bată cu tabul Angajați): avatar + nume + rol/procent (Eduard 90% administrator, Ana 10%). (4) Conturi bancare — sursa canonică a IBAN-urilor (Extrase doar le folosește; acțiunea de adăugare există în ambele locuri, datele au un singur stăpân): steag + bancă·valută + IBAN mono + copy; „+ Adaugă IBAN" → același du-modal ca pe Extrase.
- Istoricul oricărui atribut în modal (cerere BGN): ⏱ pe rând → du-modal „Istoric · [atribut]" cu lista „valoare · din — până" (demo: sediu 2 intrări, TVA neplătitor→plătitor, impozit 3%→1%); atributele fără istoric → o intrare „din 12.feb.23 · înființare". Nota modalului: „Modificările se fac prin Bono — mereu cu act justificativ" (aliniat cu mecanismul lui Cristi din Vertigo). Clientul nu editează nimic direct.
- Documentele firmei — tabel GRUPAT pe dosare (v1.2, 23 iul, propunere BGN + completări Claude): grupele — benzi bej T12 în tabel, în ordinea frecvenței de cerere: Documentele firmei · ONRC (CUI, act constitutiv, constatator, certificat de mențiuni — schimbarea sediului, specimen) · Acte fiscale · ANAF (certificat TVA + recipisă vector — grupă adăugată de Claude: certificatul de TVA n-avea loc în cele 4 propuse) · Decizii AGA (dividende, repartizare profit, schimbarea sediului) · Acte administrative (comodat, împuternicire contabil) · Dosarul de înființare (cerere ONRC + declarația beneficiarului real — documentul pe care nimeni nu-l găsește când îl cere banca). 14 documente; coloana Categorie a dispărut (grupele o înlocuiesc); filtrul devine „Toate grupele" (ascunde și benzile grupelor fără rezultate — la căutare rămân doar benzile cu potriviri); mențiunile ONRC ulterioare stau în grupa ONRC și rimează cu istoricul atributelor (certificatul de mențiuni 03.iun.2025 = schimbarea sediului din modal). Coloane: Document / Data / Sursă (ONRC, ANAF, Bono stilizat ca actor — documentele generate de motor intră singure) / kebab ⋮ (Vezi · Descarcă PDF · Trimite). Wow-ul practic: certificatul constatator — nota warn „emis acum 4 luni — băncile îl cer de max. 30 de zile" + „Cere unul proaspăt" (→ „✓ Cerere trimisă — îl primești azi"). Footer: „14 documente · toate la zi" + „Cere un document →" (du-modal cu input → „✓ Am trimis cererea contabilului tău — de obicei răspunde în aceeași zi.").
- v1.3 (4 aug, cerere BGN) — grupele = ACORDEON, colapsate implicit: thead-ul a dispărut; labels „Data" și „Sursă" stau pe banda fiecărei grupe, aliniate pe coloanele lor (banda are aceeași structură de celule ca rândurile, nu colspan); banda = pill (colțurile rotunjite ale pattern-ului inset au trecut de pe thead pe benzi) cu chevron (dreapta = închis, jos = deschis, rotire 160ms) + nume + contor de documente (mist) — click pe bandă = toggle. Banda ONRC poartă un punct WARN cât timp constatatorul e expirat (altfel alerta ar fi invizibilă la colapsare; dispare când grupa e deschisă, nota warn preia). Comportamente: căutarea auto-expandează doar grupele cu potriviri (restul benzilor dispar); filtrul pe o grupă o auto-deschide; goliți filtrele → totul revine colapsat; contorul din footer numără potrivirile, nu rândurile afișate (colapsat ≠ „Nimic de arătat").
- v1.4 (4 aug, feedback BGN): labels „Data"/„Sursă" apar doar pe grupele deschise — ascunse prin
visibilitype un span interior (pe celulă ar găuri fundalul benzii; pedisplayar sări lățimile coloanelor la expand) — și sunt centrate pe coloanele lor (regula generală „benzile la stânga" din pattern-ul de aliniere le lăsa pe stânga; override pe.gh-l). Acțiunile pe rând = 4 iconuri vizibile în ultima coloană — Vezi (ochi) · Descarcă PDF (săgeată în cerc, v1.5) · Trimite pe email (plic) · Trimite pe WhatsApp (glyph outline) — au înlocuit kebab-ul ⋮ pe această pagină (v1.5: 16px în buline de 30px, coloană min. 160px, grupul centrat sub labelul „ACȚIUNI" de pe bandă; fog → cerc ink 8% pe hover, tooltips; inerte în prototip). - v1.5 (4 aug, feedback BGN) — centrarea verticală a benzilor + coloana Acțiuni: benzile au acum înălțime fixă 42px cu
vertical-align: middle. Cauza necentrării (aceeași care umflase și vechiul thead): tabelul arevertical-align: topglobal (necesar rândurilor cu note pe 2 linii), iar celulele de Dată/Sursă aupadding-top: 14pxca să se alinieze cu prima linie a numelui — pe benzi, celulele-label moșteneau acel padding, înălțau rândul, iar textul benzii rămânea lipit sus; fix: pe.fd-ghpadding vertical 0 + middle. Banda a primit și a 4-a etichetă, „ACȚIUNI", centrată pe coloana iconurilor. - v1.6 (4 aug, feedback BGN) — rândul de deasupra tabelului restructurat: dropdown-ul „Toate grupele" a DISPĂRUT (redundant — benzile-acordeon SUNT navigarea pe grupe), căutarea a trecut pe stânga în locul lui, iar pe dreapta stă butonul „Cere un document →" — fost link în footer (footerul păstrează doar contorul). Stilul butonului (întrebare BGN „outline roz sau bej-1?", propunere Claude acceptată): alb cu border
--c-rule-input(ink 18%), text ink, hover → border+text roz — bej-1 s-ar fi confundat cu benzile de grupă, iar outline-roz reintroducea rozul pe singura pagină fără (decizie BGN); pattern-ul e cel al butonului „Încarcă-le" din alerta Cheltuieli. Iconurile de acțiuni: 18px în buline de 34px (v3 a mărimii), coloana min. 172px; centrarea label↔iconuri reparată prin paddings orizontale IDENTICE pe celula-label și celula iconurilor (22 vs 14 dădea offset). Aer între coloane (4 aug): Data și Sursă au paddings orizontale de 30px (aplicate identic pe bandă și pe date — regula centrarii), rezultând ~70px aer Data↔Sursă și ~50px Sursă↔Acțiuni. - v1.9 (4 aug, întrebare BGN „cum editezi un IBAN?") — modelul de editare a conturilor: un IBAN nu se „editează" — un număr diferit e ALT cont. Două stări: (1) în verificare (abia adăugat / greșit la tastare) → corectare liberă: creion pe hover pe rând (lângă copy) → același du-modal comută pe „Corectează IBAN-ul" (pre-completat, lead „Rescrie-l cum trebuie — îl verificăm din nou", buton „Salvează corectura") → rândul se actualizează pe loc (IBAN + copy) și primește badge AI „SE VERIFICĂ"; „+ Adaugă IBAN" refolosește același modal în modul add (titlu/câmp/buton resetate). (2) verificat/în uz → numărul NU se mai editează (are extrase legate); acțiunile corecte devin Redenumește (alias, ex. „contul de salarii") și Arhivează („nu-l mai folosesc" — istoricul rămâne legat), iar un cont nou = Adaugă + arhivezi vechiul. Starea (2) e definită dar neconstruită — de confirmat modelul cu BGN.
- v2.1 (4 aug, întrebare BGN „cum verificăm un cont?") — VALIDAREA INSTANT + gate-ul pe extrase. MODELUL ÎN DOUĂ TREPTE (formularea canonică, BGN): (1) verificare TEHNICĂ la introducere (MOD-97 + banca detectată, live, blocant) · (2) confirmare PRACTICĂ la primul extras încărcat (apartenența la firmă; tot ea îngheață numărul). Orice copy/discuție viitoare folosește acești doi termeni. un IBAN SE POATE verifica la introducere, matematic: cifrele de control MOD-97 (ISO 7064) pică la aproape orice typo, iar banca derivă din caracterele 5–8 (BTRL→BT, INGB→ING, RNCB→BCR… — nomenclator în JS, extensibil). Modalul validează live, la fiecare tastă: <24 caractere → hint fog cu contor „n/24" · valid → „✓ IBAN valid · BT" (success; bancă necunoscută → „îl verificăm noi") · invalid → warn „Nu arată a IBAN valid — verifică cifrele (cel mai des: una lipsă sau două inversate)"; butonul de salvare e blocat până e valid. Copy-ul vechi „îl verificăm și apare în câteva minute" A MURIT — contul apare INSTANT în listă (cu banca detectată + valuta aleasă dintr-un toggle Lei/Euro în modal, steag corespunzător), iar „+ Adaugă IBAN" rămâne pe loc (poți adăuga mai multe). Ce nu se poate ști instant: apartenența la firmă → badge „de confirmat" (tooltip: „îl confirmăm ca fiind al firmei când încarci primul extras din el"). Gate-ul de editare (regula BGN, corectată în aceeași zi): editabil = FĂRĂ extrase atașate (
data-ext), nu statusul de verificare — primul extras încărcat face două lucruri deodată: confirmă apartenența și îngheață numărul. Modalul blocat: „Contul e în uz — are extrase legate de el… dacă e o greșeală veche, spune-ne." - v2.0 (4 aug, decizie BGN „arhivarea în modalul de edit") — ARHIVAREA, construită: creionul deschide „administrarea contului", iar modalul se adaptează stării: cont VERIFICAT → h2 „Contul e verificat", IBAN-ul afișat dar blocat (input disabled pe bej-1), fără buton de salvare, lead onest („nu se mai modifică — are extrase legate de el; un număr nou = cont nou"); cont „se verifică" → corectura rămâne editabilă. În ambele, jos, sub separator: „Nu-l mai folosești? Arhivează contul" (text warn, hover warn-tint) cu dublă confirmare in-place („Sigur? Extrasele rămân — apasă iar", buton armat pe warn-bg). După arhivare rândul devine slim: IBAN mono mist + tag „ARHIVAT" + „Anulează" (undo — nodul original e păstrat cu tot cu listeneri și se restaurează la click). Modul „add" ascunde zona de arhivare. De construit când apare nevoia: lista conturilor arhivate persistentă + „Reactivează" (acum undo-ul e de sesiune).
- v1.8 (4 aug, feedback BGN): banda de sub tabelul documentelor a dispărut de tot (contorul „14 documente…" — inutil; empty-state-ul de pe căutare rămâne singurul feedback). Rândurile IBAN reordonate: steag-valută · IBAN · valută · bancă (+ copy la capăt) — IBAN-ul devine informația primară (mono ink, flex, tooltip cu valoarea completă), valuta fog, banca ink 500, aliniate în coloană pe dreapta. Notă infra: proiectul s-a mutat la
Proiecte IT/Bono/Dublin/; launch.json recreat acolo (server prinbash -ccucdexplicit — vechiul cwd mort dădea PermissionError), oglinda~/dublin-preview= conținutulprototype/la rădăcină. - v1.7 (4 aug, feedback BGN) — linia verticală comună a paginii: titlul „Firma ta", titlurile de secțiune („Documentele firmei"), bulina din eyebrow-ul cardurilor, textul benzilor de grupă, numele documentelor și câmpul de căutare încep toate la același x (offset 22px față de marginea cardurilor: h1 margin-left 22 · .tbl-h padding-left 36→22 · fi-card padding orizontal 21+1 border · inset-card padding 7 + celulă 14 + 1 border; filtrele și footerul cardului-tabel ajustate la fel). Verificat la pixel: toate 6 reperele la același x.
- Ce NU e aici: editare date · plafoane operaționale (parcate pentru Contabilitate — ideea lui Cristi „cât mai ai până la plafonul TVA/micro") · mijloace fixe · puncte de lucru (modul condițional, post-MVP) · setări contabile (Vertigo).
- Schelet: shell colapsat + rail; ruta
/firmaîn vercel.json (destinația FĂRĂ.html— cleanUrls; cu extensie dă 404); nav „Firma ta" legat pe toate paginile. - v1.1 (23 iul, feedback BGN): cardul „Administrator & asociați" a dispărut — Asociații sunt rând în Datele firmei („Eduard Ionescu · 90% | Ana Ionescu · 10%", cu istoric); dreapta = coloană Vector fiscal (scurt) + Conturi bancare, cu flex pe Conturi ca bazele celor două coloane să se alinieze cu Datele firmei; „Sincronizat cu ANAF · azi 06:00" urcat în linia titlului VECTOR FISCAL, aliniat dreapta (10.5px, dot succes, fără uppercase). Datele pe această pagină =
dd.mmm.yyyy(„12.feb.2023" — cerut la Înființată, aplicat pe toată pagina pentru consistența istoricelor; pagina e de referință legală, anii întregi se citesc corect; restul Dublin rămâne pedd.mmm.yyoperațional, inclusiv rail-ul).
Extrase de cont — pagină nouă (v1, 15 iul, cerere BGN)
Jobul paginii: evidența extraselor — ce e încărcat, ce lipsește, pe conturi și pe luni. Tab nou în meniu (după Cheltuieli), live la /extrase.
- Matrice cu conturile pe COLOANE, lunile pe rânduri (v1.3, feedback BGN 15 iul): lunile descrescător, cu anul („Martie 2026" sus — ultima lună ÎNCHEIATĂ, aprilie e în curs); antete „BT [steag] Lei" cu IBAN-ul complet vizibil dedesubt (mono 9.5px mist — nu doar la hover; pe strip-ul de conturi IBAN-ul rămâne la hover). Celula „încărcat" =
data + downloadtext + icon(v1.6, 15 iul): badge-uri TONALE doar-ICON, gemene (48×28, icon 17px): document-cu-săgeată-jos pe success tint (descarcă) / document-cu-săgeată-sus pe warn tint (încarcă) — iconografia calificata.ro. Fără text, fără dată în badge; totul în tooltip („Descarcă extrasul — încărcat la 02.apr.26" / „Încarcă extrasul").
Adaptare la numărul de conturi (v1.6): 1 IBAN → coloana centrată, card compact (~620px), FĂRĂ dots de paginare (apar de la 2+); >3 conturi → IBAN-ul din antet se scurtează: „RO12BT…7845" (primele 6 + ultimele 4; complet pe tooltip, copy copiază tot); banda (corectat 15 iul): „+ Adaugă IBAN" în STÂNGA · trio-ul de perioade centrat · dots+total dreapta. Toggle-ul de simulare are acum 1 / 3 / 6 IBAN (6 conturi demo: BT Lei, BT Euro, ING Lei, BCR Lei, Revolut Euro, RZB Lei — încap lejer). Fără starea „Se procesează" — decizie BGN: extrasele nu sunt percepute ca cheltuielile (nu scad baza de impozitare), procesarea nu merită semnalizată; după upload celula devine direct badge cu data de azi. Matricea începe cu ultima lună ÎNCHEIATĂ (nu există starea „din 1 mai" — luna curentă nu apare). Longevitate (15 iul, simulare 26 de luni — decizie BGN): 6 luni/pagină, cu trio de badge-uri de perioadă în banda de jos: în mijloc badge-ul ACTIV (alb, border ink, perioada bold „apr.24 – sep.24"), în stânga perioada mai NOUĂ și în dreapta cea mai VECHE — ușor faded (fundal alb 55%, text fog), clickabile; la capete, vecinul inexistent dispare. Banda: „+ Adaugă IBAN" (stânga) · trio (centru) · dots de progres + „26 luni" (dreapta). Cu 6 rânduri, banda e mereu vizibilă fără scroll. Senzația de paginare/scroll (3 semnale, 15 iul): chevrons ‹ › pe badge-urile vecine (direcția) · dots de progres (câte perioade + unde ești) · micro-animație de slide pe rânduri la schimbare (conținutul alunecă în direcția timpului, 200ms). Badge-ul activ = pattern-ul .da-tabs din DS (pill alb pe bandă bej, text ink, weight 600 — fără border ink, fără bold; corectat 15 iul).
Cazul 1 IBAN (simulare cu toggle provizoriu „1 IBAN / 3 IBAN" lângă titlu): cu un singur cont, tabelul se strânge (max-width 620px, cardul centrat pe pagină — fix 3.aug) și citește ca o listă compactă Luna → stare, nu ca o matrice cu o coloană-balenă. Capul, banda și paginarea se adaptează automat (thead generat dinamic). Explainer-ul = ⓘ lângă antetul „Luna" (tooltip dark). Observație-cheie: cu lunile descrescător, tot ce contează (lipsuri, luna proaspătă) e pe primul rând — jos rămâne doar navigarea de arhivă. Stări rămase: descarcă (tonal success) · Lipsește (tonal warn → picker real) · „din feb.26" (n/a — copy scurtat 15 iul „deschis în"→„din"; liniuța „—" scoasă 31 iul). Demo-ul are lipsuri presărate în istoric (2-5 pe mod, pe pagini diferite) ca să reflecte realitatea; la schimbarea modului de simulare, paginarea revine la prima pagină.
Cifrestrip de conturi(v1.4, 15 iul): pagina = titlu + CTA + matricea, atât. Strip-ul de conturi scos (redundant cu IBAN-urile din antete). IBAN-urile din antet au buton de copiere (icon copy → verde 1,4s la click). Așezarea celor două acțiuni (v2 — „+"-ul din antet crea o coloană goală în tabel): „Încarcă extras" = CTA-ul roz din header (acțiunea principală); „+ Adaugă cont / IBAN" = link discret în banda de jos a tabelului (dreapta explainer-ului) → du-modal-ul de IBAN; după trimitere linkul devine „Cont nou — îl verificăm și apare aici".
Tipografie aliniată la scala DS (15 iul, audit BGN pe pagina de tipografie): titlurile de pagină internă = T40 (clamp 28→40, −0.03em — nu 34px custom) pe Cheltuieli/Facturi/Extrase; capetele de tabel + labelurile KPI + mini-etichetele tabelelor de pe Acasă = T12 (12px/600/+0.10em — erau 11px/500); steagurile din antete ținute SUB eticheta de 12px (14×10.5px). Scala tipografică completă documentată în skill-ul edge-33 (secțiune nouă „Tipografie — scala completă": 3 fonturi + roluri, T60–T12, cifre financiare, speciale, anti-greșeli).
- Explainer-ul pe vocea BONO („Extrasul unei luni se încarcă la începutul lunii următoare — din el potrivim plățile cu facturile și închidem luna.") trăiește în ⓘ de lângă antetul „Luna" (tooltip dark) — banda de jos e a acțiunilor + paginării (v. mai sus).
- CTA roz „Încarcă extras" (unicul roz al paginii). Shell standard (meniu colapsat + rail).
- Rămas de validat: 3 conturi tipice (restul presupunerilor v1 s-au închis: fereastra = 6 luni/pagină; adăugarea contului = du-modal pe loc, sursa canonică în Firma ta).
De plată — Nevoie validată (22 iul 2026)
Jobul paginii: „Cât am de plătit, până când — și dă-mi tot ce-mi trebuie ca să plătesc în 30 de secunde." Citire în MVP (plata directă = post-OpenBanking); intrarea principală = cardul dark „Taxe și impozite de plată" de pe Acasă → „Vezi detalii".
Taxonomia validată de BGN — cele 5 categorii afișate:
- Impozit pe venit / profit (micro 1%/3% trimestrial · profit 16%) — ANAF, pe 25.
- Taxe salarii — pachetul D112 (impozit 10% + CAS 25% + CASS 10% + CAM 2,25%) = UN singur rând/transfer pentru client („taxele pe salarii"), nu patru.
- TVA (incl. capcana taxării inverse la achiziții externe — Google/Meta/Upwork) — pe 25.
- Impozit pe dividende (reținut de firmă, pe 25 a lunii următoare distribuirii). CASS-ul pe dividende NU apare — e obligația persoanei, nu a firmei (decizie BGN, „deocamdată").
- Impozite locale (auto, clădiri, teren) — alt beneficiar (primăria/primăriile, nu ANAF), alt ritm (31.mar + 30.sep, bonificație la integrală), posibil mai multe primării → beneficiarul se afișează explicit pe rând.
Problema localelor (BGN): nu le calculăm noi — le „impune" Direcția de Taxe din primărie. Soluția MVP (propunere agreată de explorat): (a) deducem că obligația există din activele văzute în documente (mașină din leasing/RCA/talon, sediu din acte) → rândul apare cu starea „sumă necunoscută — încarcă decizia de impunere"; (b) clientul fotografiază decizia (vine oricum prin feb-mar) → Iris extrage sume/rate/primărie — același gest ca la Cheltuieli. Ghișeul.ro / împuterniciri la primării = post-MVP, digitalizare inegală.
Confirmarea plății: automată — Iris potrivește plata din extras cu obligația (limbaj consistent cu Facturi: De plată / Plătită). Acțiunea-cheie pe rând: „Copiază detaliile plății" (beneficiar, IBAN trezorerie, sumă, cod) / „Descarcă OP". Detaliu-modal: de unde vine suma (pe vocea Bono, „calculată de Alina din decontul TVA pe aprilie"), codul declarației ca notă mică — nu în tabel.
Mix demo Youngblood: impozit micro T1 · taxe salarii martie · TVA aprilie · impozit dividende (mar) · impozit auto rata 1 (Primăria — sumă din decizia încărcată) — câte unul din fiecare categorie.
De plată — v1 construit (22 iul 2026, live la /de-plata)
KPI — ordine + stil (v1.4, 22 iul, spec BGN — materialele finale: bej / dark / alb): 1) Plătite · 🗓 2026 (bej-1 — trecutul, estompat; a trecut prin alb și înapoi) — 38.240 · 11 plăți; 2) De plată acum = CARD DARK la mijloc (var(--c-dark) + glow roz radial jos-dreapta — în oglindă cu cardul „Taxe și impozite de plată" de pe Acasă; text alb, label/unit/context pe alb 40–55%) — 12.700 lei · 3 obligații (reconciliat cu Acasă — „Vezi detalii" duce aici; v2, 3.aug: 14.967 → 12.700 la alinierea pe 1 angajat); 3) Următoarea scadență (card ALB, border 18% — viitorul, luminos în față) — valoarea mare e DATA („27.apr"), context „luni · TVA, salarii, micro" (v2, 3.aug — 25.apr.2026 e sâmbătă). Citirea materialelor: bej = trecut estompat · dark = prezentul-erou (rima cardului de pe Acasă) · alb = viitorul apropiat.
Lista pe capitole (fără filtre/căutare în v1 — listă scurtă): TVA·martie (8.740) · Taxe salarii·martie (2.625, 1 angajat — v2 3.aug) = capitol expandabil — chevron, click → cele 4 componente D112 pe sub-rânduri bej (Impozit 390 / CAS 1.500 / CASS 600 / CAM 135) · Impozit micro·T1 (1.335 = 1% din 133.470 facturați în T1 — reconciliat cu pagina Facturi) · Impozit clădiri = starea „deducem + cerem": „sumă necunoscută" + badge warn „Așteptăm decizia" + buton „Încarcă decizia" (picker real → doar confirmare de primire „a ajuns la Bono — completăm suma aici") · dividende + auto = Plătită cu „potrivită cu extrasul · data".
Acțiunea-cheie: „Copiază detaliile plății" pe rândurile de plată — pune în clipboard beneficiar + IBAN trezorerie + sumă + detalii (CUI), butonul confirmă „Copiat ✓" 1,6s. Beneficiarul e explicit sub numele obligației (ANAF / Primăria Cluj-Napoca). Rândurile simple deschid modalul de detaliu (sumă/scadență/beneficiar/status + nota pe vocea Bono: de unde vine suma, cine a calculat/depus); capitolele expandabile se deschid în loc de modal.
DECIS (v1.3, 22 iul): rămâne LISTA — Tabelul scos (toggle-ul, tabelul și modalul de detaliu eliminate; comparația s-a făcut pe live). Pagina = un card alb per categorie (TVA · Taxe salarii · Impozit pe venit·micro · Impozit pe dividende · Impozite locale). Cardul închis = UN RÂND PE COLOANE ALINIATE (v1.5, 22 iul, spec BGN — fără detalii în card): grilă comună: pe ecrane late (≥1420px) 230px · repeat(3, 1fr) · 90px — numele fix (validat BGN), Sumă/Scadență/Status pe cote egale cu conținut CENTRAT, Detalii = coloană FIXĂ 90px, dreapta (v1.8 + v2.2 — auto-ul inițial se dimensiona diferit per rând și deplasa coloanele); sub 1420px: 1fr · 140 · 170 · 150 · 90px, mijloc centrat, Detalii dreapta → Tip taxă (15px/600) · Suma (centrat pe coloană, anatomia sumelor; „—" la zi / „necunoscută" la locale, mist) · Scadența („luni · 27.apr.26" warn; „31.mar + 30.sep") · Status (badge: De plată bej / La zi verde / Așteptăm decizia warn) · „Detalii ⌄" (fog → ink pe hover, chevron se rotește). Coloanele se aliniază perfect între carduri — scanabil ca un tabel, dar fiecare rând e card. Tot restul s-a mutat în zona expandată (click oriunde pe card): descrierea pe vocea Bono + Copiază detaliile (la scadente) / Încarcă decizia (locale) + „Ultimele plăți" + la salarii componentele D112. Expandarea = TABEL UNIFICAT de plăți pe aceleași coloane (v2.1, 22 iul, spec BGN): plata curentă și cele din trecut stau în același tabel, pe grila rândului principal. Plata curentă = primul rând, cu HIGHLIGHT (bandă bej-1, radius 12; badge-ul „De plată" trece pe alb ca să rămână vizibil pe bej) și detaliile ei sub nume (11.5px fog: „din decontul depus de Vox pe 20.apr" / „1 angajat · un singur transfer" / la locale + butonul „Încarcă decizia" inline). Urmează separatorul „ULTIMELE PLĂȚI", apoi fiecare plată din trecut cu propriile detalii sub nume („potrivită cu extrasul de cont"), suma în coloana sumelor, data plății (dd.mmm.yy) în coloana scadenței, badge verde „Plătit" în coloana de status. v2.2 (22 iul): rândurile de plăți sunt single-line, fără sub-texte („potrivită cu extrasul" scos din rânduri — trăiește în detaliile per rând) și FIECARE rând/lună are propriul „Detalii ⌄" în ultima coloană → se deschide inline explicația plății (curenta: de unde vine suma; plătitele: „Plătită pe X — potrivită cu extrasul + decontul depus…"); la salarii, componentele D112 s-au mutat în detaliile rândului curent; la locale, „Încarcă decizia" trăiește în detaliile rândului de clădiri. Aliniere reparată: ultima coloană FIXĂ 90px (era auto — se dimensiona diferit per rând și deplasa coloanele 1fr). v2.3 (22 iul): tabel CONTINUU, fără separatorul „Ultimele plăți" — luna curentă (highlight) + exact 3 luni de istoric per categorie, un singur tabel curgător; „Din ce e compusă" rămâne doar în detaliile rândului de salarii. Istoric lung (23+ luni) — DECIS: MODAL, nu paginare (istoricul e secundar pe această pagină; paginarea a fost soluția la Extrase pentru că acolo matricea E pagina): sub tabel, link „Vezi toate lunile →" aliniat la DREAPTA → du-modal cu tabelul complet al categoriei — înviorat (v2.4, feedback BGN „e cam tern"): lead pe vocea Bono sub titlu („5 plăți · 23.245 lei — fiecare potrivită automat cu extrasul tău."), FIECARE RÂND = propriul card alb (v2.5 — varianta „un card per plată" aleasă de BGN peste containerul alb unic: pill-carduri albe border 18%, radius 14, gap 8px, hover pe border, plutind pe bejul modalului), separatoarele de an cu TOTALUL anului aliniat dreapta („2025 ······ 13.855 lei"), sume cu anatomia DS (dec fog + lei mist), badge-uri verzi „Plătit" reale (își pierduseră stilul în modal — rescopate), hover pe rânduri, și fără prefixul de categorie repetat pe fiecare rând (titlul îl spune o dată — rândurile zic doar „feb.26"). Numele lunilor/trimestrelor peste tot în formatele compacte (mmm.yy / Tn-yy). „Copiază detaliile" SCOS (decizie BGN). v2.6 (4 aug): caseta cu detaliile plății (beneficiar/IBAN/sumă/detalii, readusă de audit în detaliile plății curente) are COPY-ICON PER CÂMP, nu buton unic — clientul introduce câmpurile individual în internet banking (decizie BGN); v2.7 (4 aug, feedback BGN): icon 14px în buton 26px (era prea mic), centrat vertical cu textul câmpului (grila casetei pe align-items center), iar la click iconul se TRANSFORMĂ în confirmare — pill verde „✓ COPIAT" (success-bg, uppercase 11px) timp de 5s (BGN: 1,4s era prea puțin — clientul are nevoie de confirmarea vizibilă cât lipește în banking), apoi revine. Valorile copiate sunt „bancabile": IBAN fără spații (RO35TREZ…), suma fără separatori de mii și fără „lei" („8740,00"), beneficiarul și detaliile ca afișate. Bug istoric reparat cu ocazia asta: blocul JS de copiere fusese inserat ÎN INTERIORUL tagului <script src="review-control.js"> — un script cu src își ignoră conținutul inline, deci copierea din casetă NU funcționase niciodată, pe niciun browser; mutat în scriptul paginii. Explainer-ul = notă discretă sub carduri.
Regula de border generalizată (22 iul, BGN): alb pe bej-0 = ink 18% (--c-rule-input) — nu doar filtrele/căutările, ci și cardurile albe: table-card (toate paginile), cardurile Listei, KPI-ul alb, tray-urile de upload, selectorul de perioadă de pe Acasă; 12% (--c-rule-card) rămâne pentru alb pe bej-1, interiorul suprafețelor albe și dropdown-urile cu umbră. Actualizat și în skill-ul edge-33.
Reconciliere transversală: rail-urile de pe TOATE paginile ziceau „Plată impozit profit · estimat 38.420" — fals pentru o firmă pe micro → corectat în „Plată TVA + taxe salarii · estimat 13.400 lei". Sidebar-urile tuturor paginilor leagă acum De plată. Foot band: „Plătești din banca ta, cu detaliile de aici — când plata apare în extras, o bifăm noi."
Contabilitate — v3 ACORDEON (5.aug; istoric: v1 draft 23 iul → v2 tabel de tipuri → v3)
Jobul paginii: arhiva documentelor contabile produse de Bono — „banca mi-a cerut balanța" (acțiunea #6 din PRD): rar, dar urgent; + reasigurarea „contabilitatea mea e la zi" + cea mai concretă dovadă a muncii Bono. Live la /contabilitate, tab activ în nav pe toate paginile.
- Lista documentelor = ancorată în seria reală a colegilor din Drive (folderul de lucru cu V2/V3): 1.1 Registrul jurnal · 1.2 Fișa de cont · 1.3 Balanța de verificare · 1.31 Cartea Mare · 1.4 Registrul inventar · 1.5 Registrul de evidență fiscală · 1.11/1.12 Jurnale cumpărări/vânzări · 1.21 Registrul de casă · seria 2 mijloace fixe (fișă MF, registru inventar MF, PV recepție/casare, bon mișcare) · Nota contabilă · bilanț S1005/S1120 · D300.
- Status-line sub header (reasigurarea într-o propoziție): „● Contabilitatea e la zi. Ultima lună închisă: martie 2026 · verificată de Alina pe 05.apr.26."
CTA roz „Pregătește dosarul pentru bancă" + modal(v3.2, scos de BGN — cu corecție de domeniu): NU există un template general de dosar pentru bancă — fiecare bancă cere alte documente, în funcție de nevoia clientului (credit, leasing, linie de finanțare…). Deci nu un pachet pre-asamblat, ci fluxul real: clientul primește lista de la bancă → o dă lui Bono → „Cere un document →" (butonul din card, către Vox) e exact mecanismul potrivit. Pagina nu are CTA în header.v1: tabel de instanțe→v2: tabel de tipuri cu istoric→ v3 (5.aug, corecție BGN cu screenshot din „Documentele firmei"): ACORDEON DE BARE BEJ — exact pattern-ul de pe Firma ta: card alb cu căutarea sus-stânga + buton outline „Cere un document" (+ săgeată SVG; tooltip „Îi scrii lui Vox — răspunde în câteva minute") sus-dreapta, apoi bare bej-1 rotunjite una sub alta, câte una per tip de document, listă plată fără categorii (v2.1). Bara: chevron › (se rotește 90° la deschidere) + numele uppercase T12 („BALANȚA DE VERIFICARE") + descrierea lowercase fog („· situația tuturor conturilor — cerută cel mai des de bănci") + count-ul instanțelor + dot AI pulsând doar pe Bilanț (se pregătește 2025).Badge download pe bară(v3.1, corecție BGN): bara colapsată e CURATĂ — fără icon de download; descărcarea trăiește doar în istoricul deschis, per instanță. Deschiderea barei → istoricul pe alb sub ea (perioada · „generat/depusă [data]" · tag „DEPUSĂ LA ANAF" per instanță · download; bilanț 2025: „încă nu e gata"). Footer în card: „15 tipuri de documente · toate generate de Bono". Ordinea barelor = cât de des cere cineva documentul (bilanț, balanță primele).- Starea „se pregătește" = DOAR dot AI pulsând (7px, tooltip „Se pregătește — bilanțul pe 2025, termen 31.mai.26"; fără text pe bară — bara rămâne curată) pe rândul-tip al Bilanțului anual (ultima = 2025, termen 31.mai.26; în istoric: „încă nu e gata", fără download — download-ul rândului duce la ultimul DEPUS, 2024). Tag-urile „Depusă la ANAF" au coborât în istoric, per instanță — rândul-tip rămâne curat.
- Fără dropdown-uri de filtrare (v2): cu 15 tipuri grupate, Tip/Perioadă și-au pierdut sensul (perioada trăiește în istoric) — rămâne doar căutarea cu clear × (ascunde și grupele rămase goale). Fișele de cont = pachet ZIP pe lună (decizie păstrată din v1). Istoric demo: balanța 6 luni, bilanț 3 ani, D300 3 trimestre, MF per echipament (MacBook Pro + Dacia Spring — legate de cheltuielile din demo) — toate cele 15 tipuri au istoric; 45 de instanțe în total. Footer: „15 tipuri de documente · toate generate de Bono" (devine „{n} din 15 tipuri…" la căutare;
„arhiva completă din 2023"= variantă retrasă). - Decizie BGN confirmată implicit: declarațiile ANAF apar AICI (grup propriu), nu doar pe De plată — aici e arhiva, acolo obligațiile.
- Deschise: paginare/„arată mai mult" la volum mare de istoric (v3 n-are — 15 bare, 45 instanțe) · fără KPI-uri (nu există cifre de sinteză naturale — de validat) · butonul „Cere un document" e încă nefuncțional în prototip (intenția: deschide chat-ul Vox).
Conținutul dosarului pentru bancă— întrebare dizolvată de v3.2: nu există dosar-template, fluxul e „Cere un document".
Angajați — pagină nouă (v1, 24 iul, construită pe research-ul repo-urilor SalarEasy)
Nevoia (validată BGN 24 iul): 1. „Cât mă costă de fapt?" (brut/net/cost — nimeni nu explică simplu) · 2. „E totul în regulă?" (reasigurare: contract activ, Revisal, statul lunii) · 3. fluturaș/documente descărcabile · 4. „Angajez pe cineva" · 5. taxele salariale ale lunii · NU: cele 18 coloane de operator, CAS/CASS/CAM sec, pontaj, editare.
Research = repo-urile SalarEasy (3 agenți pe salareasy-api/-web/-prototip + proto-autoangajare; înlocuiește research-ul de piață): SalarEasy web = unealta OPERATORULUI (multi-firmă, tabele 9–18 coloane); singurul UI client = fluxul de autoangajare (6 ecrane, varianta orizontală în main, semnare 3 documente, „validare Revisal 3–5 zile"). API .NET pe blueprint-ul Bono: POST /employments/list (contracte cu funcție/brut/status/RegesStatus — NU /employees/list, prea slab), GET /payroll-runs/{id}/results (net, CAS, CASS, impozit, CAM, cost angajator), POST /salary-simulation (brut→net fără persistare), PDF-uri gata (fluturaș, stat, CIM). Statusuri de tradus pt client: active→Activ, pending-termination→În curs de încetare; REGES Nedepus→Înregistrat. Gol descoperit: fluxul de angajare NU arată net/cost angajator (doar brut) — Dublin îl acoperă.
Decizii BGN (24 iul): angajarea = link-out către SalarEasy (ca Emite factură→Facturare; „mai vedem apoi dacă facem ceva și în Dublin") · demo = 1 angajat (cazul realist MVP: adminul auto-angajat) · lista de job-uri confirmată.
Produs v1 (dublin-angajati.html, live /angajati, tab activ în nav pe toate paginile):
- KPI bej cu perioada în etichetă (regula globală): Cost total · 🗓 mar.26 ⌄ (default = ultima lună ÎNCHISĂ, principiul Extrase — aprilie e în curs) 6.135 / Net plătit 3.510 („57% din cost") / Taxe la stat 2.625 („43% din cost"). Perioade: mar/feb/ian.26 · Q1-26 · 2026 · 2025 (din oct., angajat 01.oct.25, brut 5.500 atunci). Cifre reale RO: brut 6.000 → CAS 1.500 + CASS 600 + impozit 390 → net 3.510; CAM 135 → cost 6.135.
- Fișă de angajat, NU tabel cu un rând (regula Extrase pentru n=1): avatar + Eduard Ionescu · „Manager general · CIM normă întreagă (8h/zi) · angajat din 01.oct.25" (funcția din config-ul de autoangajare) + badge-uri success „✓ Contract activ" / „✓ Înregistrat la Revisal". v1.2 (spec BGN): descărcarea CIM-ului e ÎN badge-ul „Contract activ" (icon ↓ la coadă, hover cu inel success, tooltip „Descarcă contractul (CIM)") — badge de status devenit status-acțiune; riscul de nedescoperire mitigat prin icon vizibil + hover + tooltip. Butonul separat a dispărut.
- Istoricul lunar = tabel în fișă (v1.1, spec BGN 24 iul): coloane Luna · Salariu net · Data plății · Taxe · Data plății · Salariul total · Fluturaș (v1.7: „Salariu brut total"→„Salariul total"; KPI „Net plătit"→„Salariu net" — feedback BGN prin pin-urile Vercel, înainte de dezactivarea lor) (v1.3, spec BGN: câte o coloană „Data plății" SEPARATĂ după fiecare sumă — sumele rămân curate; v1.2: Fluturaș cu label în cap; download-ul per rând = badge simplu alb 36×26, pill cu inset border, hover pink). Data plății: data
dd.mmm.yy+ bulina check verde DUPĂ dată („05.apr.26 ✓" — v1.4, spec BGN); neplătit = doar clepsidra pe warn tint, fără dată (tooltip „De plată până la 27.apr.26"). v1.4: toate cele 7 coloane au lățime EGALĂ (table-layout: fixed) și conținut CENTRAT — inclusiv sumele (excepție de la right-align-ul DS, decizie BGN pe tabelul din fișă). v1.5: Salariu brut total = șters (fog; brutul e context, Net/Taxe rămân pe ink). v1.6 — tipografia tabelului pe scala DS (corecție BGN, prinsă cu inspectorul de font: era 13.5px ad-hoc, în afara scalei): sume 14px — Net/Taxe 500 ink, Total 400 fog (dublu retras, corecție BGN) · luna + datele plății 12px/400 fog · badge-ul de download fluturaș cu border ink 18% (--c-rule-input, ca orice control interactiv). Separarea header↔tabel = FUNDAL, nu linie (v1.2, întrebare BGN): capul de tabel pe bandă bej-1 rotunjită — pattern-ul thead-urilor din Dublin. Default se vede doar ultima lună închisă (mar.26 — net ✓ plătit, taxe ⏳ termen 27.apr — povestea reală a lunii); „Vezi lunile anterioare (5) ⌄" expandează istoricul până la angajare (feb/ian la 6.000 brut; dec–oct.25 la 5.500 — înainte de mărirea din ianuarie). (Înlocuiește rândul de cifre + bara net/taxe din v1 — procentele rămân în KPI.) Card luna în curs („Statul de plată pe aprilie se pregătește…")— SCOS (4.aug, decizie BGN): informația era redundantă (aprobarea statului tot în DE FĂCUT aterizează, iar taxele cu termenul lor sunt pe De plată); pagina rămâne doar KPI + carduri de angajați.- Empty state = poarta de angajare (decizia din 10 iul, acum construită): icon people pink-tint + „Nu ai încă niciun angajat pe firmă" + promisiunea din fluxul real („pregătim noi contractul… Bono îl depune la Revisal, validarea vine în 3–5 zile") + CTA roz „Angajează-te ↗"; CTA-ul din header se ascunde (max 1 roz/ecran). Toggle provizoriu „1 angajat / Fără angajați" lângă titlu pentru simulare.
- AUTOANGAJAREA ÎN DUBLIN (v1, 25.aug, decizie BGN — după analiza modulului live test-salareasy.bono.ro): colegii au livrat modulul de Salarizare (verificat pe viu: fidel PRD-ului de autoangajare, backend real, CNP/buletin mascate în documente, acces pe link tokenizat + mediu de test). BGN: fluxul de autoangajare se face ȘI în Dublin — pagină-wizard nouă
dublin-autoangajare.html, live la/autoangajare, deschisă din CTA-ul „Angajează" + „Angajează-te" (empty state), fără link-out. Doar auto-angajarea, în 2 PAȘI (v2, 25.aug, spec BGN — comprimat din 3): Pasul 1 · Despre tine — mesajul de informare că se autoangajează (card pink-ultra „Mă angajez pe mine — administratorul se angajează pe firma lui") cu butonul „Angajez pe altcineva ✉" = MAILTO precompletat (către salarizare@bono.ro, subiect + corp gata scrise cu firma și CUI-ul — a înlocuit cardul cu textarea) + pe aceeași pagină, „Mai ești angajat și altundeva?" (radio Nu/Da + Casa de sănătate CNAS/OPSNAJ + Județ presetat, doar la CNAS); Pasul 2 · Contract (Review) — „Datele contractului tău": card „Datele tale" (salariu 4.325 lei (minim) · start 04.mai.26 = azi+10, regula REGES · alt job · casa — sincronizate din pasul 1) cu „Modifică" (editor inline, validări min) + „Detaliile postului" read-only cu „Cere o modificare" → confirmare + checkbox-gate. Stepper pe 2: „Despre tine · Contract". v2.1 (25.aug, simplificări BGN): fără subtitlurile de sub titluri („Flux automat…" și „Verifică — restul îl facem noi") · fără selecția casei de sănătate — CNAS presupus default, sistemic (rândul a dispărut și din review; OPSNAJ = caz tratat de echipă la nevoie) · data începerii: default 1 a lunii următoare (01.mai.26), modificabilă din picker-ul de dată cu prima dată disponibilă = azi + 10 zile (04.mai.26; sub prag se corectează automat), fără nota explicativă REGES · fără nota de telemuncă (clauza rămâne în contract, nu în UI). Final provizoriu: „Datele sunt confirmate" — documentele + semnarea = pasul următor (de decis: în Dublin sau handoff către modul). DECIS (25.aug): PAGINĂ, nu modal — fluxul e act contractual (merită focus), iar pașii viitori (citirea documentelor cu read-gate + semnătura pe canvas) nu încap într-un modal; layout focalizat fără shell, „← Angajați". Format date dd.mmm.yy; max 1 CTA roz/ecran (mailto-ul e outline). Diferență de demo asumată: wizardul e generic, demo-ul Angajați îl are pe Eduard deja angajat. Arhitectura reală de acces la modul rămâne documentată: link tokenizat per client (fără token → „Linkul nu mai este valid"; mediul de test are intrare cu date de probă) — de clarificat cu echipa formatul token-ului și evenimentul de finalizare către Dublin. - Modul 3 angajați (v2, 3.aug; forma finală v2.1, 4.aug — spec BGN „nu tabel unic, ci cardul fiecăruia"): toggle-ul devine „Fără angajați · 1 angajat · 3 angajați". La 3+, pagina = un card per angajat, identic cu fișa de la 1 angajat (stivă cu gap 14px): header cu avatar + nume + „funcție · CIM · din data" + badge-urile „✓ Contract activ ↓ (CIM)" / „✓ Înregistrat la Revisal" per om + istoricul lunar propriu (aceleași 7 coloane) cu expander per card („Vezi lunile anterioare (N)" — Eduard 5, Ana 2, Radu fără — angajat în martie, n-are istoric). (Prima iterație — tabel unic de echipă cu rând de total — respinsă de BGN în aceeași zi; totalul echipei trăiește doar în KPI-uri.) Echipa demo, calcule RO reale: Eduard (6.000 brut → 3.510/2.625/6.135) + Ana Ionescu · Designer · din 01.ian.26 (9.000 → 5.265/3.938/9.203) + Radu Popa · Dezvoltator · din 01.mar.26 (12.000 → 7.020/5.250/12.270). KPER pe două seturi (mode-aware): la 3 angajați mar = 27.608/15.795/11.813 „3 angajați", feb/ian = 15.338 „2 angajați" (Radu vine în mar.), Q1/2026 = 58.284, 2025 = doar Eduard; schimbarea modului resetează perioada pe mar.26. Notă: simulare demo — nu se reconciliază cu De plată (aliniată pe 1 angajat), ca la toggle-ul de IBAN-uri de pe Extrase.
- Deschise: detaliul/istoricul per angajat (click pe rând în modul echipă), legătura cifrelor cu De plată.
Navigație legată
Sidebar-ul (Facturi/Cheltuieli) și link-urile „Vezi toate →" din benzile tabelelor de pe Acasă duc acum în secțiuni, pe toate paginile.
Cheltuieli v2 — analiza Bruce de pagină (10 iulie 2026)
Prima „analiză de pagină" cu fluxul Bruce: rezumat decizii → nevoie draft → feedback BGN → research țintit → DIFF → produs. Research salvat în
Dublin/research-cheltuieli-10iul2026.md.
Nevoia reală a paginii (validată cu BGN):
- Scap de document în secunde (jobul #1)
- Văd că a ajuns și ce a înțeles BONO din el — statusuri de la Iris
- Înțeleg de ce e dedus X% + ce pot face să deduc mai mult (îndrumare acționabilă — ex. contract de comodat; BONO pregătește actele)
- (test) Văd cât m-au scutit deducerile la taxe
- Pot adăuga context când nu sunt de acord → Iris reanalizează
- Găsesc orice cheltuială veche (căutare)
- (nevoia BONO, nu a clientului — push) documentele lipsă la plăți
Ce s-a adăugat în prototip (v2):
- Tray de procesare efemer sub dropzone: „se încarcă…" → „Iris o citește…" → verdict cu consecința fiscală per document („Hotel Astoria · 812 lei · 100% deductibilă · −130 lei la impozit") → itemul dispare și rândul intră în tabel evidențiat (lecția FreeAgent: gata = pleacă din zonă; coada persistentă cu ETA à la Dext = anti-pattern).
- Card „· Iris a observat — Poți deduce mai mult la combustibil" (pattern DS .insight, compact): explică situația (mașina fără contract → 50%), cuantifică (~110 lei/an), oferă acțiunea: CTA „Pregătiți-l" → „În lucru la Alina". Nimeni pe piață nu face sfat contextual per cheltuială — teritoriu liber.
- „Adaugă context" în modalul de detaliu (doar la ≠100%): text liber în limbaj natural (pattern Puzzle) → „Iris reanalizează… și ține minte pentru data viitoare" (corectura antrenează sistemul, și o spunem). Rândurile de combustibil au și link „Vezi cum deduci mai mult" → duce la card.
- KPI Deductibile poartă testul de valoare: „≈ 22.860 lei economisiți la taxe · estimare" (reward-loop-ul Keeper/FlyFin, absent în B2B/RO).
- Alertă „2 plăți fără documente" (DS .alert.warn) cu „Încarcă-le" → duce la dropzone (nevoia BONO, adusă push; echivalentul „Missing Paperwork" Dext).
Layout v2.1 (feedback BGN, 10 iul):
- Rail-ul din dreapta revine pe Cheltuieli — apoi generalizat: rail pe toate paginile Dublin (inclusiv Facturi) + meniu colapsat pe secțiuni (deschis doar pe Acasă); vezi pattern-ul de secțiune actualizat mai sus.
Rafinări v2.2 (feedback BGN pe prototip, 10 iul):
- Topbar-ul (firmă + CUI + badge LIVE) urcat cu 6px — spațiul de sus micșorat, spațiul până la titlu mărit; distanța totală top→titlu neschimbată. Aplicat pe toate cele 3 pagini (pe Acasă hero-ul rămâne fix prin compensare în gap).
- Fără mini-cardul „Trage fișierul aici" (redundant) — rămâne doar butonul roz „Încarcă document".
- Coloană nouă „Plată" după Deductibilă: data plății cu bulină verde mică + check alb, sau „Neplătită" (warn). Apare și în modalul de detaliu.
- Zecimalele sumelor din tabel: font mai mic (11px) + fog — ca stilul numeric din DS (întregul rămâne dominant).
- Status nou la Deductibilă: „Se procesează" — badge în nuanțele AI din DS (ai-bg/ai) cu dot pulsând; pentru documentele abia încărcate, înainte de verdictul Iris. În detaliu: motiv „Iris o procesează chiar acum…", fără link de context (apare doar la 50%/Nu).
- Fără subtitlu — pagina cât mai aerisită.
- Upload = mini-widget în linia titlului, aliniat dreapta: buton roz „Încarcă document" + mini-card dashed „Trage fișierul aici" (dropzone-ul mare a dispărut).
- Filtre pe dropdown-uri (stânga): Tip document („Toate doc" / Facturi / Bonuri) · Dată = calendar (o zi cu un click, interval cu două; luni navigabile; „Șterge") · Deductibilitate (Toate / 100% / 50% / Nedeductibile). Căutare la dreapta, placeholder „Caută nume furnizor sau sumă…" (căutarea prinde și sumele).
Card PERMANENT de procesare (15 iul, feedback BGN): sub cardurile de acțiune (Acasă) / sub header (Cheltuieli) stă mereu cardul: spinner + max 3 thumbnail-uri de documente + „…" pentru rest + copy: „X documente sunt în curs de procesare de către contabilul tău și vor apărea în tabelul de cheltuieli pe măsură ce sunt gata." (simulare: 13). La upload, textul devine „se încarcă N documente · mărime…" apoi contorul absoarbe noile documente, cu thumbnail-urile lor în față. Nu mai e efemer — e fereastra permanentă către coada de procesare.
Ciclul de viață al documentului + coada expandabilă (22 iul, model BGN): documentele au 3 stări, fiecare cu locul ei în UI — (1) neprocesat (știm doar fișierul: nume urât, dată încărcare, sursă) → trăiește în coada de procesare, NU în tabel (ar avea toate coloanele goale); (2) procesat incomplet → rând în tabel cu golurile marcate („Se procesează" pe Deductibilă); (3) procesat complet → rând normal. Stiva de mesaje de la Bono (22 iul, idee BGN „să nu separăm informația din pagină"; v2 în aceeași zi): insight-ul „Iris a observat" + alerta „plăți fără documente" NU mai stau între KPI și tabele — s-au mutat DEASUPRA TITLULUI paginii (imediat sub topbar; „ca și cum nu sunt parte din pagină" — strat de sistem, cu stilul DS al paginii), ca stivă de notificări închizabile: alerta prima (e sarcină, warn), insight-ul al doilea (e oportunitate). Cardul roz = compact, max ~2× banda warn (spec BGN; livrat la 1.7× — 102px vs 60px la 1600): padding 11px, h3 14.5px, text 12.5px pe max 2 rânduri (copy scurtat), acțiunile pe ORIZONTALĂ în dreapta („Mai târziu · Cum funcționează? · Pregătiți-l"). Direcție notată (BGN): stiva ar putea apărea și pe alte pagini / Dashboard — același strat global de mesaje; de decis când avem 2-3 tipuri de mesaje reale. Fiecare card are × (închide) — cerc discret hover ink, absolut în colț (centrat vertical pe alertă) — și „Mai târziu" (snooze) — link subliniat fog; la snooze conținutul devine „Bine — ți-o amintim mâine." și cardul se strânge singur după 1,5s (animație height+opacity; fără persistență în prototip — refresh-ul le readuce pentru demo). Ordinea paginii devine: mesaje (stiva, deasupra titlului) → header → KPI → coadă → tabele — comunicarea sus, datele jos, un singur loc unde aterizează orice mesaj viitor de la Bono. Pe Cheltuieli, cardul permanent stă imediat înaintea tabelului (v2, 22 iul — mutat de sub header) și e intrarea către un TABEL NORMAL al neprocesatelor (v3, 22 iul — scenariul SOLO: pot fi sute de documente neprocesate, deci lista simplă din card nu scalează): „Vezi documentele ⌄" deschide sub card un .da-table-card adevărat cu rând propriu de filtre (v4, 22 iul — spec BGN: FĂRĂ căutare la neprocesate; Tip: Toate tipurile/Poze/PDF-uri/e-Factura + Dată încărcare cu presete „Oricând/Azi/Ieri/Mai vechi" — coada trăiește în zile, nu în luni, deci presete în loc de calendarul complet) + tabel NUME (icon tip fișier + nume mono, scurtat, întreg pe tooltip) · TIP = Poză / PDF / e-Factura (tipul „e-Factura" pe XML-uri absoarbe sursa — facturi de furnizor sosite prin SPV fără ca clientul să facă ceva, wow pasiv) · ÎNCĂRCAT (dd.mmm.yy · HH:MM, „ieri/azi HH:MM" pe recente) · STATUS („SE PROCESEAZĂ" AI cu dot pulsând — primele 2 din coadă FIFO / „NEPROCESAT" mist) + bandă cu paginare: „27 de documente neprocesate" stânga · ‹ pagina 1 din 3 › dreapta (10/pagină; chevrons-cerc, disabled la capete; filtrele resetează pagina; empty-state pe filtrare fără rezultat). FĂRĂ toggle pe tabelul principal — vezi decizia de mai jos; cardul cu contor = intrarea. Titlul tabelului — 4 iterații într-o zi (22 iul, închis): eyebrow T12 deasupra filtrelor ([]{v1 — „nu arată bine"}) → în capul bej, stânga (v2) → în cap, centrat 13px ink (v3 — „ceremonios, dezlipit") → FINAL (v4): heading real de secțiune deasupra filtrelor — „Cheltuieli procesate", 16px/600/ink, sentence case, margin 24/0 — poziția inițială era bună, stilul era problema (eyebrow mic fog vs heading adevărat). Tabelul neprocesatelor NU are titlu propriu — cardul cu contor de deasupra E titlul lui („27 documente… Ascunde documentele"); „DOCUMENTE NEPROCESATE" repeta informația. Rândurile cap-title = scoase. Simulare: 27 documente (12 poze + 8 PDF + 7 e-Factura, 21–24 apr; contorul de pe Acasă sincronizat la 27). Documentele urcate din picker/drag&drop intră live în coadă („chiar acum"). Decizie: FĂRĂ toggle „Neprocesate/Procesate" pe tabel (întrebare BGN, recomandare Claude acceptată tacit): un switch le-ar da rang egal, dar sunt specii diferite (coadă tranzitorie cu 4 coloane vs arhivă contabilă cu 7), iar „inbox-ul de triat" à la Dext e anti-pattern pentru poziționarea BONO — procesarea e treaba lui Bono, clientul are doar transparență; contorul din titlul cardului face treaba badge-ului de tab. Deschis: starea de eșec (ilizibil/duplicat/nu-e-document) — de definit copy + acțiune.
Coloană de VALUTĂ și la Cheltuieli procesate (22 iul, cerere BGN — „la fel ca la Facturi"): după Sumă (care rămâne doar cifră, fără „lei"), coloană Valută cu steag + Lei/Euro; 3 rânduri demo în EUR — abonamentele SaaS facturate din UE: Anthropic ×2 (106,00 €) și Google Ireland (17,40 €), cu data-suma păstrat în lei-echivalent pentru agregate; în modal suma își recapătă valuta, iar bonul-hârtie afișează „TOTAL … EUR/LEI" după caz. Tabelul are acum 7 coloane: Furnizor · Dată · Tip · Sumă · Valută · Deductibilă · Plată. Banda de închidere = varianta de paginare (22 iul, aliniere la Facturi): doar „‹ pagina 1 din 3 ›" la dreapta, 10/pagină, filtrele resetează pagina; meta-ul cu totaluri și textul de arhivă = scoase.
Standardele de tabel (22 iul, sesiune BGN — documentate și în skill-ul edge-33): rânduri single-line = 48px (padding-block 11, conținut centrat vertical; întrebare BGN „ce h la rânduri cu font de 14?" — nu exista standard, l-am creat); rânduri cu linie secundară = 62px (Acasă). Text pe DOUĂ mărimi (spec BGN „păstrăm doar 12 și 14, lucrăm din weight și culoare"): primar 14px/500/ink (nume, partea întreagă a sumei) · secundar 12px/400/fog (date, descrieri, valută, serii mono) · excepții de anatomie: zecimale/monedă 11px, badge-uri T-badge. 13px/12.5px eliminate din celule (Facturi + Cheltuieli + neprocesate + coloana Plată). CUI-ul nu mai ocupă rând sub numele clientului (spec BGN) — tooltip dark mono la hover pe nume (data-cui); căutarea îl prinde în continuare (haystack include data-atributul); rândurile Facturi au slăbit de la ~64 la 48px.
Modal detaliu Cheltuieli pe DOUĂ COLOANE (22 iul, cerere BGN; v2 în aceeași zi): modalul e la 760px (v2 — 900 era „prea lat pe coloana de info"), grilă 280px + restul: stânga = documentul justificativ randat ca „hârtie" (alb, umbră de hârtie, JetBrains Mono, generat din datele rândului: comerciant uppercase + „BON FISCAL"/„FACTURĂ FISCALĂ" + linii cu separatoare punctate + TVA 19% calculat + TOTAL + dată/oră + „Vă mulțumim!"), centrat vertical, înălțime ≤ modal; dreapta = detaliile existente (sumă/dată/tip/plată/deductibilă + context + fișier + Iris). Click pe document = lightbox — overlay întunecat 78%, hârtia mărită la 430px, click oriunde sau Esc închide („ca și cum deschizi o poză"); hint „Click pentru mărire" la hover. Escape închide întâi lightbox-ul, apoi modalul. Rândul cu fișierul („bon-omv.jpg · Vezi documentul") = SCOS (v2) — redundant, documentul e deja în stânga. Badge-ul „Nu" la Deductibilă = pe roșu (error-bg + error, tabel + modal; v2 — era bej neutru; „Nu" e singura stare care chiar doare, merită culoarea de alarmă).
Câmpul Vox — un singur canal pentru întrebări SAU context (22 iul, idee BGN „cum îl facem cool? îl legăm de Vox?"; v2 în aceeași zi = CARD DE CHAT DARK): zona Vox e un card negru (--c-dark, radius 18) ca identitatea Vox din Dashboard — separă vizual stratul conversațional de datele de deasupra: header cu bulina roz cu icon chat + „Vox · răspunde în câteva minute" (Fraunces italic roz pe alb 55%) · input alb pill curat (fără avatar în el) cu buton send roz, halo roz pe focus · chips-urile SUB input (v2 — transparent, border alb 22%, text alb 85%, hover roz) · confirmarea pe alb 75% cu actorii roz. Modal la 700px (v3 — „tot un pic prea lată" la 760), iar „Procesată de Iris în X secunde" s-a mutat sub câmpurile de detalii, înainte de cardul Vox (v2). „Întreabă-ne" + „Nu se potrivește? Adaugă context" + „Vezi cum deduci mai mult" → un singur input conversațional în subsolul modalului: pill alb cu avatarul Vox (bulină pink-tint cu icon chat) + placeholder „Întreabă orice sau dă-ne context…" (v3 — fără numele Vox în placeholder, e deja în headerul cardului) + buton send roz; chips contextuale deasupra care pre-completează: prima e dinamică pe starea deductibilității („De ce doar 50%?" / „De ce nedeductibilă?" / „Detalii despre procesare") + „Adaugă context" (prefix „Context: "); Enter sau săgeata trimite; confirmarea vine pe vocea produsului: „Vox a primit mesajul — îți răspunde în câteva minute. Dacă e context nou, Iris reanalizează și cheltuiala." — un canal, două intenții (întrebare/context), sistemul decide în spate cine răspunde. Câmpul se resetează la fiecare deschidere (fix: .dm-vox-ok[hidden]{display:none} — flex bătea hidden).
Filtrele ÎN cardul tabelului (3–4.aug, propunere BGN; v2 = varianta finală după proba pe live): rândul de filtre nu mai plutește deasupra cardului — e prima bandă a cardului, pe bej-0 (padding 12/22, border-bottom soft), iar capul de tabel rămâne pe bej-1 (v2, 4.aug — inversarea primei încercări: capul cu labels e stratul care merită greutatea, filtrele stau pe fundalul cel mai discret; gradația finală: bej-0 (comenzi) → bej-1 (cap) → alb (date)). Aplicat pe ambele tabele din Cheltuieli. Dacă BGN validează → se extinde pe Facturi, Contabilitate, Firma ta ca pattern de secțiune.
Filtrele Cheltuieli v3 (4.aug, cereri BGN): (1) filtru nou „Plată" — Toate / Plătite / Neplătite (data-pay pe rânduri); (2) taxonomia de tip refăcută: Toate / Bon fiscal / eFactura / Factură externă / Extras de cont — facturile RO devin „eFactura" (badge verde, sursa SPV), cele din UE „Externă" (badge bej — Anthropic ×2 + Google), „Extras de cont" pregătit pentru viitor (azi 0 rânduri → empty state); (3) problema filtrelor „mute" în default (întrebare BGN „există metodă established?") → pattern-ul „dimensiunea ca etichetă" (Stripe/Airbnb): în default pill-ul afișează NUMELE dimensiunii pe fog („Tip document", „Plată", „Deductibilitate", „Oricând"), iar la selecție valoarea pe ink 600 + border 30% (clasa .set); reset-ul readuce numele dimensiunii. Alternativa („Tip: Toate" cu prefix) respinsă — repetitivă.
Confirmarea eFacturilor de la furnizori noi (4.aug — plan BGN+Claude agreat, v1 construită): Problema: oricine poate emite o eFactură către CUI-ul tău (din greșeală sau glumă); confirmarea tuturor = muncă (anti-viziune), dar o factură străină doare și neplătită (intră în contabilitate la primire, umflă datoriile, strică profitul/dividendele). Soluția — 3 straturi cu volum minimizat: (1) furnizor cunoscut → zero fricțiune (auto-de-încredere, majoritatea covârșitoare; „confirmat o dată = de încredere"); (2) furnizor NOU prin e-Factura → badge „De confirmat" (warn tonal, lângă nume) + item în DE FĂCUT (push) — factura intră optimist în tabel, nu blocăm nimic; (3) gardul de la bani (ideea BGN): pe filtrul Neplătite, strip warn în card: „O factură primită prin e-Factura e de la un furnizor nou — confirmă că e a firmei tale înainte s-o plătești" cu [✓ E a noastră] / [Nu o recunosc]. „E a noastră" → badge-ul dispare, furnizor de încredere; „Nu o recunosc" → factura dispare din cheltuieli („contabilul tău o verifică și o respinge dacă e cazul" — clientul inițiază, motorul execută). Demo: Global Tools SRL · 1.240 lei · eFactura · Neplătită. MODELUL FINAL = „optimist total" (decizie BGN, 4.aug): TOATE eFacturile se înregistrează imediat în contabilitate, inclusiv cele de la furnizori noi — NU există stare „în așteptarea confirmării" (unii clienți nu vor confirma niciodată, din neglijență/lipsă de timp → am ajunge la notificări enervante; contabilitatea automată înregistrează tot și corectează excepția, consistent cu publicarea hibridă pe confidence din arhitectură). Consecințe: confirmarea e 100% neblocantă — factura contează în toate totalurile de la început; FĂRĂ item în DE FĂCUT, FĂRĂ notificări (tăiat din plan) — badge-ul „De confirmat" e pur informativ, iar singura întrebare activă e stripul de la Neplătite (contextuală, în momentul banilor); „Nu o recunosc" = cerere de CORECȚIE (copy: „Am notat — contabilul tău face corecția: o scoate din evidență și, dacă e cazul, o respinge"), executată de contabil/motor, nu de UI. Escaladarea în timp (4.aug, completare BGN — închide bucla): plata = confirmarea implicită — în mod normal plățile eFacturilor apar în extrase, Iris le potrivește, iar o factură plătită e evident a firmei (badge-ul dispare tăcut, furnizorul devine de încredere; majoritatea cazurilor se rezolvă fără nicio interacțiune). Abia neplata la 30 de zile de la primire e semnal real de anomalie → atunci, „mai activ decât badge-ul, dar nu agresiv": item în DE FĂCUT („Confirmă o factură de la Global Tools SRL · Iris · 1.240 lei · neplătită de 30 de zile") — canalul calm al produsului, nu notificări; stripul de la Neplătite se reformulează pe același semnal („O eFactură primită acum 30 de zile e încă neplătită — e a firmei tale?"). Escaladarea se oprește aici; fallback-ul uman = contabilul la închiderea lunii. Demo aliniat: factura Global Tools datată 25.mar.26 (30 de zile față de LIVE), itemul în rail pe toate paginile (count 7). Rămase deschise: pragul de 30 de zile vs scadența facturii (o factură cu scadență la 60 de zile nu e anomalie la 30 — heuristica finală ține cont de scadență, la Iris) · respingerea formală în SPV (post-MVP) · heuristica „furnizor nou" completă (+ sumă atipică, duplicat).
Materialele KPI pe Cheltuieli (4.aug, spec BGN): primul card ALB (border 18%, cu selectorul de perioadă) · al doilea DARK (var(--c-dark) + glow roz radial — Documente procesate la Micro / Deductibile la Profit) · al treilea BEJ-1 (În curs de procesare la Micro / Nedeductibile la Profit) — aliniat la ritmul alb·dark·bej de pe Facturi (Emise/Încasate/Neîncasate). Regula veche „KPI = card bej pe secțiuni" e depășită de acest mix pe paginile cu 3 KPI.
Tabelul „INSET" = PATTERNUL (4.aug — A/B pe live, BGN a ales inset): à la fișa Angajați — aer alb de jur împrejur (card padding 0 22 10), banda bej-1 a capului ROTUNJITĂ (10px), oprită înainte de borduri, filtrele pe alb, în card, fără bandă (padding vertical mărit la cererea BGN: 18px sus / 16px jos), paginarea/footerul pe alb; celulele primei/ultimei coloane la 14px de banda proprie; titlurile recalibrate la 36px (card 22 + celulă 14 = textul primei coloane). Varianta full-bleed (filtre bej-0 + cap edge-to-edge) = retrasă. Aplicat: Cheltuieli ×2, Facturi, Contabilitate, Firma ta (unde filtrele au fost și mutate în card). De adaptat separat: matricea Extrase și mini-tabelele de pe Acasă (anatomii speciale).
Centrare optică a labels în banda thead (5.aug — catch BGN pe screenshot, de DOUĂ ori): cu padding simetric (10/10), labels păreau prea SUS în bandă. Diagnostic real (după o primă corecție în direcția greșită, cauzată de o eroare de măsurare): capitalele singure erau la ~0,35px de centrul metric — dar breve-ul din Ă (DATĂ/SUMĂ/VALUTĂ/PLATĂ — 4 din 6 labels) adaugă ~2,5px de cerneală deasupra capitalelor, iar ochiul centrează blocul de cerneală întreg, nu cap-height-ul. Fix pe toate thead-urile (7 pagini, inclusiv .fd-tbl și .emp-tbl): padding-top: 11px; padding-bottom: 9px — labels fără diacritice ajung ~0,8px sub centrul metric, cele cu breve ~0,4px peste; blocul se așază optic. Regulă DS: benzile cu labels doar-majuscule românești se centrează pe cerneală (inclusiv diacritice), +2px padding în favoarea celui de sus — rudă cu lecția titlurilor din 4.aug. (Tabelele din tab-ul PRD (13, generate de build-prd.py, font 11px/padding 8px) rămân simetrice — abaterea la scara lor e sub 0,3px; pagina /plan e retrasă din nav (înlocuită de PRD) și are thead cu underline, nu bandă — neafectată.)
Alinierea în tabele (4.aug, regulă BGN): CENTRAT = implicitul — textul coloanelor și labels din cap se centrează, dacă nu se specifică altfel; excepțiile standard: prima coloană (identitatea) = stânga (ține și alinierea titlurilor de tabel) · coloana de acțiuni = la marginea dreaptă · benzile de grupă (Firma ta) = stânga. Aplicat pe toate tabelele .da-table (Facturi, Cheltuieli ×2, Contabilitate, Extrase, mini-tabelele de pe Acasă) + .fd-tbl (Firma); fișa Angajați (emp-tbl) — aliniată și ea la standard pe 4.aug seara („repara tabelul la Angajați"): centrat implicit, Luna (identitatea) stânga, Fluturaș (acțiuni) la marginea dreaptă; excepția „integral centrată" a căzut odată cu trecerea pe sistemul 12/14. Înlocuiește right-align-ul pe sume din standardul DS; documentat și în edge-33.
Titlurile de tabel (4.aug, regulă BGN; mărimi finale în aceeași zi): fiecare tabel are un titlu — 24px/600 (−0.02em, line-height 1.2; era 16px), cu 8px până la border-ul cardului (v2 — era 16; titlul aparține tabelului, stă lipit de el) — iar titlul se aliniază vertical cu TEXTUL primei coloane (padding-left 22px), nu cu marginea cardului. Cardul „documente în procesare" stă la distanță PERCEPTUAL egală între KPI-uri și titlu: 24px sus / 16px reali jos — lecție de optică (BGN a văzut inegalitatea deși metric era 24/24): cutia titlului de 24px are ~9px de aer peste litere (line-height + cap-height), deci golul de sub card se percepe cu ~9px mai mare decât e; egalizarea se face la percepție, nu la metric. Aplicat: „Cheltuieli procesate" + „Documente neprocesate" (titlu NOU pe tabelul cozii — inversează decizia din 22 iul „fără titlu, cardul-contor e titlul"; regula «fiecare tabel are titlu» câștigă) + „Documentele firmei" pe Firma ta.
Varianta MICRO + toggle Micro/Profit (3.aug, analiză + decizie BGN): clientul MVP real = SRL micro, NEplătitor de TVA → impozitul e pe VENIT, deci deductibilitatea nu se calculează și nu-i schimbă taxele; nici TVA-ul din achiziții nu se recuperează. Documentele se încarcă însă LA FEL — motivul se schimbă: contabilitate în partidă dublă obligatorie; o plată fără document = bani „luați" din firmă (la control: dividend mascat / datorie a administratorului — cont 461); profitul contabil corect = dividende fără surprize; bilanț curat pentru bancă; istoric documentat = asigurare pentru tranzițiile de plafon (micro→profit la 100k EUR din 2026; scutirea de TVA ~395k lei — cifrele de validat cu contabilii). Idee-wow notată: Bono monitorizează plafoanele din facturat și te anunță ÎNAINTE de prag. Implementare: toggle Micro/Profit după titlul paginii (pattern sim-tg; default = Micro, clientul real). La Micro: sumele cheltuite/deduse nu sunt relevante (decizie BGN, 6.aug) — cele 3 carduri arată FLUXUL documentelor (v2, tot 6.aug — cardul 3 devine coada, nu plățile): (1) Documente încărcate · 🗓 (alb, count pe perioadă, ține selectorul) / (2) Documente procesate (dark, count pe perioadă) / (3) În curs de procesare (bej-1, count = coada de neprocesate, înlocuiește rândul-tray de sub carduri; în colțul din dreapta-jos al cardului, pe linia valorii: link „Vezi documentele" — 13px fog, underline subtil, hover ink — care deschide/închide tabelul neprocesatelor). Selectorul de perioadă actualizează KPI1+KPI2; KPI3 = starea vie a cozii (27 → crește live la fiecare upload, împreună cu KPI1 pe perioadele curente). Contorizări demo reconciliate aritmetic cu pagina: 2026 = Q1 78/78 (trimestru închis) + apr 36 încărcate/9 procesate (27 în coadă = KPI3) → 114/87/27; 12 luni 342/315 · 2025 296/296 · mar.26 24/24. Restul variantei Micro neschimbat: coloana Deductibilă dispare din tabel (documentele procesate AU document prin definiție — corecție BGN: lipsa documentelor există doar la plățile din extras) · filtrul Deductibilitate dispare · rândul Deductibilă dispare din modalul de detaliu · insight-ul comodat își schimbă povestea („Mașina personală, pe firmă — curat"). Rândul-tray cu documentele în procesare rămâne DOAR la Profit (la Micro îl acoperă KPI3), poziționat după banda plăților fără documente (ordinea la Profit, spec BGN 6.aug: carduri → bandă plăți → rând procesare → tabele). La Profit: varianta completă (sumele Cheltuieli/Deductibile/Nedeductibile) — cu fix 6.aug: la revenirea din Micro toate 3 cardurile respectă perioada selectată (înainte reveneau hardcodat pe an). Deschis: KPI-urile de pe Acasă (Deductibile/Nedeductibile) de adaptat la regim; „economisiți la taxe" = doar la Profit (decizia #9).
Plăți fără documente v3 — bandă sub carduri + tabel inset (6.aug, spec BGN; înlocuiește v2-modal): banda warn se mută de sub titlu SUB cardurile KPI (în ambele regimuri; la Profit vine imediat după carduri, ÎNAINTEA rândului cu documentele în procesare) și rămâne cu un singur buton: „Vezi plățile" (fără „Mai târziu", fără ×) care deschide/închide un TABEL (nu modal) imediat sub bandă — titlu „Plăți fără documente" + card inset, coloane: Furnizor (nume + sub „Plată card · din extrasul BT Lei") · Dată · Sumă · Valută (steag+Lei) · Încarcă document (buton pill per rând, singura acțiune). Butonul devine „Ascunde plățile" cât timp tabelul e deschis. „Alege din cele încărcate" = RETRAS (motivarea BGN: dacă plata era legată de un document deja conspectat, alocarea o facem NOI; dacă documentul nu e conspectat, nu avem ce informație utilă să-i arătăm clientului — deci opțiunea nu are conținut real). Upload → rândul devine „✓ A ajuns la Bono — Iris îl potrivește cu plata.", documentul intră live în coada de neprocesate (KPI1 Încărcate și KPI3 În curs de procesare cresc la Micro), banda se actualizează (contor+sumă; la zero: „Documentele pentru plățile din aprilie sunt pe drum" + butonul dispare). Footer-ul tabelului păstrează principiul din arhitectură: „Documentul nou intră în coada de procesare; potrivirea cu plata o face Iris." Fără persistență (refresh = demo reset). (du-modalul v2 = scos din pagină; conf-strip-ul eFactura a primit clasă proprie de buton, cs-btn.) Tabelul plăților are rând de filtre complet (7.aug, spec BGN): calendar (🗓 „Oricând" — o zi sau interval din două clickuri, componenta clonată de la tabelul mare) + Valută (dimension-label: „Valută" fog → „Lei"/„Euro" ink+set) la stânga, căutare la dreapta („Caută nume furnizor sau sumă…", haystack = celule fără coloana de acțiuni + suma brută, clear-× generic); empty state pe pattern („Nicio plată nu se potrivește cu filtrarea. Șterge filtrele"). Notă tehnică: empty-row-ul tabelului mare a fost scopat la #tbl (al plăților e primul în DOM și ar fi fost capturat de selectorul global). Completare pattern inset (catch BGN, 6.aug): un tabel inset FĂRĂ rând de filtre își pierde aerul de deasupra benzii thead → modificatorul .tbl-noflt dă cardului padding-top: 16px; pe tabelul plăților nu mai e necesar (are filtre din 7.aug), dar regula rămâne în DS pentru cazuri viitoare.
Dashboard — rundă de finisaje (31 iul, cereri BGN): (1) cardul de upload pe ALB (border rule-input; celelalte 2 carduri de acțiune rămân bej) cu copy nou în dropzone: „Încarcă un document" (principal) + „sau trage un document aici" (secundar), butonul „Adaugă document ↑" (săgeata după text); (2) „Vezi toate" din benzile mini-tabelelor = discret: 12px/400/fog (era 13/500/ink — „prea mare și strident"), hover roz; (3) selectorul de perioadă mutat ÎN primul card KPI („VENITURI FACTURATE … 🗓 2026 ⌄"), ca pe secțiuni — dropdown-ul de sus-dreapta scos; opțiunile pe formatele compacte (2026·2025·Q2-26·Q1-26·12 luni·apr.26·mar.26), mecanismul existent al Dashboard-ului păstrat (id-uri neschimbate, datele lui proprii pe perioade).
Dashboard → coada de documente (31 iul, cerere BGN): cardul „27 documente sunt în curs de procesare…" de pe Acasă are la capătul drept linkul „Vezi documentele ›" → duce la cheltuieli#documente, iar pagina de Cheltuieli deschide automat coada pe hash-ul #documente (+ scroll lin la card). Un singur gest de pe Dashboard până la lista neprocesatelor.
Extrase — banda jos-dreapta (22 iul, cerere BGN): în locul totalului „26 luni", lângă dots apare „din mmm.yy" = prima lună a primului cont activ (min(opened) pe conturile modului curent — ex. „din mar.23"); numărul de luni era redundant cu dots-urile, vechimea contului e informația utilă.
Upload REAL în prototip (10 iul, feedback BGN): (v2: funcționează și de pe Acasă — click pe cardul „Încarcă bon, factură sau extras" sau pe buton deschide picker-ul; drag & drop pe toată pagina; tray-ul de confirmare apare sub rândul de carduri. Comentariile din uneltele de review = SCOASE temporar (decizie BGN) — cauza reală a lui „nu merge upload" era interceptarea click-urilor de către modul comentarii; rămân Editare text + Inspector font.)
- Butonul „Încarcă document" deschide file picker-ul (JPG/PNG/HEIC/WebP/PDF, multiplu); orice fișier se poate și trage peste pagină — apare overlay-ul „Lasă documentul aici" (chenar dashed roz, pe tot ecranul, doar cât durează drag-ul).
- Upload-ul confirmă doar PRIMIREA — decizie BGN: conspectarea (citirea + verdictul de deductibilitate) e treaba lui Iris, nu se simulează în upload. Tray-ul arată: nume fișier (sau „x documente" la mai multe, cu până la 3 thumbnail-uri suprapuse) + mărimea → „a ajuns / au ajuns la Bono — Iris le citește; apar în listă pe măsură ce sunt gata" → itemul dispare. Rândurile NU se inventează.
- Format nesuportat → item de eroare pe vocea BONO: „nu pot citi formatul ăsta — trimite JPG, PNG sau PDF".
- Fix pe parcurs: formularul „Adaugă context" din modal era mereu vizibil (CSS
display:flexbătea atributulhidden) — corectat.
De testat cu clienți: contorul „taxe economisite" (îl apreciază?) · sfaturile proactive per cheltuială · dacă pagina e vizitată voluntar sau doar push (varianta „completă" e pentru învățat; se poate simplifica după).
Caveat fiscal (pentru implementare): cifrele „economisit la taxe" din prototip sunt demo pe 16%; mecanismul real diferă pe regim (micro vs profit, TVA) — calculul per client vine din motorul BONO, nu din UI.
Idee parcată: adresă de e-mail per firmă pentru forward de facturi (pattern FGO) — ingest fără fricțiune, de evaluat la modulul de upload.
Audit de conformitate PRD ↔ prototip (3.aug.2026 — 8 agenți, tab cu tab)
Concluzia: implementarea urmează aproape peste tot decizia cea mai recentă; driftul era în majoritate PRD nesincronizat (straturi vechi netăiate), plus câteva bug-uri de coerență între pagini. Verdicte pe tab: Facturi ≈ impecabil · Angajați ≈ 95% · Cheltuieli/Extrase/De plată/Contabilitate/Firma solide, cu lacune punctuale · Acasă purta cele mai multe straturi vechi în PRD.
Corectate în prototip la audit (3.aug): „Vineri 24.apr.26" (era „Joi" — 24.apr.2026 e vineri; toate paginile) · badge Facturi = 6 peste tot (era 7 pe 4 pagini) · kebab-ul la 10px de margine (specificitatea td:last-child bătea regula — Facturi + Contabilitate) · căutarea nu mai prinde textul meniului kebab („pdf"/„vezi"/„trimite" returnau tot — Facturi, Contabilitate, Firma; pe Facturi caută acum și suma fără separator) (notă 6.aug: mențiunile de kebab pe Contabilitate/Firma = istorice — Contabilitate a trecut pe acordeon în v3, Firma pe 4 iconuri vizibile în v1.4; azi doar Facturi mai are kebab) · IBAN-urile din Extrase = sursa canonică din Firma ta (2/3 difereau) · border 18% pe cardurile albe din Contabilitate + Firma (rămăseseră pe 12%) · nav-uri moarte legate (De plată → Contabilitate/Firma; Contabilitate → Firma) · tipografia pe standardul 14/12 retro-aplicată (Extrase, Contabilitate, Firma, fișa Angajați — thead T12 + rânduri 48px) · benzile de grupă Firma = T12 · actorul din tabele = stilul DS (500/pink) · „Descarcă ZIP" pe pachetele de fișe (era „Descarcă PDF") · data constatatorului = 24.dec.2025 (nota „emis acum 4 luni" nu se lega de 18.mar) · footer documente Firma fără „toate la zi" (contrazicea rândul warn) · titlu „Documentele firmei" (heading real, pattern v4) · cifrele KPI pe perioade reconciliate transversal (Acasă ↔ Facturi ↔ Cheltuieli; pe Cheltuieli calculate din tabel: apr 21.416 / mar 6.799 / Q1 127.254) · chip „De ce doar 50%?" · titlul paginii Acasă fără jargon intern · empty-state-ul „1 IBAN" centrat pe pagină.
DECIZII LUATE LA AUDIT (BGN, 3.aug) — toate ✅ închise:
- ✅ DECIS + APLICAT (BGN, 3.aug): emiterea pe Acasă = fără modal, redirect către modulul de Facturare. Cardul cu câmpuri rămâne (pre-completează modulul), butonul „Emite factura" = link-out ↗ ca pe Facturi; modalul „Către cine emitem factura?" a fost șters din Acasă. (Notă 6.aug: pe FACTURI emiterea rapidă trăiește acum ÎN pagină — bara + modalul din §5b Facturi, 5–6.aug. → DEPĂȘITĂ integral în aceeași seară: cardul de pe Acasă a preluat și el modalul de emitere — link-out-ul din decizia de la 3.aug a dispărut de peste tot; rămâne link-out doar pentru cazurile ne-rapide: PF, firme străine, stornări.)
- ✅ DECIS + APLICAT (BGN, 3.aug): salarizarea aliniată la 1 ANGAJAT (decizia din 24 iul, acum și pe De plată): taxe salarii mar.26 = 2.625 (Impozit 390 / CAS 1.500 / CASS 600 / CAM 135) · istoricul + modalul „toate plățile" recalculate pe 1 angajat (feb/ian 2.625; oct–dec.25 2.406 — identice cu coloana „Data plății" din Angajați, incl. dec plătit 25.ian) · KPI dark „De plată acum" 14.967 → 12.700 (8.740 TVA + 2.625 salarii + 1.335 micro), oglindit și pe cardul dark de pe Acasă · scadența „mâine · 25.apr" → „luni · 27.apr.26" peste tot (25.apr.2026 = sâmbătă; termenul legal alunecă). ⚠️ Rămasă în igienă: KPER „Plătite" pe De plată — de recalculat din plățile modalelor.
- ✅ DECIS (BGN, 3.aug): rămâne „Plătit" pe De plată. Divergența e intenționată: De plată = „Plătit" (generic, despre plată/impozit), Facturi = „Plătită" (factura). Nu se mai unifică. (→ Rafinat 30–31.aug de vocabularul de pe mobil: facturile EMISE = „Încasată/Neîncasată" — „Plătită" rămâne DOAR pe facturile PRIMITE (Cheltuieli) și „Plătit" pe obligații (De plată). Aplicat pe desktop la sweep-ul din 31.aug.)
- ✅ DECIS + APLICAT (BGN, 3.aug): detaliile de plată trăiesc în expandarea rândului curent. Bloc „pay-det" pe bej (grilă etichetă/valoare): Beneficiar · IBAN trezorerie (mono) · Suma · Detalii (tip + CUI) +
buton unic „Copiază detaliile"→ v2.6/2.7 (4.aug): copy-icon PER CÂMP cu pill „✓ COPIAT" (5s); butonul unic a fost scos — pe TVA, Taxe salarii și Impozit micro (rândurile plătibile). La Impozite locale beneficiarul era deja primul în text. - ✅ DECIS + APLICAT (BGN, 3.aug): „Salariul total" = Net + Taxe. 6.000 (brutul contractual) era greșit acolo — coloana arată acum 6.135 (3.510+2.625) pe 2026 și 5.624 (3.218+2.406) pe 2025. Fără explicații suplimentare — „e evident că total = net + taxe"; dacă utilizatorii nu se prind, vedem atunci cum explicăm.
- ✅ DECIS (BGN, 3.aug): tooltip dark DS = standardul pentru orice tooltip de conținut;
titlenativ = doar fallback tehnic (ex. undeoverflow: hiddenar tăia — cazul badge-urilor din matricea Extrase, până la poziționarea laterală). Conversia paginilor = în trecerea de igienă. - ✅ DECIS + APLICAT (BGN, 3.aug): anatomia DS și pe cardul dark — „14.967,00 lei" (zecimale 13px alb 65%, „lei" 12px alb 55%); superscriptul și „Lei" cu majusculă au dispărut.
- ✅ DECIS (BGN, 3.aug): dark = doar „Contul tău" (sidebar); persoanele în conținut = avatar pink-tint cu inițială. Starea curentă respectă deja regula — consemnată ca standard.
- ✅ DECIS (BGN, 3.aug): „economisiți la taxe" = DOAR pentru firmele pe impozit pe PROFIT (acolo deductibilitatea chiar reduce impozitul). Majoritatea clienților vor fi pe MICRO (impozit pe venit — cheltuielile nu reduc taxa, cu excepția TVA-ului la plătitori) → demo-ul Youngblood (micro) rămâne FĂRĂ linia de economii. Fluxul Cheltuieli pentru Micro: BGN îl analizează într-un FORK separat (3.aug) — varianta Micro (TVA dedus la plătitori, profit contabil pentru dividende, fără „economisit la impozit") se lucrează acolo și se aduce înapoi în PRD la decizie.
- ✅ APLICAT (3.aug): rând D394 · mar.26 adăugat în Declarații ANAF (generat 23.apr, depus) · rând Bilanț anual · 2024 adăugat în Situații financiare (backing pentru „ultimul depus · 2024" din dosarul de bancă) · datele de generare mutate pe 24.apr.26 (nu mai sunt în viitor) · „martie 2026" → „mar.26" în modalul de bancă · itemul de rail „Alina revizuiește D300" (contrazicea arhiva) → „Alina arhivează dosarul T1 — toate declarațiile depuse", pe toate paginile · arhiva = 30 de documente. Rămase deliberat afară: Cartea Mare & co. (univers demo), S1005/S1120 (zero-jargon). (Notă 6.aug — istoric pre-v3: dosarul/modalul de bancă au fost SCOASE în v3.2, arhiva e acum acordeon cu 15 tipuri · 45 instanțe, iar Cartea Mare A INTRAT în listă — itemul rămâne ca jurnal al datei de 3.aug.)
- ✅ DECIS + APLICAT (BGN, 3.aug): beneficiarul revine în expandarea rândului — primul rând al blocului de detalii de plată (v. #4).
Igienă (fără decizii — le fac într-o trecere separată): ✅ CSS/JS mort — CURĂȚAT (3.aug, ~1.390 linii pe toate cele 7 pagini): scheletele moștenite tăiate (Facturi în Contabilitate/Angajați/De plată, Extrase în Firma) + formulare-modal nefolosite, kper/da-kpi, dm-, pq- vechi, fmtLei/CK_SVG duplicate; metodă: grep 0-utilizări per clasă/id înainte de ștergere, verificare vizuală + consolă curată per pagină; ce se refolosește legitim a rămas (ex. .per-menu viu prin .kper-menu) · resetul pick1 la închiderea calendarului (Facturi) · „Șterge filtrele" pe empty-state-urile Firma + neprocesate · documentul urcat aterizează pe ultima pagină a cozii fără semnal · ancore fără href (Firma) · treapta de hover 30% netokenizată · #FAF9F6 hardcodat pe hover (de facto standard — de tokenizat) · opțiunea „2026" lipsă din perioada Contabilitate (obiect dispărut — v3-acordeon n-are selector de perioadă) · lead-ul modalului IBAN pe Firma vorbește despre Extrase · ✅ REZOLVATE la verificarea din 4.aug: bug-ul data-st="ok" de pe Contabilitate (TypeError la click pe „Bilanț anual") · datele viitoare de pe /cont (facturi Bono iun–aug → feb–apr, următoarea plată 01.mai.26) · formatul dd.mmm.yyyy de pe Firma (29 date → dd.mmm.yy) · CSS-ul mort al modalului de factură de pe Acasă (~78 linii) · footer Contabilitate „toate generate" → „generate și păstrate" (anulat ulterior de rescrierea v3 — footerul curent, corect: „15 tipuri de documente · toate generate de Bono") · td 13px pe Contabilitate → 12 · redirecturile 308 lipsă pentru /cont și /prd · emp-tbl pe Angajați trecut pe sistemul 12/14 + alinierea standard (bază 12 fog centrat, sume 14 ink 500, Luna stânga, Fluturaș dreapta, rânduri 48px — „repara tabelul la Angajați", BGN). RĂMASE: id="new-inv" pe CTA-ul Angajează · clasele KPI din Facturi refolosite semantic greșit pe Angajați · KPI „27.apr" fără an pe De plată · dublin.html monolit vechi (Joi, overlay v7) — de arhivat · dublin-plan.html orfan. NOI (verificarea din 6.aug): glif Unicode „✓" pe butonul „E a noastră" din banda de confirmare eFacturi (încalcă „Interzis" #6 din DS — de trecut pe SVG) · filtrul de valută pe Facturi are doar Lei/Euro, dar bara emite și în USD/GBP (rândurile noi devin nefiltrabile) · <section class="da-table-card tbl-inset"> neînchisă pe Contabilitate + CSS rezidual mort (.tbl-inset .da-table*, du-modal fără markup) — rest de la varianta cu tabel · eticheta navului pe Acasă zice „Plan" ✅ 25.aug: „PRD" peste tot (cerere BGN) · umbra statică pe .pp-zoom (Cheltuieli — invizibilă până la hover prin opacity 0; de mutat pe hover pentru consecvență cu regula flat). DIVERGENȚE PROTOTIP ↔ SCOPE 25.aug (de aliniat când se decide forma MVP a shell-ului): lista Contabilitate din prototip (15 tipuri, cu fișe de cont/registre/PV-uri) ≠ lista canonică · „Întreabă Vox" pe toate paginile vs. chat = CS extern în MVP · rail-ul De făcut + ticker-ul prezente peste tot vs. candidate V2 · „Firmele mele" pe /cont vs. un cont = o firmă.
6. Lista features — MVP
ÎN MVP (Dublin face / arată nativ):
- Home Model B (3 piloni + 2 acțiuni rapide)
- Emite factură (via Facturare, randat în shell)
- Adaugă document — mecanism general de upload (bon / factură străină / extras; manual). Smart: arată opțiunea activă (OB / fără OB)
- Vede facturi emise (toate sursele — în MVP practic doar BONO)
- Vede cheltuieli + cum au fost procesate (deductibilitate 100/50/Nu cu motive)
- Verifică taxe de plată (cifră simplă + situație detaliată; citire)
- DE FĂCUT (confirmări, documente/plăți lipsă, prompt dividende)
- Angajați — situația angajaților (state de plată, taxe salariale, cost total) + lansează angajarea unui om nou (MVP: auto-angajare); datele și execuția prin SalarEasy (API). Empty state = punctul de intrare în angajare („Angajează-te pe tine — noi facem toate actele")
- Caută document (search) · Chat client↔BONO · Acces documente firmă
- Distribuie dividende (surfacate contextual → AGA pregătită de BONO → semnătură Rex)
- Desktop + mobil
ÎN ALT MODUL (Dublin se integrează): Facturare (modulith) · SalarEasy (API, salarizare) · Rex (semnătură, onboarding) · IRIS (procesare, invizibil)
ÎN AFARA MVP (post-MVP / V2 / north-star):
- OpenBanking (sync extrase) → MVP = upload manual
- Plată taxe directă · reminder-uri automate facturi neplătite → post-OpenBanking
- Import SPV multi-sursă (Oblio/SmartBill) → când cere primul client
- Personalizare pe comportament (home se adaptează la ce folosești) → north-star
- Onboarding wizard gamificat → la faza de onboarding
- Stocuri, magazin online, pontaj → nu
7. Principii de design (se aplică peste tot)
- Zero jargon contabil — niciun "Fisa Cont", "Balanță", "Dicționare". Limbajul antreprenorului.
- Simplitate / aerisit / cool — claritatea e esențială; clientul nu trebuie să simtă complexitate.
- Push, nu pull — îi aducem ce contează, nu-l punem să caute.
- BONO face totul — acțiunile vin la client când sunt relevante (ex: "poți distribui X dividende").
- Design system Edge-33 — tokens/componente autoritare; nu inventăm culori/type. Roz folosit rar (max 1 CTA/ecran).
- Formatul datelor (regulă BGN, 10 iul 2026; amendată 6.aug):
dd.Mmm.yy— ex.24.Apr.26, cu ziua pe 2 cifre și luna în 3 litere cu MAJUSCULĂ inițială (— forma din 10 iul, înlocuită pe 6.aug: 616 apariții convertite pe toate cele 9 pagini, inclusiv formatoarele JSdd.mmm.yycu luna micăMON/SHORT) — oriunde apare o dată în Dublin (tabele, plăți, badge LIVE, ticker, DE FĂCUT, calendar, modale, tooltips). Notă: suprascrie convenția DS „13 Apr 2026" — Dublin are formatul lui. Orele rămânHH:MM; cuvintele relative („azi", „mâine") și duratele („depășită cu 29 de zile") rămân text. Majuscula se aplică lunii abreviate în ORICE compoziție:dd.Mmm.yy·dd.Mmm(fără an) · perioada din numele unei taxe/plăți: luna =Mmm.yy(„TVA · Mar.26", „Salarii · Feb.26", „Dividende · Dec.25") și opțiunile selectorului de perioadă KPI („Apr.26 · Mar.26") · datele legale de pe Firma (dd.Mmm.yyyyunde a rămas anul întreg); trimestrul =Tn-yy(„Impozit micro · T2-25") și anul întreg =YYYY— neschimbate. Numele întregi de luni („aprilie 2026" în capul mini-calendarelor) rămân cu literă mică — regula privește doar abrevierea. - Layout pe ecrane late (regulă BGN, 22 iul 2026, corectată în aceeași zi): cele două bare rămân ancorate la margini — meniul la stânga, rail-ul (DE FĂCUT + Live) la dreapta ecranului; doar coloana de conținut se centrează între ele (
.da-contentmax-width 1180 + margin auto în track-ul ei). Prima variantă (tot blocul conținut+rail plafonat la 1470 și centrat) a fost respinsă de BGN — rail-ul trebuie să oglindească meniul, lipit de margine. Sub ~1500px nimic nu se schimbă. Pe toate paginile cu shell. Rail fluid (22 iul): coloana rail-ului crește de la 290px (min) la 400px (max) pe ecrane late —clamp(290px, calc(290px + (100vw − bază) × 0.35), 400px), unde baza = lățimea layoutului complet (1554px pe secțiuni cu meniul de 84, 1682px pe Acasă cu meniul de 212); adică rail-ul ia ~35% din spațiul suplimentar de peste bază și atinge 400px pe la ~1870px viewport. La 400px, itemele din De făcut încap pe un rând. - Căutarea din listări = 360px (22 iul, +50% față de 240px) — placeholderul „Caută după nume sau CUI firmă sau sumă…" se vede complet.
- Borderuri — regula UNIFICATĂ (22 iul, generalizată pe De plată; consolidată la audit 3.aug): alb pe bej-0 = ink 18% (
--c-rule-input) — controale interactive ȘI cardurile albe de conținut: table-cards (toate paginile), cardurile Listei De plată, KPI alb de pe Acasă, fișa de angajat, tray-uri de upload; ink 12% (--c-rule-card) rămâne pentru alb pe bej-1, interiorul suprafețelor albe și dropdown-urile cu umbră. Formularea inițială („containerele pasive rămân pe 12%") = depășită. Tokenii în bono-ds.css, documentați în edge-33. - Clear pe căutare (regulă BGN, 22 iul 2026 — valabilă în tot Dublin „și nu numai"): orice câmp de căutare primește, imediat ce ai început să scrii, opțiunea de a goli textul. Desktop = × în cerc în interiorul câmpului, dreapta (close-ul de modal la scară mică: cerc 17px, bg ink 10%, × fog; hover ink; fade 120ms; click golește + refiltrează + refocus; Esc golește — primul Esc textul, al doilea meniul). Fără roșu și fără „Șterge" scris — alea sunt pattern de mobil („Șterge" mic roșu era varianta veche de mobil). Live pe Facturi, Cheltuieli și căutarea din sidebarul de pe Acasă; pattern documentat canonic în skill-ul edge-33 („Search cu clear ×").
8. Ipoteze de validat
(Doar cele genuin incerte care ar schimba designul. Mecanismele — multe — depind de OpenBanking, deci post-MVP.)
| Acțiune | Ipoteză | Cum validăm |
|---|---|---|
| Emite factură | Vrea să factureze singur dacă e <2 min | Oferim în paralel facturare clasică ȘI conversațională (chat Claude); vedem care e preferată |
| Încarcă bon | Vrea poză→gata, zero muncă (dar unii ar adăuga ceva minor dacă văd valoarea) | Câmp opțional de enrichment cu valoare vizibilă; măsurăm completarea voluntară |
| Verifică taxe | Ar plăti taxele direct din Dublin | Post-OB: buton "plătește"; rata plată directă vs internet banking |
| Caută document | Chat AI ajută să găsești documentul | Rata de găsire cu succes |
| Întreabă | Unii preferă search vs chat; deschidere la Vox vs contabil uman | Oferim ambele; măsurăm split + escaladare Vox→contabil |
| Facturi neplătite | Clientul nu-și ține evidența — se uită în Dublin | Frecvența accesării + folosirea acțiunilor |
| Situația lunară | Formatul potrivit diferă per client | Testăm câteva formate de prezentare |
9. Stadiul curent & ce urmează
✅ Făcut
- Nevoia — închisă (job, actori, context, 9 acțiuni, servicii BONO, no-gos, ipoteze)
- Context permanent — profil client + viziune + harta sistemului (salvate în memorie)
- IA — Model B modern, decis și validat prin research. Secțiuni: Acasă · Facturi · Cheltuieli · Extrase · De plată · Angajați · Contabilitate · Firma ta + Contul tău (relația cu Bono — sub avatar, ✅ construită la
/cont: profil & securitate, firmele mele, plan & abonament, facturile de la Bono, anulare) - Decizie închisă (10 iul 2026): salarizarea în Dublin = DA — pagină „Angajați" (situația angajaților: state de plată, taxe salariale, cost) + lansarea fluxului de angajare (MVP: auto-angajare). SalarEasy rămâne modul extern (API), ca Facturare; Dublin doar afișează și lansează. Aprobarea lunară a statului de plată = item în DE FĂCUT (push, nu pull).
- HOME (desktop) — ✅ FINALIZAT 9 iulie 2026 — specificația completă în §5; prototipul
Dublin/prototype/dublin-acasa.html= sursa de adevăr vizuală. Iterat cu BGN pe: nav deschis, rail 40/60, cele 3 carduri de acțiune (selector valută, card dark fără scadență, dropzone roz + outline-pink), 2 mini-tabele ×10 rânduri cu benzi + tooltip-uri de deductibilitate, aliniere MVP (fără Plătește/OpenBanking/jargon) - CHELTUIELI + FACTURI (desktop) — ✅ FINALIZATE 10 iulie 2026 — specificația în §5b.
- TOATE cele 9 pagini construite (8 secțiuni + Contul tău) și live (22–24 iul + sesiuni paralele): Extrase · De plată · Angajați · Contabilitate · Firma ta — specificațiile în §5b.
- Tab PRD live (3.aug) — la
/prd, cu 2 tab-uri: Arhitectura (analiza de implementare) + Specificații (acest document). - Sesiunile din 3–4 aug (multiple, în paralel): pagina Contul tău (
/cont) · toggle Micro/Profit pe Cheltuieli (default Micro) · Plăți fără documente v2 (modal cu listă + atașare) · KPI Facturi pe materiale (alb/DARK/bej — „Emise/Încasate/Neîncasate") · coloana Plată pe Cheltuieli · tabelul inset pe 5 pagini · titluri de tabel 24px · module simulare Angajați (0/1/3) · De plată v2.7 (detalii de plată copiabile per câmp) · nav 400w + 10px · reconciliere completă PRD↔prototip (audit 8 agenți + verificare 4.aug). - 4 aug — decizie de arhitectură majoră (BGN + Prodi): NUCLEUL central. Se construiește un modul nou — system of record + hub („engine-ul contabil"; numele final de ales) — care stochează toate informațiile și documentele firmelor. Dublin și Vertigo devin SHELL-URI (input + afișare) peste API-ul nucleului; Iris și SAGA = procesoare atașate în aceeași priză (iau date din nucleu → prelucrează → livrează înapoi); SAGA devine astfel înlocuibilă treptat, calcul cu calcul. Pentru produs NU se schimbă nimic vizibil — principiul „inițiere sau afișare" rămâne; se schimbă doar instalația din spate. Notă de citire: etichetele [IRIS-API]/[CONT-API]/[ED→Document Gateway] din secțiunile mai vechi se citesc acum ca contracte ale nucleului (Dublin consumă un singur API — al nucleului). Modelul complet, argumentele pro/contra și regulile de perimetru: tabul Arhitectura, §4.0.c + §7.
- Sesiunile din 5–6 aug (multiple, în paralel): Facturi — quick-invoice bar + modalul „Emite factura" (pașii 1–2 în bară, 3–4 în modal; punch-list-uri v2–v4 BGN 5–6.aug — spec completă în §5b Facturi) · Contabilitate v3 ACORDEON (5.aug — bare bej per tip, 15 tipuri, istoric per instanță; „dosarul pentru bancă" scos cu corecție de domeniu) · regula „site plat" (5.aug, BGN „nu vreau umbre în site"): zero umbre statice pe toate cele 9 pagini, plutitoarele se separă prin border 18%; adâncimea doar la hover · centrarea optică a labels în banda thead (5.aug — breve-ul din Ă coboară textul; padding 11/9) · amendament aliniere: celulele Client/Descriere = stânga (labels din cap rămân centrate) · banda de confirmare eFacturi primite pe Cheltuieli („furnizor nou · neplătită de 30 zile — E a firmei tale?" cu E a noastră / Nu o recunosc + badge „De confirmat" pe rând + item în De făcut) · Firma: modal „Cere un document" + documentele pe pattern inset cu grupe-acordeon. Decizie 6.aug (BGN): seria+numărul facturii vin din mini-serviciul de SERII al modulului de facturare — alocare atomică la emitere; Dublin nu numerotează niciodată local (v. §5b Facturi). Tot 6.aug: formatul datelor →
dd.Mmm.yy(luna abreviată cu majusculă; 616 conversii pe cele 9 pagini + formatoarele JS; regula amendată în §7 — citatele mai vechi din acest jurnal păstrează grafia de la data lor). - Sesiunile din 6–7 aug (seara/noaptea): modalul de emitere adus și pe Acasă (cardul „Emite o factură nouă" = pașii 1–2, deschide același modal; link-out doar pentru PF/străine/storno) · Plăți fără documente v3 (bandă sub KPI + TABEL inset cu filtre — înlocuiește modalul v2; „alege din cele încărcate" retras: alocarea documentelor conspectate o face Bono) · finisaje modal (formula de curs în câmpul Sumă, lățime 493px, iconuri share 18px).
- 25 aug — REORGANIZAREA PRD (feedback Prodi):
/prdare acum 3 tab-uri: Funcțional (nou, default — ce afișăm / din ce sisteme / ce acțiuni + reguli & stări; fără niciun detaliu de UI; sursă:dublin-prd-functional.md) · Arhitectura · Jurnal (acest document — decision-log-ul complet, fost „Specificații"; link-urile vechi#specificatiimerg în continuare). Regula de scriere de-acum: faptul → Funcțional (starea curentă, fără arheologie) · povestea → Jurnal · pixelii → prototip + edge-33. Proiectul s-a mutat pe disc înProiecte IT/Bono/Dublin/. - 31 aug — CONCLUZIILE ECHIPEI integrate (doc „Analiza Vertigo–Dublin–IRIS — Concluzii finale", 25.aug — A1–A3 + minuta dev + minuta BGN & Prodi; repo
vertigo-product/arhiva): modelul nucleu+procesoare+shell-uri confirmat de echipă. Schimbări preluate în Funcțional + Arhitectura: (1) facturile emise = stăpânite de NUCLEU (baza facturilor; [F] rămâne motorul emiterii — serii + e-Factura; facturile externe tip Smartbill intră prin upload → Iris le identifică drept venit) · (2) reconcilierea = modul LÂNGĂ nucleu, NU în Iris (redecis — facturile pot fi anulate/modificate; Iris livrează doar plățile din extrase; fezabilitate de confirmat până la 1 oct) + mini-registrul de solduri taxe (Σ obligații SAGA − Σ plăți; salarii per IBAN, contribuții agregat) · (3) statusul canonic per document: neprocesat · primit · în lucru · respins+motiv · finalizat (identic Dublin↔Vertigo — B1) · (4) Contabilitate = lista canonică aliniată cu Vertigo (Balanță, Registru inventar, D112, D311, D100 L/T, D301 CUI/VIES, D390, D406, S1120, D101, bilanț+SAF-T anual, D205; fișele de cont + fișa MF = V2; restul la cerere) · (5) SCOPE MVP (BGN & Prodi): fără useri/roluri per firmă · un cont = o firmă · chat = aplicație CS existentă (Vox = V2) · feed live + „De făcut" = candidate V2, PRD separat · idee în analiză: buton „Plătește taxele" (card → ANAF; legal + tehnic la Cristi). PRD-urile IRIS există: iris.bgn.ro/prd + /atribute + /modele-date. Ownership modul reconciliere: PRODI (accountable) — decizie BGN, 31.aug. Fluxul documentelor pe care Iris nu le poate interpreta („în așteptare" + goluri de context): se propune ÎN IRIS, cu comunicare spre Dublin și Vertigo prin nucleu (BGN, 31.aug) — de așteptat propunerea echipei Iris. Triaj universal (BGN, 31.aug): ORICE document de la client ajunge în Iris pentru triaj (inclusiv contracte, PV-uri); ce facem cu documentele speciale după triaj = de decis în Iris. Facturile emise — înregistrarea contabilă HIBRID pe sursa descrierii (BGN, 31.aug): preset → TAC automat, fără Iris; descriere de mână → Iris/Larry. De înțeles: veniturile se înregistrează diferit pe criterii (produse/servicii/avans)? — leagă preseturile de CAEN (Otilia/Raluca). - 5 sep — a doua pagină de comparație: CHELTUIELI pe DS canonic (
/cheltuieli-38). Generată din datele paginii reale (26 rânduri, primele 10 afișate + paginare, plățile fără documente, benzile, rail-ul), cu componentele DS: sidebar.icon-only64px (modul „compact" al DS-ului — etichetele dispar, doar iconițe + tooltip; badge-urile pe colț) ·.insightpentru „Iris observă" (în locul cardului nostru roz din stivă) ·.alert.warning/.alert.neutralcu.alert-actionsîn locul benzilor proprii (plăți fără documente · confirmarea eFacturii) ·.kpi×3 cu.delta+ comutatorul Micro/Profit ca.tabs(funcțional: ascunde coloana + filtrul de deductibilitate, schimbă etichetele) · perioada ca.tabs· tabel.tblcu filtre.select+.search-wrap, badge-uri DS pentru tip/deductibilitate/plată (fără plăcintele noastre), paginare din.btn.icon-onlyîntfoot· strip „În procesare" pe.card.tonal· h1.t48. Toggle 33/38 pus și pe Cheltuieli-33 (compact, în sidebar-ul colapsat; scripturile review scoase). Lecție: clasa DS.datedin.tble stilizată cu majuscule — nu se refolosește pentru sub-rânduri (înlocuită cu clasă neutră). Verificat la 1440: fără overflow, zero erori. - 2 sep — „EDGE 38" = Edge-33 CANONIC; Home-ul rescris pe DS-ul canonic ca pagină de comparație (
/acasa-38). Investigație (canalul #-project-design-system + repobono-ro/edge-33): nu există un DS „Edge-38" — e numele vechi al repo-ului, redenumit edge-33 pe 16.06.2026; ce lucrează Octav = edge-33 pe main, v8-dev (release-uri numerotate v6→v7→v8, v8 = primul cu tag, încă netăiat,--ds-breaking-since: v8; consumatorii țin copii ștampilate — „re-stamping is a migration"). Canonicul are 3.949 linii CSS vs 753 în copia Dublin (neștampilată, pre-v6), 45+ componente cu contract, gărzi de CI, referință proprie „Dublin-aligned". Cele 8 conflicte cu deciziile Dublin, toate aplicate CUM LE ARE DS-UL (cerere BGN, pentru comparație): (1) borduri controale ink 30% (nu 18%) · (2) umbre DS (--sh-xspe sidebar activ,--sh-popoverpe popover) · (3) dark =--c-dark-grad(gradient magenta, nu negru plat + glow) · (4) flow-chrome mobil — n/a pe desktop · (5) uploadul = componenta.uploader(fără dropzone paralelă/drag global) · (6) tipografie doar prin clase DS (h1 =.t48,.t-emexplicit,.t14baseline, „Lei" cu majusculă în unități) · (7) butoane-icon =.btn.icon-only· (8) sidebar = rail DS 240px. Construit:dublin-acasa-38.htmlgenerat din datele paginii Acasă (nav 11, 2×10 rânduri, rail 7+1, ticker) pe.app-shell+.sidebarcanonic,bono-ds-38.css= copie ștampilată v8-dev · 2026-09-03 (neatinsă, linkată relativ — regula DS), KPI-uri.kpicu.delta,.card.tonal/.dark, typeahead +.selectvalută,.uploader,.tbl.compact+.badge sm,.pulse-dot,.badge.live,.vox-fab.ai; lint DS curat (zero Fraunces inline, zero hex nou, toate clasele există). Ajustare locală: pragul container-query al rândului de acțiuni 862→780px (DS l-a calibrat pe rail-ul de 64px; cu sidebar 240 coloana are ~846px la 1440). Toggle „Edge 33 · 38" în locul „Unelte review" (scoase de tot de pe Acasă, inclusiv scripturile de review — BGN: „nu mai avem nevoie"); pe 38 =.tabsDS în footer-ul sidebar-ului. Restul paginilor rămân pe Edge-33 vechi până la feedback. Verificat la 1440: 3 carduri/rând, fără overflow, zero erori. De decis după feedback BGN: migrăm pe v8 tăiat (nu v8-dev) · cele 8 conflicte se tranșează cu Octav · aplicația realăbono-ro/dublin(Prodi) aliniază deja la DS din 1–2 sept. - 31 aug, seara — „BANII TĂI ÎN FIRMĂ" (mini-Bruce cu BGN: triaj FEATURE · JTBD + Shape Up + Mom Test · 2 runde a câte 3 întrebări): nevoia = „câți bani pot scoate din firmă?" — azi BGN cere pe mail contabilului „cât pot scoate + ce împrumuturi am dat" (job real, recurent, cu round-trip uman). Decizii BGN: (1) trei buzunare — dividende + deconturi + împrumuturi, cu NET + impozitul aferent afișate; (2) dividendele = suma totală distribuibilă contabil (tot profitul acumulat nedistribuit, FĂRĂ estimări pe anul curent; o primim de la conta); (3) sumele = dreptul teoretic din contabilitate — v0 NU are soldul bancar live („dacă sunt bani"); (4) permanent pe Home, ca rând nou de carduri; (5) fluxul: clientul își face plata singur din bancă → o vedem în extras (sau ne anunță) → distribuim/formalizăm efectiv — fără plăți din Dublin în MVP; (6) metoda de calcul a impozitului (CASS pe praguri etc.) = parcată, „găsim un mod, nu ne batem capul acum". Research: Keez arată deja în dashboard suma maximă distribuibilă (+ dividende trimestriale, AGA + impozit 16%) — deci e table stakes în categorie, nu diferențiator; marginea Bono = tabloul complet (3 buzunare, nu doar dividende) + fluxul plătește-tu-întâi. CONSTRUIT pe Acasă desktop: eyebrow „· Banii tăi în firmă" + link „Cum îi scoți?" (explainer-modal pe vocea Bono: transfer → extras → acte → impozit în De plată; deconturi/împrumuturi fără impozit; „verifică să ai banii în cont") + rând de 3 carduri albe (pattern KPI Acasă): De distribuit 15.000 (net 12.600 · impozit 2.400 — coerent cu insight-ul din rail „până la 15.000") · De recuperat 2.318 (4 documente plătite personal) · Împrumuturile tale 10.000. Simetria cu cardul dark: ce datorezi statului ↔ ce e al tău. Deschise: poziția rândului (azi: sub KPI-uri, deasupra acțiunilor — de validat) · culorile buline · Home-ul MOBIL = redeschidere explicită cu sesiunea de mobil (pachetul de stare dark+trio primește un frate) · sarcina „am văzut un transfer către tine — dividende?" în De făcut (consecința fluxului, de construit) · calculul impozitului la motor.
- 8 sep — HOME pe 3 FAMILII + pagina „BANII TĂI" (
/banii), din discuția cu BGN: feedback BGN pe rândul de 6 carduri („prea multe, super aglomerat"): informația reală = 3 familii — Venituri (total · încasate · neîncasate) · Cheltuieli (total · deductibile · nedeductibile) · Poți scoate (dividende · împrumuturi). Construit pe Acasă cu comutator de comparație „3 familii / 6 carduri (azi)"; decizii pe parcurs: fără impozit în card (doar în explainer) · cele două sub-cifre SUB cifra mare (varianta inline-dreapta încercată: slim ca v6c doar peste ~1560px; la 1440px cardul are 281px și nu încape — reținut ca limită fizică) · „Împrumuturi" = deconturi + împrumuturi (BGN: „deconturile sunt tot un fel de împrumuturi" — contabil corect, 455) · cardurile = 123px (v6c: 102). Pagina „Banii tăi" (BGN: „fă pagina, îi zicem Banii tăi"): KPI bej Poți scoate·net / Dividende / Împrumuturi · tabelul Distribuiri (rând highlight „Disponibil acum" + istoric cu brut/impozit/net/stare + „Vezi decizia"; click → modal cu viața distribuirii: transfer văzut → confirmat → decizia pregătită de Alina → impozit plătit) · tabelul Împrumuturi cu grupe (împrumutul asociat cu contract „de semnat" + CTA roz „Semnează" → modal Rex → „semnat · 24.Apr.26"; „Plătite personal · 4 documente" 2.318 lei) · explainer. Nav: item nou după De plată, pe toate paginile desktop (+ rewrite/banii); cardul de pe Home = link. Default-uri alese de Claude, de validat: contractul se generează la detectarea transferului (nu înainte) · deconturile listate document cu document în grupa lor · eticheta cardului rămâne verbul („Poți scoate · net"), pagina = substantivul. Idee ridicată de BGN, DESCHISĂ: pe MICRO cardul Cheltuieli e irelevant → propunere Claude: „Până la pragul de micro" (lei rămași până la 100.000 €, % + estimarea lunii) — comutat de regim, ca pe pagina Cheltuieli; de decis cifra mare (lei vs %) și dacă estimarea intră în v0. Mobil: familia a 3-a + Banii tăi în Meniu = de tratat cu sesiunea de mobil. - 8 sep — „BANII TĂI" v2, STRUCTURA PE 3 NIVELURI (corecție BGN: „Poți scoate e totalul — nu poate sta pe aceeași linie cu sumele din care e compus"): (1) totalul ca ancoră: card alb lat „Poți scoate · net 34.158" + explainerul · (2) trei carduri bej-componente (click = lista dedesubt, o singură listă odată, ca expandarea de pe De plată): Dividende 21.840 cu cele două informații cerute — nete, decise prin AGA — de ridicat: 9.240 și profit nedistribuit: 15.000 = 12.600 net + 2.400 impozit · Deconturi 2.318 (4 documente) · Împrumuturi 10.000 cu pill-ul contractului pe card · (3) listele: Dividende (rând „Profit nedistribuit" + distribuiri cu stare: decise · de ridicat / ridicate · impozit plătit; click → viața distribuirii — martie 2026 = decisă, neridicată, cu nod de așteptare „așteaptă transferul tău") · Deconturi (documentele) · Împrumuturi (contract de semnat → Rex; ambele pill-uri se actualizează). Decizie BGN: totalul include și dividendele nete nedistribuite (profit nedistribuit − impozit) → 21.840 + 2.318 + 10.000. Home propagat: „Poți scoate · net 34.158 · Dividende 21.840 · Împrumuturi 12.318". KPI-urile v1 de pe pagină (3 egale) = retrase. Bug prins: la înlocuirea conținutului se pierduse
</div>-ul coloanei — rail-ul căzuse sub conținut; reparat pe numărătoare de div-uri. - 31 aug, seara — SWEEP-UL DESKTOP din deciziile mobile (aprobat BGN: pachetul A + C1–C5; C6 „fără texte explicative" = punctual, ulterior): (A1) vocabularul de status — Facturi + mini-tabelul de pe Acasă trecute pe „Încasată/Neîncasată" (16+7 pe Facturi, 11 pe Acasă; filtre „Încasate/Neîncasate", KPER „toate încasate"; Cheltuieli/De plată neatinse — acolo „Plătită/Plătit" e corect) · (A2) verdictul „Parțial" pe Cheltuieli (plafon de categorie; Casa Doina → Parțial cu motivul plafonului; filtru + chip „De ce parțial?" + mini-plăcintele pe toate badge-urile: 16 full · 5 half · 1 part · 3 no) · (A3) explainerul „De ce contează documentele" — link „De ce contează?" pe banda plăților fără documente → modal cu copy-ul BGN verbatim (avans spre decontare → risc ANAF) + CTA „Vezi plățile" · (A4) „Trimite" pe Contabilitate — buton per instanță (44 buc.) cu meniul Vezi documentul · Email · WhatsApp (paritate cu Firma v1.4) · (A5) pachetul „Date facturare" pe Firma — link pe cardul Datele firmei → modal cu previzualizarea exactă (Denumire · CUI: RO47281930 · J40/2214/2023 · Sediu) + Copiază (cu confirmare) / Email / WhatsApp · (A6) regula „nu primim index ANAF" în Funcțional · (C1) constatatorul + specimenul șterse din Firma (grupa ONRC 5→2 — contorul era stale și după ștergerea mențiunilor; warn-ul de vechime scos; fluxul rămas: „Cere un document", cu constatatorul ca exemplu în placeholder) · (C2) rail-ul De făcut reordonat după urgență pe toate cele 8 pagini: D394 (azi) → ANAF (termen) → extrasul (blochează luna) → lipsesc documente → confirmări → dividende (insight; bugetul „~4 itemi" de pe mobil NU s-a aplicat — e al ecranului mic) · (C3) „Rezolvate azi" sub active: item bifat demo („Încarcă extrasul BCR — rezolvat azi la 06:33", coerent cu ticker-ul), stins, cu strikethrough · (C5) timeline-ul „viața facturii" în modalul de detaliu Facturi (Emisă ✓ → e-Factura ✓/puls „se trimite" → Încasată ✓ / nod gol „așteaptă plata") — înlocuiește rândul Status + nota · (C4) checkul verde e-Factura scos de pe rândurile tabelului (21) — pe listă semnalul = doar excepția (pulsul „se trimite"); confirmarea trăiește în detaliu. Funcționalul actualizat pe toate punctele.
- Audit de conformitate PRD ↔ prototip (3.aug) — 8 agenți, tab cu tab; v. secțiunea „Audit" din §5b: corecțiile aplicate + deciziile rămase deschise. Verificare cross-sesiuni (6.aug, 3 agenți): fosilele post-v3 curățate (dosar bancă, kebab/perioadă pe Contabilitate, footere), §5b redenumit (acoperă toate cele 9 pagini), igiena completată cu constatările noi.
- Loop de feedback pe prototip — editare text inline cu export (validat în practică); toggle-uri în sidebar, stare persistentă între pagini
⏳ De făcut (următorii pași)
- **Deschise reale (revizuit 6.aug): naming Dashboard/Acasă (
eticheta „Plan"✅ 25.aug: „PRD" peste tot) · starea de eșec a documentelor (în contractul Iris) · KPI Acasă la regim Micro · KPER „Plătite" pe De plată · detaliu per angajat (mod echipă) · paginare istoric + KPI pe Contabilitate (dosar bancă— dizolvat de v3.2) · matricea Extrase + mini-tabelele Acasă la inset ·cardul „Emite o factură nouă" de pe Acasă(rezolvat 6.aug: preia comportamentul widgetului din Facturi, cu modal) · pragul de 30 zile la confirmarea eFacturilor primite (vs scadența facturii) + heuristica „furnizor nou" - Stări — empty / onboarding (wizard — idee parcată) / erori (+ starea de eșec a documentelor)
- Mobil — reluat după secțiunile desktop (desktop-first; prioritizarea mobil = parcată)
- Decizii vechi deschise: timing import SPV
- ✅ Igienă de cod — FĂCUT (3.aug) — CSS/JS mort curățat (~1.390 linii pe cele 7 pagini), fără schimbări vizuale; rămân itemii mărunți din lista „Igienă" (§5b Audit): pick1, „Șterge filtrele", ancore fără href, tokenizări hover etc.
10. Artefacte & cum rulezi prototipul
SITE DE TEST (public): https://dublin.bgn.ro ✅ LIVE (SSL activ) — deploy Vercel din Dublin/prototype/ (proiect dublin-proto, cont bgn33). URL-uri curate: / și /acasa → home · /facturi · /cheltuieli · /extrase · /de-plata · /angajati · /contabilitate · /firma · /cont · /prd · /plan (istoric, orfan — navul duce la /prd) — redirect 308 de pe vechile /dublin-*; maparea în vercel.json. Noindex (X-Robots-Tag). Alias: dublin-proto.vercel.app.
Redeploy după orice modificare: vercel deploy --prod --yes din folderul prototype.
Infra: DNS Cloudflare (A dublin → 76.76.21.21, DNS-only, adăugat via API). Token Cloudflare (Edit zone DNS · bgn.ro) salvat în Keychain macOS: service cloudflare-api, account bgn — citire: security find-generic-password -s cloudflare-api -w.
Prototipuri CURENTE: Desktop/Proiecte IT/Dublin/prototype/
dublin-acasa.html— HOME (sursa de adevăr)dublin-facturi.html·dublin-cheltuieli.html·dublin-extrase.html·dublin-deplata.html·dublin-angajati.html·dublin-contabilitate.html·dublin-firma.html · dublin-cont.html— secțiunile (§5b)dublin-prd.html— tabul PRD (generat din acest document cubuild-prd.py— rulează-l după orice modificare a PRD-ului, înainte de deploy)dublin-plan.html— harta veche (în afara meniului, pe/plan) ·dublin.html— pagina DS canonică (referință)
Preview local pentru verificare: mirror în ~/dublin-preview (serverul de preview nu are acces la Desktop) — după orice modificare: rsync -a --delete "Desktop/Proiecte IT/Dublin/prototype/" ~/dublin-preview/; server pe portul 8734 (config Desktop/.claude/launch.json).
Pornește serverul local:
python3 -m http.server 8732 --directory "/Users/bgnpro17/Desktop/Proiecte IT/Dublin/prototype"
- Home: http://localhost:8732/dublin-acasa.html
- Plan: http://localhost:8732/dublin-plan.html
Prototipuri VECHI (depășite, cu banner): SuperBoris/skills/edge-33/references/dublin-home-v2.html + dublin-home-mobile.html (port 8731).
Feedback pe prototip: unelte de review în sidebar (Acasă: switch-uri inline; secțiuni: rotița ⚙ → du-modal): Editare text (rescrii inline → Export JSON, Claude îl aplică în sursă) + Inspector font. Comentariile = scoase temporar (10 iul). Comentariile Vercel pe deploy = dezactivate (31 iul — nu ajung la Claude; feedback = screenshot în chat sau exportul de editări).
Design system: SuperBoris/skills/edge-33/ (BRAND.md, bono-ds.css, SKILL.md).
Documente conexe:
Bruce v2/produs-learnings-dublin-3iun2026.md— învățăturile de proces (pentru Bruce)- Memorie:
project_dublin.md,project_bono_system_map.md,user_bono_client_profile.md,project_bono_vision.md
Research (de salvat ca fișiere separate — momentan doar în transcript): research 12 platforme (Nevoie) + research home-vs-navigație (IA) + analiză Keez.