- Add 023_edit_sessions.sql migration with unique index on (item_id, context_level, object_id) for hard interference
- Add EditSessionRepository with Acquire, Release, ReleaseForWorkstation, GetByID, ListForItem, ListForUser, TouchHeartbeat, ExpireStale, GetConflict
- Add 4 handlers: acquire (POST), release (DELETE), list by item (GET), list by user (GET)
- Acquire auto-computes dependency_cone from DAG forward cone when available
- Hard interference returns 409 with holder info (username, workstation, context_level, object_id, acquired_at)
- Publish edit.session_acquired and edit.session_released via item-scoped SSE
- Add /api/edit-sessions (user scope) and /api/items/{pn}/edit-sessions (item scope) routes
Closes #163
18 lines
874 B
SQL
18 lines
874 B
SQL
-- 023_edit_sessions.sql — active editing context tracking
|
|
|
|
CREATE TABLE edit_sessions (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
item_id UUID NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
workstation_id UUID NOT NULL REFERENCES workstations(id) ON DELETE CASCADE,
|
|
context_level TEXT NOT NULL CHECK (context_level IN ('sketch', 'partdesign', 'assembly')),
|
|
object_id TEXT,
|
|
dependency_cone TEXT[],
|
|
acquired_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
last_heartbeat TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_edit_sessions_item ON edit_sessions(item_id);
|
|
CREATE INDEX idx_edit_sessions_user ON edit_sessions(user_id);
|
|
CREATE UNIQUE INDEX idx_edit_sessions_active ON edit_sessions(item_id, context_level, object_id);
|