feat(compliance): add content compliance detection across tenant, ops, and clients
Implements the Revision 8/9 compliance design: tenant + ops backends, ops-web content-safety pages, admin-web editor/publish gate integration, desktop publish block surfacing, and supporting migrations / shared types / config plumbing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
package compliance
|
||||
|
||||
import "time"
|
||||
|
||||
type GateDecision string
|
||||
|
||||
const (
|
||||
GateDecisionPass GateDecision = "pass"
|
||||
GateDecisionBlock GateDecision = "block"
|
||||
GateDecisionNeedsAck GateDecision = "needs_ack"
|
||||
)
|
||||
|
||||
type ManualReviewStatus string
|
||||
|
||||
const (
|
||||
ManualReviewStatusNone ManualReviewStatus = "none"
|
||||
ManualReviewStatusPending ManualReviewStatus = "pending"
|
||||
ManualReviewStatusApproved ManualReviewStatus = "approved"
|
||||
ManualReviewStatusRejected ManualReviewStatus = "rejected"
|
||||
ManualReviewStatusCancelled ManualReviewStatus = "cancelled"
|
||||
)
|
||||
|
||||
type RuntimeStatus struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
ConfigEnabled bool `json:"config_enabled"`
|
||||
MasterEnabled bool `json:"master_enabled"`
|
||||
EnforcementMode string `json:"enforcement_mode"`
|
||||
LLMJudgeEnabled bool `json:"llm_judge_enabled"`
|
||||
SnapshotReloadInterval string `json:"snapshot_reload_interval"`
|
||||
PublishGateTimeout string `json:"publish_gate_timeout"`
|
||||
DictionaryVersion int64 `json:"dictionary_version"`
|
||||
EnabledDictionaries []string `json:"enabled_dictionaries"`
|
||||
}
|
||||
|
||||
type Violation struct {
|
||||
ID int64 `json:"id"`
|
||||
RecordID int64 `json:"record_id,omitempty"`
|
||||
PlatformCode *string `json:"platform_code,omitempty"`
|
||||
Source string `json:"source"`
|
||||
DictionaryCode *string `json:"dictionary_code,omitempty"`
|
||||
DictionaryName *string `json:"dictionary_name,omitempty"`
|
||||
TermPattern *string `json:"term_pattern,omitempty"`
|
||||
MatchedText string `json:"matched_text"`
|
||||
StartOffset int `json:"start_offset"`
|
||||
EndOffset int `json:"end_offset"`
|
||||
DomPath *string `json:"dom_path,omitempty"`
|
||||
Level string `json:"level"`
|
||||
Hint *string `json:"hint,omitempty"`
|
||||
ReferenceLaw *string `json:"reference_law,omitempty"`
|
||||
}
|
||||
|
||||
type CheckResult struct {
|
||||
RecordID int64 `json:"record_id,omitempty"`
|
||||
Decision GateDecision `json:"decision"`
|
||||
Passed bool `json:"passed"`
|
||||
HighestLevel *string `json:"highest_level,omitempty"`
|
||||
Violations []Violation `json:"violations"`
|
||||
HitCount int `json:"hit_count"`
|
||||
StoredHitCount int `json:"stored_hit_count"`
|
||||
Truncated bool `json:"truncated"`
|
||||
EnforcementMode string `json:"enforcement_mode"`
|
||||
ContentHash string `json:"content_hash"`
|
||||
PolicyFingerprint string `json:"policy_fingerprint"`
|
||||
TargetPlatforms []string `json:"target_platforms"`
|
||||
ManualReviewStatus ManualReviewStatus `json:"manual_review_status"`
|
||||
ManualReviewID *int64 `json:"manual_review_id,omitempty"`
|
||||
ManualReviewReason *string `json:"manual_review_reason,omitempty"`
|
||||
ManualReviewDecidedAt *time.Time `json:"manual_review_decided_at,omitempty"`
|
||||
CheckedAt time.Time `json:"checked_at"`
|
||||
DurationMS int `json:"duration_ms"`
|
||||
}
|
||||
|
||||
type AckRecord struct {
|
||||
ID int64 `json:"id"`
|
||||
CheckRecordID int64 `json:"check_record_id"`
|
||||
ArticleID int64 `json:"article_id"`
|
||||
ArticleVersionID int64 `json:"article_version_id"`
|
||||
ContentHash string `json:"content_hash"`
|
||||
PolicyFingerprint string `json:"policy_fingerprint"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
type ManualReview struct {
|
||||
ID int64 `json:"id"`
|
||||
TenantID int64 `json:"tenant_id"`
|
||||
ArticleID int64 `json:"article_id"`
|
||||
ArticleVersionID int64 `json:"article_version_id"`
|
||||
CheckRecordID *int64 `json:"check_record_id,omitempty"`
|
||||
Status ManualReviewStatus `json:"status"`
|
||||
RequestedBy int64 `json:"requested_by"`
|
||||
RequestedAt time.Time `json:"requested_at"`
|
||||
RequestNote *string `json:"request_note,omitempty"`
|
||||
ReviewedBy *int64 `json:"reviewed_by,omitempty"`
|
||||
ReviewedAt *time.Time `json:"reviewed_at,omitempty"`
|
||||
DecisionReason *string `json:"decision_reason,omitempty"`
|
||||
CancelledBy *int64 `json:"cancelled_by,omitempty"`
|
||||
CancelledAt *time.Time `json:"cancelled_at,omitempty"`
|
||||
CancelReason *string `json:"cancel_reason,omitempty"`
|
||||
ViolationSummary []Violation `json:"violation_summary"`
|
||||
OriginalPlatforms []string `json:"original_target_platforms"`
|
||||
ArticleTitle *string `json:"article_title,omitempty"`
|
||||
ArticlePlaintext *string `json:"article_plaintext,omitempty"`
|
||||
ApplicantName *string `json:"applicant_name,omitempty"`
|
||||
TenantName *string `json:"tenant_name,omitempty"`
|
||||
}
|
||||
Reference in New Issue
Block a user