Files
ArchiTools/CLAUDE.md
T
AI Assistant 0c4b91707f audit: production safety fixes, cleanup, and documentation overhaul
CRITICAL fixes:
- Fix SQL injection in geoportal search (template literal in $queryRaw)
- Preserve enrichment data during GIS re-sync (upsert update explicit fields only)
- Fix ePay version race condition (advisory lock in transaction)
- Add requireAuth() to compress-pdf and unlock routes (were unauthenticated)
- Remove hardcoded Stirling PDF API key (env vars now required)

IMPORTANT fixes:
- Add admin role check on registratura debug-sequences endpoint
- Fix reserved slot race condition with advisory lock in transaction
- Use SSO identity in close-guard-dialog instead of hardcoded "Utilizator"
- Storage DELETE catches only P2025 (not found), re-throws real errors
- Add onDelete: SetNull for GisFeature → GisSyncRun relation
- Move portal-only users to PORTAL_ONLY_USERS env var
- Add security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy)
- Add periodic cleanup for eTerra/ePay session caches and progress store
- Log warning when ePay dataDocument is missing (expiry fallback)

Cleanup:
- Delete orphaned rgi-test page (1086 lines, unregistered, inaccessible)
- Delete legacy/ folder (5 files, unreferenced from src/)
- Remove unused ensureBucketExists() from minio-client.ts

Documentation:
- Optimize CLAUDE.md: 464 → 197 lines (moved per-module details to docs/)
- Create docs/ARCHITECTURE-QUICK.md (80 lines: data flow, deps, env vars)
- Create docs/MODULE-MAP.md (140 lines: entry points, API routes, cross-deps)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 06:40:34 +02:00

9.4 KiB

ArchiTools — Project Context for AI Assistants

Quick Start

npm install
npm run dev          # http://localhost:3000
npx next build       # verify zero errors before pushing
git push origin main # manual redeploy via Portainer UI

Project Overview

ArchiTools is a modular internal web dashboard for 3 architecture/engineering companies: Beletage (architecture), Urban Switch (urbanism), Studii de Teren (geotechnics). Production: tools.beletage.ro — Docker on-premise, Portainer CE, Traefik v3 proxy.

Stack

Layer Technology
Framework Next.js 16.x, App Router, TypeScript (strict)
Styling Tailwind CSS v4, shadcn/ui
Database PostgreSQL + PostGIS via Prisma v6 ORM
Storage DatabaseStorageAdapter (Prisma), localStorage fallback
Files MinIO (S3-compatible object storage)
Auth NextAuth v4 + Authentik OIDC (auth.beletage.ro)
Deploy Docker multi-stage → Portainer CE → Traefik v3 + SSL
Repo Gitea at git.beletage.ro/gitadmin/ArchiTools
Language Code: English, UI: Romanian

Architecture Principles

  • Module platform — each module isolated: own types/services/hooks/components
  • Feature flags gate loading (disabled = zero bundle cost)
  • Storage abstraction via StorageService interface + adapters
  • Auth via Authentik SSO — group → role/company mapping
  • All entities include visibility / createdBy from day one

Repository Structure

src/
├── app/(modules)/          # Route pages (thin wrappers)
├── core/                   # Platform: auth, storage, flags, tagging, i18n, theme
├── modules/<name>/         # Module business logic (see MODULE-MAP.md)
│   ├── components/         # UI components
│   ├── hooks/              # Module hooks
│   ├── services/           # Business logic
│   ├── types.ts            # Interfaces
│   ├── config.ts           # Module metadata
│   └── index.ts            # Public exports
├── shared/components/      # ui/ (shadcn), layout/ (sidebar/header), common/
├── config/                 # modules.ts, flags.ts, navigation.ts, companies.ts
docs/                       # Architecture, guides, module deep-dives

Modules (17 total)

Module Route Key Features
Dashboard / KPI cards, activity feed, module grid
Email Signature /email-signature Multi-company, live preview, copy/download
Word XML /word-xml Category-based XML, simple/advanced, ZIP export
Registratura /registratura Registry CRUD, legal deadlines, notifications, NAS
Tag Manager /tag-manager Tags CRUD, ManicTime sync
IT Inventory /it-inventory Equipment, rack visualization, filters
Address Book /address-book Contacts, vCard, Registratura integration
Password Vault /password-vault AES-256-GCM encrypted, WiFi QR, multi-user
Mini Utilities /mini-utilities 12+ tools: PDF compress, OCR, converters, calc
Prompt Generator /prompt-generator 18 templates, text + image targets
Digital Signatures /digital-signatures Assets CRUD, file upload, tags
Word Templates /word-templates Template library, .docx placeholder detection
AI Chat /ai-chat Multi-provider (OpenAI/Claude/Ollama)
Hot Desk /hot-desk 4 desks, week calendar, room layout
ParcelSync /parcel-sync eTerra ANCPI, PostGIS, enrichment, ePay ordering
Geoportal /geoportal MapLibre viewer, parcel search, UAT layers
Visual CoPilot /visual-copilot Placeholder — separate repo

See docs/MODULE-MAP.md for entry points, API routes, and cross-module deps.


Development Rules

TypeScript Strict Mode Gotchas

  • arr[0] is T | undefined even after length check — assign to const first
  • Record<string, T>[key] returns T | undefined — always null-check
  • Spread of possibly-undefined: { ...obj[key] } — check existence first
  • lucide-react Icons: cast through unknownReact.ComponentType<{ className?: string }>
  • Prisma $queryRaw returns unknown[] — cast with as Array<{ field: type }>
  • ?? "" on {} field produces {} not string — use typeof check

Conventions

  • Code: English | UI text: Romanian | IDs: uuid v4
  • Dates: ISO strings (YYYY-MM-DD display, full ISO timestamps)
  • Components: functional, 'use client' where needed
  • No emojis in code or UI

Storage Performance (CRITICAL)

  • NEVER storage.list() + storage.get() in loop — N+1 bug
  • ALWAYS use storage.exportAll() or storage.export(namespace) for batch-load
  • NEVER store base64 files in entity JSON — use lightweight: true for listing
  • After mutations: optimistic update OR single refresh() — never both

Middleware & Large Uploads

  • Middleware buffers entire body — exclude large-upload routes from matcher
  • Excluded routes: api/auth|api/notifications/digest|api/compress-pdf|api/address-book|api/projects
  • Excluded routes use requireAuth() from auth-check.ts instead
  • To add new upload route: (1) exclude from middleware, (2) add requireAuth()

eTerra / ANCPI Rules

  • ArcGIS: paginate with resultOffset/resultRecordCount (max 1000)
  • Sessions expire ~10min — cache TTL 9min, auto-relogin on 401
  • Health check detects maintenance — block login when down
  • WORKSPACE_TO_COUNTY (42 entries in county-refresh.ts) is authoritative
  • GisUat.geometry is huge — always select to exclude in list queries
  • Feature counts cached 5-min TTL
  • ePay: form-urlencoded body, OpenAM auth, MinIO metadata must be ASCII

Before Pushing

  1. npx next build — zero errors
  2. Test on localhost:3000
  3. Commit with descriptive message
  4. git push origin main → manual Portainer redeploy

Common Pitfalls (Top 10)

  1. Middleware body buffering — upload routes >10MB must be excluded from matcher
  2. N+1 storage queries — use exportAll(), never list() + get() loop
  3. GisUat geometry in queries — exclude with select, or 50ms → 5+ seconds
  4. Enrichment data loss on re-sync — upsert must preserve enrichment field
  5. Ghostscript corrupts fonts — use qpdf for PDF compression, never GS
  6. eTerra timeout too low — geometry pages need 60-90s; default 120s
  7. Traefik 60s readTimeout — must set 600s in static config for uploads
  8. Portainer CE can't inject env vars — all env in docker-compose.yml
  9. @prisma/client in dependencies (not devDeps) — runtime requirement
  10. output: 'standalone' in next.config.ts — required for Docker

Infrastructure Quick Reference

Service Address Purpose
App 10.10.10.166:3000 ArchiTools (tools.beletage.ro)
PostgreSQL 10.10.10.166:5432 Database (Prisma)
MinIO 10.10.10.166:9002/9003 Object storage
Authentik 10.10.10.166:9100 SSO (auth.beletage.ro)
Portainer 10.10.10.166:9000 Docker management
Gitea 10.10.10.166:3002 Git (git.beletage.ro)
Traefik 10.10.10.199 Reverse proxy + SSL
N8N 10.10.10.166:5678 Workflow automation
Stirling PDF 10.10.10.166:8087 PDF tools (needs env vars!)

Company IDs

ID Name Prefix
beletage Beletage B
urban-switch Urban Switch US
studii-de-teren Studii de Teren SDT
group Grup G

Documentation

Doc Path
Module Map docs/MODULE-MAP.md
Architecture Quick docs/ARCHITECTURE-QUICK.md
System Architecture docs/architecture/SYSTEM-ARCHITECTURE.md
Module System docs/architecture/MODULE-SYSTEM.md
Feature Flags docs/architecture/FEATURE-FLAGS.md
Storage Layer docs/architecture/STORAGE-LAYER.md
Security & Roles docs/architecture/SECURITY-AND-ROLES.md
Module Dev Guide docs/guides/MODULE-DEVELOPMENT.md
Docker Deployment docs/guides/DOCKER-DEPLOYMENT.md
Coding Standards docs/guides/CODING-STANDARDS.md
Data Model docs/DATA-MODEL.md

For module-specific deep dives, see docs/modules/.