Datamodel & ER-diagram
Kerne-entiteterne i Ressourcify, deres relationer og hvad de hver især repræsenterer.
Datamodellen er bygget op om én rod (Organization) som alt scopes til.
Resten falder i fire grupper: mennesker, arbejde, fravær og
forecast.
Forenklet ER-diagram
Entiteter
Mennesker
| Model | Funktion | Nøgle-felter |
|---|---|---|
Organization | Tenant-rod | id, name |
Department | Organisatorisk enhed (1-til-mange med User) | organizationId, name |
Team | Tværgående gruppering (mange-til-mange via UserTeam) | organizationId, name |
User | Medarbejder | email, employmentPct, defaultWeeklyHours, azureAdOid |
UserRole | Rolle med scope | role, scopeType (ORG/DEPT), scopeId |
UserTeam | Join-tabel | isCoordinator |
Arbejde
| Model | Funktion |
|---|---|
Project | Det arbejde der allokeres til |
Assignment | En allokering: bruger × projekt × periode × procent |
BulkAllocationBatch | Sporing af masseallokerings-wizard'en |
TimeEntry | Faktisk registreret tid (deprecated — se memory) |
Fravær
| Model | Funktion |
|---|---|
Leave | En fraværsperiode (ferie, sygdom, kursus, andet) |
LeaveType | Konfigurérbare fraværs-typer per organisation |
PublicHoliday | Helligdage — trækkes fra arbejdsdage automatisk |
WorkingPattern | Brugerens normalt-skema (timer per ugedag) |
Forecast & kapacitet
| Model | Funktion |
|---|---|
ForecastPlan | Aggregeret plan: projekt × år |
ForecastPlanAllocation | Forventet allokering per bruger × måned |
ForecastSize | T-shirt-størrelser (S/M/L) til hurtig forecast-indtastning |
MonthlyCapacity | Cachet beregning: brugerens nettotimer per måned |
MonthlyUtilization | Cachet beregning: udnyttelse per måned |
MonthlyForecast | Cachet aggregering af forecast per måned |
Tenant-isolation
Alle queries filtrerer på organizationId. Modeller uden eksplicit
organizationId (fx UserRole, UserTeam, Assignment) får isolation via
deres parent.
Defense-in-depth: Row-Level Security er aktiveret på alle public-tabeller
(migration enable_rls). Læs mere i Row-Level Security som
defense-in-depth.
Soft-delete vs hard-delete
| Tabel | Strategi | Hvorfor |
|---|---|---|
User | Soft (deletedAt) | Bevarer audit-trail og historiske allokeringer |
Project | Soft | Samme — historik må ikke forsvinde |
Assignment, Leave | Hard | Korte levetider; historik bevares via audit |
Department, Team | Hard, kun når tom | Strukturændringer skal være eksplicitte |
Reads på soft-delete-modeller skal altid filtrere deletedAt: null (se
CLAUDE.md → Sikkerhedsmatrix).
Hvor er sandheden
Den autoritative kilde er prisma/schema.prisma. Dette diagram er et
forenklet udsnit — relationer som Notification, JiraIssue,
AuditLog, OrganizationModule m.fl. er udeladt for læsbarheden.