{"id":"c0865","filename":"c0865_sesija_20260515_postgresql_migracija.dok.json","weise3_id":"","tip":"SESIJA_LOG","naziv":"Sesija 2026-05-15 DIO 4 — Tahograf PostgreSQL migracija","kreator":"CC-Sonnet","datum":"2026-05-15","snippet":"","status":"","prev_weise3":"","bunker_l":"#00d4ff","full":{"tip":"SESIJA_LOG","naziv":"Sesija 2026-05-15 DIO 4 — Tahograf PostgreSQL migracija","datum":"2026-05-15","autor":"CC-Sonnet","kontekst":"Ivan je uočio da tahograf-mvp koristi SQLite kao primarnu bazu i odmah naredio migraciju. ZAKON 3: baza je sjena, DokArh je istina.","sto_je_radeno":["Analiza problema: tahograf-mvp/api/models.py koristio SQLite (DB_PATH, check_same_thread), ne PostgreSQL","Kreirana PostgreSQL baza: tahograf_db, korisnik tahograf_user s jakom lozinkom","models.py potpuno repisano: SQLite engine → SQLAlchemy + psycopg2, connection pool (pool_size=5, max_overflow=10)","TAHOGRAF_DATABASE_URL dodan u .env (oba: /var/www/genesis/.env i tahograf-mvp/api/.env)","Prva iteracija migracije: 2 greške — (1) DispoJob nema bunker_seal_id kolonu, (2) String(64) za weise3_id premalo","ZAKON 27 fix: DispoJob.bunker_seal_id dodan (ZAKON 27 — svaki model mora imati weise3_id, bunker_seal_id, created_at)","Schema fix: WEISE3:: prefix + 64-char hash = 72 znaka, String(64) puca — sve *_weise3 i weise3_id kolone promijenjene na String(128)","Zahvaćeni modeli: DokDocument, Driver, Vehicle, Trip, GPSPoint, Capture, DispoJob — ukupno 20+ kolona","Tablice droppane i rekreirane s ispravnom shemom (3 iteracije dok nije prošlo čisto)","migrate_tahograf.py: SQLite → PostgreSQL migracija, 12 zapisa, 0 grešaka","Health endpoint /api/v1/tahograf/health ažuriran: SQLite check → PostgreSQL check (sa sqlite_arhiva kao backup info)","Genesis restartiran, health: ok=true, postgresql.ok=true, dispo_jobs=7","Git commit f541d4a, chain entry c0864"],"greske_i_rjesenja":[{"greska":"column 'bunker_seal_id' of relation 'dispo_jobs' does not exist","uzrok":"ZAKON 27 polje dodano u SQLite nakon inicijalne kreacije, nije bilo u novom PG modelu","rjesenje":"Dodano bunker_seal_id = Column(String(64)→128, default='', index=True) u DispoJob"},{"greska":"value too long for type character varying(64) — weise3_id: 'WEISE3::e8a41d6f...'","uzrok":"WEISE3:: prefix (8 chars) + SHA256 hash (64 chars) = 72 chars, String(64) premalo","rjesenje":"Sve *_weise3 i weise3_id kolone promijenjene na String(128) u svim modelima"},{"greska":"SSH heredoc fails — unexpected EOF while looking for matching apostrophe","uzrok":"Python kod s jednostrukim navodnicima unutar SSH heredoc-a koji koristi jednostruke navodnike","rjesenje":"Skripte pisane lokalno (Write tool) i uploadane scp-om na server"}],"kljucne_odluke":["String(128) kao standard za sve weise3 identifikatore — jednom zauvijek, bez iznimki","SQLite arhiva zadržana (ne obrisana) — backup ako treba history lookup","migrate_genesis_columns() ostaje no-op — PostgreSQL kreira sve kolone pri init_db()","Health endpoint pokazuje i postgresql i sqlite_arhiva — transparentnost o stanju baze"],"stanje_baze_postgresql":{"dispo_jobs":7,"dok_documents":3,"captures":2,"drivers":0,"vehicles":0,"trips":0,"gps_points":0,"napomena":"drivers/vehicles/trips/gps = 0 jer SQLite nije imao testnih podataka za te entitete"},"zakoni":["ZAKON 3 — baza je sjena, DokArh je istina (povod za migraciju)","ZAKON 27 — svaki model mora imati weise3_id, bunker_seal_id, created_at","ZAKON 30 — permissions ostaju www-data:www-data","ZAKON 32 — fix dokumentiran u c0864 + c0865"],"commit":"f541d4a","chain_entry_tehnicka":"c0864_migracija_tahograf_postgresql.dok.json","open_threads":["Drivers/vehicles/trips/gps tablice prazne — popunit će se kad vozači počnu koristiti digigraf.online","tahograf-mvp API endpointi (FastAPI router) još uvijek čitaju/pišu kroz models.py koji sad ide na PG — treba testirati sve CRUD operacije s pravim JWT","SQLite arhiva može se obrisati nakon 30 dana ako nema regresija"]}}