0958238b25
- CLAUDE.md: add compact registry numbers feature, sender name, test mode - ROADMAP.md: expand 8.03 with compact numbers, icon-only toolbar, test mode - REPO-STRUCTURE.md: add src/core/notifications/ directory + description - SYSTEM-ARCHITECTURE.md: add sender name, test mode, group company behavior - CONFIGURATION.md + DOCKER-DEPLOYMENT.md: NOTIFICATION_FROM_NAME=Alerte Termene Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
706 lines
33 KiB
Markdown
706 lines
33 KiB
Markdown
# ArchiTools — System Architecture
|
||
|
||
## 1. Platform Overview
|
||
|
||
ArchiTools is a modular internal web dashboard platform built for a group of architecture, urban design, and engineering companies based in Cluj-Napoca, Romania:
|
||
|
||
- **Beletage SRL** — architecture office
|
||
- **Urban Switch SRL** — architecture and urban projects
|
||
- **Studii de Teren SRL** — engineering, surveying, GIS, technical studies
|
||
|
||
The platform centralizes daily operational tools: document registries, generators, templates, inventories, AI-assisted workflows, and technical utilities. It replaces scattered standalone HTML tools and manual processes with a unified, themeable, module-driven dashboard.
|
||
|
||
**Key constraints:**
|
||
|
||
- Internal-first deployment (external/guest access planned for later phases)
|
||
- Romanian UI labels; English code and comments
|
||
- On-premise Docker deployment behind reverse proxy
|
||
- localStorage as initial persistence layer, abstracted for future database/object store migration
|
||
- Must function as a **module platform**, not a monolithic application
|
||
|
||
---
|
||
|
||
## 2. High-Level Architecture
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ NGINX PROXY MANAGER │
|
||
│ (TLS termination, routing) │
|
||
└──────────────────────────────┬──────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ DOCKER CONTAINER (Next.js) │
|
||
│ │
|
||
│ ┌───────────────────────────────────────────────────────────────┐ │
|
||
│ │ PRESENTATION LAYER │ │
|
||
│ │ App Shell │ Sidebar │ Theme │ i18n │ Module Routes │ │
|
||
│ └──────────────────────────┬────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌──────────────────────────┴────────────────────────────────────┐ │
|
||
│ │ MODULE LAYER │ │
|
||
│ │ │ │
|
||
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
|
||
│ │ │Registra- │ │ Email │ │ Word XML │ │ Prompt │ ... │ │
|
||
│ │ │ tura │ │Signature │ │Generator │ │Generator │ │ │
|
||
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │
|
||
│ │ │ │ │ │ │ │
|
||
│ └───────┼─────────────┼────────────┼─────────────┼──────────────┘ │
|
||
│ │ │ │ │ │
|
||
│ ┌───────┴─────────────┴────────────┴─────────────┴──────────────┐ │
|
||
│ │ CORE SERVICES LAYER │ │
|
||
│ │ │ │
|
||
│ │ Module Registry │ Feature Flags │ Storage Abstraction │ │
|
||
│ │ Tagging System │ i18n Engine │ Theme Provider │ │
|
||
│ │ Auth Stub │ Navigation │ Config │ │
|
||
│ └──────────────────────────┬────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌──────────────────────────┴────────────────────────────────────┐ │
|
||
│ │ STORAGE LAYER │ │
|
||
│ │ │ │
|
||
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
|
||
│ │ │ localStorage │ │ MinIO │ │ Database │ │ │
|
||
│ │ │ (current) │ │ (planned) │ │ (planned) │ │ │
|
||
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
|
||
│ └───────────────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
│
|
||
┌──────────────────┼──────────────────┐
|
||
▼ ▼ ▼
|
||
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
|
||
│ Authentik │ │ MinIO │ │ N8N │
|
||
│ (SSO) │ │ (obj store) │ │ (automation) │
|
||
└─────────────┘ └──────────────┘ └──────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Core Architecture Principles
|
||
|
||
### 3.1 Module Platform, Not Monolith
|
||
|
||
The application is a **platform that hosts modules**. The shell (layout, sidebar, theme, navigation) exists to load and present modules. No module is assumed to exist at build time — the system must function with zero modules enabled.
|
||
|
||
### 3.2 Module Isolation
|
||
|
||
Each module owns its:
|
||
- Route subtree (`/app/(modules)/[module-name]/`)
|
||
- Business logic (`/modules/[module-name]/`)
|
||
- Types, services, hooks, and components
|
||
- Storage namespace (scoped key prefix)
|
||
- Configuration entry in the module registry
|
||
|
||
Modules must never import from another module's internal directories. Cross-module communication happens exclusively through core services (tagging system, storage abstraction, shared hooks).
|
||
|
||
### 3.3 Removability
|
||
|
||
Disabling a module via feature flag must not produce build errors, runtime errors, or broken navigation. This is enforced by:
|
||
- Config-driven navigation (only enabled modules appear)
|
||
- Dynamic imports for module routes
|
||
- No direct cross-module imports
|
||
- Feature flag guards at route and component boundaries
|
||
|
||
### 3.4 Storage Independence
|
||
|
||
No module or component may call `localStorage`, `sessionStorage`, or any browser storage API directly. All persistence flows through the storage abstraction layer, which resolves to the active adapter at runtime.
|
||
|
||
### 3.5 Presentation/Logic Separation
|
||
|
||
UI components receive data via props and hooks. Business logic lives in `services/` (pure functions) and `hooks/` (stateful logic). Components do not contain data transformation, validation, or persistence logic.
|
||
|
||
---
|
||
|
||
## 4. Layer Architecture
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ PRESENTATION LAYER │
|
||
│ Next.js App Router pages, layouts, UI components │
|
||
│ shadcn/ui primitives, Tailwind styling │
|
||
│ Theme provider, i18n labels │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ MODULE LAYER │
|
||
│ Module-specific components, hooks, services │
|
||
│ Module config, types, route pages │
|
||
│ Isolated per module, lazy-loadable │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ CORE SERVICES LAYER │
|
||
│ Module registry, feature flags, navigation │
|
||
│ Storage abstraction, tagging, auth stub │
|
||
│ i18n engine, theme system, config │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ STORAGE / INTEGRATION LAYER │
|
||
│ Storage adapters (localStorage, MinIO, DB, API) │
|
||
│ External service clients │
|
||
│ Environment configuration │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Layer Rules
|
||
|
||
| Layer | May Import From | Must Not Import From |
|
||
|-------|----------------|---------------------|
|
||
| Presentation | Module Layer, Core Services, Shared | — |
|
||
| Module Layer | Core Services, Shared | Other modules |
|
||
| Core Services | Shared, Config | Module Layer, Presentation |
|
||
| Storage/Integration | Config only | Everything else |
|
||
|
||
---
|
||
|
||
## 5. Runtime Architecture
|
||
|
||
### 5.1 Next.js App Router
|
||
|
||
The application uses Next.js 15 with the App Router. The routing structure:
|
||
|
||
```
|
||
app/
|
||
├── layout.tsx → Root layout: providers, shell wrapper
|
||
├── page.tsx → Dashboard home (widget grid)
|
||
├── globals.css → Tailwind base + custom tokens
|
||
└── (modules)/ → Route group (no URL segment)
|
||
├── registratura/
|
||
│ ├── page.tsx → Module entry page
|
||
│ └── [id]/
|
||
│ └── page.tsx → Detail view
|
||
├── email-signature/
|
||
│ └── page.tsx
|
||
└── ...
|
||
```
|
||
|
||
### 5.2 Client-Side Primary, SSR Where Needed
|
||
|
||
The platform is primarily a client-side interactive application. Most module pages use `"use client"` directives because they:
|
||
- Manage complex form state
|
||
- Interact with browser storage
|
||
- Require immediate user feedback
|
||
- Handle drag-and-drop, clipboard, and other browser APIs
|
||
|
||
Server-side rendering is used for:
|
||
- The shell layout (static structure, fast first paint)
|
||
- Metadata generation
|
||
- Any future API routes serving data to external consumers
|
||
|
||
### 5.3 Provider Stack
|
||
|
||
The root layout wraps the application in a provider stack:
|
||
|
||
```
|
||
<ThemeProvider>
|
||
<I18nProvider>
|
||
<StorageProvider>
|
||
<FeatureFlagProvider>
|
||
<AppShell>
|
||
{children}
|
||
</AppShell>
|
||
</FeatureFlagProvider>
|
||
</StorageProvider>
|
||
</I18nProvider>
|
||
</ThemeProvider>
|
||
```
|
||
|
||
Each provider is independent and can be replaced or extended without affecting others.
|
||
|
||
---
|
||
|
||
## 6. Module Isolation Model
|
||
|
||
### 6.1 Module Structure
|
||
|
||
Every module follows a standard directory structure:
|
||
|
||
```
|
||
src/modules/[module-name]/
|
||
├── components/ # Module-specific React components
|
||
├── hooks/ # Module-specific React hooks
|
||
├── services/ # Pure business logic functions
|
||
├── types.ts # TypeScript interfaces and types
|
||
├── config.ts # Module metadata for the registry
|
||
└── index.ts # Public API barrel export
|
||
```
|
||
|
||
### 6.2 Module Registration
|
||
|
||
Each module exports a `ModuleConfig` object:
|
||
|
||
```typescript
|
||
interface ModuleConfig {
|
||
id: string; // Unique identifier (kebab-case)
|
||
name: string; // Romanian display name
|
||
description: string; // Romanian description
|
||
icon: string; // Lucide icon name
|
||
route: string; // Base route path
|
||
category: ModuleCategory; // Grouping for navigation
|
||
enabled: boolean; // Default enabled state
|
||
featureFlag: string; // Flag key in feature flag system
|
||
requiredRole?: UserRole; // Minimum role (future use)
|
||
visibility?: Visibility; // internal | admin | public
|
||
version: string; // Semver
|
||
storageNamespace: string; // Storage key prefix
|
||
}
|
||
```
|
||
|
||
The central module registry (`src/config/modules.ts`) imports all module configs and provides them to the navigation system and feature flag guards.
|
||
|
||
### 6.3 Module Lifecycle
|
||
|
||
```
|
||
1. Module config registered in modules.ts
|
||
2. Feature flag checked at runtime
|
||
3. If enabled: route is accessible, nav item visible
|
||
4. Module page loads (dynamic import possible)
|
||
5. Module initializes its hooks/services
|
||
6. Module reads/writes through storage abstraction
|
||
7. If disabled: route returns redirect/404, nav item hidden
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Core Systems Overview
|
||
|
||
### 7.1 Module Registry
|
||
|
||
**Location:** `src/core/module-registry/`
|
||
|
||
Central catalog of all available modules. Provides:
|
||
- List of all registered modules with metadata
|
||
- Lookup by ID, route, or category
|
||
- Filtering by enabled state, visibility, role
|
||
- Module category grouping for navigation
|
||
|
||
The registry is the single source of truth for what modules exist. Navigation, routing guards, and the dashboard widget grid all read from it.
|
||
|
||
### 7.2 Feature Flags
|
||
|
||
**Location:** `src/core/feature-flags/`
|
||
|
||
Controls module activation and experimental feature visibility.
|
||
|
||
```typescript
|
||
interface FeatureFlag {
|
||
key: string;
|
||
enabled: boolean;
|
||
scope: 'module' | 'feature' | 'experiment';
|
||
requiredRole?: UserRole;
|
||
description: string;
|
||
}
|
||
```
|
||
|
||
Flag resolution order:
|
||
1. Environment variable override (`NEXT_PUBLIC_FLAG_*`)
|
||
2. Runtime config (`src/config/flags.ts`)
|
||
3. Default from module config
|
||
|
||
Flags are checked via the `useFeatureFlag(key)` hook and the `<FeatureGate flag="key">` component wrapper.
|
||
|
||
### 7.3 Storage Abstraction
|
||
|
||
**Location:** `src/core/storage/`
|
||
|
||
All data persistence flows through a `StorageService` interface:
|
||
|
||
```typescript
|
||
interface StorageService {
|
||
get<T>(namespace: string, key: string): Promise<T | null>;
|
||
set<T>(namespace: string, key: string, value: T): Promise<void>;
|
||
delete(namespace: string, key: string): Promise<void>;
|
||
list(namespace: string): Promise<string[]>;
|
||
clear(namespace: string): Promise<void>;
|
||
}
|
||
```
|
||
|
||
**Adapters:**
|
||
|
||
| Adapter | Status | Use Case |
|
||
|---------|--------|----------|
|
||
| `LocalStorageAdapter` | Current | Browser-local persistence, demo/dev mode |
|
||
| `MinIOAdapter` | Planned | File and object storage (signatures, templates) |
|
||
| `DatabaseAdapter` | Planned | Structured data (registry entries, inventory) |
|
||
| `APIAdapter` | Planned | External service delegation |
|
||
|
||
The active adapter is resolved at startup from environment configuration. Modules never know which adapter is active.
|
||
|
||
**Namespace isolation:** Each module operates within its own namespace (e.g., `registratura:entries`, `password-vault:credentials`). Modules cannot read or write to another module's namespace without explicit cross-module service mediation.
|
||
|
||
### 7.4 Tagging System
|
||
|
||
**Location:** `src/core/tagging/`
|
||
|
||
A cross-module tagging service used by multiple modules to categorize and link entities.
|
||
|
||
Tags are structured objects:
|
||
|
||
```typescript
|
||
interface Tag {
|
||
id: string;
|
||
label: string; // Romanian display label
|
||
category: TagCategory; // project | client | domain | custom
|
||
color?: string;
|
||
metadata?: Record<string, unknown>;
|
||
createdAt: string;
|
||
}
|
||
```
|
||
|
||
The tagging system provides:
|
||
- Tag CRUD operations (stored via storage abstraction)
|
||
- Tag selector component (shared UI)
|
||
- Tag filtering and search
|
||
- Tag usage tracking across modules
|
||
|
||
Modules that use tags: Registratura, Prompt Generator, Word Templates, Digital Signatures, IT Inventory, Address Book.
|
||
|
||
### 7.5 Internationalization (i18n)
|
||
|
||
**Location:** `src/core/i18n/`
|
||
|
||
Current implementation: Romanian-only with structured label access for future multi-language support.
|
||
|
||
Labels are organized by module namespace:
|
||
|
||
```typescript
|
||
const labels = {
|
||
common: {
|
||
save: 'Salvează',
|
||
cancel: 'Anulează',
|
||
delete: 'Șterge',
|
||
search: 'Caută',
|
||
// ...
|
||
},
|
||
registratura: {
|
||
title: 'Registratură',
|
||
newEntry: 'Înregistrare nouă',
|
||
// ...
|
||
},
|
||
};
|
||
```
|
||
|
||
Access pattern: `useLabel('registratura.newEntry')` or `<Label k="common.save" />`.
|
||
|
||
The system is designed so that adding a second language requires only adding translation files, not changing component code.
|
||
|
||
### 7.6 Theme System
|
||
|
||
**Location:** `src/core/theme/`
|
||
|
||
Dark/light theme support using CSS custom properties and Tailwind's `dark:` variant.
|
||
|
||
Design tokens:
|
||
- Background and surface colors
|
||
- Text hierarchy (primary, secondary, muted)
|
||
- Border and divider colors
|
||
- Accent colors per company (Beletage, Urban Switch, Studii de Teren)
|
||
- Semantic colors (success, warning, error, info)
|
||
|
||
Theme preference is persisted in storage and respects system preference as default. The theme provider exposes `useTheme()` with `theme`, `setTheme`, and `toggleTheme`.
|
||
|
||
Visual style: professional, technical, card-based dashboard. No playful or consumer-oriented aesthetics.
|
||
|
||
### 7.7 Auth Stub
|
||
|
||
**Location:** `src/core/auth/`
|
||
|
||
Current state: no authentication enforced (internal network only).
|
||
|
||
The auth module provides a stub interface that modules can code against:
|
||
|
||
```typescript
|
||
interface AuthContext {
|
||
user: User | null;
|
||
role: UserRole; // 'admin' | 'user' | 'guest'
|
||
isAuthenticated: boolean;
|
||
company: CompanyId | null;
|
||
permissions: string[];
|
||
}
|
||
```
|
||
|
||
In the current phase, `AuthContext` returns a default internal user with admin role. When Authentik SSO integration is implemented, the auth module will resolve real user identity from SSO tokens without any module code changes.
|
||
|
||
Data model fields (`visibility`, `requiredRole`, `createdBy`) are included from day one so that enabling auth does not require data migration.
|
||
|
||
---
|
||
|
||
## 8. External Integration Points
|
||
|
||
### 8.1 Current Infrastructure
|
||
|
||
ArchiTools runs alongside existing services on the internal network:
|
||
|
||
| Service | Integration Type | Purpose |
|
||
|---------|-----------------|---------|
|
||
| **Authentik** | Future SSO provider | User authentication and role assignment |
|
||
| **MinIO** | Future storage adapter | Object/file storage for documents, signatures, templates |
|
||
| **N8N** | ✅ Active (cron) | Daily digest cron (`0 8 * * 1-5`), future: backups, workflows |
|
||
| **Brevo SMTP** | ✅ Active | Email relay for notification digests (port 587, STARTTLS) |
|
||
| **Gitea** | Development | Source code hosting |
|
||
| **Stirling PDF** | Dashboard link | PDF manipulation (external tool link) |
|
||
| **IT-Tools** | Dashboard link | Technical utilities (external tool link) |
|
||
| **Filebrowser** | Dashboard link | File management (external tool link) |
|
||
| **Uptime Kuma** | Dashboard widget | Service health status |
|
||
| **Netdata** | Dashboard widget | Server performance metrics |
|
||
|
||
### 8.2 Integration Patterns
|
||
|
||
**Dashboard links:** External tools appear as navigation entries or dashboard widgets with `target="_blank"` links. No embedding or API integration needed.
|
||
|
||
**Dashboard widgets:** Services like Uptime Kuma and Netdata can expose status endpoints or embed iframes for health/monitoring widgets on the dashboard home.
|
||
|
||
**Storage integration (MinIO):** When the MinIO adapter is implemented, modules that manage files (Digital Signatures, Word Templates) will store binary assets in MinIO buckets while keeping metadata in the primary storage.
|
||
|
||
**Automation integration (N8N):** N8N triggers scheduled workflows via API endpoints. Active: daily digest cron calls `POST /api/notifications/digest` with Bearer token auth. Future: document processing, backups.
|
||
|
||
**Email notifications (Brevo SMTP):** Platform service in `src/core/notifications/`. Nodemailer transport singleton connects to Brevo SMTP relay. Sender: "Alerte Termene" <noreply@beletage.ro>. `runDigest()` loads all registry entries, groups by company, builds digest per subscriber filtering by their preference types (urgent, overdue, expiry), renders inline-styled HTML, sends via SMTP. Test mode via `?test=true` query param. "group" company users receive digest with ALL entries. Preferences stored in KeyValueStore (namespace `notifications`).
|
||
|
||
**SSO integration (Authentik):** Authentik OIDC provides user identity. NextAuth v4 JWT/session callbacks map Authentik groups to roles and companies. Notification preferences auto-refresh user email/name/company from session on each save.
|
||
|
||
---
|
||
|
||
## 9. Data Flow Patterns
|
||
|
||
### 9.1 Module Data Read
|
||
|
||
```
|
||
User action
|
||
→ Component calls hook (e.g., useRegistryEntries())
|
||
→ Hook calls service function (e.g., getEntries())
|
||
→ Service calls StorageService.get(namespace, key)
|
||
→ StorageService resolves active adapter
|
||
→ Adapter reads from storage backend
|
||
→ Data returns up the chain
|
||
→ Hook updates state
|
||
→ Component re-renders
|
||
```
|
||
|
||
### 9.2 Module Data Write
|
||
|
||
```
|
||
User submits form
|
||
→ Component calls hook mutation (e.g., createEntry(data))
|
||
→ Hook validates via service (e.g., validateEntry(data))
|
||
→ Service calls StorageService.set(namespace, key, data)
|
||
→ Adapter writes to storage backend
|
||
→ Hook updates local state / invalidates cache
|
||
→ Component re-renders with new data
|
||
```
|
||
|
||
### 9.3 Cross-Module Data (via Tagging)
|
||
|
||
```
|
||
User tags an entity in Module A
|
||
→ Module A calls TaggingService.addTag(entityId, tagId)
|
||
→ Tag association stored in tagging namespace
|
||
|
||
User filters by tag in Module B
|
||
→ Module B calls TaggingService.getEntitiesByTag(tagId)
|
||
→ Returns entity IDs across modules
|
||
→ Module B fetches its own entities matching those IDs
|
||
```
|
||
|
||
### 9.4 Feature Flag Check
|
||
|
||
```
|
||
Route or component renders
|
||
→ <FeatureGate flag="module.registratura">
|
||
→ useFeatureFlag('module.registratura')
|
||
→ Checks env override → config → default
|
||
→ Returns boolean
|
||
→ Children render or fallback shown
|
||
```
|
||
|
||
---
|
||
|
||
## 10. Deployment Architecture
|
||
|
||
### 10.1 Container Structure
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────┐
|
||
│ Ubuntu Server (on-premise) │
|
||
│ │
|
||
│ ┌─────────────────────────────────────────────┐ │
|
||
│ │ Docker (via Portainer) │ │
|
||
│ │ │ │
|
||
│ │ ┌──────────────┐ ┌──────────────────────┐ │ │
|
||
│ │ │ ArchiTools │ │ Other containers │ │ │
|
||
│ │ │ (Next.js) │ │ (Authentik, MinIO, │ │ │
|
||
│ │ │ Port: 3000 │ │ N8N, Gitea, etc.) │ │ │
|
||
│ │ └──────┬───────┘ └──────────────────────┘ │ │
|
||
│ │ │ │ │
|
||
│ └─────────┼────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌─────────┴─────────────────────────────────────┐ │
|
||
│ │ Nginx Proxy Manager │ │
|
||
│ │ tools.internal.domain → localhost:3000 │ │
|
||
│ └────────────────────────────────────────────────┘ │
|
||
└──────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 10.2 Docker Configuration
|
||
|
||
**Dockerfile:** Multi-stage build.
|
||
1. **deps stage** — installs Node.js dependencies
|
||
2. **build stage** — runs `next build`, produces standalone output
|
||
3. **runtime stage** — minimal Node.js image, copies standalone build, exposes port 3000
|
||
|
||
**docker-compose.yml:** Single service definition for ArchiTools. Environment variables passed from `.env` file. Optional volume mounts for persistent data if needed beyond localStorage.
|
||
|
||
### 10.3 Environment Variables
|
||
|
||
```
|
||
# Application
|
||
NEXT_PUBLIC_APP_URL=https://tools.internal.domain
|
||
NEXT_PUBLIC_APP_ENV=production
|
||
|
||
# Feature flags (override defaults)
|
||
NEXT_PUBLIC_FLAG_MODULE_REGISTRATURA=true
|
||
NEXT_PUBLIC_FLAG_MODULE_AI_CHAT=false
|
||
|
||
# Future: Storage backend
|
||
STORAGE_BACKEND=localStorage
|
||
MINIO_ENDPOINT=minio.internal.domain
|
||
MINIO_ACCESS_KEY=...
|
||
MINIO_SECRET_KEY=...
|
||
|
||
# Future: Auth
|
||
AUTHENTIK_ISSUER=https://auth.internal.domain
|
||
AUTHENTIK_CLIENT_ID=...
|
||
AUTHENTIK_CLIENT_SECRET=...
|
||
```
|
||
|
||
### 10.4 Build and Deploy Flow
|
||
|
||
```
|
||
Developer pushes to Gitea
|
||
→ (future: CI pipeline builds image)
|
||
→ Docker image built (manual or Watchtower auto-update)
|
||
→ Portainer deploys/restarts container
|
||
→ Nginx Proxy Manager routes traffic
|
||
→ Users access via internal domain
|
||
```
|
||
|
||
---
|
||
|
||
## 11. Scalability Considerations
|
||
|
||
### 11.1 Current Scale
|
||
|
||
- **Users:** ~5–20 internal staff across three companies
|
||
- **Data volume:** Low (hundreds to low thousands of records per module)
|
||
- **Concurrency:** Minimal (localStorage is per-browser, no shared state conflicts)
|
||
|
||
### 11.2 Growth Path
|
||
|
||
| Concern | Current | Growth Path |
|
||
|---------|---------|-------------|
|
||
| Data persistence | localStorage (per-browser) | Database + MinIO (shared, centralized) |
|
||
| Authentication | None (network trust) | Authentik SSO with RBAC |
|
||
| Multi-user data | Isolated per browser | Centralized with user ownership |
|
||
| File storage | Not supported | MinIO buckets per module |
|
||
| Search | Client-side filter | Server-side indexed search |
|
||
| API access | None | Next.js API routes for external consumers |
|
||
| Automation | Manual | N8N webhooks triggered by module events |
|
||
|
||
### 11.3 Module Scaling
|
||
|
||
New modules are added by:
|
||
1. Creating the module directory structure
|
||
2. Registering the module config
|
||
3. Adding the feature flag
|
||
4. Creating the route pages
|
||
|
||
No changes to the shell, navigation, or other modules are required. The navigation rebuilds itself from the registry.
|
||
|
||
---
|
||
|
||
## 12. Security Boundaries
|
||
|
||
### 12.1 Current Phase: Internal Network Trust
|
||
|
||
```
|
||
┌─────────────────────────────────────────────┐
|
||
│ Internal Network │
|
||
│ │
|
||
│ ┌──────────┐ ┌──────────────────────┐ │
|
||
│ │ Users │────▶│ ArchiTools │ │
|
||
│ │ (trusted) │ │ (no auth required) │ │
|
||
│ └──────────┘ └──────────────────────┘ │
|
||
│ │
|
||
│ Security: network-level only │
|
||
│ Data: browser-local, no shared secrets │
|
||
│ Risk: low (internal, trusted users) │
|
||
└─────────────────────────────────────────────┘
|
||
```
|
||
|
||
**Current security model:**
|
||
- Network perimeter security via Crowdsec and firewall rules
|
||
- No application-level authentication
|
||
- No sensitive data in localStorage (password vault uses demo-grade encryption)
|
||
- No external API endpoints exposed
|
||
- All data stays in the user's browser
|
||
|
||
### 12.2 Future Phase: SSO + Role-Based Access
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────┐
|
||
│ │
|
||
│ ┌──────────┐ ┌────────────┐ ┌──────────────────┐│
|
||
│ │ Users │───▶│ Authentik │───▶│ ArchiTools ││
|
||
│ │(internal/ │ │ (SSO) │ │ (auth enforced) ││
|
||
│ │ external) │ └────────────┘ └──────────────────┘│
|
||
│ └──────────┘ │
|
||
│ │
|
||
│ Security: SSO + RBAC + module permissions │
|
||
│ Data: centralized DB + MinIO with access control │
|
||
│ Roles: admin, user, guest │
|
||
│ Visibility: per-field, per-module, per-company │
|
||
└──────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**Planned security layers:**
|
||
- Authentik OIDC authentication (SSO)
|
||
- Role-based module access (admin, user, guest)
|
||
- Company-scoped data visibility
|
||
- Per-field visibility metadata (internal, admin, public)
|
||
- API route protection via middleware token validation
|
||
- Audit logging for sensitive operations
|
||
|
||
**Design-for-security decisions made now:**
|
||
- All data models include `visibility` and `createdBy` fields
|
||
- Module configs include `requiredRole` field
|
||
- Feature flags support role-based activation
|
||
- Auth context interface defined (stubbed with defaults)
|
||
- Storage namespace isolation prevents cross-module data leaks
|
||
|
||
---
|
||
|
||
## Appendix A: Technology Decisions
|
||
|
||
| Decision | Choice | Rationale |
|
||
|----------|--------|-----------|
|
||
| Framework | Next.js 15 (App Router) | Modern React with file-based routing, SSR capability, API routes |
|
||
| Language | TypeScript | Type safety across modules, better refactorability |
|
||
| Styling | Tailwind CSS | Utility-first, consistent with shadcn/ui, theme support |
|
||
| Component library | shadcn/ui | Copy-paste components, full control, professional aesthetic |
|
||
| Deployment | Docker | Consistent with existing infrastructure (Portainer) |
|
||
| Initial storage | localStorage | Zero infrastructure, immediate development start |
|
||
| Storage pattern | Adapter abstraction | Allows migration without module changes |
|
||
| Auth pattern | Stub with interface | Enables SSO integration without refactoring |
|
||
|
||
## Appendix B: Module Catalog
|
||
|
||
| Module | ID | Category | Status |
|
||
|--------|----|----------|--------|
|
||
| Dashboard | `dashboard` | Core | Planned |
|
||
| Registratura | `registratura` | Registry | Planned |
|
||
| Email Signature Generator | `email-signature` | Generators | Planned (legacy exists) |
|
||
| Word XML Generators | `word-xml` | Generators | Planned (legacy exists) |
|
||
| Digital Signatures & Stamps | `digital-signatures` | Assets | Planned |
|
||
| Password Vault | `password-vault` | Security | Planned |
|
||
| IT Inventory | `it-inventory` | Infrastructure | Planned |
|
||
| Address Book | `address-book` | Contacts | Planned |
|
||
| Prompt Generator | `prompt-generator` | AI Tools | Planned |
|
||
| Word Template Library | `word-templates` | Templates | Planned |
|
||
| Tag Manager | `tag-manager` | Administration | Planned |
|
||
| Mini Utilities | `mini-utilities` | Tools | Planned |
|
||
| AI Chat | `ai-chat` | AI Tools | Planned |
|