# TEHNIČNA SPECIFIKACIJA: APLIKACIJA ZA POSODOBITEV PODATKOV STRANK

## 1. PREGLED PROJEKTA & OKOLJE
* **Naročnik:** Zavarovalnica
* **Tehnološki sklad:** Laravel, Livewire v4, Filament v5, PHP 8.5+, MySQL / MariaDB
* **Strežnik:** Dev: DDEV, Produkcija: Windows Server (IIS)
* **Obseg:** ~20.000 obstoječih strank
* **Primarni cilj:** Stranke preko unikatne kode (Gesla) dostopajo do varnega obrazca, preverijo in posodobijo svoje podatke. Sistem beleži spremembe. Administrator preko Filament vmesnika uvozi začetni Excel in izvozi očiščen Excel, kjer so spremenjene vrednosti barvno označene.

---

## 2. ARHITEKTURA PODATKOVNE BAZE (MySQL)

Za zagotavljanje sledljivosti med starim (uvoženim) in novim (posodobljenim) stanjem brez ustvarjanja kompleksnih relacijskih tabel, se uporabi pristop z dvema `JSON` stolpcema znotraj ene glavne tabele `customers`.

### Migracijska datoteka: `database/migrations/xxxx_xx_xx_xxxxxx_create_customers_table.php`

```php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('customers', function (Blueprint $table) {
            $table->id();
            
            // Kontrolni podatki in avtentikacija
            $table->string('kupec_dobavitelj')->nullable();
            $table->string('stevilka_kup_do')->nullable();
            $table->string('st_police_rent')->nullable();
            $table->string('vloga_osebe'); // SKLEN, ZAVAR, PREJEMNIK RENTE
            $table->string('password')->unique(); // "Geslo" iz Excela - unikatna vstopna koda. V Excelu je geslo v čistem besedilu; v DB se shrani hash (glej §4).
            
            // JSON polja za podatke (vseh 31 podatkovnih polj iz Excela, glej "Excel polja" spodaj)
            $table->json('original_data'); // Nespremenjeni podatki ob uvozu
            $table->json('current_data');  // Trenutni (posodobljeni) podatki
            
            // Status in sledljivost
            $table->boolean('is_updated')->default(false);
            $table->text('opombe')->nullable(); // Dodatno polje za opombe iz specifikacije
            $table->timestamp('updated_at_portal')->nullable(); // Kdaj je stranka oddala obrazec
            
            $table->timestamps();
            
            // Indeksi za hitro iskanje ob prijavi
            $table->index('password');
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('customers');
    }
};
```
## Excel polja

Polja so naslednja v enakem vrstnem redu. Prva vrstica je glava. Enaka struktura naj bo pri izvozu. Vrstni red in imena ključev so usklajeni z realno glavo v `example_empty.csv` (export iz originalnega Excela) — to je **edini avtoritativni vir** za imena stolpcev in JSON ključev; vsa nadaljnja poglavja (§2, §3) morajo uporabljati točno te ključe.

priimek_in_ime, datum_rojstva, kraj_rojstva, emso, davcna_st, drzavljanstvo, naslov, postna_stevilka, kraj, drzava, elektronski_naslov, telefonska_st, vrsta_osebnega_dokumenta, st_osebnega_dokumenta, drzava_izdajatelj, naziv_izdajatelja, datum_izdaje, datum_prenehanja, politicno_izpostavljena_oseba, funkcija, drzava_funkcije, datum_zacetka_funkcije, datum_prenehanja_funkcije, drzava_davcnega_rezidentstva, davcna_stevilka_tin, razlog_ce_tin_ne_obstaja, soglasam_z_elektronskim_obvescanjem, soglasam_s_trzenjem, potrjujem_da_so_podatki_resnicni_pravilni_in_popolni, zavezujem_se_da_bom_zavarovalnico_obvestil_o_spremembah_podatkov, potrjujem_da_sem_seznanjen_z_informacijami_o_obdelavi_osebnih_podatkov

(31 podatkovnih polj. Skupaj s 5 kontrolnimi stolpci — Kupec/Dobavitelj, Številka kup./dob., Št. police/rente, Vloga osebe, Geslo — je v `example_empty.csv` 36 stolpcev.)

### Mapiranje: stolpec v Excelu/CSV → JSON ključ

| # | Excel/CSV stolpec (label) | JSON ključ (`original_data`/`current_data`) |
| :-- | :--- | :--- |
| 1 | Priimek in ime | `priimek_in_ime` |
| 2 | Datum rojstva | `datum_rojstva` |
| 3 | Kraj rojstva | `kraj_rojstva` |
| 4 | EMŠO | `emso` |
| 5 | Davčna št. | `davcna_st` |
| 6 | Državljanstvo | `drzavljanstvo` |
| 7 | Naslov | `naslov` |
| 8 | Poštna številka | `postna_stevilka` |
| 9 | Kraj | `kraj` |
| 10 | Država | `drzava` |
| 11 | Elektronski naslov | `elektronski_naslov` |
| 12 | Telefonska št. | `telefonska_st` |
| 13 | Vrsta osebnega dokumenta | `vrsta_osebnega_dokumenta` |
| 14 | Št. osebnega dokumenta | `st_osebnega_dokumenta` |
| 15 | Država izdajatelja | `drzava_izdajatelj` |
| 16 | Naziv izdajatelja | `naziv_izdajatelja` |
| 17 | Datum izdaje | `datum_izdaje` |
| 18 | Datum prenehanja | `datum_prenehanja` |
| 19 | Politično izpostavljena oseba | `politicno_izpostavljena_oseba` |
| 20 | Funkcija | `funkcija` |
| 21 | Država funkcije | `drzava_funkcije` |
| 22 | Datum začetka funkcije | `datum_zacetka_funkcije` |
| 23 | Datum prenehanja funkcije | `datum_prenehanja_funkcije` |
| 24 | Država davčnega rezidentstva | `drzava_davcnega_rezidentstva` |
| 25 | Davčna številka (TIN) | `davcna_stevilka_tin` |
| 26 | Razlog če TIN ne obstaja | `razlog_ce_tin_ne_obstaja` |
| 27 | Soglašam z elektronskim obveščanjem | `soglasam_z_elektronskim_obvescanjem` |
| 28 | Soglašam s trženjem | `soglasam_s_trzenjem` |
| 29 | Potrjujem, da so podatki resnični, pravilni in popolni | `potrjujem_da_so_podatki_resnicni_pravilni_in_popolni` |
| 30 | Zavezujem se, da bom zavarovalnico obvestil o spremembah podatkov | `zavezujem_se_da_bom_zavarovalnico_obvestil_o_spremembah_podatkov` |
| 31 | Potrjujem, da sem seznanjen z informacijami o obdelavi osebnih podatkov | `potrjujem_da_sem_seznanjen_z_informacijami_o_obdelavi_osebnih_podatkov` |

**Opomba o poljih, ki jih §2 omenja, a jih `example_empty.csv` ne vsebuje:**
* `naslov_za_obvescanje`, `drugo_osebni_dokument` in `ameriski_tin` (glej §2.2.D) so nova polja, ki jih izvorni Excel ne vsebuje. Ker zanje ni `original_data`, se v izvozu obravnavajo kot "dodano" (ne kot klasična sprememba vrednosti) — primerjava pri barvanju mora manjkajoč ključ v `original_data` obravnavati kot različno vrednost od `current_data`. Ta polja je treba dodati kot nove stolpce v izvozno datoteko (potrjeno z naročnikom — podatki o tem trenutno ne obstajajo v Excelu, a bodo potrebni naprej).
* `datum_veljavnosti`, `pep_status`, `pep_funkcija_trajanje_drzava`, `davčni_rezident_status`, `tuji_rezident_drzava`, `tuji_rezident_tin` in `tuji_rezident_vzrok_brez_tin` iz prejšnje različice §2 so bila preimenovana/razdeljena, da se ujemajo z dejanskimi ključi zgoraj (glej popravljen §2.2).
* `postna_stevilka`, `kraj` in `drzava` (splošna polja naslova) se ob uvozu/shranjevanju samo prenašajo (passthrough) iz `original_data` v `current_data`, brez posebne validacije — trenutno niso prikazana kot uredljiva polja na obrazcu; uredljiva polja na obrazcu se lahko dodajo pozneje, če bo potrebno.

## 4. AVTENTIKACIJA STRANKE (Vstopni portal)
Aplikacija ne uporablja klasičnega Laravel Auth sistema (Fortify/Breeze). Prijava poteka preko enega samega polja: Geslo (unikatna koda).

### 4.1 Shranjevanje gesla (hash)
* V izvornem Excelu je `Geslo` v čistem besedilu. Pri uvozu se geslo zahashira in shrani samo hash — izvirno besedilo se nikjer ne hrani.
* Ker mora prijava poiskati ujemajočo vrstico po vneseni kodi (ni klasičnega "uporabnik vnese, primerjamo z enim hash-om" scenarija), navaden bcrypt (`Hash::make`, kot pri `User` modelu) **ni primeren** za stolpec `password` na `customers` — bcrypt-a se ne da neposredno iskati z `WHERE password = ?`, ker vsak klic generira nov salt, in preverjanje vseh ~20.000 vrstic z `Hash::check()` ob vsaki prijavi ni izvedljivo (prepočasno).
* Priporočeno: za stolpec `password` uporabiti deterministični keyed hash (npr. HMAC-SHA256 z `APP_KEY` ali ločenim secretom) — to omogoča hitro, indeksirano iskanje (`WHERE password = ?`), obenem pa surove kode ni mogoče rekonstruirati iz baze.
* Indeks na `password` (že v migraciji) ostane, ker je iskanje po exact-match hashu.

### 4.2 Zaščita pred brute-force / hekanjem
Ker baza vsebuje osebne podatke (EMŠO, davčne številke ipd.) ~20.000 strank, je treba prijavno pot zaščititi:
* Omeji število poskusov prijave (npr. Laravel `RateLimiter`/throttle middleware na login route) — npr. nekaj poskusov na minuto po IP, z naraščajočim zamikom/začasnim zaklepom ob preseženem številu.
* Generična napaka ob napačni kodi ("Neveljavna koda"), brez razlikovanja med "koda ne obstaja" in drugimi napakami (da se ne razkriva, katere kode obstajajo).
* Beleženje neuspešnih poskusov prijave (IP, čas) za nadzor/alarmiranje.
* Regeneracija seje (`session()->regenerate()`) ob uspešni prijavi.
* Striktno HTTPS v produkciji, varni session/cookie nastavitvami (`secure`, `httpOnly`, `SameSite`).

## 6. DINAMIČNI OBRAZEC (Livewire )
Segmentacijska logika (Dva obrazca):
Daljši obrazec (Vloga: SKLEN): Prikažejo se vsa polja (Regulatorni modul ZL).

Krajši obrazec (Vloga: ZAVAR ali PREJEMNIK RENTE): Prikaže se skrčen nabor polj (Regulatorni modul ZN) - skrijejo se polja vezana na finančne instrumente/rente oz. specifične izjave, če tako določa pravilnik (Claude naj pripravi pogoje v pogledu na podlagi $customer->vloga_osebe).

Pot: app/Livewire/CustomerForm.php
Komponenta naloži model na podlagi seje.

Polja v wire:model veže direktno na $current_data.

Ob shranjevanju:

Izvede se sanitizacija vnosov (strip_tags).

Izvede se validacija (Email format, rojstni datumi, EmsoRule, obvezna potrditvena polja/checkboxi na koncu).

is_updated se nastavi na true.

Podatki se zapišejo v current_data, `opombe` (prosto besedilo stranke, skupno polje na obeh obrazcih ZL in ZN — glej §2.1) pa v ločen stolpec `opombe` (ni del `original_data`/`current_data` JSON-a, ker za to vrstico ni starega/novega para za primerjavo). Ob izvozu se doda kot zadnji stolpec v Excelu (glej §7.2).

### 6.1 UX zahteve obrazca

**A. Vneseni podatki se ob neuspeli validaciji ne smejo izgubiti.** Ob napaki pri shranjevanju (npr. neveljaven EMŠO, manjkajoče obvezno polje) se stran ne sme ponovno naložiti s počiščenim obrazcem — vsa polja (tudi tista brez napake) morajo ohraniti natanko tisto vrednost, ki jo je stranka pravkar vnesla, napake pa se izpišejo poleg/pod ustreznimi polji (glej `.field-errors`/`.has-error` v §6.1 UI/UX). Ker so vsa polja vezana na `wire:model` (Livewire component property), je to privzeto vedenje, dokler validacija ne resetira lastnosti komponente — pri implementaciji eksplicitno paziti, da `save()` ob `ValidationException` ne počisti/ponovno naloži `$current_data` iz baze, temveč ohrani trenutno stanje lastnosti v komponenti.

**B. Prikaz obstoječe vrednosti kot placeholder, ki se ob kliku prenese v polje za urejanje.** Za polja, ki že imajo vrednost iz uvoza (`current_data[$key]` ni prazen), se polje prikaže **vizualno prazno**, z obstoječo vrednostjo prikazano kot `placeholder` (sivo "duh" besedilo), ne kot dejanska `value`. Ko stranka klikne/fokusira polje, se vrednost iz placeholderja prenese v dejansko vrednost polja, ki jo lahko stranka ureja ali zbriše. Polje, ki ga stranka nikoli ni fokusirala, šteje kot "nedotaknjeno" in se ob shranjevanju obravnava kot nespremenjeno (ohrani obstoječo vrednost iz `current_data`), tudi če je videti prazno.
* Implementacija: ker mora biti razlika med "nedotaknjeno polje" (prikazano prazno, vrednost se ob shranjevanju jemlje iz obstoječih podatkov) in "stranka je polje namerno izbrisala" (dejansko prazna vrednost) eksplicitna, je treba poleg vsake `current_data[$key]` lastnosti spremljati tudi `touched`/`edited` zastavico (npr. `$touchedFields` array v komponenti, nastavljen na `true` ob prvem `focus`/`input` dogodku na polju prek Alpine.js `x-on:focus`/Livewire `wire:focus`, ki preko klica komponente ali lokalnega Alpine stanja prenese placeholder vrednost v vnosno polje).
* To velja za vsa urejevalna polja v §2 (text/date/select), ne za checkbox/radio polja (soglasja, PEP, CRS), kjer ni smiselno — ta ostanejo prikazana z dejansko izbrano vrednostjo kot doslej.

**C. Vizualno označevanje spremenjenih polj.** Polje, katerega trenutna vrednost (po tem, ko je stranka vanj posegla) ni enaka izvirni vrednosti iz `original_data[$key]`, mora biti vizualno označeno (npr. obrobljen `form-group`/poudarjena labela/majhna oznaka "Spremenjeno" — usklajeno z barvno shemo iz §6 UI/UX, npr. odtenek rumene kot pri izvozu v §7.2, da je vizualna logika skladna med obrazcem in Excel izvozom). Oznaka se posodablja sproti (reaktivno), ne le ob shranjevanju, in izgine, če stranka vrednost povrne na izvirno.
## 7. UVOZ IN IZVOZ PODATKOV (Filament + Laravel Excel)
V ozadju (Filament Admin) ima administrator na voljo uvoz in izvoz. Uporabljala ga bosta le 1-2 administratorja — uporabi se privzeti Filament auth guard (obstoječi `User` model), brez dodatnega sistema vlog/dovoljenj (npr. brez `spatie/laravel-permission`).

### 7.1 Avtomatiziran uvoz (Faza 1)
Skripta bere naložen Excel.

Vsaka vrstica generira nov zapis v tabeli customers.

Stolpci Kupec / Dobavitelj, Številka kup. / do, Št. police / rent, Vloga osebe in Geslo se zapišejo v namenske stolpce tabele.

Vsa ostala polja se preslikajo v asociativni niz in shranijo tako v original_data kot v current_data (začetno izhodišče je enako).

### 7.2 Končni izvoz s spremembami in barvami (Faza 4)
Izvažajo se samo zapisi, kjer je is_updated = true.

Uporabi se knjižnica Maatwebsite\Excel skupaj s PhpSpreadsheet.

Logika barvnega kodiranja (WithStyles):
Skripta teče čez vrstice in primerja posamezne ključe znotraj original_data in current_data.

Če se vrednost razlikuje ($original_data[$key] !== $current_data[$key]), se specifična celica obarva rumeno (Hex: #FFFF00). Za ključe, ki jih v `original_data` ni (npr. `naslov_za_obvescanje`, `drugo_osebni_dokument`, `ameriski_tin` — glej "Excel polja"), se manjkajoča vrednost obravnava kot `null`, kar šteje za razliko, če `current_data[$key]` ni prazen.

`opombe` se doda kot zadnji stolpec exportirane vrstice (ni del primerjave original/current, ni vezan na noben JSON ključ).


## 1. SEGMENTACIJSKA LOGIKA (ZL vs. ZN)

Glede na vrednost polja `vloga_osebe` v bazi podatkov (uvoženo iz Excela) sistem aplikacije stranki dinamično prikaže ustrezen modul obrazca:

* **MODUL ZL (Daljši obrazec):** Se prikaže, če je vrednost polja `vloga_osebe` enaka **`SKLEN`** (Zavarovalci). Vsebuje celoten zakonodajni nabor (vključno s podatki o osebem dokumentu, PPDFT izjavo in CRS/FATCA samopotrdilom).
* **MODUL ZN (Krajši obrazec):** Se prikaže, če je vrednost polja `vloga_osebe` enaka **`ZAVAR`** ali **`PREJEMNIK RENTE`** (Zavarovanci / upravičenci). Ta modul je optimiziran, ne vsebuje osebnih dokumentov, PPDFT in CRS/FATCA delov, prilagojena pa so tudi končna pravna besedila in soglasja.

---

## 2. PODROBNO MAPIRANJE POLJ IN VALIDACIJSKA PRAVILA

### 2.1 Skupna polja (Prikazana v obeh modulih: ZL in ZN)

| Ključ v JSON (`current_data`) | Labela na obrazcu | Tip polja | Validacijsko pravilo |
| :--- | :--- | :--- | :--- |
| `priimek_in_ime` | Ime in priimek | Text | `required`, `string`, `max:255` |
| `naslov` | Naslov stalnega prebivališča | Text | `required`, `string`, `max:255` |
| `naslov_za_obvescanje` | Naslov za obveščanje | Text | `nullable`, `string`, `max:255` |
| `datum_rojstva` | Datum rojstva | Date | `required`, `date`, `before:today` |
| `emso` | EMŠO | Text | `required`, `digits:13` (preprosta dolžinska omejitev za zdaj; polni checksum/`App\Rules\EmsoRule` po potrebi pozneje) |
| `davcna_st` | Davčna številka | Text | `required`, `digits:8` |
| `elektronski_naslov` | Elektronski naslov | Email | `nullable`, `email`, `max:255` |
| `telefonska_st` | Telefonska številka | Text | `nullable`, `string`, `max:50` |
| `opombe` (**stolpec modela, ne ključ v `current_data` JSON**) | Opombe | Textarea | `nullable`, `string`, `max:2000` |

### 2.2 Specifična polja za MODUL ZL (`vloga_osebe == 'SKLEN'`)

#### A. Osebni podatki (Dodatno)
* `kraj_rojstva` (Kraj rojstva) -> `required`, `string`
* `drzavljanstvo` (Državljanstvo) -> `required`, `string`

#### B. Osebni dokument
* `vrsta_osebnega_dokumenta` -> Radio/Select (`osebna izkaznica`, `potni list`, `drugo`)
* `drugo_osebni_dokument` -> Text (če je izbrana možnost `drugo`; **ni stolpca v izvornem Excelu** — glej opombo v "Excel polja")
* `st_osebnega_dokumenta` (Številka osebnega dokumenta) -> `required`, `string`
* `drzava_izdajatelj` (Država izdajatelja) -> `required`, `string`
* `naziv_izdajatelja` (Naziv izdajatelja) -> `required`, `string`
* `datum_izdaje` (Datum izdaje) -> `required`, `date`
* `datum_prenehanja` (Datum prenehanja/veljavnosti dokumenta) -> `required`, `date`, `after:datum_izdaje`

#### C. Izjava o politični izpostavljenosti (PPDFT)
* `politicno_izpostavljena_oseba` -> Radio (`NISEM`, `SEM`, `DRUZINSKI_CLAN_ALI_SODELAVEC`). **Opomba:** v vzorčnih podatkih (`example_empty.csv`) je obstoječa vrednost zapisana kot `Ne` (Da/Ne), ne kot ena od teh treh vrednosti — pri uvozu je treba potrditi mapiranje legacy `Da`/`Ne` vrednosti na novi 3-stopenjski nabor (privzeto: `Ne` → `NISEM`).
* `funkcija` -> Text (obvezno, če je `politicno_izpostavljena_oseba` enako `SEM` ali `DRUZINSKI_CLAN_ALI_SODELAVEC`)
* `drzava_funkcije` -> Text (obvezno pod enakim pogojem)
* `datum_zacetka_funkcije` -> Date (obvezno pod enakim pogojem)
* `datum_prenehanja_funkcije` -> Date, nullable (funkcija je lahko še aktivna)

#### D. Samopotrdilo o davčnem rezidentstvu (CRS/FATCA)
* `drzava_davcnega_rezidentstva` -> Text (ime države, npr. "Slovenija" — v vzorčnih podatkih je to prosto besedilo, ne enum). Radio izbira (`SLO`, `TUJINA`, `US_PERSON`) na obrazcu je UI-only kategorizacija, ki glede na izbiro stranke nazaj zapiše ustrezno vrednost (npr. "Slovenija" ali ime tuje države) v ta isti ključ — ločen ključ za tujo državo ni potreben.
* `davcna_stevilka_tin` (Davčna številka v tuji državi, TIN) -> Text, neobvezno
* `razlog_ce_tin_ne_obstaja` (Če tuja davčna številka ni na voljo, navedite vzrok) -> Text (obvezno, če je `davcna_stevilka_tin` prazen)
* `ameriski_tin` (Ameriški TIN/SSN — FATCA samopotrdilo za `US_PERSON`) -> Text, `required` če je `drzava_davcnega_rezidentstva` kategoriziran kot `US_PERSON`. **Novo polje, ni v izvornem Excelu** (glej opombo v "Excel polja") — podatek doslej ni bil zbran, a bo potreben naprej.

---

## 3. SOGLASJA IN PRAVNA BESEDILA (Natančna ločitev)

Claude Code mora v vmesniku uporabiti natančna besedila, pridobljena iz modulov zavarovalnice:

### 3.1 Pogled za MODUL ZL
* **Elektronsko obveščanje (Radio/Checkbox):**
  * `soglasam_z_elektronskim_obvescanjem` -> Vrednosti: `1` (Soglašam...), `0` (Ne soglašam...)
  * *Tekst:* "Soglašam, da mi AVRIO zavarovalnica d.d. in SOP dokumente, obvestila, letna poročila... posreduje v elektronski obliki na elektronski naslov naveden v 1. točki."
* **Neposredno trženje (Radio/Checkbox):**
  * `soglasam_s_trzenjem` -> Vrednosti: `1` (Soglašam...), `0` (Ne soglašam...)
  * *Tekst:* "Soglašam, da AVRIO zavarovalnica d.d. in SOP moje kontaktne podatke... uporablja za obveščanje o novih zavarovalnih produktih..."

### 3.2 Pogled za MODUL ZN
* **Elektronsko obveščanje:**
  * Prikže se le informativni tekst (brez potrditvenih polj): "Če ste navedli elektronski naslov vam lahko zavarovalnica oziroma SOP posreduje informacije v zvezi z vašimi upravičenji iz zavarovanja in posodobitvijo podatkov tudi po elektronski pošti."
* **Neposredno trženje (Radio/Checkbox):**
  * `soglasam_s_trzenjem` -> Vrednosti: `1` (Soglašam...), `0` (Ne soglašam...)
  * *Tekst:* "Soglašam, da zavarovalnica in SOP moje kontaktne podatke... uporabljata za obveščanje o zavarovalnih produktih..."
  * *Opomba pod komponento:* "Če je zavarovanec mladoletna oseba, prijava oz. soglasje poda njegov zakoniti zastopnik."

---

## 4. FINALNA IZJAVA STRANKE (Obvezni Checkboxi pred oddajo)

Uporabnik ne more klikniti gumba "Oddaj posodobljene podatke", dokler niso označeni vsi trije spodnji kontrolni kvadratki (Checkboxi):

### Za MODUL ZL:
1. `☐ Potrjujem, da so navedeni podatki resnični, pravilni in popolni ter da jih posredujem v svojem imenu.` (`required`, `accepted`)
2. `☐ Zavezujem se, da bom zavarovalnico oz. SOP obvestil o vsaki spremembi podatkov.` (`required`, `accepted`)
3. `☐ Potrjujem, da sem seznanjen z informacijami o obdelavi osebnih podatkov.` (`required`, `accepted`)

### Za MODUL ZN:
1. `☐ Potrjujem, da so navedeni podatki resnični, pravilni in popolni ter da jih posredujem v svojem imenu oziroma kot zakoniti zastopnik osebe, za katero posodabljam podatke.` (`required`, `accepted`)
2. `☐ Zavezujem se, da bom zavarovalnico oz. SOP obvestil o vsaki spremembi podatkov.` (`required`, `accepted`)
3. `☐ Potrjujem, da sem seznanjen z informacijami o obdelavi osebnih podatkov.` (`required`, `accepted`)

---

## 6. UI/UX DIZAJN (Referenca: `demo dizajn.html`)

V repozitoriju je shranjena kopija realne strani z `avrio.si/zastopniki/dokument/...` (zastopniški ePortal — obrazec za sklepanje zavarovanj, ne naš obrazec za stranke). Gre za **vizualno/strukturno referenco**, ne za funkcijsko specifikacijo — vsebina obrazca (sklenitelj, upravičenci, način plačila ...) ni naša, prevzeti je treba le videz/komponente.

### 6.1 Kar prevzeti (vizualna identiteta in struktura)
* **Barve:** primarna zelena `#008942` (gumbi, `theme-color`, autosave kljukica). Gumbi: `base-button zelen-background` (primarni, npr. "Shrani"), `base-button zelen-outline` (sekundarni, npr. "Zapri").
* **Glava (`wizard-header`):** logotip levo (`Avrio_slogan_black_500x250.png`), naslov dokumenta (`<h1>`), akcijski gumbi desno ("Zapri", "Shrani"). Gumb "Shrani" uporablja HTML atribut `form="document-form"`, da je fizično zunaj `<form>`, a ga še vedno oddaja — v Livewire to ni potrebno, uporabi `wire:click="save"` na gumbu v istem layoutu.
* **Sekcije obrazca (`form-section` + `<h4>`):** obrazec je razdeljen na poimenovane sekcije (npr. "Sklenitelj", "Upravičenci"...). Pri nas: sekcije po skupinah iz §2 (Osebni podatki, Osebni dokument, PPDFT izjava, CRS/FATCA, Soglasja).
* **Postavitev polj (`form-row` / `form-group`):** dvostolpčna mreža — dve `form-group` polji v vsaki `form-row`. Obvezna polja imajo rdečo zvezdico `<span class="required">*</span>` (`.required { color: #dc3545; }`), neobvezna polja imajo prazen prostor v labeli za poravnavo.
* **Pomožno besedilo (`field-help-text`):** majhen sivkast tekst nad skupino polj, ki pojasni kontekst (npr. "ZAVAROVALEC - Osebni dokument") — uporabno za ločevanje skupnih polj od PPDFT/CRS-specifičnih.
* **Soglasja/checkboxi (`checkbox-group`):** checkbox + besedilo soglasja v eni `<label>`, z linkom na PDF dokument, kjer je relevantno — enak vzorec uporabi za 3 obvezne potrditvene kvadratke iz §4 in soglasja iz §3.
* **Prikaz napak (`has-error`, `field-errors`, `alert-validation`):** rdeč obrobek/senca na poljih z napako, rdeče besedilo napake pod poljem, animiran banner za splošna obvestila o napaki — to neposredno ustreza Livewire/Blade `@error('current_data.x')` prikazu, samo s temi CSS razredi.
* **Noga (`wizard-footer`):** "Copyright © {leto} AVRIO d. d." na dnu.
* **Orodna vrstica dostopnosti (a11y toolbar):** kontrast, velikost pisave, tip pisave, reset, povezava na izjavo o dostopnosti — del obstoječega standarda na avrio.si; smiselno prevzeti vsaj v osnovni obliki, ker gre za javni obrazec za ~20.000 strank.

### 6.2 Tehnična izvedba CSS-ja — odločitev
Demo dizajn temelji na Bootstrap 5 + lastnih CSS datotekah (`eportal.css`, `zastopnik_wizard.css`, `base.css`, `menu.css`, `footer.css`, `fonts.css`, vse v `demo dizajn_files/`). **Odločitev: te Bootstrap CSS datoteke se NE uvozijo.** Uporabi se izključno že nameščeni **Tailwind v4** (`resources/css/app.css`, `vite.config.js`) — videz iz §6.1 (barve, postavitev `form-section`/`form-row`/`form-group`, oznake obveznih polj, prikaz napak, glava/noga ...) se na novo zgradi s Tailwind utility razredi, demo dizajn služi izključno kot vizualna referenca (barve, razmiki, struktura), ne kot dobesedni CSS za prevzeti. Primarna zelena `#008942` naj se definira kot Tailwind tema/barva (npr. v `app.css` prek `@theme`), da se uporablja konsistentno. Filament admin del ostane na svojem privzetem Tailwind-based dizajnu.

### 6.3 Kar NE prevzeti
* **Sledilniki tretjih oseb** (Google Tag Manager, Google Ads konverzije, Facebook Pixel/`fbevents.js`) — naš obrazec obravnava osebne podatke (EMŠO, davčne številke ...), zato teh skript ne smemo vključiti.
* **PWA/manifest/install banner** — ni potrebno za enkraten obrazec za posodobitev podatkov, razen če naročnik to izrecno želi.
* **Večkorakni "wizard" koraki (`wizard-steps-nav`)** — naš obrazec je en sam (dolg ali kratek glede na ZL/ZN), ne večkoračni čarovnik kot pri sklepanju zavarovanja.
* **Avtomatsko shranjevanje v lokalno shrambo + "Shranjeno" značka** (`dokumenti_autosave.js`, banner "Vaše spremembe so bile avtomatsko shranjene v začasno shrambo") — specifikacija predvideva en sam izrecen "Oddaj" korak, ne sprotno samodejno shranjevanje. Lahko se doda kasneje kot UX izboljšava, ni del osnovnega obsega.

### 6.4 Uporabno za odprto vprašanje iz §2
Demo dizajn vsebuje pripravljen spustni seznam držav (ISO3 koda + slovensko ime, npr. `SVN` → Slovenija, `USA` → Združene države Amerike, ...). Ta seznam je smiselno ponovno uporabiti za polja `drzava`, `drzava_izdajatelj` in `drzava_davcnega_rezidentstva` (Select namesto prostega besedila), če naročnik želi bolj nadzorovan vnos kot trenutno predvideno prosto besedilo.

---

## 5. NAVODILO ZA RAZVOJ (Claude Code)
* Z uvozno skripto zagotovi, da se vsa zgoraj navedena polja pravilno inicializirajo v `original_data` in `current_data` kot prazen string oz. vrednost iz Excela.
* V Livewire pogledu (`customer-form.blade.php`) uporabi `@if($customer->vloga_osebe === 'SKLEN')` za preklop med celotnim prikazom (Modul ZL) in okrnjenim prikazom (Modul ZN).