package services import ( "context" "fmt" "github.com/google/uuid" "github.com/jmoiron/sqlx" "mgit.msbls.de/m/KanzlAI-mGMT/internal/models" ) type CaseAssignmentService struct { db *sqlx.DB } func NewCaseAssignmentService(db *sqlx.DB) *CaseAssignmentService { return &CaseAssignmentService{db: db} } // ListByCase returns all assignments for a case. func (s *CaseAssignmentService) ListByCase(ctx context.Context, tenantID, caseID uuid.UUID) ([]models.CaseAssignment, error) { var assignments []models.CaseAssignment err := s.db.SelectContext(ctx, &assignments, `SELECT ca.id, ca.case_id, ca.user_id, ca.role, ca.assigned_at FROM case_assignments ca JOIN cases c ON c.id = ca.case_id WHERE ca.case_id = $1 AND c.tenant_id = $2 ORDER BY ca.assigned_at`, caseID, tenantID) if err != nil { return nil, fmt.Errorf("list case assignments: %w", err) } return assignments, nil } // Assign adds a user to a case with the given role. func (s *CaseAssignmentService) Assign(ctx context.Context, tenantID, caseID, userID uuid.UUID, role string) (*models.CaseAssignment, error) { // Verify user is a member of this tenant var memberExists bool err := s.db.GetContext(ctx, &memberExists, `SELECT EXISTS(SELECT 1 FROM user_tenants WHERE user_id = $1 AND tenant_id = $2)`, userID, tenantID) if err != nil { return nil, fmt.Errorf("check membership: %w", err) } if !memberExists { return nil, fmt.Errorf("user is not a member of this tenant") } // Verify case belongs to tenant var caseExists bool err = s.db.GetContext(ctx, &caseExists, `SELECT EXISTS(SELECT 1 FROM cases WHERE id = $1 AND tenant_id = $2)`, caseID, tenantID) if err != nil { return nil, fmt.Errorf("check case: %w", err) } if !caseExists { return nil, fmt.Errorf("case not found") } var assignment models.CaseAssignment err = s.db.QueryRowxContext(ctx, `INSERT INTO case_assignments (case_id, user_id, role) VALUES ($1, $2, $3) ON CONFLICT (case_id, user_id) DO UPDATE SET role = EXCLUDED.role RETURNING id, case_id, user_id, role, assigned_at`, caseID, userID, role, ).StructScan(&assignment) if err != nil { return nil, fmt.Errorf("assign user to case: %w", err) } return &assignment, nil } // Unassign removes a user from a case. func (s *CaseAssignmentService) Unassign(ctx context.Context, tenantID, caseID, userID uuid.UUID) error { result, err := s.db.ExecContext(ctx, `DELETE FROM case_assignments ca USING cases c WHERE ca.case_id = c.id AND ca.case_id = $1 AND ca.user_id = $2 AND c.tenant_id = $3`, caseID, userID, tenantID) if err != nil { return fmt.Errorf("unassign: %w", err) } rows, _ := result.RowsAffected() if rows == 0 { return fmt.Errorf("assignment not found") } return nil }