KB-22DB

CHỈ THỊ KHẨN CẤP AGENT — Đếm đúng + PG TRIGGER sinh ID

5 min read Revision 1

CHỈ THỊ KHẨN CẤP — AGENT ĐỌC NGAY

Huyen chỉ đạo trực tiếp. Ưu tiên tuyệt đối. Đọc TRƯỚC KHI làm tiếp bất kỳ việc gì. search_knowledge("urgent s112 count fix") để đọc thêm context.


TÌNH HÌNH: ĐANG ĐẾM SAI, ĐANG LÀM SAI

Hệ thống đếm changelog (798) + system_issues (31) vào tổng nguyên tử. Chúng KHÔNG PHẢI nguyên tử (Điều 0 Hiến pháp: nguyên tử = entity có PREFIX-NNN). changelog và system_issues = LOG RECORDS → KHÔNG ĐẾM.

Claude Desktop ĐÃ đánh dấu trong Directus:

  • CAT-016 (changelog): status → 'log'
  • CAT-017 (system_issues): status → 'log'

VIỆC AGENT PHẢI LÀM (theo thứ tự):

BƯỚC 1: SỬA PG FUNCTION — CHỈ ĐẾM NGUYÊN TỬ

Sửa refresh_registry_counts() trên VPS:

  • Chỉ đếm meta_catalog entries có status IN ('active','published')
  • LOẠI status = 'log' (changelog, system_issues)
  • LOẠI CAT-ALL, CAT-999 (tổng hợp, không phải nguyên tử)
  • Kết quả: chỉ 16 loại nguyên tử được đếm

v_registry_summary cũng chỉ tính từ 16 loại này.

BƯỚC 2: TẠO PG TRIGGER SINH ID TỰ ĐỘNG (QUAN TRỌNG NHẤT)

Lỗ hổng hiện tại: Directus Flow gán PREFIX-NNN SAU INSERT → Flow fail → record không có code → orphan. Giải pháp: PostgreSQL TRIGGER BEFORE INSERT → gán code TRONG transaction → KHÔNG THỂ thiếu.

Cho MỖI collection nguyên tử (16 collections), tạo:

-- 1. Sequence (khởi tạo đúng số tiếp theo)
CREATE SEQUENCE IF NOT EXISTS seq_<collection> START <max_existing + 1>;

-- 2. Function sinh code
CREATE OR REPLACE FUNCTION gen_code_<collection>() RETURNS TRIGGER AS $$
BEGIN
  IF NEW.code IS NULL OR NEW.code = '' THEN
    NEW.code := '<PREFIX>-' || LPAD(nextval('seq_<collection>')::text, 3, '0');
  END IF;
  RETURN NEW;
END; $$ LANGUAGE plpgsql;

-- 3. Trigger BEFORE INSERT
CREATE TRIGGER trg_auto_code_<collection>
  BEFORE INSERT ON <collection>
  FOR EACH ROW EXECUTE FUNCTION gen_code_<collection>();

Danh sách 16 collections + prefix:

Collection Prefix Sequence bắt đầu sau
meta_catalog CAT SELECT max(substring(code,5)::int)+1 FROM meta_catalog
table_registry TBL tương tự
modules M tương tự
workflows WF tương tự
workflow_steps ND 4 chữ số (LPAD 4)
workflow_change_requests WCR tương tự
dot_tools DOT tương tự
ui_pages PG tương tự
collection_registry COL tương tự
tasks TSK tương tự
agents AGT tương tự
checkpoint_types CP tương tự
checkpoint_sets CPS tương tự
entity_dependencies DEP 4 chữ số
table_proposals TP tương tự
checkpoint_instances CPI 4 chữ số

Tạo DOT script: dot-pg-triggers-ensure (idempotent, CREATE OR REPLACE).

SAU KHI trigger hoạt động → 13 Directus AUTO-ID Flows CÓ THỂ TẮT (PG làm tốt hơn). Nhưng CHƯA TẮT trong mission này — chỉ tạo trigger + verify song song.

BƯỚC 3: FIX ORPHAN CŨ

Sau khi trigger hoạt động, chạy UPDATE gán code cho records cũ thiếu code:

-- Ví dụ cho dot_tools
UPDATE dot_tools 
SET code = 'DOT-' || LPAD(nextval('seq_dot_tools')::text, 3, '0')
WHERE code IS NULL OR code = '';

Làm cho TẤT CẢ 16 collections. Sau đó orphan = 0.

BƯỚC 4: CROSS-CHECK 3 NGUỒN

Sau khi fix xong, đối chiếu TỪNG TYPE:

Type PG count(*) Directus API count VPS files (Model B) Khớp?

Với Model A: PG = Directus API → OK. Với Model B: PG = Directus API, nhưng có thể ≠ VPS files (cần sync).

BƯỚC 5: MŨ 2

CI GREEN → merge → deploy → verify production. Verify: Header ≈ 700 nguyên tử (không phải 1500+). Orphan ≈ 0.


SCOPE LOCK

CHỈ ĐƯỢC SỬA:

  • PG function + triggers + sequences (trên VPS qua SSH)
  • dot/bin/dot-pg-triggers-ensure (NEW DOT script)
  • web/pages/knowledge/registries/index.vue (NẾU CẦN filter status='log')
  • KHÔNG sửa navigation, layout, components khác

KẾT QUẢ MONG ĐỢI

  • Tổng nguyên tử ≈ 700 (16 loại thực sự, không tính log)
  • Mồ côi = 0 (tất cả records có code nhờ PG TRIGGER + fix cũ)
  • Cross-check 3 nguồn KHỚP
  • MỌI record INSERT từ nay → TỰ ĐỘNG có PREFIX-NNN (PG đảm bảo)