# 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/`.
