mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-07 16:16:37 +08:00
refactor(msg_gateway): decouple bot gateway and push notification architecture
- Split shared monolithic consts into bot, push, and errs with typed sentinel errors - Restructure model layer into distinct bot and push subdomains - Refactor DAO layer to enforce single-owner principle and remove cross-table raw SQL queries - Decompose 1150+ line service/push.go into push_channel, push_event, push_trigger, push_worker, and push_template - Clean up controller layer with generic request handlers and parameter validation in controller/base.go - Streamline plugin.go to core Cordis lifecycle orchestration and remove re-export bloat - Verify all unit tests, race tests, Cordis architecture rules, and Swagger generation pass cleanly
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package consts defines constants, error types, and identifiers for msg_gateway.
|
||||
package consts
|
||||
|
||||
// Bot Channel type and scope constants.
|
||||
const (
|
||||
ChannelTypeTelegram = "telegram"
|
||||
ChannelTypeQQ = "qq"
|
||||
MessageChannelTypeTelegram = "telegram"
|
||||
MessageChannelTypeQQ = "qq"
|
||||
MessageOwnerScopeSystem = "system"
|
||||
)
|
||||
|
||||
// Bot Task and Schedule identifier constants.
|
||||
const (
|
||||
TaskCleanupPairingCodes = "msg_gateway:cleanup_pairing_codes"
|
||||
TaskDispatchBotMsg = "msg_gateway:dispatch_bot_msg"
|
||||
TaskTypeDispatchBotMsg = "dispatch_bot_msg"
|
||||
)
|
||||
|
||||
// Pairing code constants.
|
||||
const (
|
||||
CodeAlphabet = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"
|
||||
CodeLength = 8
|
||||
)
|
||||
+6
-67
@@ -1,69 +1,10 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package consts defines constants, sentinel errors, and user-facing error messages
|
||||
// for the msg_gateway plugin.
|
||||
package consts
|
||||
|
||||
import "errors"
|
||||
|
||||
// Channel type and scope constants.
|
||||
const (
|
||||
ChannelTypeTelegram = "telegram"
|
||||
ChannelTypeQQ = "qq"
|
||||
MessageChannelTypeTelegram = "telegram"
|
||||
MessageChannelTypeQQ = "qq"
|
||||
MessageOwnerScopeSystem = "system"
|
||||
|
||||
TypeCustom = "custom"
|
||||
TypeEmail = "email"
|
||||
TypeTelegram = "telegram"
|
||||
ChannelCustom = "custom"
|
||||
ChannelEmail = "email"
|
||||
ChannelLark = "lark"
|
||||
ChannelDingTalk = "dingtalk"
|
||||
ChannelTelegram = "telegram"
|
||||
ChannelBark = "bark"
|
||||
ChannelDiscord = "discord"
|
||||
ChannelSlack = "slack"
|
||||
ChannelPushover = "pushover"
|
||||
|
||||
DefaultLevelInfo = "INFO"
|
||||
KeyTitle = "title"
|
||||
KeyContent = "content"
|
||||
KeyLevel = "level"
|
||||
|
||||
// KeyURL represents the URL field key.
|
||||
KeyURL = "url"
|
||||
// KeyToken represents the Token field key.
|
||||
KeyToken = "token"
|
||||
// KeyOther represents the Other field key.
|
||||
KeyOther = "other"
|
||||
|
||||
// TypeText represents standard text input type.
|
||||
TypeText = "text"
|
||||
// TypePassword represents password input type.
|
||||
TypePassword = "password"
|
||||
// TypeTextarea represents textarea input type.
|
||||
TypeTextarea = "textarea"
|
||||
)
|
||||
|
||||
// Task and Schedule identifier constants.
|
||||
const (
|
||||
TaskPushNotification = "msg_gateway:push_notification"
|
||||
TaskCleanupPairingCodes = "msg_gateway:cleanup_pairing_codes"
|
||||
TaskDispatchBotMsg = "msg_gateway:dispatch_bot_msg"
|
||||
TaskTypeDispatchBotMsg = "dispatch_bot_msg"
|
||||
SendNotificationTask = "push:send"
|
||||
TaskTypeSendNotification = "send_notification"
|
||||
)
|
||||
|
||||
// Pairing code constants.
|
||||
const (
|
||||
CodeAlphabet = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"
|
||||
CodeLength = 8
|
||||
)
|
||||
|
||||
// Sentinel errors.
|
||||
var (
|
||||
ErrCodeInvalid = errors.New("invalid or expired pairing code")
|
||||
@@ -73,14 +14,15 @@ var (
|
||||
ErrBindingForbidden = errors.New("cannot unbind another user's binding")
|
||||
ErrChannelIDRequired = errors.New("channel_id is required")
|
||||
ErrChannelDisabled = errors.New("channel is not enabled")
|
||||
ErrChannelNotFound = errors.New("channel not found")
|
||||
ErrEventNotFound = errors.New("notification event not found")
|
||||
ErrUserNotFound = errors.New("user not found")
|
||||
ErrNoAdminUser = errors.New("no admin user found")
|
||||
ErrTaskServiceNotAvail = errors.New("task service not available")
|
||||
|
||||
// ErrRecordNotFound maps GORM's missing-row sentinel at the DAO boundary so
|
||||
// upper layers never import gorm. Its text matches gorm.ErrRecordNotFound verbatim.
|
||||
ErrRecordNotFound = errors.New("record not found")
|
||||
|
||||
// ErrUnsupportedUserLookupField rejects a column name that the DAO is not
|
||||
// allowed to interpolate into a WHERE clause.
|
||||
ErrUnsupportedUserLookupField = errors.New("unsupported user lookup field")
|
||||
)
|
||||
|
||||
// User-facing validation and error message constants.
|
||||
@@ -89,7 +31,7 @@ const (
|
||||
ErrTypeInvalid = "type must be telegram or qq"
|
||||
ErrTelegramTokenRequired = "telegram bot secret is required" //nolint:gosec // user-facing validation text
|
||||
ErrQQCredentialsRequired = "qq app id and secret are required" //nolint:gosec // user-facing validation text
|
||||
ErrChannelNotFound = "channel not found"
|
||||
ErrChannelNotFoundText = "channel not found"
|
||||
ErrChannelProbeFailed = "channel probe failed"
|
||||
ErrBotDispatchTextRequired = "message text is required"
|
||||
ErrBotChannelNotRegistered = "channel adapter is not registered"
|
||||
@@ -99,7 +41,6 @@ const (
|
||||
ErrInvalidBindingID = "invalid binding id"
|
||||
ErrInvalidChannelID = "invalid channel id"
|
||||
ErrInvalidEventID = "invalid event id"
|
||||
ErrEventNotFound = "notification event not found"
|
||||
ErrValidationFailed = "validation failed"
|
||||
|
||||
ErrMissingTelegramToken = "missing telegram bot token"
|
||||
@@ -120,8 +61,6 @@ const (
|
||||
ErrEventKeyOrTaskType = "either event_key or task_type must be provided"
|
||||
ErrUnsupportedEventKey = "unsupported built-in event key"
|
||||
ErrTaskServiceUnavailable = "task service not available"
|
||||
ErrUserNotFound = "user not found"
|
||||
ErrNoAdminUser = "no admin user found"
|
||||
|
||||
ErrPayloadRequired = "payload is required"
|
||||
ErrInvalidJSONFormat = "invalid json format"
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package consts
|
||||
|
||||
// Push notification channel type constants.
|
||||
const (
|
||||
TypeCustom = "custom"
|
||||
TypeEmail = "email"
|
||||
TypeTelegram = "telegram"
|
||||
ChannelCustom = "custom"
|
||||
ChannelEmail = "email"
|
||||
ChannelLark = "lark"
|
||||
ChannelDingTalk = "dingtalk"
|
||||
ChannelTelegram = "telegram"
|
||||
ChannelBark = "bark"
|
||||
ChannelDiscord = "discord"
|
||||
ChannelSlack = "slack"
|
||||
ChannelPushover = "pushover"
|
||||
)
|
||||
|
||||
// Push message template and payload keys.
|
||||
const (
|
||||
DefaultLevelInfo = "INFO"
|
||||
KeyTitle = "title"
|
||||
KeyContent = "content"
|
||||
KeyLevel = "level"
|
||||
|
||||
KeyURL = "url"
|
||||
KeyToken = "token"
|
||||
KeyOther = "other"
|
||||
|
||||
TypeText = "text"
|
||||
TypePassword = "password"
|
||||
TypeTextarea = "textarea"
|
||||
)
|
||||
|
||||
// Push task identifier constants.
|
||||
const (
|
||||
TaskPushNotification = "msg_gateway:push_notification"
|
||||
SendNotificationTask = "push:send"
|
||||
TaskTypeSendNotification = "send_notification"
|
||||
)
|
||||
Reference in New Issue
Block a user