mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 11:31:11 -05:00
Fix: Use RPC for submission claims
This commit is contained in:
@@ -324,20 +324,19 @@ export const useModerationQueue = (config?: UseModerationQueueConfig) => {
|
|||||||
.single();
|
.single();
|
||||||
|
|
||||||
const expiresAt = new Date(Date.now() + 15 * 60 * 1000);
|
const expiresAt = new Date(Date.now() + 15 * 60 * 1000);
|
||||||
const now = new Date().toISOString();
|
|
||||||
|
|
||||||
const { error } = await supabase
|
const { data, error } = await supabase.rpc('claim_specific_submission', {
|
||||||
.from('content_submissions')
|
p_submission_id: submissionId,
|
||||||
.update({
|
p_moderator_id: user.id,
|
||||||
assigned_to: user.id,
|
p_lock_duration: '15 minutes',
|
||||||
assigned_at: new Date().toISOString(),
|
});
|
||||||
locked_until: expiresAt.toISOString(),
|
|
||||||
})
|
|
||||||
.eq('id', submissionId)
|
|
||||||
.or(`assigned_to.is.null,locked_until.lt."${now}"`); // Only if unclaimed or lock expired
|
|
||||||
|
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
throw new Error('Submission is already claimed or no longer available');
|
||||||
|
}
|
||||||
|
|
||||||
setCurrentLock({
|
setCurrentLock({
|
||||||
submissionId,
|
submissionId,
|
||||||
expiresAt,
|
expiresAt,
|
||||||
|
|||||||
@@ -5403,6 +5403,14 @@ export type Database = {
|
|||||||
waiting_time: unknown
|
waiting_time: unknown
|
||||||
}[]
|
}[]
|
||||||
}
|
}
|
||||||
|
claim_specific_submission: {
|
||||||
|
Args: {
|
||||||
|
p_lock_duration?: unknown
|
||||||
|
p_moderator_id: string
|
||||||
|
p_submission_id: string
|
||||||
|
}
|
||||||
|
Returns: boolean
|
||||||
|
}
|
||||||
cleanup_expired_sessions: { Args: never; Returns: undefined }
|
cleanup_expired_sessions: { Args: never; Returns: undefined }
|
||||||
cleanup_old_page_views: { Args: never; Returns: undefined }
|
cleanup_old_page_views: { Args: never; Returns: undefined }
|
||||||
cleanup_old_request_metadata: { Args: never; Returns: undefined }
|
cleanup_old_request_metadata: { Args: never; Returns: undefined }
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
-- Create function to atomically claim a specific submission
|
||||||
|
CREATE OR REPLACE FUNCTION public.claim_specific_submission(
|
||||||
|
p_submission_id UUID,
|
||||||
|
p_moderator_id UUID,
|
||||||
|
p_lock_duration INTERVAL DEFAULT '15 minutes'
|
||||||
|
) RETURNS BOOLEAN
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
SECURITY DEFINER
|
||||||
|
SET search_path = public
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
rows_updated INTEGER;
|
||||||
|
BEGIN
|
||||||
|
-- Atomically update the submission if it's unclaimed or lock expired
|
||||||
|
UPDATE content_submissions
|
||||||
|
SET
|
||||||
|
assigned_to = p_moderator_id,
|
||||||
|
assigned_at = NOW(),
|
||||||
|
locked_until = NOW() + p_lock_duration,
|
||||||
|
first_reviewed_at = COALESCE(first_reviewed_at, NOW())
|
||||||
|
WHERE id = p_submission_id
|
||||||
|
AND (
|
||||||
|
assigned_to IS NULL
|
||||||
|
OR locked_until < NOW()
|
||||||
|
)
|
||||||
|
AND status = 'pending';
|
||||||
|
|
||||||
|
GET DIAGNOSTICS rows_updated = ROW_COUNT;
|
||||||
|
|
||||||
|
-- Log the action if successful
|
||||||
|
IF rows_updated > 0 THEN
|
||||||
|
BEGIN
|
||||||
|
PERFORM log_admin_action(
|
||||||
|
p_moderator_id,
|
||||||
|
(SELECT user_id FROM content_submissions WHERE id = p_submission_id),
|
||||||
|
'submission_claimed',
|
||||||
|
jsonb_build_object(
|
||||||
|
'submission_id', p_submission_id,
|
||||||
|
'claim_type', 'specific'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE WARNING 'Failed to log submission claim audit: %', SQLERRM;
|
||||||
|
END;
|
||||||
|
|
||||||
|
RETURN TRUE;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN FALSE;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
Reference in New Issue
Block a user