( user: ContentUser, contentId: string, reason: string )
| 911 | * Reject pending content - direct function call (no HTTP required). |
| 912 | */ |
| 913 | export async function rejectContentForUser( |
| 914 | user: ContentUser, |
| 915 | contentId: string, |
| 916 | reason: string |
| 917 | ): Promise<ContentReviewResult> { |
| 918 | if (!reason) { |
| 919 | return { |
| 920 | success: false, |
| 921 | error: 'missing_reason', |
| 922 | error_message: 'A reason is required when rejecting content', |
| 923 | }; |
| 924 | } |
| 925 | |
| 926 | const pool = getPool(); |
| 927 | |
| 928 | const contentResult = await pool.query( |
| 929 | `SELECT p.*, wg.slug as committee_slug |
| 930 | FROM perspectives p |
| 931 | LEFT JOIN working_groups wg ON wg.id = p.working_group_id |
| 932 | WHERE p.id = $1`, |
| 933 | [contentId] |
| 934 | ); |
| 935 | |
| 936 | if (contentResult.rows.length === 0) { |
| 937 | return { success: false, error: 'not_found', error_message: `No content found with id: ${contentId}` }; |
| 938 | } |
| 939 | |
| 940 | const content = contentResult.rows[0]; |
| 941 | |
| 942 | if (content.status !== 'pending_review') { |
| 943 | return { |
| 944 | success: false, |
| 945 | error: 'invalid_status', |
| 946 | error_message: `Content is not pending review (current status: ${content.status})`, |
| 947 | }; |
| 948 | } |
| 949 | |
| 950 | const userIsAdmin = await isWebUserAAOAdmin(user.id); |
| 951 | const userIsLead = content.working_group_id |
| 952 | ? await isCommitteeLead(content.working_group_id, user.id) |
| 953 | : false; |
| 954 | |
| 955 | if (!userIsAdmin && !userIsLead) { |
| 956 | return { |
| 957 | success: false, |
| 958 | error: 'permission_denied', |
| 959 | error_message: 'You do not have permission to reject this content', |
| 960 | }; |
| 961 | } |
| 962 | |
| 963 | await pool.query( |
| 964 | `UPDATE perspectives |
| 965 | SET status = 'rejected', rejection_reason = $1, |
| 966 | reviewed_by_user_id = $2, reviewed_at = NOW() |
| 967 | WHERE id = $3`, |
| 968 | [reason, user.id, contentId] |
| 969 | ); |
| 970 |
no test coverage detected