User authorized lifting CURRENT FAV whole-branch merge protection on 2026-09-23. Keep FAV_DEGRADED_READ/FAV_PUBLISHER_ENABLED default false. Drop duplicate goose 00034 (local_dev already has 00036). Preserve agentx workspace admin routes and pin-export wiring.
81 lines
2.4 KiB
Go
81 lines
2.4 KiB
Go
package docgov
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// GovernanceEngine 受控文档编制/审核/批准与认领治理引擎
|
|
type GovernanceEngine struct {
|
|
pool *pgxpool.Pool
|
|
sm *StateMachine
|
|
|
|
mu sync.RWMutex
|
|
memDocs map[string]*DocumentRecord
|
|
memComms map[string][]*DocumentComment
|
|
memProps map[string]*ChangeProposal
|
|
memAudits map[string][]*AuditLog
|
|
onApprovedHook func(ctx context.Context, doc *DocumentRecord)
|
|
onApprovedHooks []func(ctx context.Context, doc *DocumentRecord)
|
|
OnFinalArtifact func(ctx context.Context, doc *DocumentRecord, markdown []byte, snapshotID int64)
|
|
OnFinalArtifactTX func(ctx context.Context, tx pgx.Tx, doc *DocumentRecord, markdown []byte, snapshotID int64) error
|
|
}
|
|
|
|
// SetOnApprovedHook 注册文档终审批准时的回调钩子
|
|
func (e *GovernanceEngine) SetOnApprovedHook(hook func(ctx context.Context, doc *DocumentRecord)) {
|
|
e.mu.Lock()
|
|
defer e.mu.Unlock()
|
|
e.onApprovedHook = hook
|
|
}
|
|
|
|
// AddOnApprovedHook 追加文档终审批准回调(与 SetOnApprovedHook 并存)。
|
|
func (e *GovernanceEngine) AddOnApprovedHook(hook func(ctx context.Context, doc *DocumentRecord)) {
|
|
if hook == nil {
|
|
return
|
|
}
|
|
e.mu.Lock()
|
|
defer e.mu.Unlock()
|
|
e.onApprovedHooks = append(e.onApprovedHooks, hook)
|
|
}
|
|
|
|
func (e *GovernanceEngine) runApprovedHooks(ctx context.Context, doc *DocumentRecord) {
|
|
var primary func(context.Context, *DocumentRecord)
|
|
var extra []func(context.Context, *DocumentRecord)
|
|
e.mu.Lock()
|
|
primary = e.onApprovedHook
|
|
extra = append([]func(context.Context, *DocumentRecord){}, e.onApprovedHooks...)
|
|
e.mu.Unlock()
|
|
|
|
if primary != nil {
|
|
primary(ctx, doc)
|
|
}
|
|
for _, hook := range extra {
|
|
if hook != nil {
|
|
hook(ctx, doc)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (e *GovernanceEngine) UsingPG() bool {
|
|
return e != nil && e.pool != nil
|
|
}
|
|
|
|
func (e *GovernanceEngine) RunApprovedHooksAfterCommit(ctx context.Context, doc *DocumentRecord) {
|
|
e.runApprovedHooks(ctx, doc)
|
|
}
|
|
|
|
// NewGovernanceEngine 初始化治理引擎
|
|
func NewGovernanceEngine(pool *pgxpool.Pool) *GovernanceEngine {
|
|
return &GovernanceEngine{
|
|
pool: pool,
|
|
sm: NewStateMachine(),
|
|
memDocs: make(map[string]*DocumentRecord),
|
|
memComms: make(map[string][]*DocumentComment),
|
|
memProps: make(map[string]*ChangeProposal),
|
|
memAudits: make(map[string][]*AuditLog),
|
|
}
|
|
}
|