G0~G8 성과·동맹 측정 OS 작업 일괄 고정
8월 7일까지 워킹트리에만 남아 있던 미커밋 작업을 커밋한다. 여러 사본 폴더(worktree·clone)에 흩어져 있던 중간 스냅샷을 정리하기 전에 원본을 git 이력으로 고정하는 것이 목적이다. - contracts/routes/services: measurement, outcome_trajectory, rupture_repair, deliberate_practice, calibration_transfer, supervision_research, multimodal_alliance, continuous_improvement 계열 신규 모듈과 테스트 - infra/db/init: 07~16 마이그레이션(측정 기반~calibration transfer 실행) - apps/web: 세션 리뷰 카드·관리 화면·E2E 스펙 추가 - docs/ops: G0~G8 라이브 통합·배포·롤백 증거 문서와 evidence JSON/PNG - scripts: smoke·ledger·릴리스 에이전트·NAS 프리뷰 운영 스크립트 engine.public 로그 .bak과 apps/web/test-results 산출물은 커밋에서 제외했다.
This commit is contained in:
parent
93dd8f82d7
commit
16e791e044
390 changed files with 243188 additions and 499 deletions
454
scripts/check-outcome-trajectory-ledger.sql
Normal file
454
scripts/check-outcome-trajectory-ledger.sql
Normal file
|
|
@ -0,0 +1,454 @@
|
|||
\set ON_ERROR_STOP on
|
||||
|
||||
-- Destructive-looking guard checks are isolated inside this transaction. The
|
||||
-- final ROLLBACK guarantees that no smoke fixture survives in the live DB.
|
||||
BEGIN;
|
||||
|
||||
INSERT INTO app.app_user (
|
||||
user_id, external_id, email, display_name, role, cohort
|
||||
) VALUES
|
||||
('00000000-0000-0000-0000-00000000c101', 'smoke:g2:learner', 'g2-learner@example.invalid', 'G2 Learner', 'learner', 'g2-cohort-a'),
|
||||
('00000000-0000-0000-0000-00000000c102', 'smoke:g2:other', 'g2-other@example.invalid', 'G2 Other', 'learner', 'g2-cohort-b'),
|
||||
('00000000-0000-0000-0000-00000000c103', 'smoke:g2:teacher', 'g2-teacher@example.invalid', 'G2 Teacher', 'instructor', 'g2-cohort-a');
|
||||
|
||||
INSERT INTO app.case_profile (
|
||||
case_id, persona_id, learner_id, last_session_no, case_digest
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c110',
|
||||
'00000000-0000-0000-0000-00000000c109',
|
||||
'00000000-0000-0000-0000-00000000c101',
|
||||
1,
|
||||
'G2 rollback smoke case'
|
||||
);
|
||||
|
||||
INSERT INTO app.sessions (
|
||||
id, case_id, learner_id, session_no, theory_mode, ended_at
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'00000000-0000-0000-0000-00000000c110',
|
||||
'00000000-0000-0000-0000-00000000c101',
|
||||
1,
|
||||
'integrative',
|
||||
now()
|
||||
);
|
||||
|
||||
INSERT INTO app.turns (
|
||||
id, session_id, seq, speaker, text, actor_kind, visible_to
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c121',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
1,
|
||||
'client',
|
||||
'교육용 G2 근거 발화',
|
||||
'client_ai',
|
||||
ARRAY['client','counselor','evaluator','supervisor']::text[]
|
||||
);
|
||||
|
||||
INSERT INTO app.measurement_event (
|
||||
measurement_id, session_id, construct, dimension, perspective, source_kind,
|
||||
instrument_id, instrument_version, value, scale_min, scale_max, confidence,
|
||||
status, evidence_turn_ids, visible_to
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c131',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'session_outcome',
|
||||
'distress_load',
|
||||
'client_simulation',
|
||||
'simulated_state',
|
||||
'vignette-session-outcome',
|
||||
'1.0.0',
|
||||
0.7, 0, 1, 0.9,
|
||||
'ready',
|
||||
ARRAY['00000000-0000-0000-0000-00000000c121']::uuid[],
|
||||
ARRAY['counselor','evaluator','supervisor']::text[]
|
||||
);
|
||||
|
||||
SET LOCAL ROLE vignette;
|
||||
SELECT set_config('app.ai_context', '', true);
|
||||
SELECT set_config('app.current_role', 'learner', true);
|
||||
SELECT set_config('app.current_uid', '00000000-0000-0000-0000-00000000c101', true);
|
||||
SELECT set_config('app.current_cohort', 'g2-cohort-a', true);
|
||||
|
||||
-- A learner check-in is a three-axis immutable submission. Empty transcript
|
||||
-- evidence is valid because the learner response itself is the provenance.
|
||||
INSERT INTO app.measurement_event (
|
||||
measurement_id, session_id, construct, dimension, perspective, source_kind,
|
||||
instrument_id, instrument_version, value, scale_min, scale_max, confidence,
|
||||
status, evidence_turn_ids, visible_to, metadata
|
||||
) VALUES
|
||||
(
|
||||
'00000000-0000-0000-0000-00000000c161',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'session_outcome', 'distress_load', 'learner_self_report', 'learner_reported',
|
||||
'vignette-session-outcome-checkin', '1.0.0', 0.72, 0, 1, 0.9,
|
||||
'ready', ARRAY[]::uuid[], ARRAY['counselor','evaluator','supervisor']::text[],
|
||||
jsonb_build_object('submission_id','00000000-0000-0000-0000-00000000c160','submission_hash',repeat('d',64))
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-00000000c162',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'session_outcome', 'daily_functioning', 'learner_self_report', 'learner_reported',
|
||||
'vignette-session-outcome-checkin', '1.0.0', 0.44, 0, 1, 0.8,
|
||||
'ready', ARRAY[]::uuid[], ARRAY['counselor','evaluator','supervisor']::text[],
|
||||
jsonb_build_object('submission_id','00000000-0000-0000-0000-00000000c160','submission_hash',repeat('d',64))
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-00000000c163',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'session_outcome', 'learning_engagement', 'learner_self_report', 'learner_reported',
|
||||
'vignette-session-outcome-checkin', '1.0.0', 0.81, 0, 1, 0.85,
|
||||
'ready', ARRAY[]::uuid[], ARRAY['counselor','evaluator','supervisor']::text[],
|
||||
jsonb_build_object('submission_id','00000000-0000-0000-0000-00000000c160','submission_hash',repeat('d',64))
|
||||
);
|
||||
|
||||
-- A later submission creates one leaf per axis and supersedes the first set.
|
||||
INSERT INTO app.measurement_event (
|
||||
measurement_id, session_id, supersedes_id, construct, dimension,
|
||||
perspective, source_kind, instrument_id, instrument_version,
|
||||
value, scale_min, scale_max, confidence, status, evidence_turn_ids,
|
||||
visible_to, metadata
|
||||
) VALUES
|
||||
(
|
||||
'00000000-0000-0000-0000-00000000c171',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'00000000-0000-0000-0000-00000000c161',
|
||||
'session_outcome', 'distress_load', 'learner_self_report', 'learner_reported',
|
||||
'vignette-session-outcome-checkin', '1.0.0', 0.68, 0, 1, 0.91, 'ready',
|
||||
ARRAY[]::uuid[], ARRAY['counselor','evaluator','supervisor']::text[],
|
||||
jsonb_build_object('submission_id','00000000-0000-0000-0000-00000000c170','submission_hash',repeat('e',64))
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-00000000c172',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'00000000-0000-0000-0000-00000000c162',
|
||||
'session_outcome', 'daily_functioning', 'learner_self_report', 'learner_reported',
|
||||
'vignette-session-outcome-checkin', '1.0.0', 0.48, 0, 1, 0.82, 'ready',
|
||||
ARRAY[]::uuid[], ARRAY['counselor','evaluator','supervisor']::text[],
|
||||
jsonb_build_object('submission_id','00000000-0000-0000-0000-00000000c170','submission_hash',repeat('e',64))
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-00000000c173',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'00000000-0000-0000-0000-00000000c163',
|
||||
'session_outcome', 'learning_engagement', 'learner_self_report', 'learner_reported',
|
||||
'vignette-session-outcome-checkin', '1.0.0', 0.84, 0, 1, 0.87, 'ready',
|
||||
ARRAY[]::uuid[], ARRAY['counselor','evaluator','supervisor']::text[],
|
||||
jsonb_build_object('submission_id','00000000-0000-0000-0000-00000000c170','submission_hash',repeat('e',64))
|
||||
);
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF (
|
||||
SELECT count(*)
|
||||
FROM app.measurement_event m
|
||||
WHERE m.session_id = '00000000-0000-0000-0000-00000000c111'
|
||||
AND m.instrument_id = 'vignette-session-outcome-checkin'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM app.measurement_event child
|
||||
WHERE child.supersedes_id = m.measurement_id
|
||||
)
|
||||
) <> 3 THEN
|
||||
RAISE EXCEPTION 'learner check-in must keep exactly one leaf per outcome axis';
|
||||
END IF;
|
||||
|
||||
BEGIN
|
||||
INSERT INTO app.measurement_event (
|
||||
measurement_id, session_id, construct, dimension, perspective, source_kind,
|
||||
instrument_id, instrument_version, value, scale_min, scale_max, confidence,
|
||||
status, evidence_turn_ids, visible_to, metadata
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c164',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'session_outcome', 'distress_load', 'learner_self_report', 'learner_reported',
|
||||
'vignette-session-outcome-checkin', '1.0.0', 0.2, 0, 1, 0.2,
|
||||
'ready', ARRAY[]::uuid[], ARRAY['counselor']::text[],
|
||||
jsonb_build_object('submission_id','00000000-0000-0000-0000-00000000c160','submission_hash',repeat('f',64))
|
||||
);
|
||||
RAISE EXCEPTION 'duplicate submission axis was not rejected';
|
||||
EXCEPTION WHEN unique_violation THEN
|
||||
NULL;
|
||||
END;
|
||||
|
||||
BEGIN
|
||||
INSERT INTO app.measurement_event (
|
||||
measurement_id, session_id, construct, dimension, perspective, source_kind,
|
||||
instrument_id, instrument_version, value, scale_min, scale_max, confidence,
|
||||
status, evidence_turn_ids, visible_to, metadata
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c165',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'session_outcome', 'distress_load', 'learner_self_report', 'learner_reported',
|
||||
'vignette-session-outcome-checkin', '1.0.0', 0.2, 0, 1, 0.2,
|
||||
'ready', ARRAY['00000000-0000-0000-0000-00000000c199']::uuid[],
|
||||
ARRAY['counselor']::text[],
|
||||
jsonb_build_object('submission_id','00000000-0000-0000-0000-00000000c166','submission_hash',repeat('f',64))
|
||||
);
|
||||
RAISE EXCEPTION 'cross-session or missing evidence turn was not rejected';
|
||||
EXCEPTION WHEN check_violation THEN
|
||||
NULL;
|
||||
END;
|
||||
END;
|
||||
$$;
|
||||
|
||||
INSERT INTO app.outcome_trajectory_revision (
|
||||
revision_id, anchor_session_id, case_id, learner_id, expected_arc_id,
|
||||
revision_no, source_fingerprint, assessment, observation_count,
|
||||
missing_observation_count, recompute_reason, computed_by, computed_role
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c141',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'00000000-0000-0000-0000-00000000c110',
|
||||
'00000000-0000-0000-0000-00000000c101',
|
||||
'oas-g2-arc-001',
|
||||
1,
|
||||
repeat('a', 64),
|
||||
'{"schema_version":"vignette.outcome-trajectory-assessment.v1","expected_arc_id":"oas-g2-arc-001","data_classification":"synthetic_educational","clinical_claim_allowed":false,"sessions":[]}'::jsonb,
|
||||
3,
|
||||
2,
|
||||
'rollback_smoke_initial',
|
||||
'00000000-0000-0000-0000-00000000c101',
|
||||
'learner'
|
||||
);
|
||||
|
||||
INSERT INTO app.outcome_trajectory_observation (
|
||||
revision_id, measurement_id, session_id, session_no, axis, status,
|
||||
value, raw_value, scale_min, scale_max, confidence,
|
||||
source_kind, perspective, instrument_id, instrument_version,
|
||||
evidence_turn_ids, missing_reason, source_created_at
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c141',
|
||||
'00000000-0000-0000-0000-00000000c131',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
1,
|
||||
'distress_load',
|
||||
'observed',
|
||||
0.7, 0.7, 0, 1, 0.9,
|
||||
'simulated_state', 'client_simulation',
|
||||
'vignette-session-outcome', '1.0.0',
|
||||
ARRAY['00000000-0000-0000-0000-00000000c121']::uuid[],
|
||||
NULL,
|
||||
now()
|
||||
), (
|
||||
'00000000-0000-0000-0000-00000000c141',
|
||||
NULL,
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
1,
|
||||
'daily_functioning',
|
||||
'missing',
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
'observed_runtime', 'runtime_observation',
|
||||
'vignette-outcome-evidence-gap', '1.0.0',
|
||||
ARRAY[]::uuid[],
|
||||
'measurement_not_collected',
|
||||
NULL
|
||||
), (
|
||||
'00000000-0000-0000-0000-00000000c141',
|
||||
NULL,
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
1,
|
||||
'learning_engagement',
|
||||
'missing',
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
'observed_runtime', 'runtime_observation',
|
||||
'vignette-outcome-evidence-gap', '1.0.0',
|
||||
ARRAY[]::uuid[],
|
||||
'measurement_not_collected',
|
||||
NULL
|
||||
);
|
||||
|
||||
-- Same evidence can be recomputed only as a new revision linked to its predecessor.
|
||||
INSERT INTO app.outcome_trajectory_revision (
|
||||
revision_id, anchor_session_id, case_id, learner_id, expected_arc_id,
|
||||
revision_no, supersedes_revision_id, source_fingerprint, assessment,
|
||||
observation_count, missing_observation_count, recompute_reason,
|
||||
computed_by, computed_role
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c142',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'00000000-0000-0000-0000-00000000c110',
|
||||
'00000000-0000-0000-0000-00000000c101',
|
||||
'oas-g2-arc-001',
|
||||
2,
|
||||
'00000000-0000-0000-0000-00000000c141',
|
||||
repeat('a', 64),
|
||||
'{"schema_version":"vignette.outcome-trajectory-assessment.v1","expected_arc_id":"oas-g2-arc-001","data_classification":"synthetic_educational","clinical_claim_allowed":false,"sessions":[]}'::jsonb,
|
||||
3,
|
||||
2,
|
||||
'rollback_smoke_recompute',
|
||||
'00000000-0000-0000-0000-00000000c101',
|
||||
'learner'
|
||||
);
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF (SELECT count(*) FROM app.outcome_trajectory_revision) <> 2 THEN
|
||||
RAISE EXCEPTION 'owner learner must see its two trajectory revisions';
|
||||
END IF;
|
||||
IF (
|
||||
SELECT count(*) FROM app.outcome_trajectory_observation
|
||||
WHERE revision_id = '00000000-0000-0000-0000-00000000c141'
|
||||
) <> 3 THEN
|
||||
RAISE EXCEPTION 'trajectory revision must preserve all three explicit axes';
|
||||
END IF;
|
||||
IF (
|
||||
SELECT count(*) FROM app.outcome_trajectory_observation
|
||||
WHERE revision_id = '00000000-0000-0000-0000-00000000c141'
|
||||
AND status = 'missing' AND value IS NULL
|
||||
) <> 2 THEN
|
||||
RAISE EXCEPTION 'missing outcome axes must stay scoreless';
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
|
||||
RESET ROLE;
|
||||
SET LOCAL ROLE vignette;
|
||||
SELECT set_config('app.current_role', 'instructor', true);
|
||||
SELECT set_config('app.current_uid', '00000000-0000-0000-0000-00000000c103', true);
|
||||
SELECT set_config('app.current_cohort', 'g2-cohort-a', true);
|
||||
|
||||
INSERT INTO app.relationship_memory_event (
|
||||
memory_event_id, session_id, case_id, event_type, visible_to,
|
||||
evidence_turn_ids, source_kind, created_by
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c151',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'00000000-0000-0000-0000-00000000c110',
|
||||
'unresolved_rupture',
|
||||
ARRAY['counselor','supervisor']::text[],
|
||||
ARRAY['00000000-0000-0000-0000-00000000c121']::uuid[],
|
||||
'human_rated',
|
||||
'00000000-0000-0000-0000-00000000c103'
|
||||
);
|
||||
INSERT INTO app.relationship_memory_projection (
|
||||
memory_event_id, ai_view, summary
|
||||
) VALUES
|
||||
('00000000-0000-0000-0000-00000000c151', 'counselor', '과제 합의를 다음 회기에 다시 확인한다.'),
|
||||
('00000000-0000-0000-0000-00000000c151', 'supervisor', '표면 동의 뒤 남은 과제 부담을 재확인한다.');
|
||||
|
||||
INSERT INTO app.relationship_memory_event (
|
||||
memory_event_id, session_id, case_id, event_type, resolves_event_id,
|
||||
visible_to, evidence_turn_ids, source_kind, created_by
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c153',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'00000000-0000-0000-0000-00000000c110',
|
||||
'repair_confirmed',
|
||||
'00000000-0000-0000-0000-00000000c151',
|
||||
ARRAY['supervisor']::text[],
|
||||
ARRAY['00000000-0000-0000-0000-00000000c121']::uuid[],
|
||||
'human_rated',
|
||||
'00000000-0000-0000-0000-00000000c103'
|
||||
);
|
||||
INSERT INTO app.relationship_memory_projection (
|
||||
memory_event_id, ai_view, summary
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c153',
|
||||
'supervisor',
|
||||
'미해결 균열을 다음 회기 재합의로 복구했다.'
|
||||
);
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
BEGIN
|
||||
INSERT INTO app.relationship_memory_event (
|
||||
memory_event_id, session_id, case_id, event_type, visible_to,
|
||||
evidence_turn_ids, source_kind, created_by
|
||||
) VALUES (
|
||||
'00000000-0000-0000-0000-00000000c152',
|
||||
'00000000-0000-0000-0000-00000000c111',
|
||||
'00000000-0000-0000-0000-00000000c110',
|
||||
'goal_agreement', ARRAY['supervisor']::text[],
|
||||
ARRAY['00000000-0000-0000-0000-00000000c199']::uuid[],
|
||||
'human_rated', '00000000-0000-0000-0000-00000000c103'
|
||||
);
|
||||
RAISE EXCEPTION 'relationship evidence ownership violation was not rejected';
|
||||
EXCEPTION WHEN check_violation THEN
|
||||
NULL;
|
||||
END;
|
||||
END;
|
||||
$$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF (SELECT count(*) FROM app.outcome_trajectory_revision) <> 2 THEN
|
||||
RAISE EXCEPTION 'same-cohort instructor must see trajectory revisions';
|
||||
END IF;
|
||||
IF (SELECT count(*) FROM app.relationship_memory_projection) <> 2 THEN
|
||||
RAISE EXCEPTION 'instructor must see only two supervisor/evaluator projections';
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
|
||||
SELECT set_config('app.current_cohort', 'g2-cohort-b', true);
|
||||
DO $$
|
||||
BEGIN
|
||||
IF (SELECT count(*) FROM app.outcome_trajectory_revision) <> 0 THEN
|
||||
RAISE EXCEPTION 'cross-cohort instructor trajectory leak';
|
||||
END IF;
|
||||
IF (SELECT count(*) FROM app.relationship_memory_projection) <> 0 THEN
|
||||
RAISE EXCEPTION 'cross-cohort instructor memory leak';
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
|
||||
SELECT set_config('app.current_role', 'learner', true);
|
||||
SELECT set_config('app.current_uid', '00000000-0000-0000-0000-00000000c102', true);
|
||||
DO $$
|
||||
BEGIN
|
||||
IF (SELECT count(*) FROM app.outcome_trajectory_revision) <> 0 THEN
|
||||
RAISE EXCEPTION 'other learner trajectory leak';
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
|
||||
SELECT set_config('app.current_uid', '00000000-0000-0000-0000-00000000c101', true);
|
||||
DO $$
|
||||
BEGIN
|
||||
IF (SELECT count(*) FROM app.relationship_memory_projection) <> 1 THEN
|
||||
RAISE EXCEPTION 'owner learner must see exactly the counselor projection';
|
||||
END IF;
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM app.relationship_memory_projection WHERE ai_view <> 'counselor'
|
||||
) THEN
|
||||
RAISE EXCEPTION 'supervisor relationship summary leaked to learner';
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
|
||||
RESET ROLE;
|
||||
DO $$
|
||||
BEGIN
|
||||
BEGIN
|
||||
UPDATE app.outcome_trajectory_revision
|
||||
SET recompute_reason = 'forbidden mutation'
|
||||
WHERE revision_id = '00000000-0000-0000-0000-00000000c141';
|
||||
RAISE EXCEPTION 'trajectory revision mutation was not rejected';
|
||||
EXCEPTION WHEN object_not_in_prerequisite_state THEN
|
||||
NULL;
|
||||
END;
|
||||
|
||||
BEGIN
|
||||
DELETE FROM app.relationship_memory_projection
|
||||
WHERE projection_id = (
|
||||
SELECT projection_id FROM app.relationship_memory_projection LIMIT 1
|
||||
);
|
||||
RAISE EXCEPTION 'relationship projection deletion was not rejected';
|
||||
EXCEPTION WHEN object_not_in_prerequisite_state THEN
|
||||
NULL;
|
||||
END;
|
||||
END;
|
||||
$$;
|
||||
|
||||
SELECT
|
||||
(SELECT count(*) FROM app.outcome_trajectory_revision
|
||||
WHERE case_id = '00000000-0000-0000-0000-00000000c110') AS revisions_before_rollback,
|
||||
(SELECT count(*) FROM app.outcome_trajectory_observation
|
||||
WHERE session_id = '00000000-0000-0000-0000-00000000c111') AS observations_before_rollback,
|
||||
(SELECT count(*) FROM app.relationship_memory_projection p
|
||||
JOIN app.relationship_memory_event e USING (memory_event_id)
|
||||
WHERE e.case_id = '00000000-0000-0000-0000-00000000c110') AS projections_before_rollback,
|
||||
(SELECT count(*) FROM app.measurement_event
|
||||
WHERE session_id = '00000000-0000-0000-0000-00000000c111'
|
||||
AND instrument_id = 'vignette-session-outcome-checkin') AS checkins_before_rollback;
|
||||
|
||||
ROLLBACK;
|
||||
Loading…
Add table
Add a link
Reference in a new issue