{"id":"c0118","filename":"c0118_genesispos_cc2_backend_plan.dok.json","weise3_id":"cc919fdcdeee91fe071f0a3a3507c2c2f2b10180f08661cd37abee95ad120cf9","tip":"plan_izvrsavanja","naziv":"GenosisPOS CC2 — Backend / Fiscal / QR Generacija","kreator":"cc_claude","datum":"2026-05-08","snippet":"","status":"PLAN_DOGOVOREN","prev_weise3":"","bunker_l":"#7993cf","full":{"tip":"plan_izvrsavanja","naziv":"GenosisPOS CC2 — Backend / Fiscal / QR Generacija","nastao":"2026-05-08","datum":"2026-05-08","kreator":"cc_claude","sustav":"genesispos","weise3_id":"cc919fdcdeee91fe071f0a3a3507c2c2f2b10180f08661cd37abee95ad120cf9","prethodni":"c0117_genesispos_cc1_frontend_plan.dok.json","verzija":"1.0","status":"PLAN_DOGOVOREN","dogovor":"Ivan Seki, 2026-05-08 — split CC1/CC2 potvrđen, QR dodan","sto_treba":"CC2 izvršava backend/services/fiscal zadatke na GenosisPOS-u. Teritorij: services/, alati/, tasks.py, fiscal/, views.py API. Ne dira templates/static/nginx.","teritorij":{"smije":["pos/services/","pos/alati/","pos/tasks.py","pos/fiscal/","pos/views.py (API views, ne template context)","pos/models.py (nova fiscal/QR polja)","pos/migrations/ (samo fiscal/QR migration)"],"ne_smije":["pos/templates/","pos/static/","pos/ai/order_intake.py","/etc/nginx/sites-enabled/genesispos"]},"zadaci":[{"id":"T01","naziv":"omega_engine.py: threading.Thread → Celery async + N+1 fix","problem":"threading.Thread u gunicornu = connection leak. receipt_items.count() = N+1 query.","zakoni":["ZAKON 28"],"chain":"c0126"},{"id":"T02","naziv":"BunkerSeal BPZ-9: L0, L1, L3-L8 implementacija","problem":"Samo L2 implementiran od 9 slojeva BPZ-9","zakoni":["ZAKON 3"],"chain":"c0127"},{"id":"T03","naziv":"ZAKON 3: Trojna pohrana — Krunica + Dvorac noge","problem":"Samo Bršljan noga aktivna. ZAKON 3 zahtijeva sve tri.","zakoni":["ZAKON 3"],"chain":"c0128"},{"id":"T04","naziv":"BasePOSAlat: on_demand() metoda","problem":"on_demand() se poziva u zapisnici_alati.py ali nije definiran u BasePOSAlat — runtime crash","zakoni":["ZAKON 26"],"chain":"c0129"},{"id":"T05","naziv":"QR KOD GENERACIJA — Porezna uprava","novo":true,"opis":"Novi modul pos/fiscal/hr/qr_gen.py. Gradi URL https://porezna.gov.hr/provjera-racuna/?zki={ZKI}&datIzd={datum}&oib={OIB}. Generira QR PNG (qrcode[pil] paket). Sprema PNG u /media/pos/qr/{weise3_id}.png. Poziva se automatski u fiscalize_receipt Celery tasku NAKON FINA JIR odgovora. U DEMO modu: ZKI bez pravog RSA, QR od ZKI svejedno generira.","nova_polja_na_modelu":["fiscal_qr_url = CharField(max_length=500, blank=True)","fiscal_qr_image = ImageField(upload_to='pos/qr/', null=True, blank=True)"],"nova_migracija":"0021_receipt_qr_fields.py","novi_fajl":"pos/fiscal/hr/qr_gen.py","pip_deps":["qrcode[pil]==7.4.2","Pillow>=10.0.0"],"zakoni":["ZAKON 27","ZAKON 3"],"chain":"c0130"},{"id":"T06","naziv":"FINA Production: FISCAL_DEMO_MODE flag","problem":"Nema zaštite od accidental prod fiskalizacije bez .p12 certa. Nema jasnog puta do produkcije.","env_vars":{"FISCAL_HR_DEMO_MODE":"true/false (default: true)","FISCAL_HR_P12_PATH":"putanja do .p12 certifikata","FISCAL_HR_P12_PASS":"lozinka za .p12"},"zakoni":["ZAKON 29"],"chain":"c0131"},{"id":"T07","naziv":"SI FURS: sandbox ready status","problem":"6 zemalja su 100% demo. Odabrana Slovenija za prvu test-real implementaciju.","furs_info":{"sandbox_url":"https://blagajne-test.fu.gov.si:9002/v1/cash_registers","potrebno":"Test .p12 cert s FURS edavki portala","format":"TRR (TrenutniRačun) + EOR (Edinstvena Oznaka Računa)"},"zakoni":["ZAKON 32"],"chain":"c0132"},{"id":"T08","naziv":"Offline bundle API endpoint","problem":"CC1 Service Worker ne može cachirati dinamičke podatke (products, categories) bez backend endpoint-a","novi_url":"GET /pos/api/kasa/offline-bundle/ → JSON s products + categories + terminal + fiscal_demo_mode","zakoni":["ZAKON 33"],"chain":"c0133"}],"definicija_done":["threading.Thread = 0 upotreba u omega_engine.py","bunker_seal_id počinje s 'BPZ9::' na svakom novom receiptu","Trojna pohrana: Bršljan + Krunica pokušaj (Dvorac sync)","BasePOSAlat.on_demand() definiran, 0 AttributeError","pos/fiscal/hr/qr_gen.py postoji, build_verification_url() vraća ispravan URL","QR PNG sprema se u /media/pos/qr/","fiscalize_receipt task poziva attach_qr_to_receipt() nakon JIR","FISCAL_HR_DEMO_MODE=true → QR generira se, nema crash","python manage.py check → 0 errors","python manage.py test pos.tests.test_qr → pass"],"qr_specifikacija":{"url_format":"https://porezna.gov.hr/provjera-racuna/?zki={ZKI}&datIzd={dd.MM.yyyyTHH:mm:ss}&oib={OIB}","referenca":"Tehnička specifikacija fiskalizacije HR v2.5, poglavlje 6.3","library":"qrcode[pil]==7.4.2","error_correction":"ERROR_CORRECT_M (~15% recovery — balans između veličine i otpornosti)","output":"/media/pos/qr/{weise3_id}.png, 300x300px","demo_mode":"ZKI = DEMO{receipt_pk:028d}, QR se svejedno generira za testiranje","sto_radi":"Porezna uprava prima ZKI, pita FINU, prikazuje JIR i status fiskalizacije kupcu"},"faze":[{"faza":1,"naziv":"Infrastruktura (threading, BPZ-9, trojna pohrana)","zadaci":["T01","T02","T03"]},{"faza":2,"naziv":"Interface ispravci (BasePOSAlat, offline bundle)","zadaci":["T04","T08"]},{"faza":3,"naziv":"QR generacija + FINA demo mode","zadaci":["T05","T06"]},{"faza":4,"naziv":"SI FURS sandbox","zadaci":["T07"]}],"zakon":"ZAKON 3 + ZAKON 26 + ZAKON 27 + ZAKON 28 + ZAKON 29 + ZAKON 32 + ZAKON 33","plan_url":"https://genesis.limit-connect.com/plans/cc2_genesispos_backend.md","v_url":"https://genesis.limit-connect.com/v/cc919fdcdeee91fe071f0a3a3507c2c2f2b10180f08661cd37abee95ad120cf9"}}