-- Фаза 3: Отклики волонтеров и история статусов (СРЕДНИЙ ПРИОРИТЕТ) -- Запросы для управления откликами волонтеров и историей изменения статусов заявок -- ============================================================================ -- Отклики волонтеров -- ============================================================================ -- name: CreateVolunteerResponse :one INSERT INTO volunteer_responses ( request_id, volunteer_id, message ) VALUES ( $1, $2, $3 ) ON CONFLICT (request_id, volunteer_id) DO NOTHING RETURNING *; -- name: GetResponsesByRequest :many SELECT vr.*, (u.first_name || ' ' || u.last_name) as volunteer_name, u.avatar_url as volunteer_avatar, u.volunteer_rating, u.completed_requests_count, u.email as volunteer_email, u.phone as volunteer_phone FROM volunteer_responses vr JOIN users u ON u.id = vr.volunteer_id WHERE vr.request_id = $1 ORDER BY vr.created_at DESC; -- name: GetResponsesByVolunteer :many SELECT vr.*, r.title as request_title, r.status as request_status, (u.first_name || ' ' || u.last_name) as requester_name FROM volunteer_responses vr JOIN requests r ON r.id = vr.request_id JOIN users u ON u.id = r.requester_id WHERE vr.volunteer_id = $1 ORDER BY vr.created_at DESC LIMIT $2 OFFSET $3; -- name: GetResponseByID :one SELECT vr.*, (u.first_name || ' ' || u.last_name) as volunteer_name, r.title as request_title FROM volunteer_responses vr JOIN users u ON u.id = vr.volunteer_id JOIN requests r ON r.id = vr.request_id WHERE vr.id = $1; -- name: AcceptVolunteerResponse :exec UPDATE volunteer_responses SET status = 'accepted', accepted_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP WHERE id = $1; -- name: RejectVolunteerResponse :exec UPDATE volunteer_responses SET status = 'rejected', rejected_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP WHERE id = $1; -- name: CountResponsesByRequest :one SELECT COUNT(*) FROM volunteer_responses WHERE request_id = $1; -- name: CountPendingResponsesByVolunteer :one SELECT COUNT(*) FROM volunteer_responses WHERE volunteer_id = $1 AND status = 'pending'; -- ============================================================================ -- История изменения статусов заявок -- ============================================================================ -- name: CreateStatusHistoryEntry :one INSERT INTO request_status_history ( request_id, from_status, to_status, changed_by, comment ) VALUES ( $1, $2, $3, $4, sqlc.narg('comment') ) RETURNING *; -- name: GetRequestStatusHistory :many SELECT rsh.*, (u.first_name || ' ' || u.last_name) as changed_by_name FROM request_status_history rsh JOIN users u ON u.id = rsh.changed_by WHERE rsh.request_id = $1 ORDER BY rsh.created_at DESC; -- name: GetLatestStatusChange :one SELECT rsh.*, (u.first_name || ' ' || u.last_name) as changed_by_name FROM request_status_history rsh JOIN users u ON u.id = rsh.changed_by WHERE rsh.request_id = $1 ORDER BY rsh.created_at DESC LIMIT 1; -- ============================================================================ -- Рейтинги -- ============================================================================ -- name: CreateRating :one INSERT INTO ratings ( volunteer_response_id, volunteer_id, requester_id, request_id, rating, comment ) VALUES ( $1, $2, $3, $4, $5, sqlc.narg('comment') ) RETURNING *; -- name: GetRatingByResponseID :one SELECT * FROM ratings WHERE volunteer_response_id = $1; -- name: GetRatingsByVolunteer :many SELECT r.*, req.title as request_title, (u.first_name || ' ' || u.last_name) as requester_name FROM ratings r JOIN requests req ON req.id = r.request_id JOIN users u ON u.id = r.requester_id WHERE r.volunteer_id = $1 ORDER BY r.created_at DESC LIMIT $2 OFFSET $3; -- name: CalculateVolunteerAverageRating :one SELECT COALESCE(AVG(rating), 0) as average_rating, COUNT(*) as total_ratings FROM ratings WHERE volunteer_id = $1; -- name: UpdateRating :exec UPDATE ratings SET rating = $2, comment = sqlc.narg('comment'), updated_at = CURRENT_TIMESTAMP WHERE id = $1; -- ============================================================================ -- Хранимые процедуры -- ============================================================================ -- name: CallAcceptVolunteerResponse :one SELECT r.success::BOOLEAN, r.message::TEXT, r.out_request_id::BIGINT, r.out_volunteer_id::BIGINT FROM accept_volunteer_response($1, $2) AS r(success, message, out_request_id, out_volunteer_id); -- name: CallCompleteRequestWithRating :one SELECT r.success::BOOLEAN, r.message::TEXT, r.out_rating_id::BIGINT FROM complete_request_with_rating($1, $2, $3, sqlc.narg('comment')) AS r(success, message, out_rating_id); -- name: CallModerateRequest :one SELECT r.success::BOOLEAN, r.message::TEXT FROM moderate_request($1, $2, $3, sqlc.narg('comment')) AS r(success, message);