You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
41 lines
1.6 KiB
41 lines
1.6 KiB
-- Document locks: track who is currently editing a document |
|
-- Uses a heartbeat model: editors must refresh their lock periodically |
|
-- Stale locks (no heartbeat for 60s) are considered expired |
|
|
|
CREATE TABLE document_locks ( |
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), |
|
document_id UUID NOT NULL REFERENCES documents(id) ON DELETE CASCADE, |
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, |
|
locked_at TIMESTAMPTZ NOT NULL DEFAULT now(), |
|
last_heartbeat TIMESTAMPTZ NOT NULL DEFAULT now(), |
|
UNIQUE(document_id) |
|
); |
|
|
|
-- Index for fast lookups |
|
CREATE INDEX idx_document_locks_document ON document_locks(document_id); |
|
CREATE INDEX idx_document_locks_heartbeat ON document_locks(last_heartbeat); |
|
|
|
-- RLS |
|
ALTER TABLE document_locks ENABLE ROW LEVEL SECURITY; |
|
|
|
-- Anyone in the org can view locks (to see who's editing) |
|
CREATE POLICY "Org members can view document locks" ON document_locks FOR SELECT |
|
USING (EXISTS ( |
|
SELECT 1 FROM documents d |
|
JOIN org_members om ON d.org_id = om.org_id |
|
WHERE d.id = document_locks.document_id AND om.user_id = auth.uid() |
|
)); |
|
|
|
-- Users can manage their own locks |
|
CREATE POLICY "Users can insert their own locks" ON document_locks FOR INSERT |
|
WITH CHECK (user_id = auth.uid()); |
|
|
|
CREATE POLICY "Users can update their own locks" ON document_locks FOR UPDATE |
|
USING (user_id = auth.uid()); |
|
|
|
CREATE POLICY "Users can delete their own locks" ON document_locks FOR DELETE |
|
USING (user_id = auth.uid()); |
|
|
|
-- Allow taking over expired locks (heartbeat older than 60 seconds) |
|
CREATE POLICY "Anyone can delete expired locks" ON document_locks FOR DELETE |
|
USING (last_heartbeat < now() - interval '60 seconds');
|
|
|