mirror of
http://172.20.10.11:3000/gitadmin/INSIGHT-MVP.git
synced 2026-06-25 00:36:39 +02:00
Docker Infrastructure:
- docker-compose.yml with Traefik 3, PostgreSQL 16, PgBouncer, Redis 7, step-ca
- docker-compose.observability.yml with Prometheus, Grafana, Loki, Tempo, Promtail
- Traefik dynamic config (TLS, security headers, CORS, compression)
- PostgreSQL init script (uuid-ossp, pgcrypto, pg_trgm extensions)
- Grafana auto-provisioned datasources (Prometheus, Loki, Tempo)
NestJS Core-Service:
- Auth module: Login (email/password), TOTP 2FA, JWT RS256, token refresh/revocation
- Users module: CRUD, bcrypt cost 12, pagination, role-based access
- Tenants module: CRUD, member management, slug validation
- Prisma schemas: core (Users, AuthProviders, Tenants, Modules, AuditLog)
tenant (Contacts, Activities - CRM reference for Sprint 2)
- TenantPrismaService: Dynamic per-tenant DB connections with caching
- RedisService: Token blocklist, refresh token families, generic cache
- Global JwtAuthGuard with @Public() decorator, RolesGuard, GlobalExceptionFilter
- Health endpoint with DB + Redis status checks
- Swagger API documentation (dev only)
- Multi-stage Dockerfile (dev + production)
React Frontend:
- Vite 6 + React 18 + TypeScript strict
- AuthContext with silent refresh (access token in memory, NOT localStorage)
- Login page with TOTP 2FA support
- App shell with sidebar navigation
- Admin pages: Users + Tenants management tables
- API client with automatic token refresh interceptor
- Multi-stage Dockerfile (dev + nginx production)
CI/CD Pipelines:
- ci.yml: Lint, type-check, test, build on all branches
- deploy.yml: Docker build, push to Forgejo registry, SSH deploy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
111 lines
3.1 KiB
Text
111 lines
3.1 KiB
Text
// ============================================================
|
|
// INSIGHT MVP - Tenant Schema (tenant_{slug} Datenbanken)
|
|
// ============================================================
|
|
// Jeder Mandant hat eine eigene Datenbank mit diesen Tabellen.
|
|
// Schema wird per Prisma Migrate auf neue Tenant-DBs angewandt.
|
|
//
|
|
// HINWEIS: Dieses Schema wird derzeit als Referenz gefuehrt.
|
|
// Die tatsaechliche Migration auf Tenant-DBs erfolgt
|
|
// in Sprint 2+ wenn das CRM-Modul implementiert wird.
|
|
// ============================================================
|
|
|
|
generator client {
|
|
provider = "prisma-client-js"
|
|
output = "../node_modules/.prisma/tenant-client"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("TENANT_DATABASE_URL")
|
|
}
|
|
|
|
// --------------------------------------------------------
|
|
// Contact - CRM-Kontakte (Personen & Organisationen)
|
|
// --------------------------------------------------------
|
|
model Contact {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
type ContactType @default(PERSON)
|
|
|
|
// Person
|
|
firstName String? @map("first_name") @db.VarChar(100)
|
|
lastName String? @map("last_name") @db.VarChar(100)
|
|
|
|
// Organisation
|
|
companyName String? @map("company_name") @db.VarChar(200)
|
|
|
|
// Kontaktdaten
|
|
email String? @db.VarChar(255)
|
|
phone String? @db.VarChar(50)
|
|
mobile String? @db.VarChar(50)
|
|
website String? @db.VarChar(500)
|
|
|
|
// Adresse
|
|
street String? @db.VarChar(200)
|
|
zip String? @db.VarChar(20)
|
|
city String? @db.VarChar(100)
|
|
state String? @db.VarChar(100)
|
|
country String? @default("DE") @db.VarChar(2)
|
|
|
|
// Zusaetzlich
|
|
notes String? @db.Text
|
|
tags String[] @default([])
|
|
|
|
isActive Boolean @default(true) @map("is_active")
|
|
|
|
// Wer hat erstellt/bearbeitet (User-IDs aus platform_core)
|
|
createdBy String @map("created_by") @db.Uuid
|
|
updatedBy String? @map("updated_by") @db.Uuid
|
|
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relationen
|
|
activities Activity[]
|
|
|
|
@@index([email])
|
|
@@index([companyName])
|
|
@@index([lastName, firstName])
|
|
@@map("contacts")
|
|
}
|
|
|
|
enum ContactType {
|
|
PERSON
|
|
ORGANIZATION
|
|
}
|
|
|
|
// --------------------------------------------------------
|
|
// Activity - CRM-Aktivitaeten (Notizen, Anrufe, E-Mails)
|
|
// --------------------------------------------------------
|
|
model Activity {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
contactId String @map("contact_id") @db.Uuid
|
|
type ActivityType
|
|
subject String @db.VarChar(500)
|
|
description String? @db.Text
|
|
|
|
// Terminierung
|
|
scheduledAt DateTime? @map("scheduled_at")
|
|
completedAt DateTime? @map("completed_at")
|
|
|
|
// Wer hat erstellt (User-ID aus platform_core)
|
|
createdBy String @map("created_by") @db.Uuid
|
|
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
// Relationen
|
|
contact Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([contactId])
|
|
@@index([type])
|
|
@@index([scheduledAt])
|
|
@@map("activities")
|
|
}
|
|
|
|
enum ActivityType {
|
|
NOTE
|
|
CALL
|
|
EMAIL
|
|
MEETING
|
|
TASK
|
|
}
|