Distribuitor owner: lista produselor, FAB pentru produs nou, intrare în detaliu pentru editare / arhivare / ajustare stoc. Agent (distribuitor): aceeași listă, dar ajustarea stocului devine acțiunea primară direct pe cardul produsului — pentru depozit, unde fiecare tap contează.
Empty state: card cu signature shadow + CTA accent. Day-0 trebuie să simtă invitație, nu spațiu gol.
createProduct({distributorIdno, productInput, openingStockOnHandMilli}) ·
Editare → updateProduct({distributorIdno, productId, patch}) ·
Arhivare → archiveProduct(...) (refuză cu failed-precondition dacă produsul are comenzi nefinalizate) ·
Ajust. stoc → adjustStock({distributorIdno, productId, deltaMilli, reason, note?}) · scrie atomic products/{id} + entry în inventoryLedger/{id}.
Vedere completă. Tap pe card → detaliu (Phone 2). Tap pe + → sheet de creare. Empty state apare doar la day-0.
Header signature card. Stocul curent (pe mână / rezervat). Acțiuni primare: editare / ajustare / arhivare. Ledger-ul recent direct în pagină.
Aceeași listă, fără create / edit / archive. Fiecare card are un stepper — agentul ajustează stocul direct, fără să intre în detaliu.
Câmpurile corespund exact tipului Product: nume, SKU (verificat unic), UM, preț fără TVA, TVA chips 0/8/20, stoc inițial → scrie o intrare restock în ledger.
Delta cu semn + motiv obligatoriu (chips). Notă opțională. Scrie o intrare în inventoryLedger cu actorul și motivul.
Catalog gol. Invitație directă, nu spațiu mort. Mențiune că produsele devin vizibile retailerilor legați.
Adaugă primul produs ca să poată fi văzut și comandat de retailerii legați. SKU-ul trebuie să fie unic în catalogul tău.
restock în ledger.