Commit graph

19 commits

Author SHA1 Message Date
Thomas Reitz
c8b25321e7 feat(core+frontend): Profilzugriff-Gruppen für Admin mit delegierten Berechtigungen
- Neue Prisma-Modelle ProfileAccessGroup + ProfileAccessGroupMember mit canView/canExport/canEdit
- Manuelle Migration 20260314_profile_access_groups
- ProfileAccessModule: CRUD-Endpoints für Gruppen und Mitglieder (nur PLATFORM_ADMIN)
- Neue Admin-Endpoints in ExpertProfileService/-Controller für alle Profil-Mutationen
- verifyOwnership mit skipCheck-Parameter für Admin-Bypass
- ExpertProfileTab + alle Section-Komponenten erhalten apiBase-Prop für Wiederverwendung
- AdminProfileAccessPage: Gruppen-Tab (CRUD) + Profile-Tab (alle User mit Aktionen)
- AdminProfileDetailPage: Profil eines beliebigen Users im Admin-Kontext bearbeiten
- Route /admin/profile-access + /admin/profiles/:userId + Nav-Tab Profilzugriff

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 10:47:36 +01:00
Thomas Reitz
46ced98bf4 feat(core+frontend): Firmendaten im Admin + PDF-Fusszeile
Backend:
- GET/POST /settings/company (Redis-Key platform_company_settings)
  Felder: name, street, postalCode, city, phone, email, website
- ProfileExportService: RedisService injiziert, laedt Firmendaten vor PDF-Erzeugung
- PDF-Footer: Trennlinie + kompakte Zeile mit allen Firmendaten auf jeder Seite
  (bufferPages=true, switchToPage-Loop vor doc.end())

Frontend:
- AdminCompanyPage: Formular mit Vorschau der Fusszeile
- AdminLayout: neuer Tab 'Firmendaten'
- App.tsx: Route /admin/company

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 09:07:42 +01:00
Thomas Reitz
c333cbfa4b feat: Login-Screen-Branding im Global Admin (Hintergrund + Logo)
Im Bereich Anpassungen (AdminCustomizePage) kann der Platform-Admin
nun den Login-Screen individuell gestalten:
- Hintergrundtyp: Farbverlauf, Einfarbig oder Hintergrundbild
- Farbverlauf: zwei Farbpicker (Von/Bis) mit Hex-Eingabe
- Hintergrundbild: Datei-Upload max. 2MB, Live-Vorschau
- Logo auf Login-Screen: wird automatisch aus dem Sidebar-Logo uebernommen

Backend: settings.controller.ts GET/POST /settings/branding um
loginBgType, loginBgColor1, loginBgColor2, loginBgImage erweitert.
LoginPage laedt Branding per oeffentlichem Endpoint (kein Auth), leitet
containerStyle per useMemo ab und zeigt Logo-Bild statt Hardcode-Text.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 21:09:32 +01:00
Thomas Reitz
3d75a7f9de feat(frontend+core): Dashboard Kontakte-Tab (O365) + Admin Logo-/Sidebar-Breite
Dashboard Kontakte-Tab:
- DashboardContactsTab.tsx + CSS: O365-Kontakte als Visitenkarten oder Liste
- Kachelansicht (auto-fill Grid) + Listenansicht (6-spaltig) umschaltbar
- Suchfeld (Name, E-Mail, Firma) mit Live-Filter
- Klick öffnet Detail-Modal mit allen Kontaktdaten (E-Mail/Telefon als Links)
- CRM-Import-Button: mappt M365Contact → CreateContactPayload, importiert direkt
- Nicht verbunden / Laden / Fehler States
- DashboardPage: ComingSoonTab entfernt, DashboardContactsTab eingebunden

Admin Branding — Logo-Breite + Sidebar-Breite:
- settings.controller.ts: logoWidth + sidebarWidth in GET/POST Branding
- AdminCustomizePage: Slider Logo-Breite (40–240px) + Sidebar-Breite (200–360px)
  mit Live-Vorschau (skalierte Mini-Sidebar)
- AppLayout: Logo-maxWidth aus branding.logoWidth; Sidebar width + main marginLeft
  dynamisch aus branding.sidebarWidth

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 14:03:45 +01:00
Thomas Reitz
405ab5f038 feat: add SSL/Domain admin page for custom HTTPS configuration
- Backend: 4 new endpoints in SettingsController (GET/POST/DELETE /settings/ssl, POST /settings/ssl/check-dns)
- Certificate validation via Node.js crypto.X509Certificate (PEM format, expiry, SAN match)
- DNS resolution check via dns.promises.resolve4
- Auto-generates Traefik dynamic config (ssl-domain.yml) with custom domain routing + HTTP->HTTPS redirect
- Frontend: AdminSslPage with DNS name input, cert/key upload, status display
- Docker: Core-service gets access to traefik-certs volume and dynamic config directory

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:13:49 +01:00
Thomas Reitz
a85634a906 feat: add trade event (Messe-Timer) feature with admin CRUD and dashboard tiles
Backend: TradeEvent Prisma model, NestJS CRUD module with date validation
and tenant isolation. Frontend: Admin Events page with create/edit/delete
modals, dashboard countdown tiles showing upcoming/ongoing/ended events
with progress bars, and useEventCountdown hook for live timer updates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:33:19 +01:00
Thomas Reitz
8f738cadb5 chore: hide Mandanten tab from admin navigation
Temporarily removed until multi-tenancy is implemented.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 12:20:54 +01:00
Thomas Reitz
3bedda2b9d feat: dark mode, collapsible sidebar, branding customization
- Add Light/Dark/System theme toggle with ThemeContext and CSS variables
- Sidebar fully collapsible (icons-only mode, persisted in localStorage)
- Anwendungen section collapsible with chevron toggle
- Admin "Anpassungen" page: logo upload, sidebar color picker with presets
- Backend branding endpoints (GET/POST /settings/branding) stored in Redis
- Optional custom icon upload for external links (click icon field)
- Backend favicon proxy with HTML parsing for reliable icon loading
- Dark mode CSS variables for all components
- Login page SSO button and error styles use CSS variables

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:47:51 +01:00
Thomas Reitz
0f9b3d4f36 feat: backend favicon proxy with HTML parsing, collapsible sidebar sections
- Add GET /settings/favicon?url= endpoint that parses HTML for <link rel="icon"> tags
- Falls back to /favicon.ico if no icon link found in HTML
- Caches favicon URLs in Redis (24h TTL)
- Frontend uses backend proxy for reliable favicon loading (fixes Atlassian etc.)
- Anwendungen section in sidebar is now collapsible with chevron toggle

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:29:19 +01:00
Thomas Reitz
0a52606012 fix: use direct favicon.ico, open links in app mode (popup window)
- Favicon loaded directly from website's /favicon.ico instead of
  Google's service (which was unreliable/blocked on internal networks)
- Letter-initial fallback when favicon can't be loaded
- External links open in popup window (app mode) instead of new tab

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:23:11 +01:00
Thomas Reitz
65c5c7b7dd feat: use website favicons instead of manual icon upload
External links now automatically show the favicon of the target website
using Google's favicon service. No manual icon upload needed — just
enter label and URL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:19:34 +01:00
Thomas Reitz
878f8be45c fix: replace crypto.randomUUID with HTTP-compatible alternative
crypto.randomUUID() is only available in secure contexts (HTTPS).
Since the app runs over HTTP in development, this caused a blank page
crash on the external links admin page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:08:21 +01:00
Thomas Reitz
1a87356048 feat: restructure admin area with separate layout, external links management
- Admin section moved to dedicated area with horizontal tab navigation
- Sidebar now shows gear icon link to Administration (PLATFORM_ADMIN only)
- External links management page for configuring sidebar shortcuts
- External links displayed in sidebar for all authenticated users
- Backend: Redis-based CRUD endpoints for external link configuration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:04:43 +01:00
Thomas Reitz
bc156e1657 feat: dynamic SSO configuration via Admin UI
SSO config (Tenant ID, Client ID, Client Secret, Redirect URI) can now
be managed entirely from the Admin SSO page. Config is stored in Redis
(persistent) and the MSAL client is reinitialized on save — no server
restart or console access required.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 22:51:01 +01:00
Thomas Reitz
eba738fdc5 feat: add SSO configuration page in admin section
New admin page at /admin/sso with:
- Live SSO status indicator (active/not configured)
- Step-by-step Azure App Registration guide
- Required values table (Tenant ID, Client ID, Client Secret)
- API permissions list (openid, profile, email, User.Read)
- Redirect URI with copy button
- Environment variables template
- Technical reference (endpoints, security info)

Accessible via sidebar: Administration → SSO-Konfiguration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 22:39:55 +01:00
Thomas Reitz
8efaa49930 feat: add user deletion (backend endpoint + frontend with confirmation)
- Backend: DELETE /api/v1/users/:id endpoint (PLATFORM_ADMIN only)
- Frontend: "Löschen" button with confirmation modal
- Cascading deletes handle auth providers, memberships, profiles

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 22:00:06 +01:00
Thomas Reitz
85574a85aa feat: add user management UI (create, edit, activate/deactivate)
- New UserFormModal component for creating and editing users
- AdminUsersPage: add "Neuer Benutzer" button, actions column
- German role labels, toggle activate/deactivate from table
- Uses React Query mutations with query invalidation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 21:32:11 +01:00
Thomas Reitz
10f291cdda feat: implement Sprint 1 Alpha - full stack with Docker, NestJS, React
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>
2026-03-08 15:33:36 +01:00
Thomas Reitz
5f54bde55e chore: project initialization with infrastructure definition and structure
- Generate SSH deployment key (Ed25519) for server access
- Define complete server infrastructure (ProxmoxVE VM, Docker, networking)
- Create ACCESS.md with all connection details and SSH instructions
- Create INFRASTRUCTURE.md with VM setup guide and service architecture
- Set up project directory structure per briefing specification
- Add .env.example with all required environment variables
- Add .gitignore for Node.js/Docker/TypeScript project
- Create comprehensive README.md for developer onboarding
- Add Summarize.md changelog
- Include concept and briefing documents

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 10:22:55 +01:00