Restructure the monorepo into clear top-level directories: - backend/: Go module root (cmd, internal, pkg, configs, migrations, docs/swagger, scripts, tests, go.mod, Makefile, .air.toml) - deploy/: Docker (Dockerfile, docker-compose*), quickstart, fluentd - docs/: project documentation + reports/ (moved from repo root) - AGENTS.md: new AI coding-agent guide at repo root Update all references to the new layout: - Dockerfile: COPY backend/go.mod, COPY backend/ (context = repo root) - docker-compose files: context ../.., dockerfile deploy/docker/Dockerfile, env_file ../../.env, volume mounts ../../backend:/app - deploy/quickstart/compose.yaml: dockerfile deploy/docker/Dockerfile - CI: working-directory: backend for go commands, file deploy/docker/Dockerfile, coverage path backend/coverage.out, health_check backend/scripts/ - backend/Makefile: docker target uses -f ../deploy/docker/Dockerfile ../ - README: architecture tree, quickstart, config paths updated Move root stray scripts (rename_models.*, run_m11_tests.sh, verify_build.sh, gorm_bool_main.go) to backend/scripts/legacy/. All moves via git mv to preserve history. Build, vet, SQLite tests, and docker compose config verified.
89 lines
3.8 KiB
Go
89 lines
3.8 KiB
Go
package channel
|
|
|
|
// EventType defines channel lifecycle and messaging events.
|
|
// Reference: P2D §8 + Chatwoot Dispatcher + Listener event-driven architecture
|
|
// These events are published to the Event Bus for cross-module propagation.
|
|
type EventType string
|
|
|
|
const (
|
|
// Message events
|
|
EventMessageIncoming EventType = "message.incoming"
|
|
EventMessageOutgoing EventType = "message.outgoing"
|
|
EventMessageCreated EventType = "message.created"
|
|
EventMessageUpdated EventType = "message.updated"
|
|
EventMessageDeleted EventType = "message.deleted"
|
|
EventMessageStatusUpdated EventType = "message.status_updated"
|
|
|
|
// Conversation events
|
|
EventConversationCreated EventType = "conversation.created"
|
|
EventConversationUpdated EventType = "conversation.updated"
|
|
EventConversationResolved EventType = "conversation.resolved"
|
|
EventConversationOpened EventType = "conversation.opened"
|
|
EventConversationAssigned EventType = "conversation.assigned"
|
|
EventConversationUnassigned EventType = "conversation.unassigned"
|
|
EventConversationDeleted EventType = "conversation.deleted"
|
|
EventConversationMuted EventType = "conversation.muted"
|
|
EventConversationUnmuted EventType = "conversation.unmuted"
|
|
EventConversationPriorityUpdated EventType = "conversation.priority_updated"
|
|
EventConversationLabelsUpdated EventType = "conversation.labels_updated"
|
|
EventConversationTyping EventType = "conversation.typing"
|
|
EventConversationTypingOn EventType = "conversation.typing_on"
|
|
EventConversationTypingOff EventType = "conversation.typing_off"
|
|
|
|
// Contact events
|
|
EventContactCreated EventType = "contact.created"
|
|
EventContactUpdated EventType = "contact.updated"
|
|
EventContactDeleted EventType = "contact.deleted"
|
|
EventContactMerged EventType = "contact.merged"
|
|
|
|
// Channel/Inbox events
|
|
EventChannelConnected EventType = "channel.connected"
|
|
EventChannelDisconnected EventType = "channel.disconnected"
|
|
EventChannelReauthorized EventType = "channel.reauthorized"
|
|
EventInboxCreated EventType = "inbox.created"
|
|
EventInboxUpdated EventType = "inbox.updated"
|
|
EventInboxDeleted EventType = "inbox.deleted"
|
|
|
|
// Webhook events
|
|
EventWebhookReceived EventType = "webhook.received"
|
|
|
|
// Widget events
|
|
EventWebwidgetTriggered EventType = "webwidget.triggered"
|
|
|
|
// Agent events
|
|
EventAgentAdded EventType = "agent.added"
|
|
EventAgentRemoved EventType = "agent.removed"
|
|
EventAgentOnline EventType = "agent.online"
|
|
EventAgentOffline EventType = "agent.offline"
|
|
|
|
// Typing events
|
|
EventTypingStart EventType = "typing.start"
|
|
EventTypingStop EventType = "typing.stop"
|
|
)
|
|
|
|
// ChannelEvent wraps an event with full context for event bus propagation.
|
|
// Reference: P2D §8 — events carry enough context for handlers to process without DB lookups
|
|
type ChannelEvent struct {
|
|
Type EventType `json:"type"`
|
|
Channel ChannelType `json:"channel"`
|
|
AccountID uint `json:"account_id"`
|
|
InboxID uint `json:"inbox_id"`
|
|
ConversationID uint `json:"conversation_id,omitempty"`
|
|
ContactID uint `json:"contact_id,omitempty"`
|
|
UserID uint `json:"user_id,omitempty"`
|
|
Data map[string]interface{} `json:"data"`
|
|
Timestamp int64 `json:"timestamp"`
|
|
}
|
|
|
|
// NewChannelEvent creates a new channel event with timestamp.
|
|
func NewChannelEvent(eventType EventType, channelType ChannelType, accountID, inboxID uint) *ChannelEvent {
|
|
return &ChannelEvent{
|
|
Type: eventType,
|
|
Channel: channelType,
|
|
AccountID: accountID,
|
|
InboxID: inboxID,
|
|
Data: make(map[string]interface{}),
|
|
Timestamp: 0, // will be set by event bus publisher
|
|
}
|
|
}
|