# Fiken-ekvivalent za HR — ciljna arhitektura i odluka (2026-07-25)

# Fiken-ekvivalent za HR tržište — ciljna arhitektura i odluka

**MC:** #106300 · **Datum:** 2026-07-25 · **Status:** PHASE-GATE DJELIMIČNO POTPISAN — tačka 5 (RS/BA) potpisana 2026-07-29; preostalih pet iz §10 i dalje otvoreno i P1 se bez njih ne otvara
**Tim:** Petter Graff (arhitektura) · Brad Frost (IA/dizajn) · HR porezni ekspert (statutarni sloj) · Finverge (komercijalni model) · John (sinteza, verifikacija, web tiebreak)
**Temelj:** BookStack 3258 (Fiken mapa) · `~/system/evidence/106300/HR-CLONE-BRIEF.md`

---

## 0. Presuda u jednoj rečenici

**Backend se proširuje u mjestu (EXTEND), frontend se gradi iznova (greenfield ljuska).**
Ne fork, ne rebuild backenda.

Obrazloženje koje preživljava neprijateljski review: četiri najskuplja sloja već postoje i
jurisdikcijski su čista — `CountryPlugin` dispatch, GL foundation s `PostingRules` engine-om,
`ObligationCatalog`, i audit/retention program (V124-V132, prošao tri runde adversarial reviewa).
**146 migracija je fosilizovano statutarno učenje** — svaka od tih odluka je jednom već koštala
reviewa s ekspertom. Rebuild ih ne dobija besplatno.

Uz to: Fiskalizacija 2.0 upravo **ponovo prodaje cijelo HR tržište** — svaki SMB bira alat za
eRačun sada. Rebuild troši jedini nenadoknadiv resurs.

CEO-ovo „i izgled izmijenite skroz" **ne implicira backend fork**: App Router dopušta potpuno novu
ljusku nad istim API-jem, pogotovo jer navigacija ionako postaje derivat `/me/capabilities`.

### Najjači argument protiv (steelman, od samog arhitekte)
Bilko nosi multi-market teret — svaki HR potez mora ne slomiti RS/BA (4-jurisdikcijska test
matrica, 8-gate CI), a permissive-RLS i dvostruki GL su dugovi koje greenfield ne bi imao.
**Ova presuda pada pod tačno jednom premisom: ako CEO odluči da su RS i BA mrtav teret.** Tada
argument za fork postaje ozbiljan i mora se ponovo odvagati.

---

## 1. Četiri ispravke koje je ovaj rad proizveo

Vrijedi ih izdvojiti jer su sve nastale tako što je neko **provjerio umjesto da vjeruje**.

| # | Tvrdilo se | Stvarno stanje | Kako je uhvaćeno |
|---|---|---|---|
| 1 | RLS je PERMISSIVE, pokriva **9 od 69** tabela | **55 tabela** ima ENABLE RLS, **47** i FORCE RLS, **0** politika je `AS RESTRICTIVE` | Nezavisno izmjerili John i Graff nad svih 146 migracija; prvi nalaz je čitao samo V17 i to pošteno priznao |
| 2 | Storecove je aktivni eRačun put | **sveRačun/PostLink** je aktivni put (env-driven, per-org `IssuerProfile` gate); Storecove je stariji sporedni artefakt | Domenski ekspert, `docs/runbooks/sveracun-hr-go-live.md` |
| 3 | Prirez je hardkodiran za četiri grada | Kod je **stroži** od dokumenta: default 0.0 + fail-loud guard. Ali — **prirez je ukinut 1.1.2024**, pa je cijeli model strukturno pogrešan | Graff posumnjao → **John web tiebreak** → potvrđeno. **MC #106302** |
| 4 | JOPPD ne postoji | Postoji **praćenje roka** (`PaymentEventObligationService.kt:18-51`, red-zone-verifikovano pravilo „na dan isplate"), ne postoji **sam podnesak** (XML + slanje) | Domenski ekspert |

**Metodološka bilješka uz #3:** domenska persona je u istoj sesiji pisala o prirez guardu ne
primijetivši da je porez ukinut. Arhitekt bez domenskog mandata je posumnjao. Ovo je treći put da
pravilo *„persona bez weba = NEODLUČIVO, ne TAČNO"* spašava statutarnu tvrdnju.

---

## 2. Fikenovih deset odluka — presuda po odluci

| # | Odluka | Presuda | Stanje u Bilku |
|---|---|---|---|
| 1 | Jedan draft engine, N dokumenata | **ADAPT, dubinski** | Pola puta: `InvoiceDocumentType` enum postoji (V47), ali `Offers`/`OfferItems` su paralelne tabele s vlastitim servisom |
| 2 | PDV kao semantička kategorija | **ADAPT, dubinski** | **Ne postoji na dokumentu** — linija nosi sirovi `taxRate` decimal. Semantika pola postoji u GL sloju |
| 3 | Izdato = nepromjenjivo | **ADOPT + pooštriti** | Servisni guardovi rade (`InvoiceService.kt:824`, `:1039` — *John verifikovao*), ali **nije DB-enforced** |
| 4 | Soft delete svuda | **ADOPT** — već tu | `deletedAt` na Invoices/InvoiceItems/Transactions |
| 5 | Rokovi prvorazredni objekt | **ADOPT** — već tu, dograditi | `ObligationCatalog` + `ComplianceCalendarService` isporučeni. Fali drugi dio: **rok se zatvara podneskom** |
| 6 | Knjiženja po namjeri | **ADOPT** — već tu | `PostingRules` + `AccountMapping` postoje. Fali samo UI sloj s intent-dugmadima |
| 7 | Multi-kanal slanje s `auto` | **ADAPT** | `InvoiceSendEvents` = analog `dispatches[]`. HR prioritet ≠ NO: eRačun → email+PDF → SMS |
| 8 | Auto-popuna iz registra | **ADOPT** — već tu | `OibValidator` + `TaxIdLookupService` |
| 9 | Kontni plan s favoritima | **ADOPT** — jeftino | RRiF seedan (V97). Minimaxovu trajnu RRIF/RIF zamku **ne kopiramo** — kontni plan je podatak, ne sudbina |
| 10 | Entitlement pokreće navigaciju | **ADOPT + redizajn** | Mehanizam klija (`sidebar.tsx:90,138,183`), ali postoje **četiri nepovezana gating sloja** |

### 2a. Dvije najveće poluge

**Draft engine.** Ciljno: jedan `SalesDocument` pipeline, tip ∈ {invoice, cash_invoice, offer,
order_confirmation, advance, final, credit_note, repeating}. Preduslov koji se lako previdi:
**numeričke serije** — `Invoices` danas ima `unique(organizationId, invoiceNumber)`, pa bi se
ponude sudarale s računima. Treba `number_series` + `unique(org, series, number)`. HR i inače
traži odvojene serije. Rizik migracije nizak jer ponude nisu ni GL ni statutarno vezane.

**`vat_category`.** Umjesto sirove stope na liniji: kategorija (`STANDARD_25`, `REDUCED_13`,
`REDUCED_5`, `ZERO`, `EXEMPT_ART39/40`, `RC_DOMESTIC`, `RC_EU`, `EXPORT`, `OUTSIDE`, `NA_PAUSAL`)
plus `vat_rates(jurisdiction, category, valid_from, rate)`. Stopa se izvodi iz kategorije + datuma
i validira pri izdavanju; `taxRate` ostaje snapshot radi nepromjenjivosti.
**Zašto se isplati:** HR eRačun (EN 16931 + VATEX razlozi oslobođenja) i PDV obrazac traže
„zašto", ne samo stopu. Bez toga svaki izvještaj reverse-engineeruje namjeru iz brojke.
**Gate:** dual-run PDV obrasca (stari put vs derivacija) mora dati **diff=0 po orgu** prije nego
kategorija postane izvor istine.

---

## 3. GL — presuda i put

**Kanonski je `JournalEntries`/`JournalPostings`.** Sam kod je to već presudio
(`GlTables.kt:22-24`). Dvostrano knjiženje s jednim debit/credit parom ne može iskazati fakturu s
PDV-om (3+ noge) — to nije GL, to je evidencija plaćanja.

**Blokeri koje treba riješiti PRIJE proglašenja kanonskim:**
1. `JournalPostings` **nema `org_id`** → RLS na noge nemoguć, izolacija visi o JOIN-u
2. Balans nije DB-enforced — treba deferred constraint trigger `sum(debit)=sum(credit)`
3. POSTED-nepromjenjivost triggerom
4. Prava `accounting_periods` tabela (danas `locked` živi samo na `Transactions`)

**Put bez big-banga — četiri kapije:**

| Faza | Šta | Izlazna kapija |
|---|---|---|
| G1 | `GlBridge` → always-on, sinhron, u istoj transakciji, za **sve** finansijske evente (danas pokriva samo invoice-stranu; expense strana ne postoji); dual-write | svi novi eventi daju balansirane JE |
| G2 | Backfill istorije replay-em `Transactions`→JE kroz `PostingRuleEngine`; nemapabilno u review queue | **saldo diff = 0** po orgu, kontu i periodu |
| G3 | Read-flip **po orgu** (`BilkoFlags` već ima org_id mehanizam) | org se flipa tek nakon G2 diff=0 za taj org |
| G4 | Prestanak pisanja u `Transactions`; tabela ostaje read-only istorija | svi orgovi na G3 + Proveo full regression |

---

## 4. Tenant izolacija — srazmjeran odgovor

Ovo je sekcija koja se najviše promijenila kad su izmjerene stvarne brojke. **Postojeće politike
ne cure** — i to mijenja cijeli ton preporuke.

### 4.1 Izmjereno stanje
| Metrika | Vrijednost |
|---|---|
| `ENABLE ROW LEVEL SECURITY` | **55** tabela (kroz 32 migracije) |
| `FORCE ROW LEVEL SECURITY` | **47** od tih 55 |
| `AS RESTRICTIVE` politika | **0** — sve su PERMISSIVE tipa |
| **Fail-open grana u ijednoj politici** | **0** |

**Nalaz koji obara raniju preporuku:** kanonska `org_isolation` politika je **fail-closed na
nedostajući GUC**:

```sql
CASE WHEN current_setting('app.current_org_id', true) IS NULL
       OR current_setting('app.current_org_id', true) = ''
     THEN false
     ELSE organization_id = current_setting('app.current_org_id', true)::uuid
END
```

Zaboravljen `SET app.current_org_id` u pozadinskom poslu daje **0 redova, ne sve redove**. Oznaka
PERMISSIVE sama po sebi ovdje nije rupa.

### 4.2 Gdje PERMISSIVE **stvarno** boli
Ne u `org_isolation`, nego u **OR-kompoziciji**: svaka nova permissive politika na tabeli
**proširuje** pristup, i ništa u bazi ne ANDuje preko svih. A takve politike već postoje i
cross-org su po dizajnu — V134 support_agent („Row scope: ALL orgs"), V145 platform_admin, V142
rejection bypass. Izmjerena gustoća: **`support_tickets` ima 5 politika**, tri druge tabele po 4.

> Svaki bug u `USING` klauzuli bilo koje od njih = cross-tenant curenje na toj tabeli, i **nijedan
> restriktivni sloj ga danas ne presreće.** To je pravi rizik — rastuća OR-površina, ne postojeće
> politike.

### 4.3 Stvarni gap: 9 tenant tabela bez RLS-a
`journal_postings` (**nema ni `org_id`**), `invoice_send_events`, `fiscal_submission_attempts`,
`adapter_config`, `accountant_profiles` + `accountant_organization_access` (V102 header sam kaže
„deferred to Securion audit" — dug je priznat, ne zaboravljen), `chat_conversations`,
`refresh_tokens`, `account_mapping`, `absence_types`.

Ostale bez RLS-a su legitimno globalne (`currencies`, `exchange_rates`, `account_types`,
`posting_rules`, `role_permissions`, webhook event tabele…) — te samo dokumentovati.

### 4.4 Tri workstreama umjesto „flipni sve"

| WS | Šta | Kada | Cijena |
|---|---|---|---|
| **R1 — pokrivenost** | `org_id` + `ENABLE`+`FORCE` na 9 tabela iz 4.3 (V46 pattern; `journal_postings` ide zajedno s GL fazom) + `FORCE` na `organizations` i `audit_log` | **prije HR GA, obavezno** | mala, mehanička |
| **R2 — upravljanje OR-površinom** | živ inventar politika po tabeli · Securion review svakog cross-org `USING` · **CI lint: novi `CREATE POLICY` bez review-taga = fail build** | odmah, trajno | mala, deterministička |
| **R3 — RESTRICTIVE guard** | **jedna** `AS RESTRICTIVE` politika po tenant tabeli koja tvrdi „bar jedan identitetski GUC je postavljen" (org **ili** support **ili** platform_admin — mora obuhvatiti sve legitimne cross-org staze) | poslije P2/P4, uz Phase-2C gate | srednja |

**Svjesno degradiramo raniju preporuku:** potpun default-deny RESTRICTIVE prepis svih politika
**više nije cilj.** Fail-closed nalaz iz 4.1 mu briše glavno opravdanje, a puna cijena (matrica
rola × tabela × operacija preko 55 tabela + soak) ostaje. R1+R2+R3 kupuju isti sigurnosni ishod za
dio cijene. R3 je **osiguranje kompozicije unaprijed**, ne popravka današnjih politika — one su
ispravne.

Aplikativni `WHERE org_id` ostaje prvi zid, RLS drugi. RLS nikad ne postaje izgovor za aljkav
servisni kod.

---

## 5. Statutarni sloj — tri nedostajuća komada

Temelj je dobar i ostaje: `CountryPlugin` po jurisdikciji, `PluginRegistry`, `MarketCapability`,
`ObligationCatalog`. **Kod se ne forka po državi — to je već riješeno.**

**5a. Registar podnesaka** — Fikenov `Altinn-innsendinger`, kod nas **ne postoji kao koncept**.
Danas svaki kanal vodi svoje tabele i ne postoji odgovor na „šta je, kada, kome poslano i šta je
država rekla". Jedna `state_submissions` tabela (org, jurisdikcija, kanal, tip artefakta,
idempotency_key, state machine `PREPARED→SUBMITTED→ACKED/REJECTED`, dokazi) + `SubmissionChannel`
interfejs. Daje tri stvari odjednom: **dokaz** prema korisniku i inspekciji, **zatvaranje rokova**
(rok se gasi kad podnesak pređe u ACKED), i **jedan retry/idempotency model** umjesto tri.

**5b. Derivacioni princip.** PDV obrazac, URA/IRA, JOPPD, GFI-POD su **isključivo derivacije** iz
ledgera + `vat_category`. Nikad paralelno održavano stanje. Uz to: `CanonicalInvoice` se sam
deklariše kao **stub** (`EInvoiceTypes.kt:10-15`) — pun EN 16931 model je zaseban deliverable, ne
fusnota, i preduslov je i za eRačun i za fiskalizaciju.

**5c. B2C fiskalizacija — jedina istinski nova komponenta.** Sheme su kompletne
(`Tables.kt:1305-1826`), **potpisni klijent ne postoji** (nula pogodaka za CIS endpoint /
XMLSignature / xmldsig u cijelom Kotlin stablu). Zašto mijenja arhitekturu: sve ostalo u sistemu
je asinhrono i batch-tolerantno; B2C fiskalizacija je **sinhrona, sub-sekundna, na tački prodaje,
sa zakonskim offline režimom**. Traži vlastiti SLO: `FiskClient` (CIS SOAP + XML-DSig FINA
certifikatom, **privatni ključ u KeyVault — nikad u DB**), DB-atomičan per-device sequence
allocator, circuit breaker → offline queue drainer (tabela postoji, worker ne), Z-report scheduler.

> **Terminološka higijena:** `StorecoveHrFiskEInvoiceAdapter` u imenu miješa Fiskalizaciju 2.0 B2B
> (e-račun) i B2C fiskalizaciju računa. **Dva zakona, dva sistema — ne smiju dijeliti ime ni modul.**

**5d. JOPPD.** Najteži pojedinačni artefakt, i **arhitektonski drugačiji od norveškog uzora**:
A-melding je periodičan (jednom mjesečno za sve isplate), JOPPD je **transakcijski — po isplati**,
podnosi se na dan isplate. Dakle event-driven obligation model, ne batch. Blokiran do ispravke
poreskog modela (#106302).

---

## 6. Navigacija i vizuelni identitet

**Osam grupa, horizontalno:** `Tvrtka · Pregled · Prodaja · Troškovi · Banka · Plaće ·
Knjigovodstvo · Pretinac`

**Gdje svjesno odstupamo od Fikena:**

| Odstupanje | Zašto |
|---|---|
| **Banka je glavni meni** (Fiken je gura u `Annet`) | Fiken smije jer Norvežanin banku ne dira (auto-pull). Hrvat usklađuje izvode ručno od dana 1 |
| **Nema `Ostalo/Annet`** | Junk-drawer nastaje kad kategorija nema vlasnika. Sve što Fiken drži u `Annet` kod nas ima dom |
| **`Knjigovodstvo` kao gated glavna grupa** | Jedina poštena posljedica dvije publike; Bilko već ima 11-rutni back-office |
| **`Porezi i rokovi` = registar podnesaka** | HR ekvivalent `Altinn-innsendinger`, gradi se od dana 1 |
| **⌘K paleta + globalna pretraga** | 62 ekrana pod 8 grupa; Fiken to nema i njegovi korisnici plaćaju traženjem |

**Dvije publike, jedan shell.** Ne mode-toggle, ne dva shella — podjela **po objektu**: ulazni
račun je jedan entitet; vlasnik vidi „fotka / iznos / plati", računovođa nad **istim dokumentom**
dobije panel „Knjiženje". Panel se renderuje po roli+modulu, ne po ruti. Time duplikat
`expenses` ↔ `accounting/ulazni-racuni` nestaje strukturno.

**Higijena ruta:** 75 postojećih → ~62 kanonske. Šest duplikata imenovano, među njima `purchases`
(po vašem `CLAUDE.md` samo alias) i **tri rute za isti PDV obrazac**. Rute prelaze na hrvatski
namespace uz 301 sa starih.

**Screen registry.** Fikenov `dyplenke` pattern: `screenId` je vječan, ruta se smije seliti.
Resolver `/idi/[screenId]` radi auth → org kontekst → entitlement → redirect na ekran **ili na
order-stranicu**. Svaki podsjetnik, help članak i rok linkuje isključivo preko njega. Pravilo koje
se preuzima doslovno: **rok vodi na akciju koja ga zatvara**, ne na info stranicu.

**Vizuelno:** evolucija Bilko plum-a, ne rušenje. Inter s **`tnum` na svakoj brojčanoj ćeliji**
(poravnanje kolona iznosa je nepregovarački zahtjev računovodstvenog softvera), DM Mono za
OIB/IBAN/JIR, gustoća po tipu ekrana (44px vlasnički / 32px knjigovodstveni redovi), zeleno-crveno
**isključivo** za smjer novca i status roka. **Nula maskota u aplikaciji** — maskota kroz koju
prolazi porezna kontrola gubi kredibilitet kod računovođa, a one su distribucijski kanal.

> **CEO pojašnjenje 2026-07-30 — šta je značilo „i izgled izmijenite skroz":**
> *„Mislio sam evolucija na uzoru od Fiken."* Dakle **nova ljuska i nova informaciona
> arhitektura po Fikenovom uzoru, uz zadržan Bilko identitet** — ne vizuelno rušenje i ne
> novi brend. Ovaj odjeljak je time **potvrđen, ne izmijenjen**. Zapisano jer je formulacija
> „frontend se gradi iznova" (MC #106568) čitljiva i kao „bacamo izgled", što nije bila
> namjera — a to bi se skupo otkrilo tek kad neko počne raditi P6.

**Jezička mina:** Fikenovo „Jeg har solgt noe" se **ne može preslikati** — hrvatski perfekt je
rodno obilježen („prodao/prodala sam"). Rješenje: imperativ — **„Izdaj račun" / „Dodaj trošak"**.
Zadržava poentu (jezik posla, ne struke), mijenja formu iz lingvističkog razloga.

**Dvije stvari koje Fiken ne može imati:** widget fiskalizacije (istek FINA certifikata, offline
red, zadnji JIR) i za paušaliste **traka prometa prema pragu od €60k** — anksioznost broj jedan
svakog paušalca.

---

## 7. Komercijalni model

**Hibrid: jedan ulazni nivo tačno na €12, sve iznad à la carte.**

Ne čisti Fiken (ravna cijena gubi bitku sidra u prvom redu poredbene tabele), ne čisti Minimax
(četiri stepenice = četiri mjesta gdje se gubi cjenovno osjetljiv kupac).

**Bilko Start €12/mj** — neograničeni računi, eRačun/Fiskalizacija 2.0 **unmetered**, PDV
25/13/5/0 + obrazac, RRiF, OIB auto-popuna, paušal kalkulator + KPO/KPR, HUB3 barkod, 1 korisnik.
Moduli: dodatni korisnik €4 · API €9 · sati €4 **ravno** · OCR €4 · godišnja prijava €69/god.
Transakcijski: SMS €0,15 · pismo €2.

**Argument protiv €12 je provjerljiv, ne marketinški:** Minimax na €12 ima kapu od 300 računa pa
€0,05 po komadu — sezonski hrvatski SMB dobije doplatu baš u srpnju kad najviše radi.

**Odlučujuće brojke:** paušalni obrt **€12/mj** · d.o.o. s 10 zaposlenih **€20/mj**.

**eRačun se NE naplaćuje po dokumentu** — to je obavezni pod zakona, ne premium kanal. Metering
obaveze lomi i poredivost s Minimaxom koji ga već ima u svojih €12.

**Tri obrasca koja odbijamo:** Minimaxovih €10/mj da drži podatke kad licenca istekne (kod nas 90
dana besplatno + puni izvoz) · trajni izbor kontnog plana · i **naš vlastiti** `pricing-tiers.md`
koji zaključava PDF/Excel izvoz izvještaja iza plaćenog nivoa — to je isti obrazac taoca, samo
premješten.

**Dvije stavke svjesno nisu u cjenovniku:** **plaće** (JOPPD ne postoji — naplatiti usklađenost
koju proizvod nema nije cjenovna nego pravna greška) i **B2C fiskalizacija** (potpisni klijent
nepotvrđen).

---

## 8. 🔴 Crvena zona

| # | Stavka | Zašto crvena | Tražena verifikacija |
|---|---|---|---|
| 1 | GL cutover (G2 backfill + G3 flip) | integritet novca — svaki izvještaj i porez sjedi na ovome | saldo diff=0 po orgu; DB balans-constraint; adversarial review (Momjian/Kleppmann); Proveo E2E po event tipu |
| 2a | R1 pokrivenost — 9 tabela + `org_id` na `journal_postings` | porezni podaci bez DB zida | Securion review migracija; cross-tenant probe na svakoj novoj tabeli |
| 2b | **Cross-org OR-površina** (V134/V142/V145 klasa i svaka buduća) | jedina klasa gdje PERMISSIVE stvarno curi; raste tiho sa svakim support featureom | Securion review svakog `USING`; **CI lint gate na `CREATE POLICY`**; dvosmjerni pen test na multi-policy tabelama (`support_tickets` ih ima 5) |
| 2c | R3 RESTRICTIVE guard rollout | dira sve staze uklj. pozadinske poslove; pogrešan assert = platform-wide 0-rows outage | Phase-2C gate: Securion + 30d soak; test matrica kombinacija identitetskih GUC-ova |
| 3 | B2C `FiskClient` (FINA cert, ZKI/JIR, XML-DSig) | zakonska valjanost svakog maloprodajnog računa; privatni ključevi | ključ u KeyVault nikad u DB; adversarial review potpisa i monotonije sekvence; offline replay idempotencija; dokaz na Porezna test okruženju |
| 4 | eRačun izdavanje (sveRačun prod ugovor) | zakonska valjanost B2B fakture | sandbox dokaz; EN 16931 / HR CIUS validacija; duplicate-submission idempotencija |
| 5 | **Poreski model plaća (#106302)** | tuđi porezi i doprinosi; model opisuje ukinuti porez | porezni sign-off; per-općinska tabela stopa; XSD golden vektori za JOPPD |
| 6 | `vat_category` backfill | tiha pogrešna klasifikacija istorije = korumpiran PDV obrazac | dual-run diff=0 po orgu; ambiguozno u ručni review, **nikad heuristički default** |
| 7 | Nepromjenjivost izdatih dokumenata (DB triggeri) | dokazna snaga knjige | mutation-attempt testovi; `FinancialAuditLog` pokrivenost |
| 8 | Entitlement/Stripe sync | novac i pristup u istoj petlji | webhook replay / out-of-order testovi; downgrade grace; metering idempotencija |
| 9 | Accountant multi-org header (V102) | cross-tenant pristup po dizajnu | ostaje iza flaga do Securion prolaza |
| 10 | `accounting_periods` / period lock | retroaktivna manipulacija knjigom | test matrica sa storno tokovima preko zaključanog perioda |
| 11 | **Cross-border naplata** | nema HR OIB-a; sve ide kroz ALAI Norway Stripe, PDV tretman neriješen | Finverge + pravni gate **prije bilo kakvog živog Stripe proizvoda** |

**Istinski novo** (bez presedana u kodu): #3 B2C fiskalizacija, i registar podnesaka kao koncept.

---

## 9. Faze i kapije

```
P0 ─→ P1 {E1, V1, R1} ─→ P2 {G1→G2→G3} ─→ P3 {doc engine} ─→ P4 {statutarni kanali}
                └──────────── P6 {nova ljuska/IA} teče paralelno od P1
P5 {RESTRICTIVE flip} tek POSLIJE P2 i P4 pozadinskih workera
```

| Faza | Sadržaj | Ulazni uslov | Izlazna kapija |
|---|---|---|---|
| **P0 Odluke** | CEO tačke iz §10 | — | potpis na sve |
| **P1 Temelji** | E1 entitlement core + `/me/capabilities` · V1 `vat_category` + dual-run harness · **R1 RLS pokrivenost** (`org_id` u `journal_postings`) | P0(b) za E1 | dual-run PDV diff=0; Securion review R1; Proveo E2E `nav=f(entitlements)` |
| **P2 Ledger** | G1 → G2 → G3 | P1 komplet | diff=0 po orgu; `accounting_periods` živ; balans-constraint u DB |
| **P3 Doc engine** | Ponude u jedinstveni pipeline; `number_series`; immutability triggeri | P2-G1, V1 | svi tipovi kroz jedan issue pipeline; stari `/ponude` 301 |
| **P4 Statutarni** | `state_submissions` registar; `CanonicalInvoice` → pun EN 16931; `FiskClient` B2C; JOPPD | registar od P1; kanali poslije P3; JOPPD traži #106302 | sandbox dokaz po kanalu; rokovi se zatvaraju iz registra; offline replay test |
| **P5 RESTRICTIVE** | default-deny + GUC assert | svi background pisci iz P2/P4 u test mreži | Securion sign-off + 30d soak |
| **P6 Nova ljuska** | novi `apps/web` shell, horizontalna nav iz capabilities, novi brend | E1 API ugovor stabilan | frontend spec v1 invarijante (#106089) + design QA |
| **HR GA** | — | P2+P3+P4(eRačun) zeleni; **R1 obavezan** | cijela §8 tabela verifikovana |

### Obavezni pratioci (ZAKON PLAN)
- **Validacija — Proveo (Angie Jones):** end-to-end s pravim dokazom na svakoj kapiji; posebno GL
  diff=0, cross-tenant pen test, i offline replay fiskalizacije. Ne dry-run.
- **Dokumentacija — Skillforge:** BookStack stranica po fazi; obavezan refresh
  `BUILD-BLUEPRINT.md` **prije P1** (danas podbacuje rute 4×, stranice 10×, opisuje mrtav GCP).

---

## 10. Tačke za CEO odluku (phase-gate)

Bez ovih se P1 ne otvara.

1. **Komercijalni model** — potvrditi hibrid €12 + à la carte? Ovo određuje oblik entitlement
   kataloga, dakle i kod.
2. **sveRačun produkcijski ugovor** — danas postoji samo TEST ključ. Ovo je **najhitniji
   komercijalni blocker**, ne tehnički: eRačun je obavezan od 1.1.2026, kod je spreman i spava.
3. **DIRECT vs INTERMEDIARY eRačun model** — INTERMEDIARY (Bilko kao posrednik za više klijenata
   pod jednim ugovorom) **ne postoji** i traži poseban ugovor s PostLink d.o.o. Ovo je poslovna
   odluka koja diktira cijelu integracijsku arhitekturu.
4. **Brand** — evolucija Bilka ili novi HR brend? Prijedlog: evolucija.
5. ~~**RS i BA** — ostaju li?~~ **✅ POTPISANO 2026-07-29 (CEO, doslovno: „Ostaju — EXTEND stoji")**
   Ovo je bila **jedina premisa pod kojom presuda EXTEND pada**, i ona je sada potvrđena:
   ⟹ **EXTEND vrijedi.** Ne fork, ne rebuild backenda. 146 migracija fosilizovanog statutarnog
   učenja se čuva. Bilko svjesno ostaje multi-market — 4-jurisdikcijska test matrica, 8-gate CI,
   permissive-RLS i dvostruki GL ostaju teret koji nosimo otvorenih očiju.
   *(Steelman iz §0 je time razriješen, ne oboren — ostaje zapisan jer bi ponovo vrijedio ako se
   ova odluka ikad promijeni.)*
6. **Cross-border naplata** — Finverge/pravni gate za PDV tretman Norveška→EU. Bez toga nema živog
   Stripe proizvoda bez obzira na to koji model izaberemo.

---

*Sve tvrdnje o kodu su `file:line` verifikovane u glavnom stablu na dan 2026-07-25, READ-ONLY.
Statutarne tvrdnje bez izvora označene su NEPROVJERENO u izvornim izvještajima specijalista.
Otvoreno i traži primarni izvor prije implementacije: obuhvat eRačuna 1.1.2026, JIR offline rok,
Intrastat pragovi 2026, PO-SD rok, PDV-S rok nakon NN 151/2025, pun tekst Pravilnika o eRačunu
NN 11/2026, iscrpnost `vat_category` liste.*