Files
WeiCHEN a2eabe01b1 refactor(chat): break chat→app import cycle via owned ports
Invert chat dependencies on chatflow/intentflow/stageflow through
composition-root adapters; replace AssembleRequest coordinator embeds
with local DTOs and tighten the module-boundaries allowlist.
2026-09-22 21:25:44 +08:00

133 lines
4.4 KiB
Go

package chatflow
import (
"context"
"errors"
"chat-agent-system/internal/coordinator"
"chat-agent-system/internal/ctxmgr"
"chat-agent-system/internal/projectinstance"
)
var (
ErrUnauthenticated = errors.New("chatflow: unauthenticated")
ErrForbidden = errors.New("chatflow: forbidden")
ErrNotFound = errors.New("chatflow: not found")
ErrClosed = errors.New("chatflow: closed")
)
type Action string
const (
ActionReadWindow Action = "chat.read_window"
ActionReadDay Action = "chat.read_day"
ActionReadStats Action = "chat.read_stats"
ActionSearch Action = "chat.search"
ActionUnread Action = "chat.unread"
ActionExport Action = "chat.export"
ActionDigest Action = "chat.digest"
ActionAssemble Action = "context.assemble"
)
// Principal is taken only from the authenticated session. Callers must not
// copy user/project identifiers from the request body or query into UserID.
type Principal struct {
UserID int64
Action Action
}
type DayQuery struct {
SessionID string
Date string
AnchorID int64
BeforeID int64
AfterID int64
Limit int
}
type HistoryQuery struct {
SessionID string
Limit int
Offset int
}
type UnreadQuery struct {
SessionID string
SinceMessageID int64
}
type ExportQuery struct {
SessionID string
DateFrom string
DateTo string
Category string
}
type MemoryQuery struct {
Query string
ProjectID int64
SessionID string
ExcludeSessionID string
TopK int
MinScore float64
}
// AssembleUser is the chatflow-owned identity DTO for context assembly.
// It mirrors coordinator.UserInfo fields without embedding that concrete type.
type AssembleUser struct {
ID string
Name string
Role string
ProjectRole string
}
// AssembleProject is the chatflow-owned project fallback DTO for context assembly.
type AssembleProject struct {
ID string
Name string
CustomerName string
DeviceType string
IntendedUse string
TargetMarket string
CreatorUserID int64
ActiveWorkflowKey string
WorkflowSelectionVersion int
CurrentWorkflow string
CurrentStage string
StageRules []string
}
type AssembleRequest struct {
SessionID string
WorkDir string
User AssembleUser
Fallback AssembleProject
}
type StageAccessResolver func(ctx context.Context, projectID, viewerUserID int64) (*projectinstance.StageAccess, error)
// ChatLog is the consumer-side port for authorized chat_* reads.
// Table ownership stays in ctxmgr; this port never accepts request-body identity as auth fact.
type ChatLog interface {
GetWindow(ctx context.Context, p Principal, q ctxmgr.ChatWindowQuery) (*ctxmgr.ChatWindowResult, error)
GetDay(ctx context.Context, p Principal, q DayQuery) (*ctxmgr.ChatDayMessagesResult, error)
History(ctx context.Context, p Principal, q HistoryQuery) ([]ctxmgr.ChatMessageRecord, error)
ListVisible(ctx context.Context, p Principal, sessionID string) ([]ctxmgr.ChatMessageRecord, error)
CategoryStats(ctx context.Context, p Principal, sessionID string) ([]ctxmgr.ChatCategoryStat, error)
DateStats(ctx context.Context, p Principal, sessionID string) ([]ctxmgr.ChatDateStat, error)
Search(ctx context.Context, p Principal, q ctxmgr.ChatSearchQuery) ([]ctxmgr.ChatSearchHit, error)
Unread(ctx context.Context, p Principal, q UnreadQuery) (*ctxmgr.ChatUnreadSummary, error)
MarkRead(ctx context.Context, p Principal, req ctxmgr.MarkChatReadRequest) (*ctxmgr.ChatReadPosition, error)
Export(ctx context.Context, p Principal, q ExportQuery) ([]ctxmgr.ChatMessageRecord, error)
ListDigests(ctx context.Context, p Principal, sessionID, from, to string) ([]ctxmgr.DailyDigest, error)
GenerateDigest(ctx context.Context, p Principal, sessionID, dayKey string) (*ctxmgr.DailyDigest, error)
GenerateRollingSummary(ctx context.Context, p Principal, sessionID string, earlyMsgs []ctxmgr.ChatMessageRecord) (*ctxmgr.ChatSummary, error)
Restore(ctx context.Context, p Principal, sessionID string) (*ctxmgr.RestoredSessionContext, error)
SearchMemory(ctx context.Context, p Principal, q MemoryQuery) ([]ctxmgr.RecalledMemoryItem, error)
}
// ContextAssembler is the consumer-side port for prompt context assembly.
type ContextAssembler interface {
Assemble(ctx context.Context, p Principal, req AssembleRequest) (*coordinator.UserProjectContext, error)
}