feat: add email notification system (Brevo SMTP + N8N daily digest)
- Add core notification service: types, email-service (nodemailer/Brevo SMTP), notification-service (digest builder, preference CRUD, HTML renderer) - Add API routes: POST /api/notifications/digest (N8N cron, Bearer auth), GET/PUT /api/notifications/preferences (session auth) - Add NotificationPreferences UI component (Bell button + dialog with per-type toggles) in Registratura toolbar - Add 7 Brevo SMTP env vars to docker-compose.yml - Update CLAUDE.md, ROADMAP.md, DATA-MODEL.md, SYSTEM-ARCHITECTURE.md, CONFIGURATION.md, DOCKER-DEPLOYMENT.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -443,6 +443,40 @@ interface WordTemplate extends BaseEntity {
|
||||
}
|
||||
```
|
||||
|
||||
### Email Notifications (platform service)
|
||||
|
||||
```typescript
|
||||
// src/core/notifications/types.ts
|
||||
|
||||
type NotificationType = "deadline-urgent" | "deadline-overdue" | "document-expiry";
|
||||
|
||||
interface NotificationPreference {
|
||||
userId: string;
|
||||
email: string;
|
||||
name: string;
|
||||
company: CompanyId;
|
||||
enabledTypes: NotificationType[];
|
||||
globalOptOut: boolean;
|
||||
}
|
||||
|
||||
interface DigestItem {
|
||||
entryNumber: string;
|
||||
subject: string;
|
||||
label: string;
|
||||
dueDate: string; // YYYY-MM-DD
|
||||
daysRemaining: number; // negative = overdue
|
||||
color: "red" | "yellow" | "blue";
|
||||
}
|
||||
|
||||
interface DigestSection {
|
||||
type: NotificationType;
|
||||
title: string;
|
||||
items: DigestItem[];
|
||||
}
|
||||
```
|
||||
|
||||
> **Storage:** Preferences stored in `KeyValueStore` (namespace `notifications`, key `pref:<userId>`). No separate Prisma model needed.
|
||||
|
||||
---
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
@@ -430,7 +430,8 @@ ArchiTools runs alongside existing services on the internal network:
|
||||
|---------|-----------------|---------|
|
||||
| **Authentik** | Future SSO provider | User authentication and role assignment |
|
||||
| **MinIO** | Future storage adapter | Object/file storage for documents, signatures, templates |
|
||||
| **N8N** | Future webhook/API | Workflow automation (document processing, notifications) |
|
||||
| **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) |
|
||||
@@ -446,9 +447,11 @@ ArchiTools runs alongside existing services on the internal network:
|
||||
|
||||
**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):** Modules can trigger N8N webhooks for automated workflows. Example: Registratura creates a new entry, triggering an N8N workflow that sends a notification or generates a document.
|
||||
**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.
|
||||
|
||||
**SSO integration (Authentik):** The auth stub will be replaced with an Authentik OIDC client. The middleware layer will validate tokens and populate `AuthContext`. No module code changes required.
|
||||
**Email notifications (Brevo SMTP):** Platform service in `src/core/notifications/`. Nodemailer transport singleton connects to Brevo SMTP relay. `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. 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.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -57,6 +57,18 @@ NEXT_PUBLIC_STORAGE_ADAPTER=localStorage
|
||||
# Example: NEXT_PUBLIC_FLAGS_OVERRIDE=module_ai_chat=true,module_password_vault=false
|
||||
NEXT_PUBLIC_FLAGS_OVERRIDE=
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Email Notifications (Brevo SMTP)
|
||||
# -----------------------------------------------------------------------------
|
||||
# SMTP relay for daily digest emails (deadline alerts, document expiry)
|
||||
BREVO_SMTP_HOST=smtp-relay.brevo.com
|
||||
BREVO_SMTP_PORT=587
|
||||
BREVO_SMTP_USER= # Brevo SMTP login (from Brevo dashboard)
|
||||
BREVO_SMTP_PASS= # Brevo SMTP key (from Brevo dashboard)
|
||||
NOTIFICATION_FROM_EMAIL=noreply@beletage.ro
|
||||
NOTIFICATION_FROM_NAME=ArchiTools
|
||||
NOTIFICATION_CRON_SECRET= # Random Bearer token for N8N → digest API auth
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# External Services
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
@@ -200,13 +200,26 @@ NEXT_PUBLIC_STORAGE_ADAPTER=localStorage
|
||||
# MINIO_BUCKET=architools
|
||||
|
||||
# ──────────────────────────────────────────
|
||||
# Authentication (future: Authentik SSO)
|
||||
# Authentication (Authentik SSO)
|
||||
# ──────────────────────────────────────────
|
||||
# AUTHENTIK_ISSUER=https://auth.internal
|
||||
# AUTHENTIK_CLIENT_ID=architools
|
||||
# AUTHENTIK_CLIENT_SECRET=<secret>
|
||||
|
||||
# ──────────────────────────────────────────
|
||||
# Email Notifications (Brevo SMTP)
|
||||
# ──────────────────────────────────────────
|
||||
BREVO_SMTP_HOST=smtp-relay.brevo.com
|
||||
BREVO_SMTP_PORT=587
|
||||
BREVO_SMTP_USER=<brevo-login>
|
||||
BREVO_SMTP_PASS=<brevo-smtp-key>
|
||||
NOTIFICATION_FROM_EMAIL=noreply@beletage.ro
|
||||
NOTIFICATION_FROM_NAME=ArchiTools
|
||||
NOTIFICATION_CRON_SECRET=<random-bearer-token>
|
||||
```
|
||||
|
||||
> **N8N cron setup:** Create a workflow with Cron node (`0 8 * * 1-5`), HTTP Request node (POST `https://tools.beletage.ro/api/notifications/digest`, header `Authorization: Bearer <NOTIFICATION_CRON_SECRET>`). The endpoint returns `{ success, totalEmails, errors, companySummary }`.
|
||||
|
||||
### Variable Scoping Rules
|
||||
|
||||
| Prefix | Available In | Notes |
|
||||
|
||||
Reference in New Issue
Block a user