전체 문서
이 페이지 목차
Finding·승인·알림·운영 PostgreSQL 객체
finding/evidence/retest, intercept, archive, notification, log와 side-question 객체를 전수 참조한다.
기준 · core
db/schema.sql은 PostgreSQL 49개 table·최종 column 합집합 520개·명시 index 97개·function 4개·trigger 22개다. startup 보조 ledgerllm_records와llm_usage가 2개 table·31개 column·5개 index를 더해 선언 총계는 51개 table·551개 column·102개 index다.Ensure*Table실패는 로그 후 계속되므로 보조 ledger 존재는 core startup 보장이 아니다. Traffic은 별도 SQLite 3개 일반 table·FTS5 virtual table 1개·index 6개다. 아래 DDL은 고정 source revision의 선언이며 실제 운영 DB 적용 상태는 관찰하지 않았다.
객체 색인
| 객체 | 저장소 | 목적 |
|---|---|---|
settings |
PostgreSQL | settings 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다. |
task_archives |
PostgreSQL | task archive/restore/delete background job 상태와 package metadata를 저장한다. |
intercept_rules |
PostgreSQL | intercept_rules 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다. |
intercept_pending |
PostgreSQL | tool 승인 요청과 결정/audit 상태를 저장한다. |
findings |
PostgreSQL | 조회·편집·보고용 finding row를 graph finding node와 함께 유지한다. |
finding_retests |
PostgreSQL | finding_retests 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다. |
traffic_evidence_snapshots |
PostgreSQL | 캡처 exchange의 request/response metadata와 body hash를 finding용 snapshot으로 고정한다. |
finding_traffic_bindings |
PostgreSQL | finding과 snapshot의 순서·role·설명을 연결한다. |
server_logs |
PostgreSQL | server_logs 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다. |
side_question_sessions |
PostgreSQL | side_question_sessions 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다. |
side_question_requests |
PostgreSQL | side_question_requests 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다. |
asset_intercept_rules |
PostgreSQL | asset_intercept_rules 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다. |
task_intercept_rules |
PostgreSQL | task_intercept_rules 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다. |
notification_channels |
PostgreSQL | notification_channels 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다. |
notification_events |
PostgreSQL | notification_events 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다. |
notification_deliveries |
PostgreSQL | channel별 전달 시도, lease, retry, 오류를 저장한다. |
settings
settings · 관계
이 대상을 사용하는 기능·모듈·계약 · 2개
- 계약 사용 · Reporter, retest, export · Server.seedFindingRetester: read/write FROM/INSERT · db-pg-access-settings-f47899da10
- 계약 사용 · Manager 구성과 종료 · DB.GetSetting: read FROM; DB.SetSetting: write INSERT · db-pg-access-settings-244498fc06 · db-pg-access-settings-18f2c4aada
settings 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
의미·소비·운영 경계
settings 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
task_archives
task_archives · 관계
이 대상을 사용하는 기능·모듈·계약 · 4개
- 계약 사용 · 트래픽에서 증거 snapshot까지 · LockTaskEvidenceTx: read FROM · db-pg-access-task-archives-46a518e5eb
- 계약 사용 · 삭제·archive·보존 경계 · DB.AppendTaskArchiveWarning: write UPDATE; DB.ClaimTaskArchiveJob: read/write FROM/UPDATE; DB.FailTaskArchiveJob: write UPDATE; DB.GetTaskArchive: read FROM; DB.GetTaskArchiveByTask: read FROM; DB.IsTaskArchiveRestored: read FROM; DB.ListTaskArchives: read FROM; DB.QueueTaskArchive: read/write FROM/INSERT/JOIN; DB.QueueTaskArchiveDelete: read/write FROM/UPDATE; DB.QueueTaskArchiveRestore: write UPDATE; DB.RecoverTaskArchiveJobs: write UPDATE; DB.TaskArchiveBlockers: read JOIN; DB.UpdateTaskArchiveProgress: write UPDATE; DB.ArchivedAggregateStats: read FROM; DB.CompleteTaskArchive: read/write FROM/UPDATE; DB.CompleteTaskArchiveRestore: write DELETE; DB.DeleteTaskArchiveStub: read FROM; DB.restoreTaskArchive: read/write FROM/UPDATE · db-pg-access-task-archives-1d4aedee48 · db-pg-access-task-archives-bcd920f8ce · db-pg-access-task-archives-a72bb87396 · db-pg-access-task-archives-bb4a4fa0cb · db-pg-access-task-archives-8db7402369 · db-pg-access-task-archives-b349280073 · db-pg-access-task-archives-3e2f0aaac8 · db-pg-access-task-archives-bf408c8aa2 · db-pg-access-task-archives-ac239c3cfb · db-pg-access-task-archives-0e94b8026f · db-pg-access-task-archives-fb5a0b1c08 · db-pg-access-task-archives-aa7060d4f8 · db-pg-access-task-archives-3512ba58cb · db-pg-access-task-archives-55a2c514f5 · db-pg-access-task-archives-4a9623c4f7 · db-pg-access-task-archives-73da1ef42e · db-pg-access-task-archives-c1df948da6 · db-pg-access-task-archives-790681674e
- 계약 사용 · set_updated_at() · write; columns updated_at; BEFORE UPDATE ROW trigger `trg_task_archives_upd`; provenance: trigger row/table declaration · db-ddl-trigger-trg-task-archives-upd
- 의존 / 실행 · trg_task_archives_upd · fire table `task_archives` · db-ddl-trigger-trg-task-archives-upd
task archive/restore/delete background job 상태와 package metadata를 저장한다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS task_archives (
id BIGSERIAL PRIMARY KEY,
task_id BIGINT NOT NULL UNIQUE REFERENCES tasks(id) ON DELETE CASCADE,
state TEXT NOT NULL DEFAULT 'archive_queued' CHECK (state IN (
'archive_queued','archiving','archive_failed','ready',
'restore_queued','restoring','restore_failed',
'delete_queued','deleting','delete_failed'
)),
phase TEXT NOT NULL DEFAULT 'queued',
progress INTEGER NOT NULL DEFAULT 0 CHECK (progress BETWEEN 0 AND 100),
error TEXT NOT NULL DEFAULT '',
warnings JSONB NOT NULL DEFAULT '[]',
format_version INTEGER NOT NULL DEFAULT 2,
archive_path TEXT NOT NULL DEFAULT '',
sha256 TEXT NOT NULL DEFAULT '',
original_size BIGINT NOT NULL DEFAULT 0,
compressed_size BIGINT NOT NULL DEFAULT 0,
task_name TEXT NOT NULL DEFAULT '',
task_description TEXT NOT NULL DEFAULT '',
task_goal TEXT NOT NULL DEFAULT '',
original_status TEXT NOT NULL DEFAULT '',
category_id_snapshot BIGINT,
category_name_snapshot TEXT NOT NULL DEFAULT '',
source_task_ids BIGINT[] NOT NULL DEFAULT '{}',
remaining_timeout_seconds BIGINT NOT NULL DEFAULT 0,
data_counts JSONB NOT NULL DEFAULT '{}',
aggregate_stats JSONB NOT NULL DEFAULT '{}',
archived_at TIMESTAMPTZ,
requested_at TIMESTAMPTZ NOT NULL DEFAULT now(),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
후속 변경·제약
ALTER TABLE task_archives ALTER COLUMN format_version SET DEFAULT 2;
format_version ALTER는 이미 저장된 archive row를 2로 backfill하지 않고 이후 default INSERT에만 적용한다. migration 경계
인덱스
CREATE INDEX IF NOT EXISTS idx_task_archives_state ON task_archives(state, requested_at, id);CREATE INDEX IF NOT EXISTS idx_task_archives_archived ON task_archives(archived_at DESC, id DESC);CREATE INDEX IF NOT EXISTS idx_task_archives_sources ON task_archives USING GIN(source_task_ids);
의미·소비·운영 경계
task_archives 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
intercept_rules
intercept_rules · 관계
이 대상을 사용하는 기능·모듈·계약 · 3개
- 계약 사용 · Tool intercept·승인·실행 trace · DB.seedDefaultInterceptRules: write INSERT; DB.seedDefaultInterceptRulesV2: write INSERT; DB.seedDefaultInterceptRulesV3: read/write FROM/INSERT; DB.CreateInterceptRule: write INSERT; DB.DeleteInterceptRule: write DELETE; DB.ListAllIntercepts: read JOIN; DB.ListInterceptRules: read FROM; DB.ListTaskIntercepts: read JOIN; DB.ToggleInterceptRule: write UPDATE; DB.UpdateInterceptRule: write UPDATE; DB.GetInterceptDetail: read JOIN · db-pg-access-intercept-rules-e8c17cb440 · db-pg-access-intercept-rules-0df7705bea · db-pg-access-intercept-rules-f298b1fcb4 · db-pg-access-intercept-rules-a79fbc6429 · db-pg-access-intercept-rules-accf9f668f · db-pg-access-intercept-rules-c7987f8723 · db-pg-access-intercept-rules-4d227a0c05 · db-pg-access-intercept-rules-b7dff7dc43 · db-pg-access-intercept-rules-e0526c89b1 · db-pg-access-intercept-rules-4a0a98fe63 · db-pg-access-intercept-rules-b4f161c3ec
- 계약 사용 · set_updated_at() · write; columns updated_at; BEFORE UPDATE ROW trigger `trg_intercept_rules_upd`; provenance: trigger row/table declaration · db-ddl-trigger-trg-intercept-rules-upd
- 의존 / 실행 · trg_intercept_rules_upd · fire table `intercept_rules` · db-ddl-trigger-trg-intercept-rules-upd
intercept_rules 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS intercept_rules (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
enabled BOOLEAN NOT NULL DEFAULT true,
priority INTEGER NOT NULL DEFAULT 0,
match_target TEXT NOT NULL CHECK (match_target IN ('tool_name', 'tool_input')),
match_type TEXT NOT NULL CHECK (match_type IN ('string', 'regex')),
pattern TEXT NOT NULL,
action TEXT NOT NULL CHECK (action IN ('allow', 'deny', 'ask')),
message TEXT NOT NULL DEFAULT '',
timeout_enabled BOOLEAN NOT NULL DEFAULT true,
timeout_seconds INTEGER NOT NULL DEFAULT 60,
timeout_action TEXT NOT NULL DEFAULT 'deny',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
의미·소비·운영 경계
intercept_rules 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
intercept_pending
intercept_pending · 관계
이 대상을 사용하는 기능·모듈·계약 · 2개
- 계약 사용 · 삭제·archive·보존 경계 · DB.snapshotTaskArchive: read FROM; DB.CompleteTaskArchive: write DELETE; restoreInterceptRows: write INSERT · db-pg-access-intercept-pending-82c3ebdd3e · db-pg-access-intercept-pending-9b2baa67ed · db-pg-access-intercept-pending-5fc302ab64
- 계약 사용 · Tool intercept·승인·실행 trace · DB.CreateDecidedIntercept: write INSERT; DB.CreateInterceptPending: write INSERT; DB.DecideInterceptPending: write UPDATE; DB.GetInterceptPending: read FROM; DB.ListAllIntercepts: read FROM; DB.ListPendingIntercepts: read FROM; DB.ListTaskIntercepts: read FROM; DB.listInterceptsPage: read FROM; DB.CompleteIntercept: write UPDATE; DB.GetInterceptDetail: read FROM; DB.ResolveIntercept: write UPDATE · db-pg-access-intercept-pending-bc8634fbe9 · db-pg-access-intercept-pending-5c1782648d · db-pg-access-intercept-pending-081cfd8d26 · db-pg-access-intercept-pending-0d5fe02916 · db-pg-access-intercept-pending-5320363648 · db-pg-access-intercept-pending-601e88ff73 · db-pg-access-intercept-pending-b596c420be · db-pg-access-intercept-pending-1e9d6804d6 · db-pg-access-intercept-pending-ea60f9dc96 · db-pg-access-intercept-pending-34a458a45b · db-pg-access-intercept-pending-d03eb247c8
tool 승인 요청과 결정/audit 상태를 저장한다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS intercept_pending (
id BIGSERIAL PRIMARY KEY,
rule_id BIGINT REFERENCES intercept_rules(id) ON DELETE SET NULL,
conversation_id BIGINT REFERENCES conversations(id) ON DELETE CASCADE,
task_id TEXT,
agent_name TEXT NOT NULL DEFAULT '',
tool_name TEXT NOT NULL,
tool_input JSONB NOT NULL DEFAULT '{}',
status TEXT NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending', 'allowed', 'denied', 'timeout')),
-- 判定理由:规则命中时为规则 message;LLM 兜底判定时为模型给的简短理由(前缀 [模型])。
reason TEXT NOT NULL DEFAULT '',
decided_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
후속 변경·제약
ALTER TABLE intercept_pending ADD COLUMN IF NOT EXISTS reason TEXT NOT NULL DEFAULT '';ALTER TABLE intercept_pending ADD COLUMN IF NOT EXISTS audit JSONB;ALTER TABLE intercept_pending ADD COLUMN IF NOT EXISTS decision_source TEXT NOT NULL DEFAULT '';
Column 추가 뒤 startup은 decision_source=''인 row를 매번 CASE update한다. rule_id non-null은 rule, reason이 [模型]로 시작하면 model, 나머지는 unknown이므로 빈 값을 의도적으로 저장해도 다음 startup에 재분류된다. migration 경계
인덱스
CREATE INDEX IF NOT EXISTS idx_intercept_pending_status ON intercept_pending(status, created_at DESC);CREATE INDEX IF NOT EXISTS idx_intercept_pending_task ON intercept_pending(task_id, created_at DESC);
의미·소비·운영 경계
intercept_pending 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
findings
findings · 관계
이 대상을 사용하는 기능·모듈·계약 · 4개
- 계약 사용 · Reporter, retest, export · DB.SearchChatMentionsPage: read FROM; DB.TaskListMetricsAll: read FROM; ExplorationStore.CancelIntent: write DELETE; DB.buildFindingAssetTree: read FROM; DB.CreateFindingRetest: read FROM; DB.FinishFindingRetest: read FROM; DB.AddFinding: write INSERT; DB.DeleteFinding: write DELETE; DB.DeleteFindingsByTask: write DELETE; DB.FindingMetaByNodeID: read FROM; DB.FindingStats: read FROM; DB.GetFinding: read FROM; DB.ListFindingGroups: read FROM; DB.ListFindings: read FROM; DB.ListFindingsForExport: read FROM; DB.ListFindingsPage: read FROM; DB.SetFindingStatus: write UPDATE; ExplorationStore.AddFindingFollowUpIntent: read FROM; SetFindingStatusTx: read/write FROM/UPDATE; DB.DeleteTaskCascadePrepared: write DELETE; Store.StageFindingsExport: read FROM · db-pg-access-findings-f291f39a91 · db-pg-access-findings-3260bd8afb · db-pg-access-findings-03a3b0fd14 · db-pg-access-findings-1448180e23 · db-pg-access-findings-e489fd8709 · db-pg-access-findings-bc19beb437 · db-pg-access-findings-b70464a687 · db-pg-access-findings-a128b54e11 · db-pg-access-findings-57d61c0f23 · db-pg-access-findings-fdeea392af · db-pg-access-findings-4ed6d9e96d · db-pg-access-findings-800bee206e · db-pg-access-findings-eb44c224ac · db-pg-access-findings-2f5cbab72c · db-pg-access-findings-cf57444365 · db-pg-access-findings-314660f4d9 · db-pg-access-findings-26168954bb · db-pg-access-findings-3beb305938 · db-pg-access-findings-c7176e8663 · db-pg-access-findings-d36ee17ecc · db-pg-access-findings-ef093855e8
- 계약 사용 · Finding writeback transaction · RecordFindingTx: write INSERT; DB.setFindingCol: write UPDATE · db-pg-access-findings-7140513ea2 · db-pg-access-findings-c57898f68d
- 계약 사용 · 트래픽에서 증거 snapshot까지 · DB.FindingIDByNodeID: read FROM; DB.SetFindingReportVersionByNodeID: read/write FROM/UPDATE; ExplorationStore.PopulateFindingTrafficIDs: read FROM; FindingTrafficTx: read FROM; LockFindingEvidenceTx: read FROM; bumpEvidenceVersionTx: write UPDATE · db-pg-access-findings-0fed5e5c52 · db-pg-access-findings-4d5f2daace · db-pg-access-findings-c8b270380f · db-pg-access-findings-87401ddbde · db-pg-access-findings-6db51be95d · db-pg-access-findings-010d96436e
- 계약 사용 · 삭제·archive·보존 경계 · restoreFindingTrafficTx: read FROM; DB.snapshotTaskArchive: read FROM/JOIN; archiveAssetIDsQuery: read FROM; taskArchiveAggregates: read FROM; DB.CompleteTaskArchive: write DELETE; insertArchiveRows: write INSERT · db-pg-access-findings-7071b5d232 · db-pg-access-findings-a03f5a91cf · db-pg-access-findings-b9b653ba29 · db-pg-access-findings-76d247fd15 · db-pg-access-findings-076101d0cc · db-pg-access-findings-6741a035f8
조회·편집·보고용 finding row를 graph finding node와 함께 유지한다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS findings (
id BIGSERIAL PRIMARY KEY,
task_id BIGINT REFERENCES tasks(id) ON DELETE SET NULL,
node_id BIGINT REFERENCES exploration_nodes(id) ON DELETE SET NULL,
vulnclass TEXT NOT NULL DEFAULT '',
-- 漏洞名称(可读标题);为空时前端回退展示 vulnclass。severity 取值:
-- critical 严重 / high 高 / medium 中 / low 低(不加 CHECK,与 status 一致由 server 白名单校验)。
name TEXT NOT NULL DEFAULT '',
severity TEXT NOT NULL DEFAULT '',
summary TEXT NOT NULL DEFAULT '',
evidence TEXT NOT NULL DEFAULT '',
worker TEXT NOT NULL DEFAULT '',
asset_ids JSONB NOT NULL DEFAULT '[]',
-- 处置状态:pending 待处理 / in_progress 处理中 / confirmed 已确认 / resolved 已处理 / fixed 已修复 /
-- false_positive 误报 / ignored 忽略 / duplicate 重复 / risk_accepted 风险接受。
-- 取值不加 CHECK:旧库靠下面的 ALTER 补列,CHECK 无法回填,统一由 server 侧白名单校验。
status TEXT NOT NULL DEFAULT 'pending',
-- 漏洞详细报告(Markdown);默认空,仅详情页读取/展示,不进列表接口以免 payload 膨胀。
report TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
후속 변경·제약
ALTER TABLE findings ADD COLUMN IF NOT EXISTS status TEXT NOT NULL DEFAULT 'pending';ALTER TABLE findings ADD COLUMN IF NOT EXISTS name TEXT NOT NULL DEFAULT '';ALTER TABLE findings ADD COLUMN IF NOT EXISTS report TEXT NOT NULL DEFAULT '';ALTER TABLE findings ADD COLUMN IF NOT EXISTS evidence_version BIGINT NOT NULL DEFAULT 0;ALTER TABLE findings ADD COLUMN IF NOT EXISTS report_evidence_version BIGINT NOT NULL DEFAULT 0;
인덱스
CREATE INDEX IF NOT EXISTS idx_findings_task ON findings(task_id, created_at DESC);CREATE INDEX IF NOT EXISTS idx_findings_time ON findings(created_at DESC);CREATE INDEX IF NOT EXISTS idx_findings_status ON findings(status, created_at DESC);CREATE INDEX IF NOT EXISTS idx_findings_asset_ids ON findings USING GIN(asset_ids jsonb_path_ops);
의미·소비·운영 경계
findings 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
finding_retests
finding_retests · 관계
이 대상을 사용하는 기능·모듈·계약 · 2개
- 계약 사용 · Reporter, retest, export · DB.CreateFindingRetest: read/write FROM/INSERT; DB.FailPendingRetestForConversation: write UPDATE; DB.FindingRetestForConversation: read FROM; DB.FinishFindingRetest: read/write FROM/UPDATE; DB.ListActiveFindingRetests: read FROM; DB.ListFindingRetests: read FROM; DB.RecordFindingRetestResult: write UPDATE; DB.RecoverFindingRetests: write UPDATE; DB.StartFindingRetest: write UPDATE · db-pg-access-finding-retests-298bb9a6ef · db-pg-access-finding-retests-a5efabf7fd · db-pg-access-finding-retests-9dbf54a7a4 · db-pg-access-finding-retests-fe65aab8c2 · db-pg-access-finding-retests-bd3b2be0d1 · db-pg-access-finding-retests-393582fb9c · db-pg-access-finding-retests-188dbd8971 · db-pg-access-finding-retests-06180af265 · db-pg-access-finding-retests-c2e0c8aed6
- 계약 사용 · stop_deleted_conversation_retest() · write; columns status, error, finished_at; conversation_id=OLD.id AND status pending/running; provenance: function body DDL · db-ddl-function-stop-deleted-conversation-retest
finding_retests 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS finding_retests (
id BIGSERIAL PRIMARY KEY,
finding_id BIGINT NOT NULL REFERENCES findings(id) ON DELETE CASCADE,
conversation_id BIGINT UNIQUE REFERENCES conversations(id) ON DELETE SET NULL,
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','running','completed','failed','stopped')),
verdict TEXT NOT NULL DEFAULT '' CHECK (verdict IN ('','reproduced','fixed','inconclusive')),
notes TEXT NOT NULL DEFAULT '',
snapshot JSONB NOT NULL,
summary TEXT NOT NULL DEFAULT '',
evidence TEXT NOT NULL DEFAULT '',
error TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
started_at TIMESTAMPTZ,
finished_at TIMESTAMPTZ
);
인덱스
CREATE INDEX IF NOT EXISTS idx_finding_retests_history ON finding_retests(finding_id, id DESC);CREATE UNIQUE INDEX IF NOT EXISTS idx_finding_retests_active ON finding_retests(finding_id) WHERE status IN ('pending','running');
의미·소비·운영 경계
finding_retests 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
traffic_evidence_snapshots
traffic_evidence_snapshots · 관계
이 대상을 사용하는 기능·모듈·계약 · 2개
- 계약 사용 · 트래픽에서 증거 snapshot까지 · AddFindingTrafficTx: write UPDATE; FindingTrafficTx: read JOIN; InsertEvidenceSnapshotTx: write INSERT; Store.Collect: read/write DELETE/FROM/UPDATE · db-pg-access-traffic-evidence-snapshots-440ef2360f · db-pg-access-traffic-evidence-snapshots-52431e10a6 · db-pg-access-traffic-evidence-snapshots-73a114ef04 · db-pg-access-traffic-evidence-snapshots-364a62b0c1
- 계약 사용 · 삭제·archive·보존 경계 · restoreFindingTrafficTx: write UPDATE; DB.snapshotTaskArchive: read FROM · db-pg-access-traffic-evidence-snapshots-7c615da87f · db-pg-access-traffic-evidence-snapshots-282a93d25a
캡처 exchange의 request/response metadata와 body hash를 finding용 snapshot으로 고정한다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS traffic_evidence_snapshots (
id TEXT PRIMARY KEY,
source_traffic_id TEXT NOT NULL,
captured_at BIGINT NOT NULL,
url TEXT NOT NULL,
method TEXT NOT NULL,
status INTEGER NOT NULL,
content_type TEXT NOT NULL DEFAULT '',
req_head TEXT NOT NULL,
resp_head TEXT NOT NULL,
req_hash TEXT NOT NULL,
resp_hash TEXT NOT NULL,
req_len BIGINT NOT NULL,
resp_len BIGINT NOT NULL,
unreferenced_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
의미·소비·운영 경계
traffic_evidence_snapshots 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
finding_traffic_bindings
finding_traffic_bindings · 관계
이 대상을 사용하는 기능·모듈·계약 · 3개
- 계약 사용 · 트래픽에서 증거 snapshot까지 · AddFindingTrafficTx: read/write FROM/INSERT; DB.EditFindingTraffic: write DELETE/UPDATE; ExplorationStore.PopulateFindingTrafficIDs: read FROM; FindingTrafficTx: read FROM; DB.FindingMetaByNodeID: read FROM; DB.GetFinding: read FROM; DB.ListFindings: read FROM; Store.Collect: read FROM · db-pg-access-finding-traffic-bindings-5728bd167b · db-pg-access-finding-traffic-bindings-e927eacd9e · db-pg-access-finding-traffic-bindings-b832923bf8 · db-pg-access-finding-traffic-bindings-57db4cbc9b · db-pg-access-finding-traffic-bindings-019d6081a9 · db-pg-access-finding-traffic-bindings-4a01758636 · db-pg-access-finding-traffic-bindings-ec3301eeff · db-pg-access-finding-traffic-bindings-b3482f8a30
- 계약 사용 · 삭제·archive·보존 경계 · restoreFindingTrafficTx: read/write FROM/INSERT; DB.snapshotTaskArchive: read FROM · db-pg-access-finding-traffic-bindings-abe00c0cea · db-pg-access-finding-traffic-bindings-b08bb2bd09
- 계약 사용 · PostgreSQL table-level constraint matrix · fresh table-level constraint contract for `finding_traffic_bindings` · db-table-constraints
finding과 snapshot의 순서·role·설명을 연결한다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS finding_traffic_bindings (
id BIGSERIAL PRIMARY KEY,
finding_id BIGINT NOT NULL REFERENCES findings(id) ON DELETE CASCADE,
snapshot_id TEXT NOT NULL REFERENCES traffic_evidence_snapshots(id),
role TEXT NOT NULL DEFAULT 'supporting',
note TEXT NOT NULL DEFAULT '',
position INTEGER NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE(finding_id, snapshot_id)
);
인덱스
CREATE INDEX IF NOT EXISTS idx_finding_traffic_order ON finding_traffic_bindings(finding_id, position, id);CREATE INDEX IF NOT EXISTS idx_finding_traffic_snapshot ON finding_traffic_bindings(snapshot_id);
의미·소비·운영 경계
finding_traffic_bindings 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
server_logs
server_logs · 관계
이 대상을 사용하는 기능·모듈·계약 · 1개
- 계약 사용 · Background loop와 완료 신호 · DB.InsertLog: write INSERT; DB.ListLogsBefore: read FROM; DB.RecentLogs: read FROM · db-pg-access-server-logs-e65f653e56 · db-pg-access-server-logs-d11fca0e4d · db-pg-access-server-logs-fb5556b4c7
server_logs 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS server_logs (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
level TEXT NOT NULL DEFAULT 'info',
tag TEXT NOT NULL DEFAULT '',
text TEXT NOT NULL DEFAULT ''
);
인덱스
CREATE INDEX IF NOT EXISTS idx_server_logs_id ON server_logs(id DESC);
의미·소비·운영 경계
server_logs 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
side_question_sessions
side_question_sessions · 관계
이 대상을 사용하는 기능·모듈·계약 · 3개
- 계약 사용 · Side Question(/btw) · ExplorationStore.CancelIntent: write DELETE; ExplorationStore.SoftDeleteIntent: write DELETE; DB.ClearSideHistory: write UPDATE; DB.ExistingSideRequest: read FROM; DB.SaveSideMemory: write UPDATE; DB.SaveSideSnapshot: write INSERT; DB.SideMemory: read FROM; DB.SideSnapshot: read FROM; DB.StartSideRequest: read FROM; DB.UpdateSideRequest: read FROM · db-pg-access-side-question-sessions-beefdcdbfd · db-pg-access-side-question-sessions-27a4bb437d · db-pg-access-side-question-sessions-a8da5d3ae6 · db-pg-access-side-question-sessions-4ea67bc037 · db-pg-access-side-question-sessions-97967a6843 · db-pg-access-side-question-sessions-cde2679568 · db-pg-access-side-question-sessions-6149530f35 · db-pg-access-side-question-sessions-957b1e871e · db-pg-access-side-question-sessions-93e8d0b365 · db-pg-access-side-question-sessions-1e41caa46d
- 계약 사용 · 삭제·archive·보존 경계 · DB.snapshotTaskArchive: read FROM/JOIN; DB.CompleteTaskArchive: write DELETE; insertArchiveRows: write INSERT · db-pg-access-side-question-sessions-8801a31633 · db-pg-access-side-question-sessions-d5127dfa7f · db-pg-access-side-question-sessions-e1e83729ca
- 계약 사용 · PostgreSQL table-level constraint matrix · fresh table-level constraint contract for `side_question_sessions` · db-table-constraints
side_question_sessions 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS side_question_sessions (
session_key TEXT PRIMARY KEY,
conversation_id BIGINT REFERENCES conversations(id) ON DELETE CASCADE,
task_id BIGINT REFERENCES tasks(id) ON DELETE CASCADE,
exploration_id BIGINT REFERENCES explorations(id) ON DELETE CASCADE,
intent_id BIGINT REFERENCES exploration_nodes(id) ON DELETE CASCADE,
run_id BIGINT NOT NULL,
version BIGINT NOT NULL,
snapshot JSONB NOT NULL,
generation BIGINT NOT NULL DEFAULT 0,
CHECK ((conversation_id IS NOT NULL AND task_id IS NULL AND exploration_id IS NULL AND intent_id IS NULL)
OR (conversation_id IS NULL AND task_id IS NOT NULL AND exploration_id IS NOT NULL))
);
후속 변경·제약
ALTER TABLE side_question_sessions ADD COLUMN IF NOT EXISTS memory JSONB NOT NULL DEFAULT '{}';
인덱스
CREATE INDEX IF NOT EXISTS idx_side_sessions_conv ON side_question_sessions(conversation_id);CREATE INDEX IF NOT EXISTS idx_side_sessions_task ON side_question_sessions(task_id);CREATE INDEX IF NOT EXISTS idx_side_sessions_exp ON side_question_sessions(exploration_id);CREATE INDEX IF NOT EXISTS idx_side_sessions_intent ON side_question_sessions(intent_id);
의미·소비·운영 경계
side_question_sessions 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
side_question_requests
side_question_requests · 관계
이 대상을 사용하는 기능·모듈·계약 · 3개
- 계약 사용 · Side Question(/btw) · DB.ClearSideHistory: write DELETE; DB.CurrentSideRequest: read FROM; DB.ExistingSideRequest: read FROM; DB.InterruptSideRequests: write UPDATE; DB.SaveSideMemory: read FROM; DB.SideHistory: read FROM; DB.SideMemory: read JOIN; DB.SideReplay: read FROM; DB.SideReplayPage: read FROM; DB.SideRequest: read FROM; DB.StartSideRequest: read/write FROM/INSERT; DB.UpdateSideRequest: write UPDATE · db-pg-access-side-question-requests-a5f44ede43 · db-pg-access-side-question-requests-e1a9f07799 · db-pg-access-side-question-requests-33fa928102 · db-pg-access-side-question-requests-9bb182569a · db-pg-access-side-question-requests-90bbb7e005 · db-pg-access-side-question-requests-b5400e3847 · db-pg-access-side-question-requests-9556cf1f3a · db-pg-access-side-question-requests-827040a9e8 · db-pg-access-side-question-requests-edb55d3298 · db-pg-access-side-question-requests-6e2bc0595c · db-pg-access-side-question-requests-dcffa93c98 · db-pg-access-side-question-requests-1be6e19fcd
- 계약 사용 · 삭제·archive·보존 경계 · DB.snapshotTaskArchive: read FROM; insertArchiveRows: write INSERT · db-pg-access-side-question-requests-62486f492d · db-pg-access-side-question-requests-2313c7c779
- 계약 사용 · PostgreSQL table-level constraint matrix · fresh table-level constraint contract for `side_question_requests` · db-table-constraints
side_question_requests 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS side_question_requests (
id TEXT PRIMARY KEY,
ordinal BIGSERIAL UNIQUE,
session_key TEXT NOT NULL REFERENCES side_question_sessions(session_key) ON DELETE CASCADE,
generation BIGINT NOT NULL,
client_id TEXT NOT NULL,
question TEXT NOT NULL,
answer TEXT NOT NULL DEFAULT '',
status TEXT NOT NULL CHECK(status IN ('running','completed','failed','cancelled','interrupted')),
error TEXT NOT NULL DEFAULT '',
model JSONB NOT NULL,
snapshot_at TIMESTAMPTZ NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
sequence BIGINT NOT NULL DEFAULT 0,
usage JSONB NOT NULL DEFAULT '{}',
UNIQUE(session_key,generation,client_id)
);
후속 변경·제약
ALTER TABLE side_question_requests ADD COLUMN IF NOT EXISTS context_info JSONB NOT NULL DEFAULT '{}';
인덱스
CREATE UNIQUE INDEX IF NOT EXISTS idx_side_request_running ON side_question_requests(session_key) WHERE status='running';CREATE INDEX IF NOT EXISTS idx_side_requests_history ON side_question_requests(session_key,ordinal DESC);
의미·소비·운영 경계
side_question_requests 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
asset_intercept_rules
asset_intercept_rules · 관계
이 대상을 사용하는 기능·모듈·계약 · 3개
- 계약 사용 · Tool intercept·승인·실행 trace · DB.CreateAssetInterceptRule: write INSERT; DB.DeleteAssetInterceptRule: write DELETE; DB.ListAssetInterceptRules: read FROM; DB.ToggleAssetInterceptRule: write UPDATE; DB.UpdateAssetInterceptRule: write UPDATE; DB.seedDefaultAssetInterceptRules: write INSERT · db-pg-access-asset-intercept-rules-268b1fbdb1 · db-pg-access-asset-intercept-rules-445d96292d · db-pg-access-asset-intercept-rules-8e1f052eac · db-pg-access-asset-intercept-rules-de1d0d5f6d · db-pg-access-asset-intercept-rules-47862794d6 · db-pg-access-asset-intercept-rules-d1098f8cc5
- 계약 사용 · set_updated_at() · write; columns updated_at; BEFORE UPDATE ROW trigger `trg_asset_intercept_rules_upd`; provenance: trigger row/table declaration · db-ddl-trigger-trg-asset-intercept-rules-upd
- 의존 / 실행 · trg_asset_intercept_rules_upd · fire table `asset_intercept_rules` · db-ddl-trigger-trg-asset-intercept-rules-upd
asset_intercept_rules 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS asset_intercept_rules (
id BIGSERIAL PRIMARY KEY,
enabled BOOLEAN NOT NULL DEFAULT true,
kind TEXT NOT NULL CHECK (kind IN (
'exact_domain', 'exact_ip', 'exact_url',
'fuzzy_domain', 'fuzzy_ip', 'fuzzy_url',
'cidr')),
pattern TEXT NOT NULL,
note TEXT NOT NULL DEFAULT '',
builtin BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
인덱스
CREATE INDEX IF NOT EXISTS idx_asset_intercept_enabled ON asset_intercept_rules(enabled);
의미·소비·운영 경계
asset_intercept_rules 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
task_intercept_rules
task_intercept_rules · 관계
이 대상을 사용하는 기능·모듈·계약 · 3개
- 계약 사용 · Tool intercept·승인·실행 trace · AssetStore.CreateTaskInterceptRule: write INSERT; AssetStore.DeleteTaskInterceptRule: write DELETE; AssetStore.ListTaskInterceptRules: read FROM; AssetStore.ToggleTaskInterceptRule: write UPDATE; AssetStore.UpdateTaskInterceptRule: write UPDATE; insertTaskInterceptRules: write INSERT · db-pg-access-task-intercept-rules-05a2133849 · db-pg-access-task-intercept-rules-70760af03b · db-pg-access-task-intercept-rules-ea22772e81 · db-pg-access-task-intercept-rules-26009d3fc6 · db-pg-access-task-intercept-rules-e10d568bcc · db-pg-access-task-intercept-rules-5289e2be79
- 계약 사용 · set_updated_at() · write; columns updated_at; BEFORE UPDATE ROW trigger `trg_task_intercept_rules_upd`; provenance: trigger row/table declaration · db-ddl-trigger-trg-task-intercept-rules-upd
- 의존 / 실행 · trg_task_intercept_rules_upd · fire table `task_intercept_rules` · db-ddl-trigger-trg-task-intercept-rules-upd
task_intercept_rules 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS task_intercept_rules (
id BIGSERIAL PRIMARY KEY,
task_id BIGINT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
enabled BOOLEAN NOT NULL DEFAULT true,
action TEXT NOT NULL DEFAULT 'block' CHECK (action IN ('block','allow')),
kind TEXT NOT NULL CHECK (kind IN (
'exact_domain', 'exact_ip', 'exact_url',
'fuzzy_domain', 'fuzzy_ip', 'fuzzy_url',
'cidr')),
pattern TEXT NOT NULL,
note TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
후속 변경·제약
ALTER TABLE task_intercept_rules ADD COLUMN IF NOT EXISTS action TEXT NOT NULL DEFAULT 'block';
Fresh CREATE는 action IN ('block','allow') CHECK를 만들지만 legacy ADD COLUMN은 CHECK를 추가하지 않는다. upgraded DB의 action 무결성은 backend 쓰기 검증에 의존한다. migration 경계
인덱스
CREATE INDEX IF NOT EXISTS idx_task_intercept_task ON task_intercept_rules(task_id);
의미·소비·운영 경계
task_intercept_rules 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
notification_channels
notification_channels · 관계
이 대상을 사용하는 기능·모듈·계약 · 3개
- 계약 사용 · Reporter, retest, export · DB.DeleteNotificationChannel: write DELETE; DB.ListNotificationChannels: read FROM; DB.NotificationChannelByID: read FROM; DB.NotificationStatsSnapshot: read FROM; DB.SaveNotificationChannel: write INSERT/UPDATE; DB.SetNotificationChannelEnabled: write UPDATE; listEnabledNotificationChannelsTx: read FROM; DB.ClaimDigestBatch: read JOIN; DB.ClaimRealtimeDeliveries: read JOIN; DB.DigestBatchDue: read JOIN; DB.ListNotificationDeliveries: read JOIN; loadDeliveriesTx: read JOIN · db-pg-access-notification-channels-1c73b6e6ff · db-pg-access-notification-channels-3c998953c9 · db-pg-access-notification-channels-790746d20d · db-pg-access-notification-channels-ef0d56b704 · db-pg-access-notification-channels-71a8049a70 · db-pg-access-notification-channels-16ab658a14 · db-pg-access-notification-channels-1d231f183b · db-pg-access-notification-channels-37f497fe6b · db-pg-access-notification-channels-a477c0e7b3 · db-pg-access-notification-channels-db1fb1f29a · db-pg-access-notification-channels-d5b73cdd8d · db-pg-access-notification-channels-826904f61d
- 계약 사용 · set_updated_at() · write; columns updated_at; BEFORE UPDATE ROW trigger `trg_notification_channels_upd`; provenance: trigger row/table declaration · db-ddl-trigger-trg-notification-channels-upd
- 의존 / 실행 · trg_notification_channels_upd · fire table `notification_channels` · db-ddl-trigger-trg-notification-channels-upd
notification_channels 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS notification_channels (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
-- dingtalk 钉钉 / feishu 飞书 / wecom 企业微信 / webhook 通用 / telegram / email
kind TEXT NOT NULL,
enabled BOOLEAN NOT NULL DEFAULT true,
-- 凭据(明文存储,UI 掩码回显;见 server 侧 maskChannelSecrets)。六种渠道字段差异极大,
-- 统一 JSONB + Go 侧按 kind 严格校验,避免为每渠道加一堆 NULL 列:
-- dingtalk {webhook,secret}
-- feishu {webhook,secret}
-- wecom {webhook}
-- webhook {url,method,content_type,headers{},body_template}
-- telegram {bot_token,chat_id,base_url}
-- email {host,port,username,password,from,to[],tls}
config JSONB NOT NULL DEFAULT '{}',
-- 推送时机:realtime 命中即推 / digest 进批次按全局周期汇总成一条。
mode TEXT NOT NULL DEFAULT 'realtime',
-- 过滤条件,字段全部可选(缺省=不过滤):
-- min_severity ''|low|medium|high|critical
-- task_ids/asset_ids 空数组=不限;非空则须交集非空
-- vulnclass_include/exclude 关键词数组(大小写不敏感子串);include 空=全收
-- on_status_change bool,仅 realtime 模式有意义
filter JSONB NOT NULL DEFAULT '{}',
-- 每分钟投递上限;0=不限流。默认 20 对齐钉钉/企微官方硬限。
-- 超限不丢消息,只把投递推迟到下一个 tick。
rate_per_min INTEGER NOT NULL DEFAULT 20,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
의미·소비·운영 경계
notification_channels 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
notification_events
notification_events · 관계
이 대상을 사용하는 기능·모듈·계약 · 1개
- 계약 사용 · Reporter, retest, export · DB.AddNotificationEvent: write INSERT; DB.FanOutPendingEvents: read/write FROM/UPDATE; RecordNotificationEventTx: write INSERT; DB.ListNotificationDeliveries: read JOIN; loadDeliveriesTx: read JOIN · db-pg-access-notification-events-d671b8097a · db-pg-access-notification-events-eee01ab57c · db-pg-access-notification-events-e2d1dca210 · db-pg-access-notification-events-b58979bce9 · db-pg-access-notification-events-01cb13b683
notification_events 도메인의 영속 상태를 저장한다. 정확한 의미는 필드 정의와 사용 모듈을 함께 본다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS notification_events (
id BIGSERIAL PRIMARY KEY,
-- finding_created | finding_status_changed
kind TEXT NOT NULL,
finding_id BIGINT NOT NULL,
snapshot JSONB NOT NULL,
-- fan-out 幂等标记:dispatcher 按此列取待分派事件,处理完置 true。
-- 用列而非删行,以便投递历史能回溯到事件。
fanned_out BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
인덱스
CREATE INDEX IF NOT EXISTS idx_notification_events_pending ON notification_events(id) WHERE NOT fanned_out;
의미·소비·운영 경계
notification_events 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.
notification_deliveries
notification_deliveries · 관계
이 대상을 사용하는 기능·모듈·계약 · 1개
- 계약 사용 · Reporter, retest, export · DB.FanOutPendingEvents: write INSERT; DB.NotificationStatsSnapshot: read FROM; DB.SetNotificationChannelEnabled: write UPDATE; DB.ClaimDigestBatch: read/write FROM/UPDATE; DB.ClaimRealtimeDeliveries: read FROM; DB.DeferDeliveries: write UPDATE; DB.DigestBatchDue: read FROM; DB.FailDeliveries: write UPDATE; DB.ListNotificationDeliveries: read FROM; DB.MarkDeliveriesSent: write UPDATE; DB.RescheduleDeliveries: write UPDATE; DB.RetryNotificationDelivery: write UPDATE; DB.claimDeliveries: write UPDATE; loadDeliveriesTx: read FROM · db-pg-access-notification-deliveries-e3bd3204a8 · db-pg-access-notification-deliveries-2a3b18de73 · db-pg-access-notification-deliveries-4792232261 · db-pg-access-notification-deliveries-41525f8214 · db-pg-access-notification-deliveries-8feff6dd1d · db-pg-access-notification-deliveries-1cb1f5dd43 · db-pg-access-notification-deliveries-a2a50b4454 · db-pg-access-notification-deliveries-0832492f88 · db-pg-access-notification-deliveries-1ba7713700 · db-pg-access-notification-deliveries-4733db6f9b · db-pg-access-notification-deliveries-7a521922df · db-pg-access-notification-deliveries-8403471de4 · db-pg-access-notification-deliveries-3f8ba0a0c7 · db-pg-access-notification-deliveries-8d676caafb
channel별 전달 시도, lease, retry, 오류를 저장한다.
정의 원본은 db/schema.sql다. 등록 근거
CREATE TABLE IF NOT EXISTS notification_deliveries (
id BIGSERIAL PRIMARY KEY,
event_id BIGINT NOT NULL REFERENCES notification_events(id) ON DELETE CASCADE,
channel_id BIGINT NOT NULL REFERENCES notification_channels(id) ON DELETE CASCADE,
-- pending 待发 / sent 已发 / failed 重试耗尽(可手动重发) / skipped 渠道停用或批次取消
-- pending 待发 / sending 已被某 dispatcher 领取(租约未到期) / sent 已发 /
-- failed 重试耗尽或永久失败(可手动重发) / skipped 渠道停用。取值不加 CHECK,
-- 与 findings.status 同理,由 server 侧白名单校验。
state TEXT NOT NULL DEFAULT 'pending',
attempts INTEGER NOT NULL DEFAULT 0,
-- 兼作「下次可领取时间」与「租约到期时间」:领取时把它推到未来即构成租约,
-- 于是「租约未到期」与「未到重试时间」共用同一个条件表达,不需要额外的
-- lease_until 列。进程崩溃留下的 sending 行会因租约到期被下一轮重新领取。
next_attempt_at TIMESTAMPTZ NOT NULL DEFAULT now(),
last_error TEXT NOT NULL DEFAULT '',
-- digest 模式同批次共享;realtime 恒为 NULL。整批渲染成一条消息后一起置 sent。
batch_id BIGINT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
sent_at TIMESTAMPTZ
);
인덱스
CREATE INDEX IF NOT EXISTS idx_notification_deliveries_due ON notification_deliveries(next_attempt_at) WHERE state='pending';CREATE INDEX IF NOT EXISTS idx_notification_deliveries_history ON notification_deliveries(id DESC);CREATE INDEX IF NOT EXISTS idx_notification_deliveries_batch ON notification_deliveries(batch_id) WHERE batch_id IS NOT NULL;CREATE INDEX IF NOT EXISTS idx_notification_deliveries_channel ON notification_deliveries(channel_id, id DESC);
의미·소비·운영 경계
notification_deliveries 필드 의미, reader/writer, index 비용과 retention 판정에서 물리 DDL과 별도로 C/A/U를 확인한다. 운영 DB 적용·row 규모·query plan·role은 관찰하지 않았다.