23-P3C1 — §0.1 UX State Foundation Notes (rev2 — per-actor)
23-P3C1 — §0.1 UX State Foundation Notes (rev2)
Date: 2026-05-07 Status: Companion document cho P3C1 execution prompt. Rev2: Per-actor last-view watermark thay global. Agent: đọc file này trước khi chạy P3C1.
1. Timestamp Discipline
Mọi edit/comment/apply/review/stale/withdraw đều có timestamp. P3B schema đã có: draft.created_at, draft.applied_at, draft.stale_at, comment.created_at. P3C1 functions dùng DEFAULT now(). Sắp xếp mặc định: ORDER BY created_at DESC (newest-first). Index idx_uec_draft_created hỗ trợ.
2. Automatic Signature / Actor Card
P3C1 nhận p_actor/p_author explicit. Hook dài hạn (2 dòng per function, chờ approve):
-- Agent sign-in 1 lần per session:
SELECT set_config('app.iu_actor', 'agent:opus', false);
-- Trong function:
v_actor := COALESCE(NULLIF(btrim(p_actor), ''), current_setting('app.iu_actor', true));
IF v_actor IS NULL OR v_actor = '' THEN RETURN invalid_input; END IF;
Cùng actor identity dùng cho: created_by, author_ref, applied_by, reviewer_ref. AI không ký tay trong comment body. PG-native session GUC, zero infrastructure. Explicit param override GUC. P3C1 chưa implement — ghi hook.
3. Read/Unread — Per-Actor Last-View Watermark
Mô hình
Mỗi reviewer/actor có watermark riêng. Không dùng 1 global last_viewed_at — nếu Opus xem lúc 10:30 rồi GPT xem lúc 10:40, hệ thống phải nhớ CẢ HAI.
Future table (chưa implement, ghi hook)
-- unit_edit_review_state
CREATE TABLE unit_edit_review_state (
id uuid NOT NULL DEFAULT gen_random_uuid(),
draft_id uuid NOT NULL REFERENCES unit_edit_draft(id),
reviewer_ref text NOT NULL,
last_viewed_at timestamptz NOT NULL,
last_viewed_comment_created_at timestamptz NULL,
last_viewed_comment_id uuid NULL REFERENCES unit_edit_comment(id),
decision text NULL,
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
updated_at timestamptz NOT NULL DEFAULT now(),
CONSTRAINT pk_review_state PRIMARY KEY (id),
CONSTRAINT uq_review_state UNIQUE (draft_id, reviewer_ref)
);
Unread query (reviewer chỉ đọc comment mới)
SELECT c.*
FROM unit_edit_comment c
LEFT JOIN unit_edit_review_state s
ON s.draft_id = c.draft_id AND s.reviewer_ref = :reviewer
WHERE c.draft_id = :draft_id
AND (s.last_viewed_at IS NULL OR c.created_at > s.last_viewed_at)
ORDER BY c.created_at DESC;
Latest 3–5 viewers
SELECT reviewer_ref, last_viewed_at
FROM unit_edit_review_state
WHERE draft_id = :draft_id
ORDER BY last_viewed_at DESC
LIMIT 5;
Scope
- KHÔNG implement review_state table trong P3C1. Future P3D/P3E hook.
- KHÔNG hack read/unread vào comment body.
- KHÔNG dùng JSONB metadata cho hot-path read state.
- Column/table riêng khi implement.
4. PG First / Native / Driven
| Nhu cầu | PG primitive | Function mới? |
|---|---|---|
| Timestamp | DEFAULT now() + columns | Không |
| Sắp xếp | ORDER BY + index | Không |
| Actor identity | Session GUC | Không |
| Unread inbox | WHERE created_at > watermark + index | Không |
| Per-actor state | Table UNIQUE(draft_id, reviewer_ref) | Chỉ DDL |
Không overbuild workflow engine. Query SQL + index đủ. Function chỉ cho business logic.
Report Requirements
- ✓ draft/comment có created_at used
- ✓ fn_iu_comment candidates ORDER BY created_at DESC
- ☐ Auto-signature GUC = deferred hook
- ☐ Per-actor review state = deferred hook (unit_edit_review_state)
§0.1 UX State Foundation Notes rev2 | 2026-05-07 | Per-actor watermark model