0c4b91707f
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>
9.4 KiB
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
StorageServiceinterface + adapters - Auth via Authentik SSO — group → role/company mapping
- All entities include
visibility/createdByfrom 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]isT | undefinedeven after length check — assign to const firstRecord<string, T>[key]returnsT | undefined— always null-check- Spread of possibly-undefined:
{ ...obj[key] }— check existence first - lucide-react Icons: cast through
unknown→React.ComponentType<{ className?: string }> - Prisma
$queryRawreturnsunknown[]— cast withas Array<{ field: type }> ?? ""on{}field produces{}notstring— usetypeofcheck
Conventions
- Code: English | UI text: Romanian | IDs: uuid v4
- Dates: ISO strings (
YYYY-MM-DDdisplay, 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()orstorage.export(namespace)for batch-load - NEVER store base64 files in entity JSON — use
lightweight: truefor 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()fromauth-check.tsinstead - 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 incounty-refresh.ts) is authoritativeGisUat.geometryis huge — alwaysselectto exclude in list queries- Feature counts cached 5-min TTL
- ePay: form-urlencoded body, OpenAM auth, MinIO metadata must be ASCII
Before Pushing
npx next build— zero errors- Test on
localhost:3000 - Commit with descriptive message
git push origin main→ manual Portainer redeploy
Common Pitfalls (Top 10)
- Middleware body buffering — upload routes >10MB must be excluded from matcher
- N+1 storage queries — use
exportAll(), neverlist()+get()loop - GisUat geometry in queries — exclude with
select, or 50ms → 5+ seconds - Enrichment data loss on re-sync — upsert must preserve enrichment field
- Ghostscript corrupts fonts — use qpdf for PDF compression, never GS
- eTerra timeout too low — geometry pages need 60-90s; default 120s
- Traefik 60s readTimeout — must set 600s in static config for uploads
- Portainer CE can't inject env vars — all env in docker-compose.yml
@prisma/clientin dependencies (not devDeps) — runtime requirementoutput: '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/.