classDiagram
class User {
+status
+classification
+platform_role_level
}
class UserProfile {
+employment_percent
+workdays
}
class AvailabilityEntry {
+starts_on
+ends_on
+day_fraction
+status
}
class Task {
+estimate_seconds
+start_date
+due_date
+status
}
class Project {
+name
+start/due
}
class ProjectMembership
class Skill {
+code
+category
+is_active
}
class UserSkill {
+level 1..5
+rated_by_user_id
+rated_at
}
class TeamMatchRun {
+briefing_text
+period_start
+period_end
+min_free_capacity_pct = 20
+min_required_level = 3
+status
}
class MatchRequirement {
+kind: required|wanted
+min_level
+source: ai|pm
+confirmed_by_pm
}
class MatchRoleSlot {
+role_code
+headcount
+source: ai|pm
}
class MatchCandidate {
+skill_score
+capacity_score
+total_score
+free_hours
+free_capacity_pct
+excluded_reason
+rank
}
class MatchRating {
+grade 1..5
+comment
}
User "1" –> "1" UserProfile
User "1" –> "*" AvailabilityEntry
User "1" –> "*" UserSkill
Skill "1" –> "*" UserSkill
User "1" –> "*" Task : assignee
Project "1" –> "*" Task
Project "1" –> "*" ProjectMembership
Project "0..1" –> "*" TeamMatchRun
User "1" –> "*" TeamMatchRun : erstellt von PM
TeamMatchRun "1" –> "*" MatchRequirement
TeamMatchRun "1" –> "*" MatchRoleSlot
TeamMatchRun "1" –> "*" MatchCandidate
TeamMatchRun "1" –> "0..1" MatchRating
MatchCandidate "*" –> "1" User
MatchCandidate "0..1" –> "1" MatchRoleSlot : besetzt
Skill "1" –> "*" MatchRequireme