diff --git a/apps/server/db/query/problem.sql b/apps/server/db/query/problem.sql index 3c989ee..3fae95a 100644 --- a/apps/server/db/query/problem.sql +++ b/apps/server/db/query/problem.sql @@ -135,3 +135,15 @@ LIMIT $1 OFFSET $2; -- name: CountAllProblems :one SELECT COUNT(*) FROM problems WHERE archived_at IS NULL; +-- name: CheckProblemInActiveAssignments :one +SELECT COUNT(*) +FROM assignment_problems ap +JOIN assignments a ON ap.assignment_id = a.id +WHERE ap.problem_id = $1 + AND a.status = 'active' + AND a.archived_at IS NULL; + +-- name: CheckProblemInAssignmentGroups :one +SELECT COUNT(*) +FROM assignment_group_problems +WHERE problem_id = $1; diff --git a/apps/server/go.mod b/apps/server/go.mod index f8d76d9..0c09ae6 100644 --- a/apps/server/go.mod +++ b/apps/server/go.mod @@ -1,6 +1,6 @@ module github.com/coderz-space/coderz.space -go 1.24.3 +go 1.25.0 require ( github.com/go-playground/validator/v10 v10.30.1 diff --git a/apps/server/internal/db/sqlc/assignment.sql.go b/apps/server/internal/db/sqlc/assignment.sql.go index d9a5667..805558b 100644 --- a/apps/server/internal/db/sqlc/assignment.sql.go +++ b/apps/server/internal/db/sqlc/assignment.sql.go @@ -279,7 +279,7 @@ func (q *Queries) GetAssignmentGroup(ctx context.Context, id pgtype.UUID) (Assig } const getAssignmentProblem = `-- name: GetAssignmentProblem :one -SELECT ap.id, ap.assignment_id, ap.problem_id, ap.status, ap.solution_link, ap.notes, ap.completed_at, ap.created_at, ap.updated_at, p.title, p.difficulty +SELECT ap.id, ap.assignment_id, ap.problem_id, ap.status, ap.solution_link, ap.notes, ap.completed_at, ap.created_at, ap.updated_at, p.title, p.difficulty FROM assignment_problems ap JOIN problems p ON ap.problem_id = p.id WHERE ap.assignment_id = $1 AND ap.problem_id = $2 @@ -564,7 +564,7 @@ func (q *Queries) ListAssignmentGroupsByBootcamp(ctx context.Context, arg ListAs } const listAssignmentProblemsStatus = `-- name: ListAssignmentProblemsStatus :many -SELECT ap.id, ap.assignment_id, ap.problem_id, ap.status, ap.solution_link, ap.notes, ap.completed_at, ap.created_at, ap.updated_at, p.title, p.difficulty +SELECT ap.id, ap.assignment_id, ap.problem_id, ap.status, ap.solution_link, ap.notes, ap.completed_at, ap.created_at, ap.updated_at, p.title, p.difficulty FROM assignment_problems ap JOIN problems p ON ap.problem_id = p.id WHERE ap.assignment_id = $1 diff --git a/apps/server/internal/db/sqlc/problem.sql.go b/apps/server/internal/db/sqlc/problem.sql.go index ab85fa8..c926bac 100644 --- a/apps/server/internal/db/sqlc/problem.sql.go +++ b/apps/server/internal/db/sqlc/problem.sql.go @@ -643,3 +643,32 @@ func (q *Queries) UpdateTag(ctx context.Context, arg UpdateTagParams) (Tag, erro ) return i, err } + +const checkProblemInActiveAssignments = `-- name: CheckProblemInActiveAssignments :one +SELECT COUNT(*) +FROM assignment_problems ap +JOIN assignments a ON ap.assignment_id = a.id +WHERE ap.problem_id = $1 + AND a.status = 'active' + AND a.archived_at IS NULL +` + +func (q *Queries) CheckProblemInActiveAssignments(ctx context.Context, problemID pgtype.UUID) (int64, error) { + row := q.db.QueryRow(ctx, checkProblemInActiveAssignments, problemID) + var count int64 + err := row.Scan(&count) + return count, err +} + +const checkProblemInAssignmentGroups = `-- name: CheckProblemInAssignmentGroups :one +SELECT COUNT(*) +FROM assignment_group_problems +WHERE problem_id = $1 +` + +func (q *Queries) CheckProblemInAssignmentGroups(ctx context.Context, problemID pgtype.UUID) (int64, error) { + row := q.db.QueryRow(ctx, checkProblemInAssignmentGroups, problemID) + var count int64 + err := row.Scan(&count) + return count, err +} diff --git a/apps/server/internal/modules/problem/service.go b/apps/server/internal/modules/problem/service.go index f45f1f3..7cf0c9d 100644 --- a/apps/server/internal/modules/problem/service.go +++ b/apps/server/internal/modules/problem/service.go @@ -128,8 +128,24 @@ func (s *Service) UpdateProblem(ctx context.Context, req UpdateProblemRequest, p } func (s *Service) DeleteProblem(ctx context.Context, problemID pgtype.UUID) error { - // TODO: Check if problem is referenced by assignments (requires assignment queries) - // For now, just archive the problem + // Check if problem is referenced by active assignments + activeCount, err := s.queries.CheckProblemInActiveAssignments(ctx, problemID) + if err != nil { + return err + } + if activeCount > 0 { + return errors.New("cannot delete problem: referenced by active assignments") + } + + // Check if problem is referenced by assignment groups + groupCount, err := s.queries.CheckProblemInAssignmentGroups(ctx, problemID) + if err != nil { + return err + } + if groupCount > 0 { + return errors.New("cannot delete problem: referenced by assignment groups") + } + return s.queries.ArchiveProblem(ctx, problemID) }