{"id":"c0160","filename":"c0160_satink_worktime_mvp_plan_za_cc.dok.json","weise3_id":"","tip":"plan","naziv":"c0160 — sati.ink Rebrand: Evidencija radnog vremena MVP","kreator":"Ivan Brtan + CC","datum":"2026-05-08","snippet":"","status":"","prev_weise3":"","bunker_l":"#00d4ff","full":{"tip":"plan","naziv":"c0160 — sati.ink Rebrand: Evidencija radnog vremena MVP","sto_treba":"Port worktime modula iz fina-connect u fenix-v3. Arhiva seli na evalidator.eu/archive/. sati.ink postaje SaaS za evidenciju radnog vremena (HR+DE tržište).","kreator":"Ivan Brtan + CC","datum":"2026-05-08","prioritet":"P0","ne_dira":["vetra.live","evalidator-bridge","KrunicaChain"],"kontekst":{"sati_ink_sad":"Digitalna Arhiva PWA na /pub/arhiva/ — funkcionira, ima korisnike, REBRAND","worktime_izvor":"fina-connect/worktime/ — 995 linija models.py, 2125 linija timesheet_views.py, 22 template-a, KOMPLETAN modul","worktime_podaci":"~20 realnih radnika od 06-11-2025 (u fina_erp ili lokalnoj bazi koju Ivan zna). 309 EmployeeProfile je Synesis greška — ignorirati.","viskovic_bau":"Pilot klijent: viskovic-group.de, ~/20 radnika, građevinarska firma (DE), ArbZG zakon","genesis_sso":"GenesisLoginView, GenesisStatusView, GenesisLogoutView VEĆ POSTOJE u arhiva/views_pwa_auth.py — reusati!"},"faze":[{"id":"F0","naziv":"Arhiva seli — nginx rewrite (0 koda, 15 min)","opis":"sati.ink/ → evalidator.eu/archive/ redirect. Ništa se ne briše, samo URL se mijenja.","koraci":["nginx evalidator conf: dodati location /archive/ → proxy /pub/arhiva/ na port 8001 s Host=sati.ink","nginx sati-ink conf: location / → return 301 https://evalidator.eu/archive/$request_uri (sve stare URL-ove preusmjeri)","Zadržati sati.ink/genesis/ i sati.ink/accounts/ kao proxy (SSO flow mora raditi za archive korisnika)","Test: curl -L https://sati.ink/ → mora stići na evalidator.eu/archive/","nginx -t && systemctl reload nginx"],"test":"9 TempArhivaEntry dostupno na evalidator.eu/archive/dashboard/"},{"id":"F1","naziv":"sati.ink nova landing stranica (radna vremena)","opis":"Minimalna landing koja jasno govori što je sati.ink — ne arhiva, nego evidencija rada.","koraci":["Kreirati fenix-v3/sati_worktime/ Django app (NOVA, čista — ne miješati s arhiva app!)","Template: sati_worktime/templates/sati_worktime/landing.html","Sadržaj: headline 'Evidencija radnog vremena — HR + DE zakon', CTA 'Besplatno 30 dana', Genesis SSO gumb","URL: sati.ink/ → sati_worktime views (bez /pub/arhiva/ prefix)","INSTALLED_APPS dodati 'sati_worktime'","nginx sati-ink conf: location / → proxy fenix-v3 (bez rewrite) — samo / i /login/ i /dashboard/"],"zakon":"ZAKON 27: ako postoji model u ovoj app, mora imati weise3_id + bunker_seal_id + created_at"},{"id":"F2","naziv":"Port worktime modula","opis":"Kopiraj worktime Django app iz fina-connect u fenix-v3 kao nova, čista app. NE kopiraj Synesis integracije.","sto_kopirati":["worktime/models.py → fenix-v3/worktime/models.py (ZAKON 27 dodati na TimeEntry + Project + EmployeeProfile)","worktime/timesheet_views.py → fenix-v3/worktime/ (prilagodi imports za fenix-v3 modele)","worktime/travel_views.py → fenix-v3/worktime/","worktime/urls.py → fenix-v3/worktime/urls.py","worktime/templates/ → fenix-v3/templates/worktime/ (22 template-a)","payroll/models.py → fenix-v3/payroll/ (PayrollRun, Payslip — za platne liste)","payroll/urls.py, payroll/views.py → fenix-v3/payroll/"],"sto_ne_kopirati":["Synesis integracije (synesis_views, magic_link za viskovic-group.de)","burza.ProjectLead FK (ne postoji u fenix-v3)","fina-connect specifični signals.py","Sve što ima CONN_MAX_AGE — fenix-v3 koristi direktni PostgreSQL"],"modifikacije":["TimeEntry: dodati weise3_id + bunker_seal_id CharField(64) (ZAKON 27)","Project: dodati weise3_id + bunker_seal_id (ZAKON 27)","EmployeeProfile: koristiti fenix-v3 Company model (ne fina-connect Company)","settings.py: dodati 'worktime', 'payroll' u INSTALLED_APPS","core/urls_hr.py: dodati path('worktime/', include('worktime.urls'))","makemigrations worktime payroll && migrate"]},{"id":"F3","naziv":"Genesis SSO integracija na sati.ink worktime","opis":"Radnici se logiraju kroz Genesis SSO (genesislogin.online) — ne kreiraju lokalni account.","koraci":["sati_worktime/views.py: WorktimeLandingView + WorktimeDashboardView","sati_worktime/urls.py: path('', landing), path('dashboard/', dashboard), path('genesis-login/', GenesisLoginView...)","Reusati GenesisLoginView iz arhiva.views_pwa_auth (ili kopirati logiku)","Session: tg_session_token u Redis DB4 (isti kao digigraf — unified Genesis session)","nginx sati-ink: location /genesis/ → direktno na fenix-v3/genesis/ (bez /pub/ prefix)"]},{"id":"F4","naziv":"Viskovic Bau pilot — migracija ~20 radnika","opis":"Identificirati i migrirati realne podatke od 06-11-2025.","koraci":["PITANJE ZA IVANA: Gdje je baza s podacima od 06-11-2025? (fina_erp PostgreSQL ima samo 4 TimeEntry od 2026-03-15). Možda lokalni export?","Ako je CSV/Excel export: kreirati management/commands/import_viskovic.py","Ako je MySQL dump: konvertirati i uvesti u fenix-v3 worktime tablice","EmployeeProfile: kreirati za ~20 radnika s OIB, hourly_rate, weekly_hours","Project: kreirati 'VISKOVIC-BAUSANIERUNG-2025' s hourly_rate=25.00, is_billable=True","TimeEntry: uvesti sve zapise s calculate_payroll() pozivom za HR/DE zakonski izračun"],"napomena":"Synesis EmployeeProfile (309 profila) se NE migrira — to su fake profili iz sync greške."},{"id":"F5","naziv":"PWA mobile clock in/out","opis":"Radnici na terenu (Viskovic Bau gradilište) clockaju na mobitelima.","koraci":["Adaptirati worktime/templates/worktime/clock_inout.html za PWA","Dodati manifest.json u sati_worktime (name: 'sati.ink', start_url: '/clock/')","Service Worker: offline queue za clock in/out (ZAKON 33 offline-first)","API: POST /worktime/api/clock-in/ + /worktime/api/clock-out/ (već postoje!)","GPS lokacija (optional): ProjectPhoto.lat/lon za dokazivanje prisutnosti na gradilištu"]},{"id":"F6","naziv":"DE lokalizacija + DATEV export","opis":"ArbZG compliance je već u modelu — samo treba UI upozorenja.","koraci":["locale/de/LC_MESSAGES/django.po — prevesti sve worktime stringove na DE","TimeEntry.compliance_note → UI alert badge (žuto/crveno za ArbZG §3/4 kršenja)","DATEV export: /worktime/export/datev/ → koristi evalidator/datev_adapter.py (VEĆ POSTOJI u fenix-v3!)","PDF platna lista: payroll/joppd.py → JOPPD obrazac (HR zakon)","viskovic-group.de integracija: Magic Link API za pristup bez lozinke (za DE zaposlenike)"]}],"commit_plan":["feat(sati-ink): F0 nginx archive redirect na evalidator.eu","feat(sati-worktime): F1 nova landing app + template","feat(worktime): F2 port modula iz fina-connect — modeli + ZAKON 27","feat(worktime): F3 Genesis SSO integracija na sati.ink","feat(worktime): F4 Viskovic Bau pilot import","feat(worktime): F5 PWA clock in/out mobile","feat(worktime): F6 DE lokalizacija + DATEV export"],"tržišni_model":{"free":"1 radnik, 30 dana, clock in/out + PDF export","starter":"5 radnika, €9/mj, + manager odobravanje + JOPPD","pro":"neograničeno, €29/mj, + DATEV export + ProjectPhoto + analytics","enterprise":"custom, + API, + Konjik fakturiranje, + ArbZG izvještaj za DE inspekciju"},"lijevak":"sati.ink besplatno → radnik → radnik pritišće šefa → šef plaća €9-29/mj","veza_s_arhivom":"Svaki TimeEntry → vetra.live API → zapečaćen (dokaz radnog sata) → evalidator DokArh (ZAKON 32)","zakon":"ZAKON 0 (fizička izolacija), ZAKON 27 (Model Trinity), ZAKON 32 (svaki fix ima chain entry)","KRITICNO_ZA_CC":{"poruka":"ZAKON 3 — TROJNA POHRANA NIJE OPCIJA. Svaki model.objects.create() koji pohranjuje poslovne podatke MORA odmah pozvati get_trojna(). PostgreSQL = brzi upiti = SJENA. Krunica = jedina istina.","greska_koju_cc_pravi":"CC pise objects.create() i smatra da je pohrana gotova. NIJE. Bez get_trojna() podaci ne postoje u lancu.","koji_modeli_moraju_imati_trojna":["TimeEntry — svaki clock-in/clock-out","SatiClockLog — svaki GPS clock zapis","PayrollRun — svaka platna lista","Payslip — svaka placa"],"kod_primjer":["from services.krunica_dvorac_sync import get_trojna","rez = get_trojna().pohrani_sync(obj.weise3_id, podaci, sadrzaj=obj.weise3_id, kreator=kreator, tip='time_entry', prev_hash='', kljuc=None)","assert rez['sve_ok'], f'Trojna pohrana pala: {rez[\"noge\"]}'"],"provjera":"grep -n 'objects.create' views.py — svaki redak mora imati odgovarajuci get_trojna() call ispod"}}}