Commit Graph

256 Commits

Author SHA1 Message Date
AI Assistant 0f555c55ee feat: simplify registry number format to B-2026-00001
New format: single-letter prefix + year + 5-digit sequence.
No direction code (IN/OUT) in the number — shown via arrow icon.
Sequence is shared across directions within the same company+year.

Changes:
- REGISTRY_COMPANY_PREFIX: BTG→B, USW→U, SDT→S, GRP→G
- OLD_COMPANY_PREFIX map for backward compat with existing entries
- allocateSequenceNumber: searches both old and new format entries
  to find the actual max sequence (backward compat)
- recalculateSequence: same dual-format search
- parseRegistryNumber: supports 3 formats (current, v1, legacy)
- isNewFormat: updated regex for B-2026-00001
- CompactNumber: already used single-letter badges, just updated comment
- debug-sequences endpoint: updated for new format
- Notification test data: updated to new format
- RegistrySequence.type: now "SEQ" (shared) instead of "IN"/"OUT"

After deploy: POST /api/registratura/debug-sequences to clean up
old counters, then recreate test entries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:49:35 +02:00
AI Assistant 46de088423 fix: use only actual entries as source of truth for registry numbers
The previous fix still used MAX(actualMax, counterVal) which meant a
stale counter (from entries deleted before the fix was deployed) would
override the actual entry count. Changed to use ONLY actualMax + 1.

The RegistrySequence counter is now just a cache that gets synced —
it never overrides the actual entries count.

Also added /api/registratura/debug-sequences endpoint:
- GET: shows all counters vs actual entry max (for diagnostics)
- POST: resets all counters to match actual entries (one-time fix)

After deploy, call POST /api/registratura/debug-sequences to reset
the stale counters, then delete the BTG-2026-OUT-00004 entry and
recreate it — it will get 00001.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:20:58 +02:00
AI Assistant dbed7105b7 fix: bulletproof registry number allocation using actual DB entries as source of truth
The old allocateSequenceNumber blindly incremented a counter in
RegistrySequence, which drifted out of sync when entries were deleted
or moved between companies — producing wrong numbers (e.g., #6 for
the first entry of a company).

New approach:
- Uses pg_advisory_xact_lock inside a Prisma interactive transaction
  to serialize concurrent allocations
- Always queries the actual MAX sequence from KeyValueStore entries
  (the source of truth) before allocating the next number
- Takes MAX(actual entries, counter) + 1 so the counter can never
  produce a stale/duplicate number
- Upserts the counter to the new value for consistency
- Also adds recalculateSequence to DELETE handler so the counter
  stays in sync after entry deletions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:11:52 +02:00
AI Assistant 8e56aa7b89 fix: detail panel scroll and missing TooltipProvider in status badge
- Add min-h-0 + overflow-hidden on ScrollArea to enable scrolling
  in the detail side panel (flex child needs bounded height)
- Wrap external status badge Tooltip in TooltipProvider to fix
  "Tooltip must be used within TooltipProvider" runtime crash

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:55:15 +02:00
AI Assistant d7bd1a7f5d feat: external status monitor for registratura (Primaria Cluj-Napoca)
- Add ExternalStatusTracking types + ExternalDocStatus semantic states
- Authority catalog with Primaria Cluj-Napoca (POST scraper + HTML parser)
- Status check service: batch + single entry, change detection via hash
- API routes: cron-triggered batch (/api/registratura/status-check) +
  user-triggered single (/api/registratura/status-check/single)
- Add "status-change" notification type with instant email on change
- Table badge: Radio icon color-coded by status (amber/blue/green/red)
- Detail panel: full monitoring section with status, history, manual check
- Auto-detection: prompt when recipient matches known authority
- Activation dialog: configure petitioner name + confirm registration data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:42:21 +02:00
AI Assistant 1c51236c31 fix: registry number re-allocation on company change + extreme PDF large file support
- Registratura: re-allocate number when company/direction changes on update,
  recalculate old company's sequence counter from actual entries
- Extreme PDF: stream body to temp file instead of req.formData() to support large files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:05:13 +02:00
AI Assistant dff0bbe97c Shorten company badges to single letters and remove intern direction
Company badges: US→U, SDT→S (B and G already single letter).
Direction: only intrat (↓ green) and iesit (↑ orange), removed intern since no longer used.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 09:10:50 +02:00
AI Assistant 98c6fcb619 ui: compact registry numbers with company badge + direction icon
Replace full "BTG-0042/2026" with compact [B] ↓ 0042/2026 format:
- Colored company badge (B=blue, US=violet, SDT=green, G=gray)
- Direction arrow icon (↓ green=intrat, ↑ orange=iesit, ↔ gray=intern)
- Plain number without prefix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 09:07:12 +02:00
AI Assistant f10a112de6 ui: make toolbar buttons icon-only with title tooltip (Bune practici, Notificari)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 08:52:12 +02:00
AI Assistant 974d06fff8 feat: add email notification system (Brevo SMTP + N8N daily digest)
- Add core notification service: types, email-service (nodemailer/Brevo SMTP), notification-service (digest builder, preference CRUD, HTML renderer)
- Add API routes: POST /api/notifications/digest (N8N cron, Bearer auth), GET/PUT /api/notifications/preferences (session auth)
- Add NotificationPreferences UI component (Bell button + dialog with per-type toggles) in Registratura toolbar
- Add 7 Brevo SMTP env vars to docker-compose.yml
- Update CLAUDE.md, ROADMAP.md, DATA-MODEL.md, SYSTEM-ARCHITECTURE.md, CONFIGURATION.md, DOCKER-DEPLOYMENT.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 01:12:36 +02:00
AI Assistant 6941074106 fix: copy button uses plain number format (nr. 42 din 11.03.2026)
Strips company prefix and leading zeros from registry number.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 00:37:53 +02:00
AI Assistant 8e9753fd29 feat: add copy button next to registry number in table
Copies "nr. BTG-0042/2026 din 11.03.2026" to clipboard on click.
Small icon, subtle until hover, green check feedback on copy.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 00:35:12 +02:00
AI Assistant 7094114c36 fix: hooks order violation in DeadlineResolveDialog causing crash
useMemo was called after early return (when deadline=null), violating
React Rules of Hooks. Moved all hooks before the conditional return.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 00:30:38 +02:00
AI Assistant 959590acfe feat: add Convocare CTATU document type
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 00:21:36 +02:00
AI Assistant 1c5ad7c988 feat: restructure Completari + rename Contestatie → Litigii + remove ac-prelungire
- Remove ac-prelungire backward deadline (redundant with AC validity tracker)
- Completari: now 2 beneficiary reminders (L350=60z, L50=3luni) instead of 4 mixed entries
- Rename contestatie → litigii ("Litigii / Sanctiuni / Contestatii")
- Add new litigii deadlines: prescriptie contraventie (3 ani), plangere PV (15z), CNSC (10z)
- Update existing: plangere prealabila, actiune instanta, atacare urbanism labels

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 00:08:24 +02:00
AI Assistant a2b9ff75b5 feat(registratura): restructure Autorizare deadlines — no tacit approval
- ac-verificare (5z lucr.) now auto-track, created automatically with
  any AC emitere type. Informational: authority notifies if incomplete.
- ac-emitere (30z cal.) now chains to ac-emitere-dupa-completari when
  interrupted — term recalculates from completion submission date.
- ac-emitere-urgenta (7z lucr.) and ac-emitere-anexe (15z cal.) kept.
- New: ac-prelungire-emitere (15z lucr.) — authority communicates
  decision on AC extension within 15 working days.
- Info box in DeadlineAddDialog for autorizare category explaining
  auto-tracked verification + interruption mechanism.
- None of the autorizare deadlines have tacit approval.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 23:55:39 +02:00
AI Assistant a96dce56a2 feat(registratura): revert intrat full categories + add urbanism deadlines
- Revert: only iesit+cerere/aviz gets full permitting categories
- Urbanism: furnizare date retele (15z cal, doar autoritati publice)
- Urbanism: aviz oportunitate PUZ — verificare (30z) + convocare CTATU
  (30z, chain) + emitere dupa comisie (15z, auto-track)
- Urbanism: aviz arhitect sef PUD/PUZ — convocare CTATU (30z, chain)
  + emitere (15z, auto-track)
- Urbanism: promovare CL (30z) + vot CL (45z dupa dezbatere publica)
- None of the urbanism deadlines have tacit approval

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 23:45:25 +02:00
AI Assistant 8bcb0bcc81 fix: show all permitting deadline categories for cerere/aviz regardless of direction
Previously DIRECTION_CATEGORIES limited intrat to only completari+contestatie,
so cerere/aviz on intrat direction lost certificat/avize/urbanism/autorizare.
Now cerere/aviz doc types unlock all 6 categories on both directions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 23:24:02 +02:00
AI Assistant 4467e70973 fix: tooltip {proiect} hint visibility — use amber-300 on dark tooltip bg
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 23:00:10 +02:00
AI Assistant f50ad5e020 feat(registratura): auto-detect {proiect} placeholder in subject and switch to template mode
Typing {proiect}, {nr}, {an}, {detalii} or {text} in the subject field
now auto-transforms to template mode with the appropriate input widgets
(project dropdown, number fields, etc.).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 22:52:31 +02:00
AI Assistant 442a1565fd feat: avize deadline restructure with interruption mechanism + comisie toggle
- Add "Necesita analiza in comisie" toggle for avize category (mirrors CJ toggle)
  - When OFF: auto-creates 5-day working limit for completari requests
  - When ON: no limit (institution can request completions anytime)
- Add interruption mechanism: resolve aviz as "intrerupt" when institution
  requests completions → auto-creates new 15-day deadline from completions date
- New resolution type "intrerupt" with yellow badge + chain support
- Restructure avize catalog entries:
  - aviz-ac-15 (L50) and aviz-urbanism-30 (L350) now have chain to
    aviz-emitere-dupa-completari for interruption flow
  - aviz-mediu: updated hints about procedure closure prerequisite
  - aviz-cultura-comisie: 2-phase with auto-track depunere la comisie (30 days)
  - aeronautica, ISU, transport-eu: all get interruption chain
- 3 new auto-track entries: aviz-completari-limit (5zl), aviz-emitere-dupa-completari
  (15zc), aviz-cultura-depunere-comisie (30zc)
- New document type: "Convocare sedinta"
- Info boxes in dialog explaining auto-track behavior + interruption mechanism

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 22:41:14 +02:00
AI Assistant 31565b418a fix: doc type persistence on edit + filter deadlines by document type
- Fix doc type showing "altele" after edit: preserve initial documentType
  in allDocTypes map even if not in defaults or Tag Manager
- Filter deadline categories by document type: only cerere/aviz unlock
  full permitting categories (CU, avize, urbanism, autorizare)
- Other doc types (scrisoare, notificare, etc.) only get completari +
  contestatie as deadline categories
- Add completari to intrat direction (was missing)
- Pass documentType to DeadlineAddDialog for category filtering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 21:58:06 +02:00
AI Assistant 4ac4a48cad fix: differentiate Conex (linkedEntryIds) vs Inchide (threadParentId) semantics
- Conex button now adds to linkedEntryIds (for clarificari/solicitari)
  instead of setting threadParentId
- Inchide button sets threadParentId (direct reply) + auto-closes parent
- Fix Sterge button persistence bug: threadParentId now saves as empty
  string instead of undefined (which was stripped in JSON serialization)
- Card headers: "Conex cu X" (amber) vs "Raspuns la X" (blue + green)
- Add conexTo prop to RegistryEntryForm for linked entry pre-fill

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 21:29:56 +02:00
AI Assistant 85077251f3 feat(registratura): fix thread clear, close via conex entry
- Fix threadParentId clear: always show "Sterge" button even when parent not found in allEntries
- Bigger clear button with text label instead of tiny X icon
- Fallback display when parent not in current list (shows truncated ID)
- Close via conex: table/detail "Inchide" now creates a new reply entry that closes the original
- Header shows "Conex la BTG-XXX" + "Inchide originala" badge when closing via conex
- After saving the new conex entry, parent is auto-closed with resolution "finalizat"
- onClose signature changed from (id: string) to (entry: RegistryEntry) across table + detail

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 21:15:40 +02:00
AI Assistant f5e19ce3d1 feat(registratura): add Conex (reply) + Inchide buttons, reorder completari last
- Conex button on table rows (Reply icon, blue) — opens new entry with threadParentId pre-set + flipped direction
- Conex button on detail panel — same behavior
- Inchide button on table rows (CheckCircle2 icon, green) — only for open entries
- replyTo prop on RegistryEntryForm: pre-sets threadParentId + direction flip (intrat→iesit, iesit→intrat)
- Card header shows "Conex la BTG-0042/2026" with blue badge when replying
- Completari moved to last position in deadline category order

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 20:40:12 +02:00
AI Assistant f01fe47af4 feat(registratura): remove publicitate category, auto-track comunicare, late receipt badge, AC validity conditional
- Remove publicitate/comunicare category entirely (AC publicity handled by AC validity tracker)
- comunicare-aviz-beneficiar moved to auto-track: created alongside any iesit deadline
- Late receipt badge on incoming aviz entries: shows "Primit cu X zile intarziere" when document date < today
- Valabilitate document + AC Validity Tracker visible only when documentType is "aviz" (act administrativ)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 19:26:05 +02:00
AI Assistant b2519a3b9c feat(registratura): redesign CU deadline tracking — direction filtering, CJ toggle, auto-track, verification badge
- CU has NO tacit approval on any entry
- Direction-dependent categories: iesiri (CU, Avize, Completari, Urbanism, Autorizare), intrari (Contestatie)
- Rename: Analiza → Urbanism (PUD/PUZ/PUG), Autorizare (AC) → Autorizare (AD/AC)
- Auto-track deadlines: cu-verificare (10zl) created automatically with CU emitere
- CJ toggle: auto-creates arhitect-sef solicita aviz (3zc) + primar emite aviz (5zc)
- Verification badge: after 10 days shows "Nu mai pot returna documentatia"
- Prelungire helper: CU issue date + 6/12/24 month calculator
- cu-prelungire-emitere changed to 30zc (practica administrativa)
- New DeadlineTypeDef fields: autoTrack, directionFilter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 18:58:50 +02:00
AI Assistant f5ffce2e23 feat(registratura): restructure legal deadline catalog — 35 deadlines from Legea 50/1991 & 350/2001
Complete rewrite of deadline-catalog.ts based on comprehensive legislative extracts:

Certificat de Urbanism (6): verificare 10zl, emitere L50 15zl, emitere L350 30zc,
  suport tehnic 10zl, prelungire depunere 15zc backward, prelungire emitere 15zc

Avize (15): AC standard 15zc, urbanism 30zc, Mediu 15zc, Cultura comisie 30zc,
  Min.Culturii 30zl, Aeronautica 30zc, ISU 15zc, transport EU 10zc, comisie
  agenda 30zc, comisie emitere 15zc, oportunitate analiza/emitere (fara tacit!),
  reconfirmare 5zl, primar 5zc, monument fara AC 30zc

Completari (4): notificare 5zl, beneficiar 60zc, emitere 15zc, AC beneficiar 90zc

Autorizare (5): verificare 5zl, emitere 30zc, urgenta 7zl, agricol 15zc,
  prelungire 45zl backward

Publicitate (2): AC 30zc, comunicare aviz 1zc

Contestatie (4): plangere prealabila 30zc, contestare AC 60zc,
  contestare urbanism 5 ani, plangere contraventionala 15zc

Each deadline now includes legalReference field displayed in the dialog.
Dialog shows legal reference, scroll for long lists, contestatie category added.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:24:02 +02:00
AI Assistant eb7c28ca14 feat(registratura): smart defaults per direction, new doc types, expanded cerere templates
- Default doc type: aviz (intrat) / cerere (iesit); auto-switches on direction toggle
- New default doc types: Proces verbal, Notificare, Comunicare (with full seed templates)
- Cerere templates rewritten: emiterea CU/AC, prelungirea valabilitatii, completare
  documentatie, indreptarea erorilor materiale, inaintare dispozitie de santier,
  eliberarea certificatului, aviz, racordare
- Aviz label renamed to "Aviz / Act administrativ"
- Scrisoare label renamed to "Scrisoare / Adresa", raport to "Raport / Studiu"
- Moved PV/notificare/comunicare templates from scrisoare/altele to their own types
- Cleaned up duplicate templates across categories

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:02:46 +02:00
AI Assistant b62e01b153 feat(registratura): expand seed templates — memoriu justificativ, comunicare, deviz, borderou
- Add Comunicare, Instiintare under scrisoare
- Add Memoriu justificativ, Studiu de fezabilitate, Audit energetic, Caiet de sarcini under raport
- Add Aviz racordare, Acord unic under aviz
- Add Contract proiectare, PV predare-primire under contract
- Add Borderou, Fisa tehnica, Tema de proiectare, Deviz general, Conventie under altele
- Total seed templates: ~55 across 11 document types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 13:31:36 +02:00
AI Assistant 8cec9646c3 feat(registratura): add administrative acts seed templates (CU, AC, avize concrete)
- Add CU/AC/Prelungire CU/AC templates under aviz type for received acts
- Add Aviz ISU/DSP/Mediu/APM concrete templates
- Add PV receptie, Proces verbal, Referat verificare, Expertiza tehnica, RTE, Memoriu tehnic
- Add Cerere completari, Raspuns completari, Somatie templates
- Update dynamic placeholders for intrat (CU/AC examples) and iesit (Cerere CU)
- Update tooltip examples: intrat shows CU/AC/Aviz, iesit shows Cerere/Solicitare

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 13:05:45 +02:00
AI Assistant e30b437dce feat(registratura): smart subject autocomplete v2 — seed templates, project linking, dynamic placeholders
- Add SEED_TEMPLATES catalog (11 doc types x 2-4 templates = ~30 predefined patterns)
- Add {proiect} field type with mini-autocomplete from Tag Manager projects
- Pre-fill {an} fields with current year on template selection
- Dynamic placeholder changes based on documentType + direction (22 combinations)
- Dropdown on empty focus: "Sabloane recomandate" + "Recente" sections
- Direction-aware tooltip on Subiect field (intrat vs iesit examples)
- getRecommendedTemplates() merges seeds + DB-learned, DB takes priority

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 12:46:05 +02:00
AI Assistant 3a3db3f366 fix(registratura): lower subject template min length from 8 to 3 chars
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 08:48:34 +02:00
AI Assistant b3b585e7c8 feat(registratura): subject autocomplete with inline template fields
- New subject-template-service: extracts reusable templates from existing
  subjects by detecting variable parts (numbers, years, text after separators)
- Template input component: inline editable fields within static text
  (e.g., "Cerere CU nr. [___]/[____] — [___________]")
- Two-tier autocomplete dropdown: templates sorted by frequency (top) +
  matching existing subjects (bottom)
- Learns from database: more entries = better suggestions
- Follows existing contact autocomplete pattern (focus/blur, onMouseDown)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 08:40:37 +02:00
AI Assistant eb96af3e4b feat(registratura): add best practices popover + contextual tooltips on form fields
- "Bune practici" button in registry header opens a popover with internal rules
  (numerotare, completare, termene, atașamente, închidere)
- Info tooltips on form labels: Direcție, Tip document, Subiect, Expeditor,
  Destinatar, Atașamente (consistent with existing pattern on Data document)
- Install shadcn/ui Popover component

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 08:21:54 +02:00
AI Assistant 6786ac07d1 fix(registratura): remove intern direction — only intrat/iesit are valid
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 08:01:29 +02:00
AI Assistant a0dd35a066 feat(registratura): atomic numbering, reserved slots, audit trail, API endpoints + theme toggle animation
Registratura module:
- Atomic sequence numbering (BTG-2026-IN-00125 format) via PostgreSQL upsert
- Reserved monthly slots (2/company/month) for late registrations
- Append-only audit trail with diff tracking
- REST API: /api/registratura (CRUD), /api/registratura/reserved, /api/registratura/audit
- Auth: NextAuth session + Bearer API key support
- New "intern" direction type with UI support (form, filters, table, detail panel)
- Prisma models: RegistrySequence, RegistryAudit

Theme toggle:
- SVG mask-based sun/moon morph with 360° spin animation
- Inverted logic (sun in dark mode, moon in light mode)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 07:54:32 +02:00
AI Assistant ca4d7b5d8d feat(auth): force Authentik login on first visit, fix ManicTime sync
Auth:
- Add middleware.ts that redirects unauthenticated users to Authentik SSO
- Extract authOptions to shared auth-options.ts
- Add getAuthSession() helper for API route protection
- Add loading spinner during session validation
- Dev mode bypasses auth (stub user still works)

ManicTime:
- Fix hardcoded companyId="beletage" — now uses group context from Tags.txt
- Fix extended project format label parsing (extracts name after year)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 12:26:08 +02:00
AI Assistant 12b7bca990 Mini Utilities v0.2.0: extreme PDF compression (GS+qpdf), DWG→DXF, paste support, drag-drop layers
- Extreme PDF compression via direct Ghostscript + qpdf pipeline
  (PassThroughJPEGImages=false, QFactor 1.5, 72 DPI downsample)
- DWG→DXF converter via libredwg (Docker only)
- PDF unlock in-app via Stirling PDF proxy
- Removed PDF/A tab (unused)
- Paste (Ctrl+V) on all file drop zones
- Mouse drag-drop reordering on thermal layers
- Tabs reorganized into 2 visual rows
- Dockerfile: added ghostscript, qpdf, libredwg
2026-03-08 21:44:43 +02:00
AI Assistant 94b342e5ce Hot Desk 0.2.0: room layout proportions, name quick-select, remove notes 2026-03-08 19:33:25 +02:00
AI Assistant 4d2f924537 pre-launch hardening: Address Book type sort, Hot Desk proportions, TVA calculator, ROADMAP Phase 4B
- Address Book: type dropdown always sorted alphabetically (ro locale), including custom types
- Hot Desk: window ~half height (top-[35%] bottom-[35%]), door ~double height (h-16)
- Mini Utilities: TVA calculator (19%) with add/extract modes, RON formatting, copy buttons
- ROADMAP: new Phase 4B Pre-Launch Hardening with 10 structured tasks
- CLAUDE.md: bumped versions (Address Book 0.1.1, Mini Utilities 0.1.1, Hot Desk 0.1.1), Visual Copilot separate repo note
2026-03-08 14:08:48 +02:00
AI Assistant a6fa94deec docs + fix: eTerra health check keywords from real maintenance page
- Added real eTerra maintenance keywords observed 2026-03-08:
  'serviciu indisponibil', 'activități de mentenanță sunt în desfășurare'
- Extract actual maintenance message from HTML response for UI display
- Updated CLAUDE.md: ParcelSync module #15, Visual Copilot #16,
  eTerra/PostGIS integrations, TS strict gotchas, eTerra API rules
- Updated ROADMAP.md: Phase 7B (ParcelSync) with 5 completed tasks
- Updated SESSION-LOG.md: full session entry with bugs/learnings
2026-03-08 13:04:11 +02:00
AI Assistant b7a236c45a feat(parcel-sync): eTerra health check + maintenance detection
- New eterra-health.ts service: pings eTerra periodically (3min),
  detects maintenance (503, keywords), tracks consecutive failures
- New /api/eterra/health endpoint for explicit health queries
- Session route blocks login when eTerra is in maintenance (503 response)
- GET /api/eterra/session now includes eterraAvailable/eterraMaintenance
- ConnectionPill shows amber 'Mentenanță' state with AlertTriangle icon
  instead of confusing red error when eTerra is down
- Auto-connect skips when maintenance detected, retries when back online
- 30s session poll auto-detects recovery and re-enables auto-connect
2026-03-08 10:28:30 +02:00
AI Assistant 6557cd5374 feat(parcel-sync): per-UAT analytics dashboard in Database tab
- New API route /api/eterra/uat-dashboard with SQL aggregates
  (area stats, intravilan/extravilan split, land use, top owners, fun facts)
- CSS-only dashboard component: KPI cards, donut ring, bar charts
- Dashboard button on each UAT card in DB tab, expands panel below
2026-03-08 10:18:34 +02:00
AI Assistant 6558c690f5 feat(parcel-sync): owner name search (proprietar) in Search tab
- New search mode toggle: Nr. Cadastral / Proprietar
- Owner search queries:
  1. Local DB first (enrichment PROPRIETARI/PROPRIETARI_VECHI ILIKE)
  2. eTerra API fallback (tries personName/titularName/ownerName filter keys)
- DB search works offline (no eTerra connection needed) — uses enriched data
- New API route: POST /api/eterra/search-owner
- New eterra-client method: searchImmovableByOwnerName()
- Owner results show source badge (DB local / eTerra online)
- Results can be added to saved list and exported as CSV
- Relaxed search tab guard: only requires UAT selection (not eTerra connection)
- Cadastral search still requires eTerra connection (shows hint when offline)
2026-03-08 03:48:23 +02:00
AI Assistant 8bb4a47ac5 fix(eterra): increase default timeout 40s -> 120s for large geometry pages
- DEFAULT_TIMEOUT_MS: 40_000 -> 120_000 (1000 features with full geometry
  from Feleacu regularly exceed 40s on the eTerra server)
- Add timeoutMs option to syncLayer() for caller override
- syncLayer now passes timeoutMs through to EterraClient.create()

Fixes 'timeout of 40000ms exceeded' on TERENURI_ACTIVE sync.
2026-03-08 03:31:18 +02:00
AI Assistant d7d78c0cc1 fix(eterra-client): reduce default pageSize to 1000 + retry on ArcGIS errors
- DEFAULT_PAGE_SIZE: 2000 -> 1000 (matches eTerra maxRecordCount, avoids
  requesting more than the server supports on first try)
- PAGE_SIZE_FALLBACKS: [500, 200] (removed 1000 since it's now the default)
- Add retry-once logic for 'Error performing query operation':
  Wait 2s and retry same page before falling to smaller sizes.
  These errors are often transient server-side timeouts.
- Longer delay (1s vs 0.5s) between page size fallback attempts

Fixes Feleacu (7951 features) background sync failure.
2026-03-08 03:06:44 +02:00
AI Assistant 041bfd4138 fix(parcel-sync): fix ArcGIS 1000 server cap pagination + scan improvements
- eterra-client: detect server maxRecordCount cap in fetchAllLayerByWhere
  When server returns exactly 1000 (or other round cap) but we asked for 2000,
  recognize this as a server limit, adjust pageSize, and CONTINUE paginating.
  Previously: 1000 < 2000 -> break (lost all data beyond page 1).

- no-geom-sync: count layers first, pass total to fetchAllLayer
  Belt-and-suspenders: even if cap detection misses, known total prevents
  early termination. Also use pageSize 1000 to match typical server cap.
  Clădiri count uses countLayer instead of fetching all OBJECTIDs.

- UI: add include-no-geom checkbox in background sync section
  Users can toggle it independently of scan status.
  Shows '(scanare in curs)' hint when scan is still running.
2026-03-08 02:37:39 +02:00
AI Assistant d12f01fc02 fix(parcel-sync): add 2min timeout to no-geom scan, non-blocking UI
- Server: Promise.race with 120s timeout on no-geom-scan API route
- Client: AbortController with 120s timeout on scan fetch
- UI: show 'max 2 min' during scanning + hint that buttons work without scan
- UI: timeout state shows retry button + explains no-geom won't be available
- Prevents indefinitely stuck 'Se scanează...' on slow eTerra responses
2026-03-08 02:28:51 +02:00
AI Assistant e57ca88e7e fix: increase background job progress retention to 6h, localStorage recovery to 8h 2026-03-08 01:59:09 +02:00