-- name: ListProjects :many SELECT * FROM project WHERE workspace_id = $1 AND (sqlc.narg('status')::text IS NULL OR status = sqlc.narg('status')) AND (sqlc.narg('priority')::text IS NULL OR priority = sqlc.narg('priority')) ORDER BY created_at DESC; -- name: GetProject :one SELECT * FROM project WHERE id = $1; -- name: GetProjectInWorkspace :one SELECT * FROM project WHERE id = $1 AND workspace_id = $2; -- name: CreateProject :one INSERT INTO project ( workspace_id, title, description, icon, status, lead_type, lead_id, priority, start_date, due_date ) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10 ) RETURNING *; -- name: UpdateProject :one UPDATE project SET title = COALESCE(sqlc.narg('title'), title), description = sqlc.narg('description'), icon = sqlc.narg('icon'), status = COALESCE(sqlc.narg('status'), status), priority = COALESCE(sqlc.narg('priority'), priority), lead_type = sqlc.narg('lead_type'), lead_id = sqlc.narg('lead_id'), start_date = sqlc.narg('start_date'), due_date = sqlc.narg('due_date'), updated_at = now() WHERE id = $1 RETURNING *; -- name: DeleteProject :exec -- Defense-in-depth: workspace_id is a SQL-layer tenant guard. See DeleteIssue. WITH project_views AS ( SELECT id FROM issue_view WHERE workspace_id = $2 AND scope_type = 'project' AND scope_id = $1 ), cleared_view_preferences AS ( DELETE FROM issue_view_preference WHERE workspace_id = $2 AND ( (scope_type = 'project' AND scope_id = $1) OR default_view_id IN (SELECT id FROM project_views) ) ), cleared_view_pins AS ( DELETE FROM pinned_item WHERE workspace_id = $2 AND item_type = 'view' AND item_id IN (SELECT id FROM project_views) ), cleared_views AS ( DELETE FROM issue_view WHERE workspace_id = $2 AND scope_type = 'project' AND scope_id = $1 ) DELETE FROM project WHERE project.id = $1 AND project.workspace_id = $2; -- name: CountIssuesByProject :one SELECT count(*) FROM issue WHERE project_id = $1; -- name: GetProjectIssueStats :many SELECT project_id, count(*)::bigint AS total_count, count(*) FILTER (WHERE status IN ('done', 'cancelled'))::bigint AS done_count FROM issue WHERE project_id = ANY(sqlc.arg('project_ids')::uuid[]) GROUP BY project_id;