Files
teOS/.claude/agent-memory/senior-code-reviewer/MEMORY.md
Flexomatic81 fe305f6fc8 feat: complete tOS project with HR, LEAN, Dashboard and Integrations modules
Full enterprise web operating system including:
- Next.js 14 frontend with App Router, i18n (DE/EN), shadcn/ui
- NestJS 10 backend with Prisma, JWT auth, Swagger docs
- Keycloak 24 SSO with role-based access control
- HR module (employees, time tracking, absences, org chart)
- LEAN module (3S planning, morning meeting SQCDM, skill matrix)
- Integrations module (PlentyONE, Zulip, Todoist, FreeScout, Nextcloud, ecoDMS, GembaDocs)
- Dashboard with customizable drag & drop widget grid
- Docker Compose infrastructure (PostgreSQL 16, Redis 7, Keycloak 24)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 19:37:55 +01:00

6.0 KiB

tOS Project Code Review Memory

Project Overview

  • Type: Enterprise Web Operating System with HR, LEAN modules
  • Stack: Next.js 14 + NestJS 10 + Prisma + PostgreSQL + Keycloak
  • Structure: pnpm monorepo with turbo (apps/web, apps/api, packages/shared)

Code Standards (from PLAN.md)

Area Language Convention
Code & Comments English Required
UI Text German (via i18n) next-intl
Variables camelCase employeeId
Components PascalCase DashboardWidget
Files kebab-case user-service.ts
Constants UPPER_SNAKE_CASE MAX_VACATION_DAYS

Critical Patterns Found

Authentication

  • Global JwtAuthGuard with @Public() opt-out decorator
  • Global RolesGuard with @Roles() decorator
  • Keycloak integration via NextAuth (frontend) and passport-jwt (backend)
  • IMPORTANT: Always verify JWT signatures, never just decode
  • Guards registered in correct order: JWT -> Roles -> Permissions (app.module.ts L74-88)
  • JWT strategy validates user exists and is active on every request

Frontend Architecture

  • Server/Client split: Server page.tsx -> Client *-content.tsx
  • State: Zustand (sidebar, dashboard), TanStack Query (server state)
  • i18n: next-intl with de.json/en.json, default locale = "de"
  • Dashboard: dnd-kit widget grid, widget registry pattern
  • Styling: Tailwind + shadcn/ui, HSL CSS vars, dark mode via class

Integration Architecture (Phase 3 - Disabled)

  • Location: apps/api/integrations.backup/
  • Only PlentyONE/Zulip/Todoist extend BaseConnector
  • FreeScout/Nextcloud/ecoDMS/GembaDocs have independent implementations

Keycloak Client ID Mismatch (CRITICAL - RECURRING)

  • Realm: tos-frontend / tos-backend
  • apps/api/.env: tos-api | apps/web/.env: tos-nextauth (MISMATCH)

Key Issues to Watch

  1. params API: Mixed sync/async patterns across pages
  2. Hardcoded German: dashboard-content.tsx, widget-grid.tsx bypass i18n
  3. Mock Data: HR hooks (employees, time-tracking, absences) use mock data
  4. Type Conflicts: types/index.ts vs types/hr.ts have conflicting exports
  5. Auth Layout: (auth)/layout.tsx is 'use client' -- blocks SSR
  6. Error pages: Link to /dashboard without locale prefix
  7. ENCRYPTION_KEY: optional() in validation -- must be required

Backend-Specific Issues (from Phase 7 Review)

  1. Morning Meeting Permissions: ALL endpoints use DASHBOARD_VIEW -- any user can CRUD meetings
  2. Private method access: time-tracking.controller.ts L237-239 uses bracket notation this.service['privateMethod']
  3. Prisma cleanDatabase(): Uses Promise.all ignoring FK constraints (prisma.service.ts L48-61)
  4. Roles guard leaks info: Error messages reveal required role names (roles.guard.ts L31-33)
  5. enableImplicitConversion: In ValidationPipe (main.ts L44) -- can cause type coercion bugs
  6. Break tracking via string parsing: time-tracking uses note field for break detection (L216-219, L257-258)
  7. Audit interceptor: oldData always undefined (audit.interceptor.ts L60), salary not sanitized (L131)
  8. Unregistered interceptors: LoggingInterceptor and TimeoutInterceptor defined but never registered
  9. N+1 queries: skill-entries.service.ts analyzeGaps (L515-523), s3-planning findAll (L173-178)
  10. bulkUpsert not transactional: skill-entries.service.ts L429-476 -- partial failures possible
  11. No backdating limit: Manual time entries have no restriction on how far back entries can be created
  12. Holiday calculation missing: absences calculateWorkingDays does not account for public holidays
  13. Vacation carry-over TODO: BUrlG compliance gap (absences.service.ts L979)

File Locations

Purpose Path
Prisma Schema apps/api/prisma/schema.prisma
Frontend Types apps/web/src/types/
HR Hooks apps/web/src/hooks/hr/
LEAN Hooks apps/web/src/hooks/lean/
Dashboard apps/web/src/components/dashboard/
i18n Messages apps/web/messages/
Integration Backup apps/api/integrations.backup/
Auth Guards apps/api/src/auth/guards/
Auth Permissions apps/api/src/auth/permissions/
Encryption Service apps/api/src/common/services/encryption.service.ts
HR Employees apps/api/src/modules/hr/employees/
HR Time Tracking apps/api/src/modules/hr/time-tracking/
HR Absences apps/api/src/modules/hr/absences/
LEAN Skill Matrix apps/api/src/modules/lean/skill-matrix/
LEAN Morning Meeting apps/api/src/modules/lean/morning-meeting/
LEAN S3 Planning apps/api/src/modules/lean/s3-planning/
Audit Module apps/api/src/modules/audit/
Config Validation apps/api/src/config/config.validation.ts

Review History

Phase 7 Full Backend Review (2026-02-06)

  • Overall: 7.8/10 | 3 Critical, 14 Important issues
  • Scores: Auth 8 | Prisma 7 | HR/Emp 8 | HR/Time 7 | HR/Abs 8
  • LEAN/Skill 8 | LEAN/Morning 7 | LEAN/S3 8 | Dashboard 8
  • Common 8 | Users 8 | Audit 7 | app.module 9
  • See: phase7-backend-review.md

Phase 6 Frontend Review (2026-02-06)

  • 5 Critical, 9 Important, detailed 10-area review
  • See: phase6-frontend-review.md

Infrastructure + Integration Review (2026-02-06)

  • Docker 7/10 | Keycloak 7/10 | Env 4/10 | Integration 6/10
  • See: infra-integration-review.md

Phase 5 Review (2026-02-05)

  • HR modules: Employees, Time Tracking, Absences

Phase 3 Review (2026-02-05)

  • Integration connectors reviewed; module now disabled

Phase 1 Review (2024)

  • JWT validation, type sync, CORS, Keycloak fixes applied

Backend Architecture Notes

  • Global guards chain: JwtAuthGuard -> RolesGuard -> PermissionsGuard
  • Response envelope via TransformInterceptor: {success, data, timestamp}
  • Global HttpExceptionFilter catches all exceptions, no internal leaks
  • AES-256-GCM encryption for salary + bank accounts (fixed salt issue noted)
  • Audit via decorator @AuditLog() + global AuditInterceptor
  • Permissions enum uses entity:action format (e.g., employees:read)
  • DEFAULT_ROLE_PERMISSIONS maps roles to permission arrays