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>
198 lines
9.4 KiB
Markdown
198 lines
9.4 KiB
Markdown
# ArchiTools — Project Context for AI Assistants
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
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 `unknown` → `React.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/`.
|