39 lines
1.7 KiB
SQL
39 lines
1.7 KiB
SQL
-- =============================================================================
|
|
-- Vignette · migration 23 — 관리자 감정 관측용 Jev 전이 trace
|
|
-- =============================================================================
|
|
-- 기존 turns/session_state 행은 수정하지 않는다. trace는 성공한 client 턴에만
|
|
-- 연결되며, 앱 런타임은 client turn INSERT와 state UPSERT를 같은 트랜잭션에 둔다.
|
|
|
|
CREATE TABLE IF NOT EXISTS app.client_affect_trace (
|
|
turn_id UUID PRIMARY KEY REFERENCES app.turns(id) ON DELETE CASCADE,
|
|
session_id UUID NOT NULL REFERENCES app.sessions(id) ON DELETE CASCADE,
|
|
trace JSONB NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_client_affect_trace_session_created
|
|
ON app.client_affect_trace (session_id, created_at DESC);
|
|
|
|
ALTER TABLE app.client_affect_trace ENABLE ROW LEVEL SECURITY;
|
|
|
|
DROP POLICY IF EXISTS p_client_affect_trace_select_admin ON app.client_affect_trace;
|
|
DROP POLICY IF EXISTS p_client_affect_trace_insert_learner ON app.client_affect_trace;
|
|
|
|
CREATE POLICY p_client_affect_trace_select_admin
|
|
ON app.client_affect_trace FOR SELECT
|
|
USING (app.current_role_name() = 'admin');
|
|
|
|
CREATE POLICY p_client_affect_trace_insert_learner
|
|
ON app.client_affect_trace FOR INSERT
|
|
WITH CHECK (
|
|
app.current_role_name() = 'learner'
|
|
AND EXISTS (
|
|
SELECT 1
|
|
FROM app.turns AS turn_row
|
|
JOIN app.sessions AS session_row ON session_row.id = turn_row.session_id
|
|
WHERE turn_row.id = app.client_affect_trace.turn_id
|
|
AND turn_row.session_id = app.client_affect_trace.session_id
|
|
AND turn_row.speaker = 'client'
|
|
AND session_row.learner_id = app.current_uid()
|
|
)
|
|
);
|