diff --git a/.agents/skills/push-notification/SKILL.md b/.agents/skills/push-notification/SKILL.md
index 857778ef..d82ce14c 100644
--- a/.agents/skills/push-notification/SKILL.md
+++ b/.agents/skills/push-notification/SKILL.md
@@ -15,7 +15,7 @@ Wavelet 的消息推送机制采用了**元数据驱动 + 统一触发器 + 异
| 目录/包名 | 职责定位 | 包含内容与设计细节 |
| :--- | :--- | :--- |
-| **`pkg/push/`** | 推送基础设施层 | 静态定义、不依赖系统数据库和任何框架。定义了统一接口 `Pusher`、单例 `PusherPool` 和多实现(Lark, Webhook, Email 等),提供配置验证及发送功能。 |
+| **`plugins/domain/message_gateway/push/`** | 推送基础设施层 | 静态定义、不依赖系统数据库和任何框架。定义了统一接口 `Pusher` 和多实现(Lark, Webhook, Email 等),提供配置验证及发送功能。 |
| **`internal/apps/admin/push/`** | 通知服务与后台任务层 | 包含以下核心文件:
1. `events.go`:定义通知事件的结构模型(`NotificationMessage`, `EventMetadata`)、内置事件的动态注册中心(`BuiltInEvents` 及 `RegisterBuiltInEvent` 函数)以及统一触发器类 `EventTrigger`(包括其底层的派发引擎逻辑)。
2. `tasks.go`:定义 Asynq 后台异步发送任务、处理器 `PushHandler` 及其校验逻辑,并记录推送历史审计。
3. `routers.go`:管理端接口,负责获取事件配置列表和更新配置。 |
| **`internal/apps/admin/push/custom_events/`** | 自定义通知事件包 | 事件元数据定义与 push 侧处理逻辑;**一个 Go 文件代表一个事件**。在 `register.go` 统一装配,禁止 `init()` 副作用。 |
| **`internal/listener/`** | 域事件分发层 | 核心域发射事件(如 `EmitAdminLoggedIn`),push 在 bootstrap 阶段通过 `OnAdminLoggedIn` 订阅,避免 auth/user 直接依赖 push。 |
diff --git a/Makefile b/Makefile
index 47358049..740104b4 100644
--- a/Makefile
+++ b/Makefile
@@ -36,8 +36,8 @@ build-embedded:
code-check:
@echo "==> Architecture guards..."
@command -v rg >/dev/null 2>&1 || { echo 'error: rg (ripgrep) is required for architecture guards' >&2; exit 1; }
- @if [ -d pkg/model ] && rg -n 'db\.DB\(|db\.Redis' pkg/model --glob '*.go' -g '!*_test.go' ; then \
- echo 'error: pkg/model must not access db.DB or db.Redis (non-test code)' >&2; \
+ @if [ -d pkg/model ] && rg -n 'database\.DB\(|cachepkg\.Redis' pkg/model --glob '*.go' -g '!*_test.go' ; then \
+ echo 'error: pkg/model must not access database.DB or cachepkg.Redis (non-test code)' >&2; \
exit 1; \
fi
golangci-lint run
diff --git a/cmd/banner.go b/cmd/banner.go
index 0bf4dc72..f2779a9c 100644
--- a/cmd/banner.go
+++ b/cmd/banner.go
@@ -14,7 +14,7 @@ import (
"github.com/Rain-kl/Wavelet/pkg/buildinfo"
"github.com/Rain-kl/Wavelet/pkg/config"
- "github.com/Rain-kl/Wavelet/pkg/persistence/migrator"
+ "github.com/Rain-kl/Wavelet/pkg/migrator"
)
//nolint:unused // startup banner formatting utilities
diff --git a/cmd/banner_test.go b/cmd/banner_test.go
index d5a38ed1..de64db75 100644
--- a/cmd/banner_test.go
+++ b/cmd/banner_test.go
@@ -9,7 +9,7 @@ import (
"github.com/Rain-kl/Wavelet/pkg/buildinfo"
"github.com/Rain-kl/Wavelet/pkg/config"
- "github.com/Rain-kl/Wavelet/pkg/persistence/migrator"
+ "github.com/Rain-kl/Wavelet/pkg/migrator"
)
func TestFormatStartupBanner(t *testing.T) {
diff --git a/cmd/reset_passwd.go b/cmd/reset_passwd.go
index 30c24552..8f247b28 100644
--- a/cmd/reset_passwd.go
+++ b/cmd/reset_passwd.go
@@ -13,9 +13,9 @@ import (
"os"
"strings"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/persistence/migrator"
+ "github.com/Rain-kl/Wavelet/pkg/migrator"
userdomain "github.com/Rain-kl/Wavelet/plugins/domain/user"
+ "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/plugins/domain/auth"
"github.com/spf13/cobra"
@@ -90,7 +90,7 @@ var resetPasswdCmd = &cobra.Command{
log.Fatalf("加密密码失败: %v\n", err)
}
- err = db.DB(ctx).Transaction(func(tx *gorm.DB) error {
+ err = database.DB(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Model(&user).Update("password", user.Password).Error; err != nil {
return err
}
diff --git a/cmd/root.go b/cmd/root.go
index 68aa339e..62272801 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -12,7 +12,7 @@ import (
"github.com/Rain-kl/Wavelet/pkg/buildinfo"
"github.com/Rain-kl/Wavelet/pkg/config"
"github.com/Rain-kl/Wavelet/pkg/logger"
- "github.com/Rain-kl/Wavelet/pkg/persistence/migrator"
+ "github.com/Rain-kl/Wavelet/pkg/migrator"
"github.com/Rain-kl/Wavelet/pkg/trace"
"github.com/spf13/cobra"
)
diff --git a/coverage.out b/coverage.out
deleted file mode 100644
index 3ed5407e..00000000
--- a/coverage.out
+++ /dev/null
@@ -1,7437 +0,0 @@
-mode: atomic
-github.com/Rain-kl/Wavelet/main.go:20.13,22.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:73.39,75.18 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:75.18,77.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:78.2,79.46 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:79.46,82.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:83.2,85.13 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:86.16,87.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:88.16,89.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:90.16,91.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:92.10,93.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:96.2,96.32 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:96.32,97.30 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:97.30,99.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:100.3,100.47 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:102.2,102.46 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:106.69,108.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:108.16,110.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:112.2,114.79 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:114.79,116.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:116.8,118.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:120.2,121.42 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:121.42,123.15 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:123.15,125.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:126.3,126.38 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:127.8,129.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:131.2,132.145 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:132.145,134.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:136.2,137.43 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:137.43,139.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:139.8,141.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:143.2,150.8 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:154.71,159.72 4 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:159.72,161.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:161.8,163.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:165.2,167.124 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:167.124,169.15 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:169.15,171.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:172.3,172.38 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:173.8,175.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:177.2,178.147 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:178.147,180.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:182.2,184.141 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:184.141,186.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:186.8,187.44 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:187.44,189.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:189.9,191.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:194.2,201.8 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:215.36,217.19 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:217.19,220.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:222.2,225.37 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:225.37,227.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:227.8,229.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:231.2,231.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:231.16,234.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:236.2,236.46 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:250.35,252.19 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:252.19,255.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:257.2,260.37 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:260.37,262.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:262.8,264.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:266.2,266.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:266.16,269.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:271.2,271.44 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:275.37,277.48 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:277.48,280.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:282.2,283.19 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:283.19,286.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:289.2,292.93 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:292.93,295.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:297.2,298.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:298.16,300.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:301.2,302.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:302.16,304.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:306.2,307.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:307.16,310.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:311.2,311.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:311.15,313.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:315.2,316.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:316.16,319.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:321.2,322.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:322.16,325.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:327.2,331.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:335.85,337.18 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:337.18,340.26 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:340.26,342.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:344.3,344.54 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:344.54,346.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:348.3,349.32 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:349.32,351.33 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:351.33,354.37 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:354.37,356.6 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:357.5,357.29 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:358.10,358.42 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:358.42,360.37 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:360.37,362.6 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:363.5,363.26 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:364.10,366.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:368.3,368.36 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:370.2,370.21 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:374.103,376.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:376.16,378.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:379.2,379.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:379.15,381.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:383.2,384.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:384.16,386.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:388.2,389.18 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:389.18,392.26 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:392.26,394.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:396.3,396.54 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:396.54,398.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:400.3,401.32 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:401.32,403.33 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:403.33,405.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:405.10,407.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:409.3,409.36 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:412.2,419.8 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:423.106,425.21 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:425.21,427.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:429.2,434.8 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:451.33,453.47 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:453.47,456.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:458.2,459.19 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:459.19,462.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:464.2,465.22 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:465.22,468.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:470.2,476.35 5 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:476.35,477.38 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:477.38,479.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:483.2,486.13 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:486.13,488.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:488.8,490.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:492.2,492.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:492.16,495.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/db_manage/routers.go:497.2,497.42 1 0
-github.com/Rain-kl/Wavelet/docs/docs.go:8469.13,8471.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/logics.go:12.71,14.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:35.37,38.2 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:54.40,56.47 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:56.47,59.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:61.2,63.121 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:63.121,66.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:68.2,68.123 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:68.123,71.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:73.2,73.120 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:73.120,76.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:78.2,80.41 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:94.33,95.59 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:95.59,98.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/cache/routers.go:99.2,99.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/middlewares.go:18.43,19.30 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/middlewares.go:19.30,27.83 4 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/middlewares.go:27.83,29.19 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/middlewares.go:29.19,32.5 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/middlewares.go:35.3,35.20 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/middlewares.go:35.20,38.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/middlewares.go:41.3,44.11 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:47.43,50.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:50.16,54.3 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:55.2,56.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:56.16,60.3 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:61.2,62.29 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:62.29,64.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:65.2,74.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:77.55,79.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:79.16,80.46 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:80.46,82.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:83.3,83.33 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:85.2,85.11 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:85.11,87.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:88.2,88.10 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:91.50,92.35 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:92.35,93.37 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:93.37,95.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:96.3,96.35 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:98.2,98.38 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:98.38,100.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/log_database.go:101.2,101.19 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:73.39,75.18 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:75.18,77.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:78.2,79.46 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:79.46,82.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:83.2,85.13 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:86.16,87.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:88.16,89.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:90.16,91.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:92.10,93.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:101.2,101.32 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:101.32,102.30 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:102.30,104.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:105.3,105.47 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:107.2,107.46 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:111.45,118.14 6 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:118.14,120.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:121.2,121.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:121.15,123.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:124.2,124.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:124.17,126.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:127.2,127.30 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:127.30,129.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:130.2,130.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:143.38,151.9 6 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:152.49,153.73 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:154.20,155.24 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:156.10,157.21 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:160.2,161.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:161.17,163.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:163.8,165.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:167.2,198.41 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:209.62,215.21 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:215.21,217.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:218.2,219.19 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:219.19,221.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:222.2,223.92 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:223.92,225.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:226.2,226.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:230.64,237.19 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:237.19,239.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:240.2,241.85 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:241.85,243.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:244.2,244.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:257.38,259.37 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:259.37,261.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:261.8,263.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:264.2,264.42 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:278.37,279.37 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:279.37,281.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:281.8,283.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:287.35,289.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:289.16,291.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:293.2,294.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:294.16,297.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:298.2,298.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:298.15,299.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:299.45,301.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:304.2,305.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:305.16,308.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:310.2,314.71 5 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:318.37,323.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:323.16,326.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:328.2,337.26 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:337.26,339.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:339.8,341.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:343.2,351.34 7 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/status/routers.go:351.34,354.3 1 0
-github.com/Rain-kl/Wavelet/core/extpoints/migration.go:31.48,35.2 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/migration.go:39.82,44.34 4 3
-github.com/Rain-kl/Wavelet/core/extpoints/migration.go:44.34,46.3 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/migration.go:48.2,55.45 2 3
-github.com/Rain-kl/Wavelet/core/extpoints/migration.go:55.45,56.31 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/migration.go:56.31,57.30 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/migration.go:57.30,59.10 2 1
-github.com/Rain-kl/Wavelet/core/extpoints/migration.go:62.8,64.3 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/migration.go:66.2,66.28 1 3
-github.com/Rain-kl/Wavelet/core/extpoints/migration.go:70.56,76.2 5 1
-github.com/Rain-kl/Wavelet/core/extpoints/migration.go:79.73,84.2 4 2
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:41.42,43.2 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:46.50,50.2 3 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:53.46,59.2 5 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:62.83,68.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:71.87,83.2 5 15
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:86.76,88.2 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:91.77,93.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:96.76,98.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:101.79,103.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:106.78,108.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:111.77,113.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:116.80,118.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:121.78,124.28 3 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:124.28,126.3 1 7
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:127.2,127.13 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:131.53,137.2 5 4
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:147.47,149.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:152.80,163.2 5 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:166.84,184.2 9 16
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:187.73,189.2 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:192.74,194.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:197.73,199.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:202.76,204.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:207.75,209.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:212.74,214.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:217.77,219.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:222.75,225.28 3 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:225.28,227.3 1 7
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:228.2,228.13 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:232.50,234.2 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:237.43,241.2 3 1
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:243.33,244.13 1 33
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:244.13,246.3 1 0
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:247.2,247.32 1 33
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:247.32,249.3 1 0
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:250.2,250.45 1 33
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:250.45,252.3 1 0
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:253.2,253.10 1 33
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:256.46,257.31 1 17
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:257.31,259.3 1 0
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:260.2,260.39 1 17
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:260.39,262.3 1 0
-github.com/Rain-kl/Wavelet/core/extpoints/router.go:263.2,265.41 3 17
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:17.61,18.38 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:18.38,19.24 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:19.24,21.4 1 0
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:22.3,22.24 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:42.46,46.2 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:49.104,60.27 4 4
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:60.27,61.17 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:61.17,63.4 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:66.2,66.45 1 4
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:66.45,67.36 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:67.36,68.33 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:68.33,70.10 2 1
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:73.8,75.3 1 3
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:77.2,77.25 1 4
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:81.108,83.2 1 3
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:86.61,92.2 5 2
-github.com/Rain-kl/Wavelet/core/extpoints/schedule.go:95.76,100.2 4 2
-github.com/Rain-kl/Wavelet/core/extpoints/setting.go:32.44,36.2 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/setting.go:40.58,41.22 1 5
-github.com/Rain-kl/Wavelet/core/extpoints/setting.go:41.22,42.62 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/setting.go:45.2,48.47 3 4
-github.com/Rain-kl/Wavelet/core/extpoints/setting.go:48.47,49.34 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/setting.go:49.34,50.30 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/setting.go:50.30,52.10 2 1
-github.com/Rain-kl/Wavelet/core/extpoints/setting.go:55.8,57.3 1 3
-github.com/Rain-kl/Wavelet/core/extpoints/setting.go:59.2,59.31 1 4
-github.com/Rain-kl/Wavelet/core/extpoints/setting.go:63.53,69.2 5 2
-github.com/Rain-kl/Wavelet/core/extpoints/setting.go:72.65,77.2 4 2
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:22.54,23.34 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:23.34,25.3 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:29.42,30.34 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:30.34,32.3 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:36.56,37.34 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:37.34,39.3 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:43.55,44.34 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:44.34,45.25 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:45.25,47.4 1 0
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:48.3,48.25 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:67.38,71.2 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:74.82,84.27 4 3
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:84.27,85.17 1 7
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:85.17,87.4 1 6
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:90.2,90.44 1 3
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:90.44,91.32 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:91.32,92.31 1 1
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:92.31,94.10 2 1
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:97.8,99.3 1 2
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:101.2,101.24 1 3
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:105.49,111.2 5 2
-github.com/Rain-kl/Wavelet/core/extpoints/task.go:114.67,119.2 4 2
-github.com/Rain-kl/Wavelet/core/app.go:23.42,24.22 1 8
-github.com/Rain-kl/Wavelet/core/app.go:24.22,25.17 1 8
-github.com/Rain-kl/Wavelet/core/app.go:25.17,27.4 1 8
-github.com/Rain-kl/Wavelet/core/app.go:32.45,33.22 1 12
-github.com/Rain-kl/Wavelet/core/app.go:33.22,35.3 1 12
-github.com/Rain-kl/Wavelet/core/app.go:39.47,40.22 1 14
-github.com/Rain-kl/Wavelet/core/app.go:40.22,42.3 1 14
-github.com/Rain-kl/Wavelet/core/app.go:46.60,47.22 1 0
-github.com/Rain-kl/Wavelet/core/app.go:47.22,49.3 1 0
-github.com/Rain-kl/Wavelet/core/app.go:53.60,54.22 1 2
-github.com/Rain-kl/Wavelet/core/app.go:54.22,56.3 1 2
-github.com/Rain-kl/Wavelet/core/app.go:60.59,61.22 1 2
-github.com/Rain-kl/Wavelet/core/app.go:61.22,62.18 1 2
-github.com/Rain-kl/Wavelet/core/app.go:62.18,64.4 1 2
-github.com/Rain-kl/Wavelet/core/app.go:85.37,93.27 2 22
-github.com/Rain-kl/Wavelet/core/app.go:93.27,94.17 1 38
-github.com/Rain-kl/Wavelet/core/app.go:94.17,96.4 1 38
-github.com/Rain-kl/Wavelet/core/app.go:99.2,99.12 1 22
-github.com/Rain-kl/Wavelet/core/app.go:103.34,105.2 1 5
-github.com/Rain-kl/Wavelet/core/app.go:108.33,112.2 3 9
-github.com/Rain-kl/Wavelet/core/app.go:115.49,120.2 4 8
-github.com/Rain-kl/Wavelet/core/app.go:123.48,125.2 1 1
-github.com/Rain-kl/Wavelet/core/app.go:129.43,133.28 3 15
-github.com/Rain-kl/Wavelet/core/app.go:133.28,134.15 1 17
-github.com/Rain-kl/Wavelet/core/app.go:134.15,135.12 1 1
-github.com/Rain-kl/Wavelet/core/app.go:137.3,138.17 2 16
-github.com/Rain-kl/Wavelet/core/app.go:138.17,139.12 1 0
-github.com/Rain-kl/Wavelet/core/app.go:142.3,142.45 1 16
-github.com/Rain-kl/Wavelet/core/app.go:142.45,143.39 1 1
-github.com/Rain-kl/Wavelet/core/app.go:143.39,144.32 1 1
-github.com/Rain-kl/Wavelet/core/app.go:144.32,146.11 2 1
-github.com/Rain-kl/Wavelet/core/app.go:149.9,151.4 1 15
-github.com/Rain-kl/Wavelet/core/app.go:152.3,152.24 1 16
-github.com/Rain-kl/Wavelet/core/app.go:155.2,155.10 1 15
-github.com/Rain-kl/Wavelet/core/app.go:159.34,166.2 5 2
-github.com/Rain-kl/Wavelet/core/app.go:169.50,175.2 4 3
-github.com/Rain-kl/Wavelet/core/app.go:178.63,183.2 4 0
-github.com/Rain-kl/Wavelet/core/app.go:186.63,188.2 1 0
-github.com/Rain-kl/Wavelet/core/app.go:192.36,194.15 2 21
-github.com/Rain-kl/Wavelet/core/app.go:194.15,197.3 2 0
-github.com/Rain-kl/Wavelet/core/app.go:198.2,203.28 5 21
-github.com/Rain-kl/Wavelet/core/app.go:203.28,204.40 1 13
-github.com/Rain-kl/Wavelet/core/app.go:204.40,206.4 1 1
-github.com/Rain-kl/Wavelet/core/app.go:208.2,208.12 1 20
-github.com/Rain-kl/Wavelet/core/app.go:212.56,214.23 2 20
-github.com/Rain-kl/Wavelet/core/app.go:214.23,216.3 1 17
-github.com/Rain-kl/Wavelet/core/app.go:218.2,222.19 4 3
-github.com/Rain-kl/Wavelet/core/app.go:222.19,224.85 1 1
-github.com/Rain-kl/Wavelet/core/app.go:224.85,226.4 1 1
-github.com/Rain-kl/Wavelet/core/app.go:229.2,229.19 1 3
-github.com/Rain-kl/Wavelet/core/app.go:229.19,231.3 1 0
-github.com/Rain-kl/Wavelet/core/app.go:233.2,233.53 1 3
-github.com/Rain-kl/Wavelet/core/app.go:233.53,235.3 1 1
-github.com/Rain-kl/Wavelet/core/app.go:237.2,237.12 1 2
-github.com/Rain-kl/Wavelet/core/app.go:247.51,249.15 2 22
-github.com/Rain-kl/Wavelet/core/app.go:249.15,252.3 2 1
-github.com/Rain-kl/Wavelet/core/app.go:253.2,257.9 4 21
-github.com/Rain-kl/Wavelet/core/app.go:258.37,259.19 1 21
-github.com/Rain-kl/Wavelet/core/app.go:260.20,261.30 1 0
-github.com/Rain-kl/Wavelet/core/app.go:262.10,263.33 1 0
-github.com/Rain-kl/Wavelet/core/app.go:267.2,267.41 1 21
-github.com/Rain-kl/Wavelet/core/app.go:267.41,272.3 4 1
-github.com/Rain-kl/Wavelet/core/app.go:275.2,275.49 1 20
-github.com/Rain-kl/Wavelet/core/app.go:275.49,280.3 4 1
-github.com/Rain-kl/Wavelet/core/app.go:283.2,289.31 6 19
-github.com/Rain-kl/Wavelet/core/app.go:289.31,290.37 1 30
-github.com/Rain-kl/Wavelet/core/app.go:290.37,292.4 1 15
-github.com/Rain-kl/Wavelet/core/app.go:296.2,296.35 1 19
-github.com/Rain-kl/Wavelet/core/app.go:296.35,297.42 1 14
-github.com/Rain-kl/Wavelet/core/app.go:297.42,305.43 6 1
-github.com/Rain-kl/Wavelet/core/app.go:305.43,307.5 1 1
-github.com/Rain-kl/Wavelet/core/app.go:309.4,309.72 1 1
-github.com/Rain-kl/Wavelet/core/app.go:312.3,314.16 3 13
-github.com/Rain-kl/Wavelet/core/app.go:318.2,320.12 2 18
-github.com/Rain-kl/Wavelet/core/app.go:330.50,332.16 2 19
-github.com/Rain-kl/Wavelet/core/app.go:332.16,335.3 2 1
-github.com/Rain-kl/Wavelet/core/app.go:336.2,343.35 7 18
-github.com/Rain-kl/Wavelet/core/app.go:343.35,345.3 1 18
-github.com/Rain-kl/Wavelet/core/app.go:345.8,349.3 3 0
-github.com/Rain-kl/Wavelet/core/app.go:351.2,356.41 3 18
-github.com/Rain-kl/Wavelet/core/app.go:356.41,358.45 2 12
-github.com/Rain-kl/Wavelet/core/app.go:358.45,360.4 1 0
-github.com/Rain-kl/Wavelet/core/app.go:364.2,364.41 1 18
-github.com/Rain-kl/Wavelet/core/app.go:364.41,365.41 1 18
-github.com/Rain-kl/Wavelet/core/app.go:365.41,367.4 1 0
-github.com/Rain-kl/Wavelet/core/app.go:370.2,372.29 2 18
-github.com/Rain-kl/Wavelet/core/app.go:379.49,381.9 2 8
-github.com/Rain-kl/Wavelet/core/app.go:382.37,383.18 1 8
-github.com/Rain-kl/Wavelet/core/app.go:384.20,385.29 1 0
-github.com/Rain-kl/Wavelet/core/app.go:386.10,387.32 1 0
-github.com/Rain-kl/Wavelet/core/app.go:390.2,393.40 3 8
-github.com/Rain-kl/Wavelet/core/app.go:393.40,395.3 1 0
-github.com/Rain-kl/Wavelet/core/app.go:398.2,403.28 4 8
-github.com/Rain-kl/Wavelet/core/app.go:407.32,411.2 3 7
-github.com/Rain-kl/Wavelet/core/app.go:414.41,421.2 5 2
-github.com/Rain-kl/Wavelet/core/app.go:424.48,426.18 2 7
-github.com/Rain-kl/Wavelet/core/app.go:426.18,428.3 1 7
-github.com/Rain-kl/Wavelet/core/app.go:428.8,430.3 1 0
-github.com/Rain-kl/Wavelet/core/app.go:431.2,431.46 1 7
-github.com/Rain-kl/Wavelet/core/app.go:437.80,439.23 2 7
-github.com/Rain-kl/Wavelet/core/app.go:439.23,441.3 1 0
-github.com/Rain-kl/Wavelet/core/app.go:443.2,444.22 2 7
-github.com/Rain-kl/Wavelet/core/app.go:444.22,446.10 2 7
-github.com/Rain-kl/Wavelet/core/app.go:447.47,448.62 1 1
-github.com/Rain-kl/Wavelet/core/app.go:449.40,450.55 1 1
-github.com/Rain-kl/Wavelet/core/app.go:451.39,452.28 1 5
-github.com/Rain-kl/Wavelet/core/app.go:456.2,457.19 2 7
-github.com/Rain-kl/Wavelet/core/app.go:460.58,462.14 2 30
-github.com/Rain-kl/Wavelet/core/app.go:463.22,464.14 1 9
-github.com/Rain-kl/Wavelet/core/app.go:465.18,466.30 1 5
-github.com/Rain-kl/Wavelet/core/app.go:467.21,468.32 1 4
-github.com/Rain-kl/Wavelet/core/app.go:469.23,470.35 1 8
-github.com/Rain-kl/Wavelet/core/app.go:471.10,472.36 1 4
-github.com/Rain-kl/Wavelet/core/app.go:476.42,477.55 1 50
-github.com/Rain-kl/Wavelet/core/app.go:478.21,479.20 1 10
-github.com/Rain-kl/Wavelet/core/app.go:480.16,481.23 1 8
-github.com/Rain-kl/Wavelet/core/app.go:482.39,483.25 1 12
-github.com/Rain-kl/Wavelet/core/app.go:484.34,485.20 1 15
-github.com/Rain-kl/Wavelet/core/app.go:486.10,487.11 1 5
-github.com/Rain-kl/Wavelet/core/container.go:19.49,25.2 1 96
-github.com/Rain-kl/Wavelet/core/container.go:27.24,28.14 1 14
-github.com/Rain-kl/Wavelet/core/container.go:28.14,30.3 1 1
-github.com/Rain-kl/Wavelet/core/container.go:31.2,32.18 2 13
-github.com/Rain-kl/Wavelet/core/container.go:33.121,34.19 1 13
-github.com/Rain-kl/Wavelet/core/container.go:35.10,36.15 1 0
-github.com/Rain-kl/Wavelet/core/container.go:41.46,42.16 1 15
-github.com/Rain-kl/Wavelet/core/container.go:42.16,43.49 1 1
-github.com/Rain-kl/Wavelet/core/container.go:45.2,45.20 1 14
-github.com/Rain-kl/Wavelet/core/container.go:45.20,46.44 1 2
-github.com/Rain-kl/Wavelet/core/container.go:49.2,50.46 2 12
-github.com/Rain-kl/Wavelet/core/container.go:53.67,60.38 5 12
-github.com/Rain-kl/Wavelet/core/container.go:60.38,61.94 1 1
-github.com/Rain-kl/Wavelet/core/container.go:61.94,63.4 1 1
-github.com/Rain-kl/Wavelet/core/container.go:65.2,67.31 2 12
-github.com/Rain-kl/Wavelet/core/container.go:67.31,69.3 1 1
-github.com/Rain-kl/Wavelet/core/container.go:73.45,75.16 2 130
-github.com/Rain-kl/Wavelet/core/container.go:75.16,77.3 1 1
-github.com/Rain-kl/Wavelet/core/container.go:79.2,81.16 3 129
-github.com/Rain-kl/Wavelet/core/container.go:81.16,83.3 1 10
-github.com/Rain-kl/Wavelet/core/container.go:85.2,86.9 2 119
-github.com/Rain-kl/Wavelet/core/container.go:86.9,88.3 1 0
-github.com/Rain-kl/Wavelet/core/container.go:89.2,89.22 1 119
-github.com/Rain-kl/Wavelet/core/container.go:92.67,95.43 2 130
-github.com/Rain-kl/Wavelet/core/container.go:95.43,98.3 2 119
-github.com/Rain-kl/Wavelet/core/container.go:101.2,101.44 1 11
-github.com/Rain-kl/Wavelet/core/container.go:101.44,102.34 1 11
-github.com/Rain-kl/Wavelet/core/container.go:102.34,103.50 1 4
-github.com/Rain-kl/Wavelet/core/container.go:103.50,106.5 2 0
-github.com/Rain-kl/Wavelet/core/container.go:109.2,112.21 2 11
-github.com/Rain-kl/Wavelet/core/container.go:112.21,114.3 1 1
-github.com/Rain-kl/Wavelet/core/container.go:116.2,116.66 1 10
-github.com/Rain-kl/Wavelet/core/container.go:120.40,122.16 2 2
-github.com/Rain-kl/Wavelet/core/container.go:122.16,123.89 1 1
-github.com/Rain-kl/Wavelet/core/container.go:125.2,125.10 1 1
-github.com/Rain-kl/Wavelet/core/container.go:129.36,132.2 2 4
-github.com/Rain-kl/Wavelet/core/container.go:135.56,137.16 2 52
-github.com/Rain-kl/Wavelet/core/container.go:137.16,139.3 1 1
-github.com/Rain-kl/Wavelet/core/container.go:140.2,141.12 2 51
-github.com/Rain-kl/Wavelet/core/container.go:145.68,148.32 3 3
-github.com/Rain-kl/Wavelet/core/container.go:148.32,150.3 1 2
-github.com/Rain-kl/Wavelet/core/container.go:151.2,152.12 2 1
-github.com/Rain-kl/Wavelet/core/container.go:156.79,160.47 4 2
-github.com/Rain-kl/Wavelet/core/container.go:160.47,162.3 1 1
-github.com/Rain-kl/Wavelet/core/container.go:163.2,164.12 2 1
-github.com/Rain-kl/Wavelet/core/container.go:169.46,170.16 1 3
-github.com/Rain-kl/Wavelet/core/container.go:170.16,171.46 1 1
-github.com/Rain-kl/Wavelet/core/container.go:174.2,178.42 3 2
-github.com/Rain-kl/Wavelet/core/container.go:178.42,180.3 1 1
-github.com/Rain-kl/Wavelet/core/container.go:183.2,185.74 3 2
-github.com/Rain-kl/Wavelet/core/container.go:185.74,186.31 1 1
-github.com/Rain-kl/Wavelet/core/container.go:186.31,188.4 1 1
-github.com/Rain-kl/Wavelet/core/context.go:41.48,42.17 1 42
-github.com/Rain-kl/Wavelet/core/context.go:42.17,44.3 1 2
-github.com/Rain-kl/Wavelet/core/context.go:45.2,58.3 2 42
-github.com/Rain-kl/Wavelet/core/context.go:62.60,64.2 1 1
-github.com/Rain-kl/Wavelet/core/context.go:67.42,69.2 1 2
-github.com/Rain-kl/Wavelet/core/context.go:72.31,74.2 1 1
-github.com/Rain-kl/Wavelet/core/context.go:78.38,80.32 2 4
-github.com/Rain-kl/Wavelet/core/context.go:80.32,83.3 2 1
-github.com/Rain-kl/Wavelet/core/context.go:84.2,86.39 2 3
-github.com/Rain-kl/Wavelet/core/context.go:86.39,88.3 1 0
-github.com/Rain-kl/Wavelet/core/context.go:90.2,90.21 1 3
-github.com/Rain-kl/Wavelet/core/context.go:90.21,92.3 1 2
-github.com/Rain-kl/Wavelet/core/context.go:94.2,94.12 1 1
-github.com/Rain-kl/Wavelet/core/context.go:98.47,100.2 1 8
-github.com/Rain-kl/Wavelet/core/context.go:103.41,106.21 3 101
-github.com/Rain-kl/Wavelet/core/context.go:106.21,108.3 1 0
-github.com/Rain-kl/Wavelet/core/context.go:109.2,109.21 1 101
-github.com/Rain-kl/Wavelet/core/context.go:113.44,116.21 3 50
-github.com/Rain-kl/Wavelet/core/context.go:116.21,118.3 1 0
-github.com/Rain-kl/Wavelet/core/context.go:119.2,120.14 2 50
-github.com/Rain-kl/Wavelet/core/context.go:124.42,126.2 1 143
-github.com/Rain-kl/Wavelet/core/context.go:129.37,131.2 1 1
-github.com/Rain-kl/Wavelet/core/context.go:135.35,137.2 1 53
-github.com/Rain-kl/Wavelet/core/context.go:142.66,143.17 1 54
-github.com/Rain-kl/Wavelet/core/context.go:143.17,145.3 1 1
-github.com/Rain-kl/Wavelet/core/context.go:146.2,166.14 6 54
-github.com/Rain-kl/Wavelet/core/context.go:170.38,172.2 1 114
-github.com/Rain-kl/Wavelet/core/context.go:175.54,177.2 1 57
-github.com/Rain-kl/Wavelet/core/context.go:180.61,182.2 1 80
-github.com/Rain-kl/Wavelet/core/context.go:185.51,187.2 1 57
-github.com/Rain-kl/Wavelet/core/context.go:190.50,192.2 1 3
-github.com/Rain-kl/Wavelet/core/context.go:195.59,197.2 1 57
-github.com/Rain-kl/Wavelet/core/context.go:200.58,202.2 1 3
-github.com/Rain-kl/Wavelet/core/context.go:205.57,207.2 1 57
-github.com/Rain-kl/Wavelet/core/context.go:210.56,212.2 1 3
-github.com/Rain-kl/Wavelet/core/context.go:216.37,217.15 1 8
-github.com/Rain-kl/Wavelet/core/context.go:217.15,219.3 1 1
-github.com/Rain-kl/Wavelet/core/context.go:221.2,222.24 2 7
-github.com/Rain-kl/Wavelet/core/context.go:223.16,224.8 1 1
-github.com/Rain-kl/Wavelet/core/context.go:225.20,226.8 1 3
-github.com/Rain-kl/Wavelet/core/context.go:227.14,228.20 1 2
-github.com/Rain-kl/Wavelet/core/context.go:228.20,231.4 2 2
-github.com/Rain-kl/Wavelet/core/context.go:232.10,233.83 1 1
-github.com/Rain-kl/Wavelet/core/context.go:236.2,238.38 3 6
-github.com/Rain-kl/Wavelet/core/context.go:242.35,244.16 2 21
-github.com/Rain-kl/Wavelet/core/context.go:244.16,247.3 2 1
-github.com/Rain-kl/Wavelet/core/context.go:248.2,261.42 8 20
-github.com/Rain-kl/Wavelet/core/context.go:261.42,262.47 1 1
-github.com/Rain-kl/Wavelet/core/context.go:262.47,264.4 1 1
-github.com/Rain-kl/Wavelet/core/context.go:268.2,268.43 1 20
-github.com/Rain-kl/Wavelet/core/context.go:268.43,269.40 1 6
-github.com/Rain-kl/Wavelet/core/context.go:269.40,271.4 1 1
-github.com/Rain-kl/Wavelet/core/context.go:275.2,275.21 1 20
-github.com/Rain-kl/Wavelet/core/context.go:275.21,277.3 1 20
-github.com/Rain-kl/Wavelet/core/context.go:280.2,280.21 1 20
-github.com/Rain-kl/Wavelet/core/context.go:280.21,282.3 1 1
-github.com/Rain-kl/Wavelet/core/context.go:284.2,284.29 1 20
-github.com/Rain-kl/Wavelet/core/context.go:287.48,290.35 3 1
-github.com/Rain-kl/Wavelet/core/context.go:290.35,291.22 1 1
-github.com/Rain-kl/Wavelet/core/context.go:291.22,293.9 2 1
-github.com/Rain-kl/Wavelet/core/context.go:299.37,303.2 3 23
-github.com/Rain-kl/Wavelet/core/context.go:306.50,307.14 1 33
-github.com/Rain-kl/Wavelet/core/context.go:307.14,309.3 1 1
-github.com/Rain-kl/Wavelet/core/context.go:311.2,314.12 4 32
-github.com/Rain-kl/Wavelet/core/context.go:318.38,325.2 5 20
-github.com/Rain-kl/Wavelet/core/context.go:328.64,332.30 3 3
-github.com/Rain-kl/Wavelet/core/context.go:332.30,333.29 1 5
-github.com/Rain-kl/Wavelet/core/context.go:333.29,335.4 1 2
-github.com/Rain-kl/Wavelet/core/context.go:337.2,337.19 1 1
-github.com/Rain-kl/Wavelet/core/events.go:35.30,39.2 1 50
-github.com/Rain-kl/Wavelet/core/events.go:54.59,55.20 1 78
-github.com/Rain-kl/Wavelet/core/events.go:55.20,56.46 1 1
-github.com/Rain-kl/Wavelet/core/events.go:59.2,62.35 3 77
-github.com/Rain-kl/Wavelet/core/events.go:62.35,63.74 1 1
-github.com/Rain-kl/Wavelet/core/events.go:66.2,67.30 2 76
-github.com/Rain-kl/Wavelet/core/events.go:67.30,68.104 1 1
-github.com/Rain-kl/Wavelet/core/events.go:71.2,72.16 2 75
-github.com/Rain-kl/Wavelet/core/events.go:72.16,73.103 1 1
-github.com/Rain-kl/Wavelet/core/events.go:76.2,77.17 2 74
-github.com/Rain-kl/Wavelet/core/events.go:77.17,79.44 2 62
-github.com/Rain-kl/Wavelet/core/events.go:79.44,80.89 1 1
-github.com/Rain-kl/Wavelet/core/events.go:82.3,82.20 1 61
-github.com/Rain-kl/Wavelet/core/events.go:85.2,92.15 2 73
-github.com/Rain-kl/Wavelet/core/events.go:93.9,93.9 0 10
-github.com/Rain-kl/Wavelet/core/events.go:95.9,97.39 2 5
-github.com/Rain-kl/Wavelet/core/events.go:97.39,99.4 1 2
-github.com/Rain-kl/Wavelet/core/events.go:99.9,102.4 2 3
-github.com/Rain-kl/Wavelet/core/events.go:103.9,105.40 2 58
-github.com/Rain-kl/Wavelet/core/events.go:105.40,106.98 1 1
-github.com/Rain-kl/Wavelet/core/events.go:108.3,110.34 3 57
-github.com/Rain-kl/Wavelet/core/events.go:113.2,120.22 6 72
-github.com/Rain-kl/Wavelet/core/events.go:120.22,121.26 1 29
-github.com/Rain-kl/Wavelet/core/events.go:121.26,123.4 1 1
-github.com/Rain-kl/Wavelet/core/events.go:125.3,129.26 4 28
-github.com/Rain-kl/Wavelet/core/events.go:129.26,130.26 1 94
-github.com/Rain-kl/Wavelet/core/events.go:130.26,132.10 2 28
-github.com/Rain-kl/Wavelet/core/events.go:136.3,136.34 1 28
-github.com/Rain-kl/Wavelet/core/events.go:136.34,138.4 1 4
-github.com/Rain-kl/Wavelet/core/events.go:140.3,140.13 1 28
-github.com/Rain-kl/Wavelet/core/events.go:145.111,146.16 1 2
-github.com/Rain-kl/Wavelet/core/events.go:146.16,147.59 1 1
-github.com/Rain-kl/Wavelet/core/events.go:149.2,149.31 1 1
-github.com/Rain-kl/Wavelet/core/events.go:157.79,158.16 1 164
-github.com/Rain-kl/Wavelet/core/events.go:158.16,160.3 1 1
-github.com/Rain-kl/Wavelet/core/events.go:162.2,164.28 3 164
-github.com/Rain-kl/Wavelet/core/events.go:164.28,167.3 2 72
-github.com/Rain-kl/Wavelet/core/events.go:169.2,174.20 5 92
-github.com/Rain-kl/Wavelet/core/events.go:174.20,176.3 1 91
-github.com/Rain-kl/Wavelet/core/events.go:178.2,179.30 2 92
-github.com/Rain-kl/Wavelet/core/events.go:179.30,182.32 2 242
-github.com/Rain-kl/Wavelet/core/events.go:182.32,183.17 1 242
-github.com/Rain-kl/Wavelet/core/events.go:183.17,184.33 1 242
-github.com/Rain-kl/Wavelet/core/events.go:184.33,186.6 1 1
-github.com/Rain-kl/Wavelet/core/events.go:189.4,190.63 2 242
-github.com/Rain-kl/Wavelet/core/events.go:190.63,192.5 1 2
-github.com/Rain-kl/Wavelet/core/events.go:193.4,193.17 1 241
-github.com/Rain-kl/Wavelet/core/events.go:196.3,196.17 1 242
-github.com/Rain-kl/Wavelet/core/events.go:196.17,198.4 1 3
-github.com/Rain-kl/Wavelet/core/events.go:201.2,201.29 1 92
-github.com/Rain-kl/Wavelet/core/events.go:204.110,205.18 1 242
-github.com/Rain-kl/Wavelet/core/events.go:205.18,207.3 1 8
-github.com/Rain-kl/Wavelet/core/events.go:209.2,210.14 2 234
-github.com/Rain-kl/Wavelet/core/events.go:210.14,212.3 1 231
-github.com/Rain-kl/Wavelet/core/events.go:214.2,214.18 1 234
-github.com/Rain-kl/Wavelet/core/events.go:214.18,217.3 2 232
-github.com/Rain-kl/Wavelet/core/events.go:219.2,219.13 1 234
-github.com/Rain-kl/Wavelet/core/events.go:222.100,223.27 1 232
-github.com/Rain-kl/Wavelet/core/events.go:223.27,225.3 1 0
-github.com/Rain-kl/Wavelet/core/events.go:227.2,230.38 2 232
-github.com/Rain-kl/Wavelet/core/events.go:230.38,232.3 1 228
-github.com/Rain-kl/Wavelet/core/events.go:235.2,235.39 1 4
-github.com/Rain-kl/Wavelet/core/events.go:235.39,237.3 1 1
-github.com/Rain-kl/Wavelet/core/events.go:240.2,240.82 1 3
-github.com/Rain-kl/Wavelet/core/events.go:240.82,241.26 1 2
-github.com/Rain-kl/Wavelet/core/events.go:241.26,243.4 1 1
-github.com/Rain-kl/Wavelet/core/events.go:244.3,244.34 1 1
-github.com/Rain-kl/Wavelet/core/events.go:248.2,248.85 1 1
-github.com/Rain-kl/Wavelet/core/events.go:248.85,252.3 3 1
-github.com/Rain-kl/Wavelet/core/events.go:255.2,255.33 1 0
-github.com/Rain-kl/Wavelet/core/events.go:259.48,263.2 3 5
-github.com/Rain-kl/Wavelet/core/events.go:266.38,271.28 4 1
-github.com/Rain-kl/Wavelet/core/events.go:271.28,273.3 1 1
-github.com/Rain-kl/Wavelet/core/events.go:274.2,274.15 1 1
-github.com/Rain-kl/Wavelet/core/manifest.go:30.36,31.37 1 2
-github.com/Rain-kl/Wavelet/core/manifest.go:31.37,33.3 1 1
-github.com/Rain-kl/Wavelet/core/manifest.go:34.2,34.12 1 1
-github.com/Rain-kl/Wavelet/core/types.go:104.88,106.2 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:54.30,59.64 4 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:59.64,62.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:63.2,63.76 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:63.76,65.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:66.2,66.22 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:66.22,68.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:70.2,76.22 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:76.22,78.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:80.2,80.42 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:94.41,98.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:98.16,100.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:101.2,101.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:101.15,101.35 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:104.2,109.17 4 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:109.17,111.7 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:111.7,113.18 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:113.18,115.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:120.2,120.6 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:120.6,121.10 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:122.15,123.10 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:124.26,125.11 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:125.11,127.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:128.4,131.56 4 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:131.56,133.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:160.98,164.20 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:164.20,166.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:166.17,168.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:169.3,169.27 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:172.2,172.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:172.41,174.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:176.2,176.57 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:176.57,177.58 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:177.58,179.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:182.2,182.51 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:182.51,183.56 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:183.56,185.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:188.2,188.20 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:191.58,192.59 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:192.59,194.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:195.2,195.49 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:198.75,199.20 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:199.20,201.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:203.2,205.28 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:205.28,206.37 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:206.37,207.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:209.3,210.41 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:213.2,214.71 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:214.71,215.27 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:215.27,217.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:219.2,219.22 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:219.22,220.46 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:220.46,223.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:245.36,248.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:248.16,251.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:253.2,254.14 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:254.14,256.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:257.2,258.18 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:258.18,260.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:261.2,261.28 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:261.28,263.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:265.2,266.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:266.16,269.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:270.2,270.55 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:270.55,273.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:275.2,276.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:276.16,279.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:280.2,280.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:280.16,283.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:285.2,286.31 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:286.31,299.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:300.2,305.5 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:346.39,349.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:349.16,352.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:354.2,357.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:357.16,360.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:361.2,362.36 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:362.36,367.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:369.2,370.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:370.16,373.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:374.2,375.38 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:375.38,380.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:382.2,383.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:383.16,386.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:388.2,390.38 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:390.38,396.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:398.2,398.22 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:398.22,404.24 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:404.24,405.28 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:405.28,413.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:415.3,415.27 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:415.27,416.61 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:416.61,419.5 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/routers.go:423.2,427.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:57.78,59.52 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:59.52,61.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:62.2,63.28 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:63.28,65.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:66.2,67.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:67.16,69.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:70.2,70.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:73.39,74.11 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:75.36,76.24 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:77.31,78.22 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:79.30,80.26 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:82.2,82.10 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:85.33,87.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:90.101,92.52 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:92.52,94.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:95.2,96.54 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:96.54,98.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:100.2,101.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:101.16,104.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:105.2,107.59 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:107.59,109.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:110.2,110.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:110.15,111.51 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:111.51,113.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:116.2,116.48 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:116.48,118.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:120.2,121.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:121.16,123.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:124.2,125.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:125.16,127.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:129.2,129.61 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:129.61,131.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:132.2,133.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:133.16,135.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:136.2,136.36 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:136.36,137.76 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:137.76,139.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:142.2,142.58 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:142.58,144.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:145.2,145.55 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:145.55,147.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:148.2,150.111 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:153.63,155.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:155.16,157.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:158.2,158.22 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:158.22,160.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:161.2,161.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:162.24,163.40 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:163.40,165.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:166.22,167.38 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:167.38,169.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:170.20,171.37 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:171.37,173.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:175.2,175.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:178.62,180.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:180.16,182.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:183.2,183.21 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:183.21,185.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:186.2,186.23 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:189.60,191.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:193.64,195.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:197.78,200.6 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:200.6,202.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:202.17,204.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:205.3,205.21 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:205.21,206.9 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:208.3,208.67 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:208.67,210.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:211.3,214.32 4 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:214.32,215.9 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/tasks.go:218.2,218.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:20.40,22.43 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:22.43,24.20 2 7
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:24.20,26.5 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:29.4,30.55 2 6
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:30.55,32.5 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:35.4,36.115 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:36.115,39.44 3 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:39.44,41.68 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:41.68,43.7 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:46.4,46.16 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:52.60,53.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:53.13,56.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:57.2,58.25 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:58.25,60.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/logs/utils.go:61.2,62.18 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:51.38,53.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:53.16,56.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:57.2,57.45 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:73.39,75.47 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:75.47,78.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:80.2,91.82 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:91.82,94.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:95.2,97.44 3 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:115.39,117.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:117.16,120.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:122.2,123.47 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:123.47,126.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:129.2,144.94 4 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:144.94,147.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:151.2,151.21 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:151.21,153.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:154.2,158.16 4 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:158.16,161.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:162.2,163.45 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:180.39,182.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:182.16,185.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:187.2,188.47 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:188.47,191.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:193.2,193.91 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:193.91,196.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:197.2,198.41 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:213.39,215.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:215.16,218.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:219.2,219.77 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:219.77,222.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:223.2,224.41 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:227.52,229.15 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:229.15,231.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:232.2,233.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:233.16,235.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:236.2,237.73 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:237.73,239.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:240.2,240.16 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/auth_source/routers.go:245.50,250.2 4 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:22.45,24.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:34.35,36.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:36.16,39.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:40.2,40.42 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:54.36,56.47 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:56.47,59.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:60.2,61.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:61.16,64.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:65.2,65.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:81.36,83.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:83.16,86.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:87.2,88.47 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:88.47,91.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:92.2,93.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:93.16,94.40 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:94.40,97.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:98.3,99.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:101.2,101.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:114.36,116.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:116.16,119.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:120.2,120.63 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:120.63,121.40 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:121.40,124.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:125.3,126.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:128.2,128.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:142.34,144.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:144.16,147.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:148.2,148.62 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:148.62,149.40 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:149.40,152.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:153.3,154.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/handlers.go:156.2,156.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:80.40,100.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:102.87,104.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:104.16,106.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:107.2,109.16 3 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:109.16,111.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:112.2,113.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:113.16,115.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:116.2,117.24 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:117.24,119.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:120.2,128.66 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:128.66,130.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:131.2,131.38 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:134.98,136.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:136.16,137.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:137.45,139.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:140.3,140.27 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:142.2,143.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:143.16,145.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:146.2,147.21 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:147.21,149.17 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:149.17,151.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:152.3,152.18 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:154.2,154.24 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:154.24,156.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:157.2,157.59 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:157.59,159.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:160.2,160.56 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:160.56,162.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:163.2,163.62 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:163.62,165.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:166.2,166.24 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:166.24,168.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:169.2,169.27 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:169.27,171.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:172.2,172.24 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:172.24,174.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:175.2,175.61 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:175.61,177.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:178.2,179.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:179.16,181.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:182.2,184.66 3 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:184.66,186.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:187.2,187.38 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:190.62,192.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:192.16,194.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:195.2,196.22 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:196.22,198.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:198.17,200.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:201.3,201.77 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:203.2,203.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:206.58,207.65 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:207.65,208.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:208.45,210.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:211.3,211.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:213.2,213.49 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:216.57,218.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:218.16,219.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:219.45,221.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:222.3,222.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:224.2,225.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:225.16,227.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:228.2,229.70 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:229.70,231.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:232.2,232.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:235.100,239.13 4 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:240.40,242.57 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:242.57,244.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:245.34,248.60 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:248.60,250.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:250.9,252.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:253.3,253.63 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:253.63,255.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:256.10,257.46 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:259.2,259.56 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:259.56,261.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:262.2,262.26 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:265.69,266.13 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:267.40,268.50 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:268.50,270.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:271.34,272.95 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:272.95,274.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:275.10,276.36 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:278.2,278.12 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:281.82,291.49 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:291.49,293.3 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:294.2,294.56 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:294.56,296.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:297.2,297.50 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:297.50,299.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:300.2,302.12 3 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:305.94,306.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:307.40,309.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:309.17,311.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:312.3,314.17 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:314.17,316.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:317.3,318.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:318.17,320.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:321.3,321.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:321.16,321.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:322.3,324.39 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:324.39,326.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:327.3,330.55 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:330.55,332.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:333.3,333.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:333.17,335.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:336.3,336.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:337.34,343.13 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/logics.go:344.10,345.36 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/routers.go:10.51,12.2 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/message_gateway/routers.go:12.2,19.3 6 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/custom_events/admin_login.go:27.74,28.23 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/custom_events/admin_login.go:28.23,30.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/custom_events/admin_login.go:32.2,37.52 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/custom_events/register.go:14.17,17.2 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:20.44,22.2 1 16
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:24.83,25.35 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:25.35,27.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:28.2,29.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:29.16,31.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:32.2,32.12 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:32.12,34.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:36.2,43.68 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:43.68,45.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:47.2,48.76 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:48.76,50.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:51.2,51.12 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:54.94,56.2 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:58.83,60.2 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:62.95,63.31 1 6
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:63.31,65.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:66.2,67.16 2 6
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:67.16,69.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:71.2,72.41 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:72.41,74.75 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:74.75,76.4 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:78.3,79.17 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:79.17,81.4 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:82.3,82.27 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:85.2,85.59 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:85.59,89.28 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:89.28,92.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:93.3,93.75 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:93.75,96.4 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:97.3,97.66 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:97.66,99.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:100.3,101.13 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:102.17,104.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:106.2,107.12 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:116.3,117.65 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:117.65,119.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:121.2,122.66 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:122.66,124.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:125.2,125.37 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:125.37,127.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:129.2,134.16 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/logics.go:134.16,136.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:61.41,63.47 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:63.47,66.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:67.2,67.35 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:67.35,70.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:72.2,72.69 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:72.69,73.37 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:73.37,76.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:77.3,78.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:81.2,81.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:96.40,98.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:98.16,101.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:103.2,103.25 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:103.25,105.3 1 39
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:107.2,107.45 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:123.38,125.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:125.16,126.45 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:126.45,128.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:128.9,130.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:131.3,131.9 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:134.2,136.44 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:155.41,157.47 2 6
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:157.47,160.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:162.2,163.31 2 6
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:163.31,166.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:167.2,167.74 1 6
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:167.74,168.45 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:168.45,171.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:172.3,172.42 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:172.42,175.4 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:176.3,177.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:180.2,180.41 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:183.68,184.73 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:184.73,186.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:187.2,187.33 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:187.33,189.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:192.73,195.41 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:195.41,200.3 4 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:201.2,201.47 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:201.47,204.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:206.2,206.76 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:206.76,208.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:238.31,240.47 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:240.47,243.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:245.2,246.35 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:246.35,247.111 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:247.111,249.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:252.2,269.16 6 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:269.16,271.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:273.2,273.42 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:276.53,285.2 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:287.52,288.17 1 40
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:288.17,290.3 1 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:291.2,291.13 1 35
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:292.35,293.27 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:294.36,296.61 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:296.61,298.52 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:298.52,300.5 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:303.2,303.14 1 34
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:308.109,310.75 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:310.75,312.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:314.2,315.63 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:315.63,317.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:320.2,321.88 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:321.88,323.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:326.2,327.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:327.16,329.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:331.2,331.33 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:334.111,335.63 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:335.63,339.42 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:339.42,341.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:342.3,342.22 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:342.22,344.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:345.3,345.72 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:345.72,347.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:348.3,350.60 3 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:353.2,353.62 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:353.62,355.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:356.2,356.61 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:359.84,362.2 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:364.103,366.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:366.16,368.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:369.2,369.46 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:369.46,371.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/system_config/routers.go:372.2,372.12 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:29.45,31.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:41.35,43.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:43.16,46.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:47.2,47.46 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:71.36,73.47 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:73.47,76.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:78.2,79.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:79.16,82.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:83.2,83.45 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:107.36,109.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:109.16,112.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:114.2,115.47 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:115.47,118.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:120.2,121.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:121.16,122.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:122.45,125.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:126.3,127.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:129.2,129.45 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:141.36,143.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:143.16,146.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:148.2,148.67 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:148.67,149.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:149.45,152.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:153.3,154.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:156.2,156.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:179.34,181.47 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:181.47,184.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:186.2,188.16 3 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:188.16,191.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:193.2,193.33 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:193.33,195.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:197.2,205.47 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:205.47,208.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:209.2,213.21 4 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:214.19,216.23 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:217.20,218.86 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:219.23,220.89 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:221.10,230.59 3 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:233.2,244.54 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:244.54,247.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:248.2,248.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:261.40,264.26 3 15
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:264.26,266.3 1 15
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:267.2,267.10 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels.go:270.73,278.2 7 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels_definition.go:48.48,52.2 3 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels_definition.go:55.37,62.26 5 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels_definition.go:62.26,63.34 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels_definition.go:63.34,65.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels_definition.go:68.2,68.32 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels_definition.go:68.32,70.27 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels_definition.go:70.27,71.14 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels_definition.go:71.14,73.10 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels_definition.go:76.3,76.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels_definition.go:76.13,78.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels_definition.go:80.2,80.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/channels_definition.go:83.13,183.2 4 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:32.55,38.26 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:38.26,40.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:41.2,41.12 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:65.47,67.2 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:78.94,80.17 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:80.17,81.18 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:81.18,83.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:84.3,84.66 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:84.66,86.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:88.3,89.17 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:89.17,90.46 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:90.46,92.5 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:93.4,94.10 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:96.3,97.31 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:97.31,99.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:101.3,103.60 3 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:107.157,112.26 4 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:112.26,115.17 3 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:115.17,119.4 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:120.8,122.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:124.2,124.20 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:124.20,126.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:127.2,127.25 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:127.25,128.56 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:128.56,129.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:131.3,131.39 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:131.39,133.4 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:136.2,136.30 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:139.153,144.72 4 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:144.72,146.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:148.2,148.61 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:148.61,150.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:150.8,152.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:153.2,155.67 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:155.67,157.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:157.8,159.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:160.2,162.61 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:162.61,164.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:164.8,166.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:167.2,170.35 3 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:173.110,179.37 5 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:179.37,181.46 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:181.46,182.36 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:182.36,184.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:184.10,186.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:189.2,189.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:192.156,193.45 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:193.45,195.17 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:195.17,197.12 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:199.3,199.104 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:203.197,204.29 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:204.29,207.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:209.2,209.39 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:209.39,212.3 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:215.168,219.22 3 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:220.19,222.35 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:223.20,225.86 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:226.23,227.113 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:228.10,236.48 3 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:236.48,238.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:239.3,239.71 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:242.2,249.54 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:249.54,251.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:254.70,256.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:256.16,258.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:259.2,260.12 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:263.54,265.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:265.16,267.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:268.2,269.60 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:269.60,271.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:273.2,275.19 3 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:278.73,279.22 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:279.22,281.19 2 21
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:281.19,283.4 1 17
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:284.3,284.46 1 21
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:284.46,286.4 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:286.9,288.4 1 19
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:292.104,294.18 2 14
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:294.18,296.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:298.2,299.37 2 14
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:299.37,301.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:302.2,302.74 1 12
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:302.74,304.3 1 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:306.2,307.12 2 7
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:307.12,309.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:310.2,310.49 1 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:310.49,312.3 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:313.2,313.52 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:313.52,315.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:316.2,316.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:319.75,320.16 1 14
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:321.23,322.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:322.41,324.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:325.3,325.36 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:325.36,327.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:328.35,329.47 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:329.47,331.4 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:332.3,332.42 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:332.42,334.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:335.34,336.44 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:336.44,338.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:339.3,339.39 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:339.39,341.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/events.go:343.2,343.15 1 10
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:27.53,38.2 5 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:40.51,41.37 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:41.37,43.45 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:43.45,45.83 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:45.83,47.5 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:48.4,56.66 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:56.66,58.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:59.9,59.24 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:59.24,61.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:63.2,63.12 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:66.69,68.2 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:70.92,72.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:72.16,74.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:76.2,77.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:77.16,79.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:80.2,80.15 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:80.15,82.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:84.2,85.23 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:85.23,87.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:87.8,89.71 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:89.71,91.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:94.2,95.21 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:95.21,97.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:98.2,99.20 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:99.20,101.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:103.2,112.41 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:112.41,114.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:115.2,115.64 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:115.64,117.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:118.2,118.19 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:121.60,123.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:123.16,125.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:126.2,126.48 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:129.84,131.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:131.16,133.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:135.2,139.41 5 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:139.41,141.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:142.2,142.46 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:145.68,147.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:147.16,149.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:151.2,152.41 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:152.41,154.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:155.2,155.80 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:155.80,157.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:158.2,158.21 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:161.122,163.2 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:165.78,166.69 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:166.69,168.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:169.2,170.44 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:170.44,172.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:173.2,174.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:174.16,176.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:177.2,179.28 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:182.73,184.2 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:186.98,188.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:188.16,190.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:191.2,191.15 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:191.15,193.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:195.2,204.43 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:204.43,206.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:207.2,207.68 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:207.68,209.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:210.2,210.21 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:213.109,215.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:215.16,217.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:219.2,225.43 7 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:225.43,227.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:228.2,228.66 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:228.66,230.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:231.2,231.21 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:234.62,236.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:236.16,238.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:239.2,239.52 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:242.110,243.20 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:243.20,245.17 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:245.17,247.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:248.3,248.70 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:250.2,250.53 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:253.102,255.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:257.72,258.51 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:258.51,260.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:262.2,262.57 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:262.57,263.67 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:263.67,265.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:268.2,268.55 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:268.55,269.75 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:269.75,271.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:273.2,273.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:276.91,280.17 4 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:280.17,282.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:283.2,283.17 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:283.17,285.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:287.2,288.18 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:288.18,289.27 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:289.27,293.34 4 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:293.34,295.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:296.9,298.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:301.2,311.52 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:314.91,318.64 3 7
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:318.64,319.60 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:319.60,322.4 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:324.2,324.12 1 7
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:324.12,325.72 1 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:325.72,328.4 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:330.2,330.20 1 7
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:333.95,334.69 1 12
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:334.69,336.3 1 7
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:337.2,338.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:338.16,340.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:341.2,341.54 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:341.54,343.3 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:344.2,344.57 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:344.57,346.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:347.2,347.23 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:350.96,351.30 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:351.30,353.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:354.2,355.44 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:355.44,357.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:358.2,359.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:359.16,361.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:362.2,362.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:362.15,364.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:365.2,365.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:365.17,367.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:368.2,368.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:368.17,370.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:371.2,371.26 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:374.53,377.2 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:379.75,380.24 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:380.24,382.18 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:382.18,384.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:385.3,393.17 5 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:393.17,395.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:396.3,396.56 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:399.2,399.24 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:399.24,401.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:403.2,404.12 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:404.12,406.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:408.2,409.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:409.16,411.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/logics.go:412.2,412.59 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:38.44,40.2 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:50.33,53.16 3 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:53.16,56.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:57.2,57.44 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:70.57,71.37 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:71.37,72.22 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:72.22,74.4 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:76.2,76.31 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:87.40,89.2 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:101.34,103.47 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:103.47,106.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:108.2,109.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:109.16,112.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:113.2,113.43 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:125.34,127.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:127.16,130.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:132.2,132.65 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:132.65,133.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:133.45,136.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:137.3,138.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:140.2,140.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:154.34,156.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:156.16,159.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:161.2,162.47 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:162.47,165.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:167.2,167.70 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:167.70,168.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:168.45,171.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:172.3,173.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:175.2,175.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:187.34,189.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:189.16,192.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:194.2,195.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:195.16,196.45 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:196.45,199.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:200.3,201.9 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:203.2,203.45 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:226.36,229.14 3 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:229.14,231.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:232.2,232.18 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:232.18,234.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:236.2,242.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:242.16,245.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:247.2,250.5 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:263.31,265.47 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:265.47,268.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:270.2,271.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:271.16,274.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:275.2,275.58 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:275.58,278.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:280.2,287.103 3 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:287.103,290.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/routers.go:291.2,291.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:18.30,20.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:22.119,24.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:24.16,27.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:28.2,28.22 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:28.22,30.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:32.2,40.20 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:40.20,42.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:42.8,44.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:45.2,45.19 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:45.19,47.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:47.8,49.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:51.2,52.29 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:52.29,53.80 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:53.80,56.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:58.2,58.42 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:58.42,60.75 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:60.75,63.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:66.2,66.31 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:66.31,73.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:76.88,77.51 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:77.51,79.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:80.2,80.57 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:80.57,82.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:85.56,86.57 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:86.57,88.24 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:88.24,89.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:91.3,91.26 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:92.16,93.14 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:93.14,95.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:96.12,97.14 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:97.14,99.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:100.14,101.14 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:101.14,103.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:104.15,105.18 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:106.15,107.59 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:107.59,109.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:112.2,112.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:115.50,116.54 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:116.54,117.43 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:117.43,118.44 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:118.44,120.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/task_listener.go:123.2,123.11 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:57.71,58.23 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:58.23,60.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:62.2,63.54 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:63.54,65.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:67.2,67.30 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:67.30,69.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:71.2,71.26 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:75.94,77.54 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:77.54,80.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:82.2,85.16 3 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:85.16,88.31 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:88.31,90.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:91.3,91.22 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:95.2,101.16 5 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:101.16,103.25 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:103.25,105.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:106.3,106.31 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:106.31,108.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:109.3,109.56 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:112.2,113.24 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:113.24,115.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:116.2,120.8 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:123.105,124.72 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/push/tasks.go:124.72,126.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:14.93,16.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:16.16,18.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:19.2,19.12 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:19.12,21.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:23.2,32.40 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:32.40,34.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:35.2,35.62 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:35.62,37.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:38.2,38.18 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:41.67,43.2 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:45.75,47.2 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:49.105,51.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:51.16,53.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:55.2,60.40 6 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:60.40,62.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:63.2,63.60 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:63.60,65.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:66.2,66.18 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:69.60,71.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:71.16,73.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:74.2,74.19 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:74.19,76.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/logics.go:77.2,77.46 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:35.62,36.16 1 7
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:36.16,38.3 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:39.2,39.44 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:39.44,42.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:43.2,44.13 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:45.53,47.14 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:49.2,50.13 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:67.37,69.47 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:69.47,72.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:74.2,75.37 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:75.37,77.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:79.2,79.42 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:93.36,95.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:95.16,98.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:100.2,100.47 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:116.34,118.37 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:118.37,120.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:122.2,122.42 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:141.37,143.47 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:143.47,146.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:148.2,149.37 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:149.37,151.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:153.2,153.42 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:170.37,171.97 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:171.97,173.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/template/routers.go:175.2,175.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:36.36,38.2 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:63.35,65.47 2 6
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:65.47,68.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:70.2,71.17 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:71.17,74.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:76.2,77.42 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:77.42,79.3 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:81.2,82.16 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:82.16,85.3 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:87.2,88.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:88.16,91.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:93.2,93.44 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:110.41,112.48 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:112.48,115.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:117.2,117.24 1 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:117.24,118.58 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:118.58,120.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:123.2,124.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:124.16,127.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:129.2,134.5 1 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:150.39,152.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:152.16,155.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:157.2,158.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:158.16,161.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:163.2,163.47 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:180.32,182.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:182.16,185.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:187.2,188.16 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:188.16,190.10 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:191.46,192.37 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:193.158,194.39 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:195.11,196.74 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:198.3,198.9 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:201.2,201.47 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:214.36,216.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:216.16,219.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:220.2,220.47 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:246.37,248.47 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:248.47,251.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:254.2,254.56 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:254.56,257.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:260.2,261.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:261.17,264.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:267.2,268.42 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:268.42,270.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:271.2,272.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:272.16,275.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:277.2,285.81 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:285.81,288.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:291.2,291.52 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:291.52,293.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:295.2,295.46 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:323.37,325.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:325.16,328.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:330.2,331.47 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:331.47,334.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:337.2,338.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:338.16,341.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:344.2,344.56 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:344.56,347.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:350.2,351.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:351.17,354.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:357.2,358.42 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:358.42,360.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:361.2,362.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:362.16,365.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:367.2,373.81 6 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:373.81,376.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:379.2,379.52 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:379.52,381.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:383.2,383.46 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:399.37,401.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:401.16,404.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:406.2,406.75 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:406.75,409.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:412.2,412.52 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:412.52,414.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/task/routers.go:416.2,416.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:90.46,92.39 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:92.39,94.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:95.2,95.38 1 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:95.38,97.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:98.2,98.30 1 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:98.30,100.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:101.2,101.16 1 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:104.50,106.15 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:106.15,108.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:110.2,110.35 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:110.35,112.55 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:112.55,114.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:115.3,115.46 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:118.2,119.71 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:119.71,121.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:122.2,123.54 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:123.54,125.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:126.2,126.18 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:129.43,131.31 2 8
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:131.31,133.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:134.2,134.89 1 8
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:137.58,139.76 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:139.76,141.28 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:141.28,143.33 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:143.33,145.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:146.4,146.112 1 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:149.2,149.14 1 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:152.108,157.35 4 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:157.35,159.37 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:159.37,160.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:162.3,163.40 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:163.40,165.39 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:165.39,166.27 1 7
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:166.27,168.11 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:171.4,171.79 1 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:171.79,172.13 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:174.4,174.77 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:174.77,178.5 3 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:182.2,182.27 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:182.27,184.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:185.2,185.37 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:188.109,195.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:195.16,197.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:198.2,203.16 5 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:203.16,205.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:206.2,206.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:206.15,209.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:210.2,210.38 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:210.38,212.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:214.2,216.50 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:216.50,218.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:220.2,221.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:221.16,223.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:224.2,225.28 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:228.58,230.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:230.16,232.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:233.2,233.38 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:236.77,238.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:238.16,240.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:241.2,242.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:242.16,244.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:246.2,266.15 5 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:269.111,270.52 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:270.52,272.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:273.2,275.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:275.16,277.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:278.2,281.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:281.16,283.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:284.2,284.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:284.15,287.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:288.2,288.38 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:288.38,290.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:292.2,293.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:293.16,295.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:297.2,298.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:298.16,301.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:302.2,302.37 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:302.37,304.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:305.2,305.55 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:305.55,307.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:308.2,309.12 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:312.64,314.116 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:314.116,316.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:317.2,319.100 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:319.100,321.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:322.2,322.20 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:325.61,326.39 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:326.39,327.32 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:327.32,328.42 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:328.42,330.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:331.9,332.25 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:332.25,334.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:337.2,337.14 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:340.77,344.31 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:344.31,346.85 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:346.85,348.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:349.3,349.34 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:349.34,350.24 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:350.24,352.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:354.3,354.30 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:357.2,357.76 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:357.76,359.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:360.2,362.14 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:365.69,366.11 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:366.11,368.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:369.2,375.34 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:375.34,376.36 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:376.36,378.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:381.2,381.31 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:381.31,383.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:386.2,386.62 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:389.81,391.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:391.16,393.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:394.2,394.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:394.15,396.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:398.2,399.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:399.16,401.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:402.2,402.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:402.15,404.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:406.2,408.6 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:408.6,410.29 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:410.29,411.9 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:413.3,413.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:413.17,415.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:416.3,416.101 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:416.101,418.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:421.2,421.24 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:421.24,423.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:426.2,426.32 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:426.32,427.55 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:427.55,429.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:432.2,432.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:435.79,437.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:437.16,439.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:440.2,440.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:440.15,442.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:444.2,445.35 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:445.35,446.91 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:446.91,448.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:451.2,451.24 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:451.24,453.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:456.2,456.32 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:456.32,457.55 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:457.55,459.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:462.2,462.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:465.122,467.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:467.16,469.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:471.2,473.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:473.16,475.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:476.2,476.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:476.15,479.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:480.2,481.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:481.16,483.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:484.2,484.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:484.15,487.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:489.2,490.6 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:490.6,492.29 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:492.29,493.9 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:495.3,495.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:495.17,497.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:498.3,498.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:498.41,499.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:501.3,502.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:502.17,504.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:505.3,506.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:506.17,508.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:509.3,511.21 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:511.21,513.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:514.3,514.22 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:514.22,516.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:517.3,517.31 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:517.31,519.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:520.3,521.21 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:523.2,523.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:526.120,528.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:528.16,530.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:532.2,534.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:534.16,536.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:537.2,537.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:537.15,540.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:541.2,541.35 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:541.35,542.39 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:542.39,543.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:545.3,546.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:546.17,548.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:549.3,550.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:550.17,552.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:553.3,554.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:554.17,557.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:558.3,561.21 4 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:561.21,563.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:564.3,564.27 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:564.27,566.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:567.3,567.28 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:567.28,569.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:570.3,570.31 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:570.31,572.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:573.3,574.21 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:576.2,576.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:579.79,580.31 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:580.31,582.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:583.2,583.47 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:583.47,585.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:587.2,589.17 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:589.17,591.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:593.2,594.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:594.16,596.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:597.2,597.29 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:597.29,599.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:601.2,604.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:604.16,606.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:607.2,608.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:608.16,610.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:612.2,613.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:613.16,615.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:617.2,618.75 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:618.75,622.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:624.2,628.43 4 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:628.43,630.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:630.8,632.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:633.2,633.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:633.16,637.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:638.2,640.38 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/logics.go:643.35,647.2 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/restart_unix.go:20.63,25.65 4 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/restart_unix.go:25.65,27.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/restart_unix.go:29.2,29.54 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/restart_unix.go:29.54,31.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/restart_unix.go:33.2,33.60 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/restart_unix.go:33.60,36.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/restart_unix.go:38.2,38.66 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/restart_unix.go:38.66,42.3 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/restart_unix.go:44.2,49.56 4 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/routers.go:29.38,31.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/routers.go:31.16,35.3 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/routers.go:36.2,36.44 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/routers.go:51.34,53.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/routers.go:53.16,57.3 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/routers.go:59.2,62.17 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/routers.go:62.17,64.69 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/updater/routers.go:64.69,67.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/custom/routers.go:23.28,25.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/health/routers.go:23.29,25.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:29.92,31.59 2 4
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:31.59,33.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:34.2,35.62 2 4
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:35.62,37.17 2 2
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:37.17,39.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:40.3,41.17 2 2
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:41.17,43.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:44.3,45.17 2 2
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:45.17,47.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:48.3,52.5 2 2
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:55.2,57.41 3 2
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:57.41,63.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/inbound.go:64.2,67.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:32.26,33.34 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:33.34,36.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:46.39,52.36 3 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:52.36,54.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:55.2,57.6 3 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:57.6,58.10 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:59.21,61.20 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:62.19,63.68 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:63.68,65.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:66.4,66.38 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:66.38,68.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:79.51,81.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:81.16,83.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:84.2,85.27 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:85.27,87.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:89.2,92.33 3 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:92.33,94.65 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:94.65,96.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:99.2,99.28 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:99.28,100.19 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:100.19,101.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:103.3,103.33 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:103.33,104.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:106.3,106.49 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:106.49,108.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:110.2,110.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:113.84,114.33 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:114.33,117.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:119.2,120.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:120.16,123.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:124.2,125.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:125.9,127.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:129.2,135.77 3 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:135.77,138.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:139.108,140.19 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:140.19,142.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:143.4,143.34 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:146.2,152.73 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:152.73,153.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:153.16,154.36 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:154.36,156.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:158.3,158.31 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:160.2,160.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:160.16,163.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:164.2,165.43 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:165.43,169.3 3 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:170.2,173.12 4 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:176.62,178.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:178.9,180.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:181.2,182.47 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:182.47,184.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:185.2,186.24 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:189.48,192.28 3 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:192.28,194.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:197.68,198.21 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:198.21,200.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:201.2,202.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:202.16,205.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:206.2,206.11 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:209.60,210.21 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:210.21,212.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:213.2,215.6 3 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:215.6,216.10 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:217.21,218.10 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:219.19,220.56 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:225.63,226.21 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:226.21,228.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:229.2,229.42 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:232.32,234.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/runner/runner.go:236.22,239.2 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:17.54,19.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:30.35,31.52 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:31.52,34.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:35.2,36.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:36.16,39.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:40.2,40.42 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:52.35,54.24 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:54.24,57.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:58.2,59.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:59.16,62.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:63.2,63.42 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:78.34,80.24 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:80.24,83.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:84.2,85.47 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:85.47,88.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:89.2,90.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:90.16,91.46 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:91.46,94.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:95.3,96.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:98.2,98.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:112.36,114.24 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:114.24,117.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:118.2,119.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:119.16,122.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:123.2,123.72 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:123.72,124.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:124.41,127.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:128.3,128.42 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:128.42,131.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:132.3,133.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/handlers.go:135.2,135.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:36.91,38.34 2 3
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:38.34,40.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:41.2,42.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:42.16,44.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:45.2,46.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:46.16,47.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:47.45,49.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:50.3,50.27 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:52.2,52.42 1 3
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:52.42,54.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:55.2,55.36 1 2
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:55.36,57.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:58.2,59.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:59.16,60.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:60.45,62.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:63.3,63.27 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:65.2,65.17 1 2
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:65.17,67.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:69.2,70.59 2 2
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:70.59,72.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:73.2,73.35 1 2
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:73.35,74.32 1 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:74.32,76.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:77.3,78.41 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:81.2,86.66 2 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:86.66,88.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:89.2,89.72 1 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:89.72,91.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:92.2,92.35 1 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:102.81,104.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:104.16,106.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:107.2,108.27 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:108.27,110.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:111.2,111.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:114.81,116.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:116.16,118.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:119.2,120.22 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:120.22,122.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:122.17,124.12 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:126.3,126.48 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:128.2,128.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:131.73,133.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:133.16,134.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:134.45,136.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:137.3,137.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:139.2,139.26 1 2
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:139.26,141.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:142.2,142.56 1 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:145.83,153.15 2 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:153.15,156.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/logics.go:157.2,157.12 1 1
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/routers.go:13.55,16.2 3 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/routers.go:16.2,21.3 4 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:16.29,18.26 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:18.26,20.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:21.2,22.35 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:26.66,27.18 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:27.18,29.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:30.2,31.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:31.16,33.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:34.2,34.51 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:38.71,39.22 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:39.22,41.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:42.2,43.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:43.16,45.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:46.2,47.60 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:47.60,49.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:50.2,50.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:50.16,52.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:53.2,53.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:57.47,58.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:58.15,60.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:61.2,62.72 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:62.72,64.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:65.2,65.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:69.50,70.18 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:70.18,72.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:73.2,74.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:74.16,76.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/message_gateway/secret.go:77.2,77.20 1 0
-github.com/Rain-kl/Wavelet/internal/apps/config/routers.go:26.38,29.16 3 1
-github.com/Rain-kl/Wavelet/internal/apps/config/routers.go:29.16,32.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/config/routers.go:34.2,35.33 2 1
-github.com/Rain-kl/Wavelet/internal/apps/config/routers.go:35.33,37.3 1 14
-github.com/Rain-kl/Wavelet/internal/apps/config/routers.go:39.2,39.42 1 1
-github.com/Rain-kl/Wavelet/internal/apps/config/routers.go:49.35,53.27 4 0
-github.com/Rain-kl/Wavelet/internal/apps/config/routers.go:53.27,55.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/config/routers.go:56.2,56.69 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:35.61,40.2 1 4
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:43.98,45.16 2 4
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:45.16,47.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:49.2,55.67 2 4
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:67.117,69.18 2 53
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:69.18,71.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:73.2,76.16 3 53
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:76.16,78.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:80.2,82.28 3 53
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:82.28,84.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:86.2,87.16 2 53
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:87.16,89.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:90.2,90.10 1 53
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:90.10,92.3 1 49
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:94.2,95.16 2 4
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:95.16,97.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:99.2,108.80 8 4
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:108.80,110.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:112.2,116.8 1 4
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:120.102,121.17 1 54
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:121.17,123.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:124.2,125.35 2 54
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:125.35,127.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:128.2,137.16 7 54
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:137.16,139.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:140.2,140.13 1 54
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:140.13,142.3 1 51
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:144.2,145.38 2 3
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:145.38,147.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:149.2,150.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:150.16,152.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:153.2,155.56 2 3
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:155.56,157.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:159.2,159.37 1 3
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:159.37,161.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:163.2,163.18 1 3
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:166.95,167.18 1 54
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:167.18,169.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:170.2,170.37 1 54
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:179.35,180.17 1 3
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:180.17,182.87 2 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:182.87,184.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:185.3,185.23 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:185.23,187.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:189.3,190.77 2 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:190.77,192.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:192.9,194.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:196.3,196.45 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/manager.go:198.2,198.23 1 3
-github.com/Rain-kl/Wavelet/internal/apps/cap/middleware.go:13.67,14.30 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/middleware.go:14.30,15.46 1 4
-github.com/Rain-kl/Wavelet/internal/apps/cap/middleware.go:15.46,18.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/middleware.go:19.3,19.17 1 3
-github.com/Rain-kl/Wavelet/internal/apps/cap/middleware.go:19.17,22.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/middleware.go:24.3,25.18 2 3
-github.com/Rain-kl/Wavelet/internal/apps/cap/middleware.go:25.18,28.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/middleware.go:30.3,31.27 2 2
-github.com/Rain-kl/Wavelet/internal/apps/cap/middleware.go:31.27,34.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/middleware.go:36.3,36.11 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:38.32,42.21 3 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:42.21,44.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:46.2,47.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:47.16,50.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:51.2,52.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:52.16,56.3 3 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:58.2,58.42 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:72.29,74.47 2 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:74.47,77.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:79.2,79.21 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:79.21,81.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:83.2,84.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:84.16,87.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:88.2,89.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:89.16,93.3 3 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:95.2,95.19 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:95.19,98.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/routers.go:100.2,100.42 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:50.54,52.40 2 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:52.40,54.3 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:55.2,55.12 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:67.42,70.2 2 2
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:73.68,75.2 1 17
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:78.50,80.16 2 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:80.16,82.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:83.2,83.30 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:87.34,89.2 1 13
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:92.36,94.2 1 5
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:97.66,101.2 3 4
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:103.86,106.52 2 17
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:106.52,108.3 1 11
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:110.2,110.79 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:110.79,111.53 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:111.53,113.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:115.3,116.21 2 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:116.21,118.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:120.3,121.23 2 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:123.2,123.16 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:123.16,125.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:127.2,128.9 2 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:128.9,130.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:131.2,131.22 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:134.72,136.16 2 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:136.16,138.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:139.2,139.43 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:142.82,151.59 2 7
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:151.59,152.62 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:152.62,154.4 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:156.2,156.61 1 7
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:156.61,157.68 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:157.68,159.4 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:161.2,161.60 1 7
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:161.60,162.66 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:162.66,164.4 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:166.2,166.66 1 7
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:166.66,167.78 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:167.78,169.4 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:171.2,171.59 1 7
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:171.59,172.78 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:172.78,174.4 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:176.2,176.55 1 7
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:176.55,177.78 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:177.78,179.4 1 6
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:182.2,182.17 1 7
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:185.61,187.2 1 17
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:189.49,190.21 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:190.21,192.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:194.2,194.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:194.17,196.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:196.16,198.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:200.3,200.37 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:200.37,204.72 2 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:204.72,206.13 2 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:208.4,208.82 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/runtime_settings.go:208.82,210.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/cap/testhelper_hook.go:8.13,10.2 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:18.88,26.2 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:28.72,30.2 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:32.74,34.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:34.16,36.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:37.2,37.30 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:37.30,39.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:41.2,42.13 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:42.13,44.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:46.2,47.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:47.16,49.14 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:49.14,50.33 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:50.33,52.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:55.2,55.12 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:58.76,59.31 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:59.31,61.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:62.2,63.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:63.16,65.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:66.2,66.19 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:66.19,68.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:70.2,73.16 3 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:73.16,75.32 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:75.32,77.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:79.2,79.12 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:82.81,88.24 5 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:88.24,90.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:91.2,91.21 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:91.21,93.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:94.2,94.43 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:94.43,96.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:98.2,99.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:99.16,101.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:102.2,102.15 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:102.15,104.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:106.2,107.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:107.16,109.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:110.2,110.20 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:110.20,112.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:114.2,123.28 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:123.28,125.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:126.2,126.67 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:126.67,128.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:129.2,129.61 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:129.61,131.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:132.2,132.21 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:143.89,148.23 4 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:148.23,150.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:152.2,153.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:153.16,155.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:158.2,158.71 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:158.71,160.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:163.2,163.37 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:163.37,165.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:165.17,167.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:168.3,168.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:168.16,170.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:174.2,174.69 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:174.69,176.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:179.2,181.22 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:181.22,183.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:186.2,187.31 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:187.31,189.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:190.2,193.26 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:193.26,194.73 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:194.73,196.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:200.2,201.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:201.16,203.23 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:203.23,204.33 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:204.33,206.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/logics.go:209.2,209.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:58.49,60.27 2 9
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:60.27,63.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:64.2,64.17 1 9
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:67.32,85.2 1 6
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:87.118,88.16 1 10
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:88.16,90.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:91.2,91.44 1 8
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:91.44,94.3 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:95.2,96.35 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:96.35,97.15 1 9
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:97.15,100.4 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:102.2,102.34 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:102.34,103.15 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:103.15,106.4 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:108.2,110.13 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:126.32,128.48 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:128.48,131.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:133.2,134.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:134.16,138.3 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:140.2,141.39 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:141.39,143.3 1 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:145.2,148.5 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:165.30,167.9 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:167.9,169.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:171.2,172.57 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:172.57,174.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:176.2,176.56 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:200.39,202.47 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:202.47,205.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:207.2,208.9 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:208.9,210.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:212.2,212.80 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:212.80,213.78 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:213.78,215.4 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:216.3,217.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:220.2,220.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:237.33,239.9 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:239.9,241.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:243.2,244.73 2 4
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:244.73,245.95 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:245.95,247.4 1 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:248.3,249.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:252.2,252.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:279.33,281.47 2 5
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:281.47,284.3 2 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:286.2,287.132 2 3
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:287.132,289.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:291.2,291.53 1 1
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:318.33,320.47 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:320.47,323.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:325.2,326.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:326.9,328.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:330.2,339.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:339.16,340.137 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:340.137,342.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:343.3,344.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/admin/user/routers.go:347.2,347.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:25.41,28.22 3 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:28.22,30.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:32.2,33.130 2 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:33.130,35.30 2 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:35.30,36.19 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:36.19,37.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:39.4,39.30 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:41.3,42.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:42.17,44.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:45.3,45.53 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:47.93,49.19 2 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:49.19,51.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:52.4,52.108 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:54.134,56.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:58.2,58.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:58.16,61.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:63.2,65.64 3 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:69.47,71.19 2 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:71.19,73.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:74.2,74.25 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:78.26,80.19 2 4
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:80.19,82.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:83.2,83.24 1 4
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:87.55,89.37 2 1
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:89.37,91.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:92.2,92.28 1 1
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:96.87,101.16 5 3
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:101.16,105.3 3 3
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:108.71,112.2 3 5
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:117.39,119.19 2 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:119.19,121.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:122.2,123.22 2 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:123.22,125.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:126.2,129.6 4 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:129.6,130.24 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:130.24,131.27 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:131.27,133.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:133.10,133.52 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:133.52,135.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:136.9,138.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:139.3,139.10 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:140.21,141.20 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/logics.go:142.19,142.19 0 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:22.46,23.30 1 4
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:23.30,25.40 1 4
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:25.40,28.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:31.3,31.21 1 3
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:31.21,34.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:36.3,43.32 4 3
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:43.32,45.4 1 2
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:48.3,51.30 3 1
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:51.30,54.39 2 1
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:54.39,56.5 1 2
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:57.4,59.68 2 1
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:59.68,61.5 1 1
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:64.3,66.17 3 1
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:66.17,68.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:68.9,68.36 1 1
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:68.36,70.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/risk_control/middleware.go:72.3,86.26 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:34.34,38.2 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:41.73,43.117 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:43.117,47.3 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:48.2,53.117 4 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:53.117,55.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:57.2,60.30 4 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:63.74,65.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:65.16,67.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:68.2,68.9 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:68.9,70.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:72.2,75.60 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:75.60,77.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:79.2,80.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:80.16,83.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/access_state.go:85.2,87.14 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:22.88,24.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:27.98,28.46 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:28.46,30.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:32.2,35.54 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:35.54,37.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:39.2,39.26 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:39.26,41.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:43.2,45.63 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:45.63,47.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:47.8,49.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:51.2,52.61 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:52.61,54.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:56.2,57.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:57.16,59.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:60.2,61.59 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:61.59,63.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:64.2,64.20 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:68.105,70.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:70.16,72.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:73.2,77.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:77.16,79.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/migration.go:80.2,80.32 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/storage_ops.go:15.41,17.26 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/storage_ops.go:17.26,20.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/storage_ops.go:21.2,21.23 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/storage_ops.go:25.95,27.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/storage_ops.go:27.16,29.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/storage/storage_ops.go:30.2,30.42 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:13.40,14.71 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:14.71,15.20 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:15.20,17.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:19.2,19.14 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:23.42,24.82 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:24.82,25.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:25.15,27.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:29.2,29.14 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:33.43,34.131 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:34.131,35.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:35.15,37.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:39.2,39.14 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:43.51,44.34 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:45.82,46.34 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/media.go:47.10,48.35 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:25.38,26.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:26.15,28.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:30.2,30.38 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:30.38,32.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:34.2,34.33 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:34.33,36.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:38.2,38.35 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:38.35,40.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:42.2,42.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:47.79,49.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:49.16,51.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:53.2,54.34 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:55.30,56.20 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:57.33,58.20 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:59.35,60.20 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:61.10,62.20 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:65.2,70.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:70.16,72.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/util/utils.go:74.2,74.25 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/audit.go:18.73,30.16 3 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/audit.go:30.16,33.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/audit.go:33.8,35.3 1 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:17.51,19.16 2 23
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:19.16,21.3 1 16
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:22.2,22.16 1 7
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:25.91,27.16 2 20
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:27.16,29.17 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:29.17,31.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:32.3,32.24 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:32.24,34.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:35.3,35.68 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:37.2,37.56 1 19
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:40.63,42.28 2 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:42.28,44.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:46.2,47.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:47.16,49.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:50.2,51.35 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:51.35,61.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:62.2,62.16 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:65.71,67.53 2 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:67.53,69.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:70.2,70.57 1 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:73.137,74.19 1 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:74.19,76.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:78.2,78.37 1 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:78.37,80.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:83.2,90.16 5 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:90.16,92.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:93.2,95.22 3 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:95.22,97.3 1 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:98.2,98.46 1 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:98.46,100.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:102.2,108.18 1 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:111.56,112.30 1 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:112.30,113.20 1 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:113.20,115.4 1 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/auth_source_resolver.go:117.2,117.14 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:43.45,45.2 1 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:47.41,49.2 1 14
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:51.33,52.21 1 7
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:52.21,54.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:55.2,55.59 1 7
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:58.44,63.17 4 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:63.17,68.16 4 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:68.16,70.4 1 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:72.3,72.18 1 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:72.18,75.4 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:77.3,77.37 1 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:77.37,79.67 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:79.67,81.5 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:81.10,83.5 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:88.73,89.21 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:89.21,91.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:92.2,92.75 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:95.32,96.21 1 17
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:96.21,98.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:99.2,99.57 1 17
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:102.43,107.17 4 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:107.17,112.16 4 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:112.16,114.4 1 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:116.3,116.18 1 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:116.18,119.4 2 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:121.3,121.37 1 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:121.37,123.67 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:123.67,125.5 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:125.10,125.78 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:125.78,127.5 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:132.69,133.21 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:133.21,135.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:136.2,136.95 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:140.88,143.53 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:143.53,145.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:147.2,147.21 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:147.21,150.54 3 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:150.54,154.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:156.2,156.38 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:160.86,164.21 3 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:164.21,167.3 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:171.67,175.21 3 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:175.21,179.3 3 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:183.77,186.49 2 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:186.49,188.3 1 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:190.2,190.21 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:190.21,193.50 3 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:193.50,197.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:199.2,199.38 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:203.71,207.21 3 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:207.21,210.3 2 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:214.63,218.21 3 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:218.21,222.3 3 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:226.31,227.32 1 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:227.32,229.31 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:229.31,231.4 1 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:232.3,233.26 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:235.2,237.31 2 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:237.31,239.30 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:239.30,241.4 1 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:242.3,243.25 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:245.2,245.32 1 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/cache.go:249.34,252.2 2 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/constants.go:44.73,46.16 2 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/constants.go:46.16,48.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/constants.go:49.2,49.26 1 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/constants.go:52.71,54.64 2 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/constants.go:54.64,56.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/constants.go:57.2,57.21 1 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/gin_context.go:9.66,11.13 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/gin_context.go:11.13,14.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/gin_context.go:15.2,16.18 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/gin_context.go:20.63,22.2 1 12
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:33.34,35.30 2 9
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:35.30,38.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:40.2,41.16 2 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:41.16,44.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:46.2,46.22 1 7
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:46.22,49.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:51.2,53.11 3 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:53.11,54.40 1 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:54.40,57.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:60.2,62.64 3 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:62.64,65.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:67.2,74.16 3 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:74.16,77.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:78.2,78.154 1 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:78.154,81.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:83.2,84.16 2 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:84.16,87.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:88.2,88.88 1 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:91.101,93.16 2 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:93.16,95.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:96.2,97.16 2 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:97.16,99.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:100.2,100.21 1 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:100.21,102.3 1 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:103.2,103.43 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:106.75,107.42 1 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:107.42,109.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:110.2,112.16 3 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:112.16,114.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:115.2,115.12 1 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:115.12,117.3 1 9
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:118.2,118.28 1 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:118.28,120.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:121.2,121.12 1 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:135.32,137.30 2 7
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:137.30,140.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:142.2,143.16 2 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:143.16,146.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:148.2,148.22 1 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:148.22,151.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:152.2,153.33 2 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:153.33,155.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:157.2,159.48 3 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:159.48,162.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:164.2,165.11 2 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:165.11,166.40 1 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:166.40,169.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:172.2,173.64 2 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:173.64,176.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:178.2,185.16 3 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:185.16,188.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:189.2,189.154 1 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:189.154,192.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:194.2,195.16 2 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:195.16,198.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_authorize.go:199.2,199.88 1 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:37.31,39.47 2 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:39.47,42.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:44.2,47.16 4 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:47.16,50.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:51.2,54.16 3 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:54.16,57.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:59.2,62.63 3 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:62.63,65.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:67.2,68.24 2 7
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:68.24,71.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:73.2,73.52 1 7
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:73.52,76.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:78.2,78.76 1 7
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:78.76,81.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:83.2,83.30 1 7
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:83.30,86.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:88.2,89.16 2 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:89.16,92.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:94.2,94.22 1 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:94.22,97.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:99.2,100.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:100.16,103.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:105.2,106.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:106.16,109.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:110.2,110.57 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:110.57,113.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:114.2,114.24 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:114.24,116.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:118.2,118.41 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:118.41,121.3 2 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:123.2,123.47 1 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:127.119,129.17 2 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:129.17,132.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:133.2,134.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:134.16,137.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:138.2,144.17 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:144.17,147.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:148.2,150.73 3 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:154.120,158.9 3 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:159.18,161.21 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:161.21,164.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:165.3,165.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:166.46,168.10 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:168.10,170.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:171.3,171.17 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:172.10,174.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:177.2,179.55 3 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:179.55,182.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:184.2,190.77 4 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:195.142,197.19 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:197.19,199.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:201.2,201.26 1 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:201.26,204.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:206.2,207.22 2 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:207.22,210.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:211.2,214.77 3 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:214.77,217.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:218.2,224.17 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:224.17,227.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_callback.go:228.2,230.19 2 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_external_accounts.go:28.43,31.16 3 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_external_accounts.go:31.16,34.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_external_accounts.go:35.2,35.46 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_external_accounts.go:49.44,51.17 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_external_accounts.go:51.17,54.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_external_accounts.go:55.2,57.27 3 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_external_accounts.go:57.27,60.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_external_accounts.go:61.2,61.97 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_external_accounts.go:61.97,64.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_external_accounts.go:65.2,65.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/handler_sources.go:20.38,22.2 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:32.100,35.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:35.16,37.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:37.17,39.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:40.3,41.46 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:44.2,45.34 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:45.34,47.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:47.17,49.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:50.3,51.47 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:53.2,53.31 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:57.62,62.20 3 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:62.20,64.57 2 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:64.57,66.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:70.2,70.20 1 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:70.20,71.74 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:71.74,73.33 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:73.33,75.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:76.4,78.20 3 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:83.2,84.17 2 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:84.17,86.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:88.2,89.34 2 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:89.34,92.21 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:92.21,94.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:95.3,96.35 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:100.2,100.25 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:100.25,103.35 3 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:103.35,105.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:109.2,113.31 3 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:113.31,115.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:117.2,117.18 1 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:121.38,122.30 1 34
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:122.30,128.17 4 6
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:128.17,131.4 2 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:134.3,140.11 3 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:145.42,146.30 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:146.30,147.71 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:147.71,150.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/middlewares.go:151.3,151.11 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:18.71,20.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:20.16,22.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:24.2,25.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:25.16,27.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:30.2,31.38 2 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:31.38,33.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:36.2,36.36 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:36.36,38.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:41.2,41.29 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:41.29,43.42 2 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:43.42,45.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:48.2,48.50 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:51.149,53.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:53.16,55.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:57.2,58.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:58.16,60.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:62.2,63.21 2 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:63.21,64.90 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:64.90,66.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:69.2,69.65 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:69.65,71.3 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:72.2,72.53 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:72.53,74.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:75.2,75.51 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:75.51,77.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:78.2,78.25 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:78.25,80.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:82.2,82.22 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:86.145,88.9 2 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:88.9,90.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:91.2,92.22 2 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:92.22,94.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:95.2,95.43 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:95.43,97.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:98.2,98.61 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:98.61,100.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:101.2,101.12 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:104.66,111.65 6 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:111.65,113.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:114.2,114.53 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:114.53,116.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:117.2,117.51 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:117.51,119.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:120.2,120.29 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:120.29,122.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:123.2,123.25 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:123.25,125.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:126.2,126.22 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:126.22,128.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:129.2,129.12 1 5
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:132.79,134.17 2 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:134.17,137.3 2 3
-github.com/Rain-kl/Wavelet/internal/apps/oauth/oauth_userinfo.go:138.2,138.15 1 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:40.60,42.84 2 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:42.84,44.3 1 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:45.2,45.11 1 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:50.93,53.36 2 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:53.36,56.3 2 7
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:57.2,61.56 3 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:61.56,64.37 2 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:64.37,67.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:68.3,71.17 3 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:71.17,73.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:75.3,78.16 4 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:80.2,80.16 1 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:80.16,82.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:83.2,83.32 1 8
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:88.55,92.2 3 22
-github.com/Rain-kl/Wavelet/internal/apps/oauth/provider_cache.go:97.49,99.2 1 22
-github.com/Rain-kl/Wavelet/internal/apps/oauth/routers.go:35.74,50.2 1 4
-github.com/Rain-kl/Wavelet/internal/apps/oauth/routers.go:63.31,72.2 4 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/routers.go:92.29,96.19 4 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/routers.go:96.19,98.36 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/routers.go:98.36,100.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/routers.go:100.9,100.49 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/routers.go:100.49,102.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/routers.go:102.9,102.57 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/routers.go:102.57,104.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/routers.go:106.2,108.39 3 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/routers.go:108.39,111.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/routers.go:112.2,112.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session.go:16.53,25.2 1 14
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session.go:28.73,30.23 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session.go:30.23,32.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session.go:34.2,35.28 2 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session.go:35.28,36.43 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session.go:36.43,39.28 3 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session.go:39.28,42.85 3 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session.go:42.85,43.14 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session.go:45.5,45.35 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session.go:47.4,47.64 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session.go:48.9,50.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session.go:52.2,52.35 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:21.54,23.9 2 29
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:23.9,25.3 1 14
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:26.2,26.15 1 15
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:30.50,33.2 2 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:35.60,37.24 2 10
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:37.24,41.3 3 9
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:42.2,42.21 1 1
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:45.44,49.2 3 17
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:51.42,52.68 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:52.68,53.43 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:53.43,55.4 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:60.109,68.21 7 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:68.21,69.37 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:69.37,71.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:75.2,79.16 4 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:79.16,80.10 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:81.23,83.33 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:84.21,85.28 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:86.22,87.26 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:90.2,92.39 2 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:92.39,94.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:96.2,96.21 1 2
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:96.21,98.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/oauth/session_context.go:100.2,100.12 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:64.36,66.16 2 10
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:66.16,67.45 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:67.45,70.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:71.3,71.43 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:71.43,74.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:75.3,76.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:79.2,79.61 1 9
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:79.61,82.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:84.2,84.24 1 8
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:88.65,94.16 5 10
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:94.16,96.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:98.2,99.16 2 10
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:99.16,101.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:103.2,103.21 1 9
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:106.65,110.69 3 8
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:110.69,112.3 1 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:113.2,113.39 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:113.39,115.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:116.2,116.39 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:116.39,118.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:119.2,119.22 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:123.56,129.18 4 8
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:130.21,131.43 1 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:131.43,134.4 2 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:135.3,135.14 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:136.10,137.47 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:141.60,142.58 1 8
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:142.58,144.3 1 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:144.8,146.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:149.78,153.42 3 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:153.42,156.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:158.2,158.26 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:161.81,165.42 3 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:165.42,168.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:170.2,171.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:171.16,172.25 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:172.25,176.4 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:177.3,179.9 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:182.2,182.48 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:190.25,194.16 4 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:194.16,196.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:197.2,197.45 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:197.45,199.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:201.2,201.75 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:201.75,203.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:204.2,204.16 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:204.16,206.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:208.2,209.39 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:217.39,221.16 3 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:221.16,223.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:224.2,224.45 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:224.45,226.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:228.2,229.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:229.16,231.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:233.2,234.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:234.16,236.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:238.2,238.84 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:238.84,243.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:245.2,245.58 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:249.76,258.2 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:260.58,262.16 2 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:262.16,265.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:266.2,266.15 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:266.15,266.39 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:267.2,267.84 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:270.86,272.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:272.16,274.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:275.2,275.15 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:275.15,275.39 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:276.2,276.29 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:279.66,282.85 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:282.85,284.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:284.8,286.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:286.17,288.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:290.2,290.22 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:290.22,292.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:293.2,293.28 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:293.28,295.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:296.2,296.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:300.76,301.28 1 9
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:301.28,303.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:305.2,305.59 1 9
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:305.59,306.75 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:306.75,307.57 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:307.57,309.5 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/filesrv/file_server.go:312.2,312.12 1 8
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/category.go:23.51,27.73 3 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/category.go:27.73,29.3 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/category.go:30.2,30.43 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/category.go:30.43,32.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/category.go:33.2,33.43 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/category.go:33.43,35.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/category.go:36.2,36.146 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/category.go:36.146,38.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/category.go:39.2,39.108 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/category.go:39.108,41.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/category.go:42.2,42.17 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:18.75,20.2 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:23.78,25.2 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:28.52,29.56 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:29.56,30.77 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:30.77,32.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:34.3,35.97 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:35.97,37.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:39.3,39.26 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:39.26,40.70 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:40.70,42.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:44.3,44.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:48.89,49.59 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:49.59,51.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:52.2,52.56 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:52.56,54.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:58.83,59.72 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:59.72,61.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:63.2,66.19 4 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:66.19,68.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:70.2,80.32 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:80.32,81.102 1 12
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:81.102,83.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:85.2,85.12 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:88.99,113.2 1 12
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:116.70,117.57 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:117.57,119.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:123.73,124.60 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:124.60,126.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/stats/stats_counter.go:129.59,131.2 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:35.26,42.2 5 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:45.58,46.21 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:46.21,48.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:51.34,53.2 1 8
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:55.45,56.21 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:56.21,58.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:60.2,60.17 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:60.17,66.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:66.16,68.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:70.3,70.30 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:70.30,72.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:77.64,81.2 3 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:83.71,87.125 3 8
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:87.125,91.3 3 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:92.2,97.125 4 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:97.125,99.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:101.2,104.33 4 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:107.72,110.33 3 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:110.33,112.3 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:113.2,113.14 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:116.61,118.34 2 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:118.34,120.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:122.2,123.91 2 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:123.91,125.3 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:127.2,128.25 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:128.25,130.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:131.2,131.18 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:134.58,137.29 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:137.29,139.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:139.17,141.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/access_cache.go:143.2,143.18 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:36.43,38.2 1 16
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:40.52,42.2 1 10
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:44.38,45.21 1 17
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:45.21,47.3 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:48.2,48.69 1 14
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:51.49,56.17 4 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:56.17,59.16 3 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:59.16,61.4 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:63.3,63.18 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:63.18,66.4 2 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:68.3,68.37 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:68.37,70.91 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:70.91,72.13 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:74.4,74.40 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:79.71,80.21 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:80.21,82.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:83.2,84.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:84.16,86.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:87.2,87.70 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:91.74,94.54 2 10
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:94.54,96.3 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:98.2,99.21 2 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:99.21,101.55 2 6
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:101.55,104.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:107.2,110.36 2 6
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:110.36,112.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:114.2,115.20 2 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:119.68,122.19 2 6
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:122.19,124.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:126.2,128.21 3 6
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:128.21,130.3 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:134.64,138.21 3 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:138.21,141.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:145.36,147.2 1 17
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:150.36,151.37 1 13
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:151.37,153.36 2 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:153.36,155.4 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:156.3,157.31 2 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/cache/meta_cache.go:159.2,159.38 1 13
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:27.37,29.25 2 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:29.25,31.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:32.2,32.20 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:32.20,34.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:35.2,35.22 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:35.22,37.3 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:40.62,41.21 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:41.21,43.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:44.2,44.50 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:44.50,46.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:47.2,47.10 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:50.70,52.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:52.16,53.45 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:53.45,55.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:56.3,56.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:58.2,58.20 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:58.20,60.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:62.2,63.41 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:63.41,64.43 1 6
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:64.43,66.4 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:68.2,68.48 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:71.53,73.2 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:75.52,76.28 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:76.28,78.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:79.2,79.44 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:82.148,83.33 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:83.33,85.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:87.2,88.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:88.16,91.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:93.2,94.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:94.16,97.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:99.2,100.24 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:103.93,104.59 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:104.59,106.24 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:106.24,107.69 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:107.69,109.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:111.3,111.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:113.2,114.12 2 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:117.77,118.56 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:118.56,119.63 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:119.63,121.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:122.3,122.60 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:126.97,142.80 3 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:142.80,144.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:145.2,150.8 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:153.54,155.2 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:157.72,158.32 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:158.32,160.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:161.2,161.29 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:161.29,162.70 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:162.70,164.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:167.2,170.16 4 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:170.16,172.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:174.2,189.69 3 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:189.69,191.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/helpers.go:193.2,197.8 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:16.63,18.20 2 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:18.20,20.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:21.2,21.23 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:21.23,23.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:24.2,24.18 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:24.18,26.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:28.2,28.20 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:29.51,30.40 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:31.20,32.35 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:33.10,34.59 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:39.85,41.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:43.77,45.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:45.16,46.21 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:47.30,51.10 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:52.29,53.34 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:53.34,55.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:56.4,56.48 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:59.2,59.59 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:59.59,61.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/ingest.go:63.2,63.34 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:18.73,20.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:20.16,22.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:23.2,23.64 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:23.64,25.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:26.2,27.20 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:31.86,33.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:33.16,35.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:36.2,36.29 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:36.29,38.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:39.2,39.64 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:39.64,41.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:42.2,43.20 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:46.81,48.59 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:48.59,49.67 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:49.67,51.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:52.3,52.69 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:53.17,55.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/ingest/remove.go:56.2,57.12 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:53.32,57.48 3 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:57.48,60.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:61.2,61.19 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:61.19,63.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:64.2,64.45 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:64.45,66.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:68.2,76.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:76.16,79.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:81.2,86.5 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:100.33,102.33 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:102.33,105.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:107.2,108.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:108.16,111.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:113.2,113.59 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:113.59,114.28 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:114.28,117.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:118.3,119.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:121.2,121.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:135.45,137.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:137.16,140.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:141.2,141.43 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:173.34,178.48 4 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:178.48,181.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:182.2,182.19 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:182.19,184.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:185.2,185.45 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:185.45,187.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:189.2,196.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:196.16,199.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:201.2,206.5 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:220.35,223.33 3 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:223.33,226.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:228.2,229.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:229.16,232.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:234.2,234.77 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:234.77,235.28 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:235.28,238.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:239.3,239.33 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:239.33,242.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:243.3,244.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:246.2,246.41 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:267.35,270.33 3 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:270.33,273.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:275.2,276.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:276.16,279.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:281.2,282.47 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:282.47,285.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:287.2,288.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:288.16,289.28 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:289.28,292.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:293.3,293.33 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:293.33,296.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:297.3,298.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/file_management.go:301.2,301.44 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:17.110,19.2 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:21.127,24.2 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:26.83,28.2 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:30.96,32.2 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:34.69,36.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:36.16,38.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:39.2,40.19 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:48.119,50.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:50.16,52.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:53.2,53.29 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:53.29,55.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:57.2,58.26 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:58.26,60.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:61.2,61.29 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:61.29,63.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:64.2,64.71 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:64.71,66.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:67.2,67.51 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:67.51,69.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:70.2,70.50 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:70.50,72.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:73.2,73.20 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:76.93,78.2 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:80.71,82.2 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/logics.go:84.39,86.2 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:60.33,70.16 7 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:70.16,73.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:75.2,76.16 2 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:76.16,79.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:80.2,80.15 1 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:80.15,80.35 1 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:82.2,82.40 1 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:82.40,85.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:87.2,89.15 3 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:89.15,91.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:93.2,96.16 4 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:96.16,99.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:101.2,104.74 3 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:104.74,107.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:109.2,112.18 3 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:112.18,115.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:117.2,118.18 2 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:118.18,121.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:123.2,136.16 2 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:136.16,137.48 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:137.48,140.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:141.3,141.49 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:141.49,144.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:145.3,145.46 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:145.46,148.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:149.3,150.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:153.2,153.51 1 6
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:169.35,171.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:171.16,172.45 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:172.45,175.4 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:176.3,176.43 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:176.43,179.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:180.3,181.9 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:184.2,184.69 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:184.69,187.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:189.2,193.53 4 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:193.53,195.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:195.16,197.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:197.9,199.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:202.2,203.32 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:218.41,222.47 3 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:222.47,225.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:227.2,228.32 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:228.32,230.17 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:230.17,233.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:234.3,234.24 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:237.2,238.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:238.16,241.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:243.2,243.23 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:243.23,246.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:248.2,253.15 5 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:253.15,256.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:258.2,260.33 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:260.33,261.71 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:261.71,263.12 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:266.3,267.51 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:267.51,272.4 4 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:272.9,274.4 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:276.3,277.17 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:277.17,279.12 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:282.3,283.17 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:283.17,285.12 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:287.3,291.17 4 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:291.17,293.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:297.79,299.25 2 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:299.25,300.51 1 6
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:300.51,302.4 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:303.3,303.15 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:306.2,307.56 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:307.56,309.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:310.2,310.23 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:313.90,316.23 3 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:316.23,317.68 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:317.68,319.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:321.2,324.17 4 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:327.89,329.87 2 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:329.87,331.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/routers.go:332.2,332.17 1 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:47.35,51.16 3 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:51.16,54.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:56.2,60.54 5 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:60.54,65.3 4 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:67.2,76.37 4 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:76.37,78.3 1 6
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:80.2,80.29 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:80.29,81.25 1 9
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:82.39,84.29 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:85.38,90.6 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:91.42,92.49 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:92.49,96.5 3 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:97.39,98.48 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:98.48,101.5 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:105.2,106.37 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:106.37,108.3 1 6
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:110.2,111.34 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:111.34,117.3 1 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/handler/stats.go:119.2,125.5 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:50.97,51.33 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:51.33,53.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:54.2,63.6 7 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:63.6,69.43 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:69.43,72.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:74.3,74.30 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:74.30,75.9 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:78.3,80.35 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:80.35,83.61 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:83.61,86.68 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:86.68,88.6 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:90.5,91.19 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:91.19,93.6 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:94.5,94.59 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:94.59,96.6 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:98.5,98.15 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:99.19,102.13 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:105.4,108.17 4 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:112.2,115.126 4 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:115.126,117.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:117.8,117.33 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:117.33,118.103 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:118.103,120.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:120.9,122.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:123.8,125.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:127.2,129.16 3 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:129.16,132.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:132.8,138.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:140.2,142.19 3 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:142.19,145.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:145.8,149.3 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/cleanup.go:151.2,159.44 3 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/rebuild_stats.go:39.102,44.41 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/rebuild_stats.go:44.41,47.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/rebuild_stats.go:49.2,51.60 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/rebuild_stats.go:51.60,54.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/rebuild_stats.go:56.2,59.39 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/rebuild_stats.go:59.39,62.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/rebuild_stats.go:64.2,71.44 3 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:61.76,63.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:63.16,65.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:66.2,67.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:67.16,69.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:70.2,70.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:70.12,72.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:73.2,73.24 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:77.99,78.21 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:78.21,86.17 4 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:86.17,88.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:89.3,89.10 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:89.10,91.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:93.3,95.16 2 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:95.16,100.4 4 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:103.3,103.18 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:103.18,106.8 3 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:106.8,107.12 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:108.21,111.14 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:112.24,113.12 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:114.23,115.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:121.2,122.16 2 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:122.16,124.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:125.2,126.16 2 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:126.16,128.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:129.2,129.36 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:129.36,130.67 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:130.67,132.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:133.3,135.49 3 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:138.2,139.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:139.16,141.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:142.2,142.16 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:142.16,143.67 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:143.67,145.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:146.3,148.49 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:151.2,152.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:152.16,154.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:155.2,156.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:156.16,158.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:160.2,162.16 3 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:162.16,164.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:166.2,166.66 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:166.66,168.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:169.2,171.48 3 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:174.62,181.2 3 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:183.68,185.23 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:185.23,187.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:188.2,188.122 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:203.18,209.6 6 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:209.6,210.35 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:210.35,212.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:214.3,220.25 4 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:220.25,222.4 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:223.3,226.37 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:226.37,228.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:229.3,229.24 1 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:229.24,231.9 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:234.3,240.34 5 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:240.34,242.22 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:242.22,243.104 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:243.104,245.6 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:246.5,247.15 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:251.3,251.34 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:251.34,253.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:255.3,255.108 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:257.2,257.41 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:266.9,267.50 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:267.50,270.3 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:272.2,274.16 3 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:274.16,275.27 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:275.27,277.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:278.3,278.68 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:280.2,283.19 4 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:283.19,285.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:286.2,286.21 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:286.21,288.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:290.2,290.38 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:290.38,293.20 3 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:293.20,295.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:296.3,296.48 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:296.48,298.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:299.3,300.63 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:300.63,303.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:304.3,306.31 3 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:306.31,308.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:309.3,309.90 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:312.2,312.38 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:312.38,316.60 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:316.60,318.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:320.2,321.12 2 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:328.8,330.61 2 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:330.61,332.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:333.2,333.15 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:333.15,335.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:337.2,337.48 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:344.9,350.44 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:350.44,352.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:353.2,355.65 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:355.65,357.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:358.2,358.33 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:358.33,360.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:361.2,361.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:364.38,365.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:365.16,367.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:368.2,368.36 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:368.36,370.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:371.2,372.98 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:372.98,373.36 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:373.36,375.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/storage_migration.go:377.2,377.14 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:62.81,63.23 1 7
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:63.23,65.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:67.2,68.54 2 6
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:68.54,70.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:72.2,75.42 2 5
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:75.42,77.3 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:79.2,79.26 1 3
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:83.104,85.16 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:85.16,88.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:90.2,91.64 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:91.64,93.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:95.2,111.6 11 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:111.6,112.35 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:112.35,114.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:116.3,126.37 2 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:126.37,129.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:131.3,131.24 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:131.24,132.9 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:135.3,138.26 4 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:138.26,139.36 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:139.36,141.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:143.4,148.18 5 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:148.18,151.38 3 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:151.38,153.6 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:154.5,154.13 1 0
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:156.4,156.16 1 4
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:156.16,159.13 3 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:161.4,162.20 2 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:165.3,172.4 1 2
-github.com/Rain-kl/Wavelet/internal/apps/upload/task/tasks.go:175.2,183.44 3 2
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:30.47,31.47 1 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:31.47,33.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:34.2,35.25 2 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:35.25,38.42 3 3
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:38.42,40.4 1 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:42.2,42.19 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:46.20,47.34 1 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:47.34,49.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:50.2,50.30 1 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:50.30,51.74 1 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:51.74,53.4 1 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:55.2,55.14 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:58.13,61.22 2 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:61.22,63.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:66.2,70.45 3 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:70.45,71.56 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:71.56,73.57 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:73.57,75.5 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:77.3,79.65 3 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:79.65,81.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:85.2,86.44 2 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:86.44,88.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:90.2,97.14 4 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:97.14,102.3 4 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:105.2,108.17 2 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:111.36,112.27 1 2
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:112.27,114.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:115.2,115.29 1 2
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:115.29,117.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:123.42,124.36 1 50
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:124.36,126.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:127.2,127.17 1 50
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:130.43,131.36 1 16
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:131.36,132.44 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:132.44,134.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:136.2,136.17 1 16
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:139.49,140.36 1 2
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:140.36,141.56 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:141.56,143.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:145.2,145.17 1 2
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:148.55,149.36 1 2
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:149.36,150.54 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:150.54,152.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:154.2,154.17 1 2
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:157.46,158.36 1 14
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:158.36,159.49 1 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:159.49,161.4 1 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:163.2,163.17 1 13
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:167.40,194.42 23 2
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:194.42,196.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:197.2,201.45 3 2
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:201.45,204.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:205.2,214.50 8 2
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:214.50,217.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:218.2,237.31 12 2
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:237.31,243.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:247.34,249.16 2 1
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:249.16,252.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/config/config.go:253.2,253.72 1 1
-github.com/Rain-kl/Wavelet/internal/infra/config/model.go:37.41,39.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/config.go:43.29,50.2 1 10
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/config.go:52.34,53.22 1 10
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/config.go:53.22,55.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/config.go:56.2,56.25 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/config.go:56.25,58.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/config.go:59.2,59.24 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/config.go:59.24,61.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/config.go:62.2,62.26 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/config.go:62.26,64.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/config.go:65.2,65.24 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/config.go:65.24,67.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/config.go:68.2,68.12 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:58.75,59.28 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:59.28,61.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:65.56,66.28 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:66.28,68.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:72.88,73.18 1 11
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:73.18,75.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:76.2,76.39 1 10
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:76.39,78.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:80.2,85.27 2 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:85.27,87.3 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:88.2,88.15 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:92.51,93.24 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:93.24,100.3 5 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:104.53,110.15 5 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:110.15,112.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:114.2,114.23 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:114.23,116.3 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:118.2,118.9 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:119.14,120.13 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:121.20,122.19 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:127.36,130.17 3 3
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:130.17,132.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:133.2,133.9 1 3
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:134.16,135.15 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:136.10,137.14 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:143.45,147.15 4 18
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:147.15,150.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:152.2,152.9 1 18
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:153.18,154.14 1 16
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:155.10,157.15 2 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:162.35,165.17 3 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:165.17,167.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:168.2,168.31 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:172.31,175.17 3 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:175.17,177.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:178.2,178.18 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:182.31,184.2 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:187.35,196.2 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:198.27,204.18 5 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:204.18,205.22 1 14
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:205.22,207.4 1 5
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:208.3,209.53 2 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:209.53,211.29 2 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:211.29,213.5 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:215.3,216.31 2 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:219.2,219.15 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:219.15,222.3 2 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:224.2,224.6 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:224.6,225.10 1 36
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:226.27,227.11 1 25
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:227.11,229.5 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:230.4,230.23 1 16
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:230.23,232.5 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:233.4,234.40 2 16
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:234.40,236.5 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:237.19,238.71 1 11
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:238.71,240.5 1 3
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:245.103,246.19 1 11
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:246.19,248.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:249.2,249.63 1 11
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:249.63,251.3 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:252.2,252.56 1 9
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:252.56,254.3 1 5
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:255.2,255.60 1 4
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:258.40,260.21 2 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:260.21,262.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/batchwriter/writer.go:263.2,263.16 1 1
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:48.34,49.28 1 0
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:49.28,56.3 4 0
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:57.2,57.20 1 0
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:61.38,63.2 1 1
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:66.55,68.23 1 1
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:68.23,70.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:73.2,74.132 2 1
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:74.132,75.83 1 1
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:75.83,77.4 1 1
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:81.2,82.125 2 1
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:82.125,83.80 1 1
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:83.80,85.4 1 1
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:89.2,90.125 2 1
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:90.125,91.61 1 1
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:91.61,93.4 1 1
-github.com/Rain-kl/Wavelet/internal/infra/diskcache/cache.go:96.2,96.51 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:38.13,39.39 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:39.39,41.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:43.2,44.24 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:44.24,46.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:48.2,52.16 4 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:52.16,54.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:56.2,56.57 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:56.57,58.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:60.2,65.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:65.16,67.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:69.2,77.16 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:77.16,79.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:81.2,82.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:82.16,84.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:86.2,90.65 4 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:93.51,116.2 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:118.34,126.46 3 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:126.46,128.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:130.2,136.23 6 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:140.41,141.17 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:141.17,143.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:144.2,144.30 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:148.33,150.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/clickhouse.go:153.38,155.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:28.13,29.37 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:29.37,33.3 2 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:35.2,35.16 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:39.19,41.22 2 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:41.22,43.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:45.2,54.16 3 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:54.16,56.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:59.2,67.16 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:67.16,69.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:71.2,71.61 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:75.21,95.16 6 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:95.16,97.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:100.2,110.16 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:110.16,112.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:114.2,114.32 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:114.32,116.45 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:116.45,118.22 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:118.22,120.5 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:121.4,122.22 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:122.22,124.5 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:125.4,129.7 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:132.3,142.41 3 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:142.41,144.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:145.3,145.105 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:146.8,148.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:151.2,152.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:152.16,154.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:156.2,159.81 4 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:164.72,171.20 3 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:171.20,173.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:175.2,177.19 3 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:177.19,179.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:180.2,181.31 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:181.31,183.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:184.2,184.26 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:184.26,186.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:187.2,187.36 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:187.36,189.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:190.2,190.36 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:190.36,192.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:194.2,195.24 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:195.24,196.21 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:196.21,198.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:199.3,199.41 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:201.2,203.23 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:207.39,208.15 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:208.15,210.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:211.2,211.28 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres.go:215.24,217.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:28.81,32.2 3 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:34.84,35.35 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:35.35,37.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:40.84,41.35 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:41.35,43.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:46.85,47.36 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:47.36,49.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:52.124,54.9 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:55.129,57.136 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:58.90,61.116 3 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:62.37,64.113 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:68.41,69.16 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:69.16,71.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:72.2,72.13 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:75.54,77.15 2 3
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:78.16,79.27 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:80.15,81.26 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:82.14,83.25 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:84.14,85.25 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:86.15,87.25 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/postgres_logger.go:88.10,89.25 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:27.13,30.18 2 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:30.18,33.3 2 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:35.2,35.21 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:35.21,52.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:52.8,70.27 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:70.27,76.4 4 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:76.9,79.4 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:83.2,90.16 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:90.16,92.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:95.2,96.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:96.16,98.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:101.77,103.13 2 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:103.13,105.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:106.2,106.47 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:110.37,112.18 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:112.18,114.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:115.2,115.21 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:123.83,125.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:125.16,127.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:129.2,129.88 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:129.88,131.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:133.2,133.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:137.75,138.41 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:138.41,140.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:141.2,141.82 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:141.82,143.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:144.2,144.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:152.84,154.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:154.16,156.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:158.2,158.58 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:158.58,160.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:162.2,162.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:169.69,171.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:171.16,173.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:175.2,175.50 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:175.50,177.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:179.2,179.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:187.94,189.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:189.16,191.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:193.2,193.85 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:193.85,195.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/redis.go:197.2,197.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/idgen/snowflake.go:23.13,29.16 5 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/idgen/snowflake.go:29.16,31.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/idgen/snowflake.go:32.2,32.85 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/idgen/snowflake.go:37.28,38.63 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/idgen/snowflake.go:38.63,40.14 2 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/idgen/snowflake.go:40.14,42.4 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/idgen/snowflake.go:43.3,43.105 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/idgen/snowflake.go:45.2,45.97 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:80.29,88.2 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:91.54,99.18 6 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:99.18,101.42 2 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:101.42,102.67 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:102.67,104.5 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:106.3,106.18 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:109.2,109.76 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:112.88,114.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:114.16,115.45 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:115.45,117.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:118.3,118.23 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:120.2,120.39 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:120.39,122.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:123.2,123.68 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:123.68,125.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:126.2,126.22 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:130.39,131.20 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:132.19,133.46 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:133.46,135.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:136.16,137.45 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:138.16,139.92 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:139.92,141.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:142.3,142.45 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:143.19,144.50 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:144.50,146.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:147.3,147.47 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:148.17,149.48 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:149.48,151.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:152.3,152.45 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:153.20,154.51 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:154.51,156.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:157.10,158.65 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:160.2,160.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:163.74,164.63 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:164.63,166.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:167.2,167.41 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:167.41,169.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:170.2,170.41 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:170.41,172.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:173.2,173.94 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:173.94,175.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:176.2,176.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:180.62,182.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:184.93,185.56 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:185.56,187.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:188.2,188.55 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:188.55,191.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:192.2,192.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:195.108,197.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:197.16,199.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:200.2,209.40 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:209.40,211.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:212.2,212.57 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:216.54,217.65 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:217.65,218.36 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:218.36,220.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:221.3,221.40 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:221.40,223.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:225.2,229.40 5 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:229.40,231.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:232.2,232.13 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:236.37,237.42 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:237.42,238.30 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:238.30,240.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:241.3,241.34 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:241.34,243.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:245.2,249.31 5 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:249.31,251.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/config.go:252.2,252.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/http.go:16.79,18.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/http.go:18.16,20.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/http.go:21.2,22.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/http.go:22.16,24.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/http.go:25.2,28.16 4 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/http.go:28.16,30.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/http.go:31.2,31.42 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/http.go:31.42,34.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/http.go:35.2,36.23 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/http.go:36.23,38.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/http.go:39.2,43.8 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:20.62,22.16 2 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:22.16,24.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:25.2,25.39 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:28.113,30.16 2 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:30.16,32.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:33.2,33.72 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:33.72,35.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:36.2,41.16 2 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:41.16,43.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:44.2,44.47 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:44.47,48.3 3 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:49.2,49.37 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:49.37,52.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:53.2,53.51 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:56.76,58.16 2 2
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:58.16,60.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:61.2,62.16 2 2
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:62.16,64.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:65.2,66.16 2 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:66.16,69.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:70.2,71.23 2 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:71.23,73.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:74.2,74.87 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:77.68,79.16 2 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:79.16,81.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:82.2,83.24 2 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:83.24,85.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:86.2,86.12 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:89.54,91.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:93.57,94.25 1 4
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:94.25,97.17 3 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:97.17,99.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:100.3,101.17 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:101.17,103.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:104.3,105.49 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:105.49,107.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:108.3,108.24 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:110.2,111.76 2 4
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:111.76,113.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:114.2,116.48 3 4
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:116.48,118.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/local.go:119.2,119.18 1 4
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:23.59,27.24 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:27.24,29.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:30.2,35.8 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:38.113,45.16 3 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:45.16,47.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:48.2,48.51 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:51.76,53.20 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:53.20,55.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:56.2,60.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:60.16,62.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:63.2,64.31 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:64.31,66.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:67.2,67.103 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:70.68,75.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:75.16,77.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:78.2,78.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:81.54,83.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:83.16,85.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:86.2,86.9 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:86.9,88.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:89.2,89.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:92.45,94.66 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:94.66,96.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/oss.go:97.2,97.32 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:25.78,34.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:34.16,36.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:37.2,37.63 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:37.63,38.25 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:38.25,40.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:41.3,41.39 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:43.2,48.8 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:51.78,52.24 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:52.24,54.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:55.2,56.31 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:59.125,68.16 3 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:68.16,70.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:71.2,71.51 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:74.75,76.20 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:76.20,78.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:79.2,83.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:83.16,85.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:86.2,87.31 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:87.31,89.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:90.2,91.33 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:91.33,93.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:94.2,94.87 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:97.67,102.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:102.16,104.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:105.2,105.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:108.53,110.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:110.16,112.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:113.2,113.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:116.44,118.66 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:118.66,120.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/s3.go:121.2,121.32 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:53.30,53.46 1 2
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:69.19,76.2 6 4
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:79.52,80.21 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:80.21,82.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:86.28,87.21 1 2
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:87.21,89.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:90.2,90.17 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:90.17,92.16 2 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:92.16,94.4 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:96.3,97.16 2 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:97.16,99.4 1 1
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:104.59,105.43 1 2
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:105.43,107.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:109.2,113.18 4 2
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:113.18,117.3 3 2
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:118.2,124.69 4 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:124.69,126.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:128.2,129.59 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:129.59,131.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:133.2,136.58 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:136.58,138.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:140.2,141.39 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:141.39,142.64 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:142.64,144.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:147.2,148.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:148.16,150.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:152.2,156.41 4 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:165.131,166.65 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:166.65,168.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:169.2,169.33 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:172.81,174.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:176.73,178.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:180.55,182.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:189.10,192.16 3 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:192.16,194.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:198.82,199.46 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:199.46,201.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:202.2,202.16 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:203.19,204.36 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:205.16,206.35 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:207.16,208.35 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:209.19,210.38 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:211.17,212.32 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:213.20,214.38 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/storage.go:215.10,216.66 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:23.81,25.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:34.65,41.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:43.73,50.2 3 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:52.119,55.52 3 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:55.52,56.62 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:56.62,58.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:60.2,60.87 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:60.87,62.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:63.2,63.33 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:66.79,70.16 4 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:70.16,72.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:73.2,74.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:74.16,76.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:77.2,78.92 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:78.92,80.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:81.2,81.87 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:84.71,86.50 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:86.50,88.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:89.2,89.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:92.57,94.41 2 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:94.41,96.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:97.2,97.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/objectstore/webdav.go:100.48,102.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:33.33,34.39 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:34.39,36.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:38.2,61.16 4 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:61.16,64.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:66.2,73.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:73.16,76.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:77.2,78.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:78.16,81.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:83.2,83.61 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:83.61,86.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:87.2,88.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:88.16,91.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:92.2,100.3 3 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:103.39,104.38 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/clickhouse.go:104.38,106.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:25.22,26.37 1 4
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:26.37,28.3 1 4
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:29.2,29.21 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:46.28,47.37 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:47.37,49.3 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:50.2,50.24 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:53.28,54.37 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:54.37,56.3 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:57.2,57.25 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:61.23,63.19 2 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:63.19,65.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:67.2,68.16 2 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:68.16,70.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:72.2,73.57 2 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:73.57,75.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:76.2,77.16 2 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:77.16,79.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:80.2,80.56 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:80.56,82.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:84.2,86.16 3 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:86.16,88.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:90.2,96.3 2 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:99.31,100.89 1 2
-github.com/Rain-kl/Wavelet/internal/infra/persistence/migrator/migrator.go:100.89,102.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/handlers/register.go:17.17,43.2 14 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/middlewares.go:17.59,18.74 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/middlewares.go:18.74,20.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:20.26,39.58 5 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:39.58,41.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:44.2,44.29 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:48.49,63.58 5 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:63.58,65.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:67.2,67.47 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:67.47,69.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:70.2,70.25 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:74.45,78.42 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:78.42,79.49 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:79.49,80.38 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:80.38,82.5 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:87.2,87.22 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:87.22,91.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/worker/worker.go:93.2,93.15 1 0
-github.com/Rain-kl/Wavelet/internal/model/access_token.go:34.39,36.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/access_token.go:39.44,41.44 2 0
-github.com/Rain-kl/Wavelet/internal/model/access_token.go:41.44,43.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/access_token.go:44.2,44.61 1 0
-github.com/Rain-kl/Wavelet/internal/model/access_token.go:48.37,52.2 3 0
-github.com/Rain-kl/Wavelet/internal/model/access_token.go:55.43,56.33 1 0
-github.com/Rain-kl/Wavelet/internal/model/access_token.go:56.33,58.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/access_token.go:59.2,59.64 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:38.38,40.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:55.43,57.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:72.39,81.30 9 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:81.30,83.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:84.2,84.62 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:84.62,86.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:90.44,92.23 2 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:92.23,94.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:95.2,95.53 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:95.53,97.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:98.2,98.39 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:98.39,100.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:101.2,101.37 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:101.37,103.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:104.2,104.77 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:104.77,106.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:107.2,107.12 1 0
-github.com/Rain-kl/Wavelet/internal/model/auth_source.go:111.38,114.2 2 0
-github.com/Rain-kl/Wavelet/internal/model/message_gateway.go:32.42,32.73 1 0
-github.com/Rain-kl/Wavelet/internal/model/message_gateway.go:44.42,44.73 1 0
-github.com/Rain-kl/Wavelet/internal/model/message_gateway.go:56.46,56.82 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:38.39,40.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:45.41,51.19 5 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:51.19,53.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:55.2,55.45 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:55.45,57.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:59.2,59.19 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:59.19,61.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:62.2,62.37 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:62.37,64.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:65.2,65.42 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:65.42,67.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:69.2,69.68 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:69.68,71.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:73.2,73.17 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:74.18,75.21 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:75.21,77.4 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:78.3,78.32 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:79.17,79.17 0 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:81.20,82.21 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:82.21,84.4 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:86.2,86.12 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:89.35,91.61 2 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:91.61,93.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:94.2,95.60 2 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:95.60,97.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_channel.go:98.2,98.65 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_event.go:27.37,29.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_event.go:32.39,37.23 4 0
-github.com/Rain-kl/Wavelet/internal/model/push_event.go:37.23,39.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_event.go:40.2,40.19 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_event.go:40.19,42.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_event.go:43.2,43.23 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_event.go:43.23,45.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_event.go:46.2,46.41 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_event.go:46.41,48.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_event.go:49.2,49.12 1 0
-github.com/Rain-kl/Wavelet/internal/model/push_history.go:25.39,27.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/schedule.go:23.36,25.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/system_configs.go:66.40,68.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/task_execution.go:51.41,53.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:29.36,31.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:34.32,41.18 7 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:41.18,43.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:47.37,49.17 2 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:49.17,51.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:52.2,52.18 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:52.18,54.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:55.2,55.21 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:55.21,57.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:58.2,58.12 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:62.61,65.21 2 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:65.21,67.17 2 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:67.17,69.4 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:70.3,71.60 2 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:71.60,73.4 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:74.3,74.28 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:78.2,79.16 2 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:79.16,81.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:82.2,83.60 2 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:83.60,85.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/templates.go:87.2,87.39 1 0
-github.com/Rain-kl/Wavelet/internal/model/upload_stats.go:26.38,28.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/uploads.go:52.34,54.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:30.40,31.15 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:31.15,33.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:35.2,35.17 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:35.17,36.62 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:36.62,38.4 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:40.2,40.10 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:64.32,66.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:69.51,72.2 2 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:75.60,76.20 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:76.20,79.3 2 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:80.2,81.16 2 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:81.16,83.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:84.2,85.12 2 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:89.43,91.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:94.52,95.40 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:95.40,97.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:98.2,98.29 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:98.29,100.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:101.2,101.31 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:105.62,112.2 6 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:115.36,116.17 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:116.17,118.3 1 0
-github.com/Rain-kl/Wavelet/internal/model/users.go:119.2,119.12 1 0
-github.com/Rain-kl/Wavelet/internal/model/analytics/user_access_log.go:32.41,34.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/analytics/user_access_log.go:37.45,39.2 1 0
-github.com/Rain-kl/Wavelet/internal/model/analytics/user_access_log.go:42.46,44.2 1 0
-github.com/Rain-kl/Wavelet/internal/platform/lifecycle/lifecycle.go:29.47,33.2 3 0
-github.com/Rain-kl/Wavelet/internal/platform/lifecycle/lifecycle.go:36.32,43.31 6 0
-github.com/Rain-kl/Wavelet/internal/platform/lifecycle/lifecycle.go:43.31,46.18 3 0
-github.com/Rain-kl/Wavelet/internal/platform/lifecycle/lifecycle.go:46.18,49.34 3 0
-github.com/Rain-kl/Wavelet/internal/platform/lifecycle/lifecycle.go:49.34,51.5 1 0
-github.com/Rain-kl/Wavelet/internal/platform/lifecycle/lifecycle.go:51.10,53.5 1 0
-github.com/Rain-kl/Wavelet/internal/platform/lifecycle/lifecycle.go:57.2,58.17 2 0
-github.com/Rain-kl/Wavelet/internal/platform/lifecycle/lifecycle.go:58.17,61.3 2 0
-github.com/Rain-kl/Wavelet/internal/platform/lifecycle/lifecycle.go:63.2,63.9 1 0
-github.com/Rain-kl/Wavelet/internal/platform/lifecycle/lifecycle.go:64.14,65.61 1 0
-github.com/Rain-kl/Wavelet/internal/platform/lifecycle/lifecycle.go:66.20,67.64 1 0
-github.com/Rain-kl/Wavelet/internal/listener/admin_login.go:28.52,30.2 1 0
-github.com/Rain-kl/Wavelet/internal/listener/admin_login.go:33.74,34.34 1 0
-github.com/Rain-kl/Wavelet/internal/listener/admin_login.go:34.34,36.3 1 0
-github.com/Rain-kl/Wavelet/internal/listener/admin_login.go:38.2,39.48 2 0
-github.com/Rain-kl/Wavelet/internal/listener/admin_login.go:39.48,41.3 1 0
-github.com/Rain-kl/Wavelet/internal/listener/message_gateway.go:26.68,28.2 1 1
-github.com/Rain-kl/Wavelet/internal/listener/message_gateway.go:31.89,32.30 1 2
-github.com/Rain-kl/Wavelet/internal/listener/message_gateway.go:32.30,34.3 1 1
-github.com/Rain-kl/Wavelet/internal/listener/message_gateway.go:35.2,36.56 2 1
-github.com/Rain-kl/Wavelet/internal/listener/message_gateway.go:36.56,38.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:30.37,32.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:35.29,39.26 3 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:39.26,44.42 3 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:44.42,47.4 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:49.3,52.42 3 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:52.42,54.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:56.2,56.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:60.22,64.28 3 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:64.28,67.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:69.2,69.21 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:69.21,72.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:76.30,81.28 3 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:81.28,84.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:87.2,88.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:88.16,90.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:92.2,93.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:93.16,95.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:98.2,106.30 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:106.30,108.18 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:108.18,109.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:113.3,120.17 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:120.17,123.12 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:128.2,128.45 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:128.45,130.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:131.2,134.12 3 0
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:137.70,138.9 1 2
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:139.14,140.15 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/scheduler/scheduler.go:141.17,142.14 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:56.58,60.2 3 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:62.52,66.12 4 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:66.12,69.3 2 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:70.2,70.13 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:74.50,78.47 3 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:78.47,83.17 5 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:83.17,85.4 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:87.2,87.12 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:91.22,92.30 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:92.30,94.3 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:98.33,99.41 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:99.41,101.3 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:105.40,106.48 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:106.48,107.100 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:107.100,109.38 2 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:109.38,111.5 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:112.4,118.5 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:124.30,125.38 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:125.38,127.3 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:131.20,135.2 3 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:138.23,142.2 3 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:145.26,147.2 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:150.20,155.2 4 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:159.46,160.28 1 2
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:160.28,161.57 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:161.57,164.4 2 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:166.3,166.82 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:166.82,168.18 2 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:168.18,170.5 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:171.4,171.25 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:173.3,181.47 3 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:181.47,183.4 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:185.3,185.52 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:185.52,187.4 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:188.3,188.15 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:188.15,190.4 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:194.60,196.59 2 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:196.59,198.3 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:199.2,200.19 2 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:200.19,202.37 2 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:202.37,204.4 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:205.3,205.39 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:205.39,207.4 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:208.3,208.103 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:208.103,210.4 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:211.3,211.13 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:213.2,213.17 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:214.20,215.40 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:215.40,217.4 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:218.18,219.38 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:219.38,221.4 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:222.16,223.37 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:223.37,225.4 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:226.10,227.64 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:229.2,229.12 1 1
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:233.32,235.2 1 0
-github.com/Rain-kl/Wavelet/internal/platform/bootstrap/bootstrap.go:238.36,240.2 1 2
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:37.48,39.2 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:43.65,45.2 1 26
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:48.59,51.2 2 4
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:56.88,58.9 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:58.9,60.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:61.2,61.53 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:61.53,63.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:64.2,64.21 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:81.69,83.2 1 5
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:86.44,87.48 1 9
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:87.48,89.3 1 7
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:90.2,90.11 1 2
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:94.47,97.36 3 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:97.36,99.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:100.2,100.31 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:105.73,107.18 2 7
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:107.18,111.3 2 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:113.2,114.80 2 6
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:114.80,116.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:120.109,122.17 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:122.17,124.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:127.2,142.71 3 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:142.71,144.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:147.2,153.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:153.16,162.3 7 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:164.2,164.203 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:164.203,166.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:168.2,168.20 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:172.64,174.16 2 4
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:174.16,176.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:178.2,178.57 1 3
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:178.57,180.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:182.2,182.26 1 2
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:182.26,184.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:187.2,202.74 3 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:202.74,204.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:206.2,208.17 3 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:208.17,210.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:213.2,219.16 2 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:219.16,227.3 7 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:229.2,229.252 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:229.252,231.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:233.2,233.23 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:238.60,261.9 9 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:261.9,266.3 4 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:269.2,271.16 3 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:271.16,273.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:275.2,275.22 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:275.22,278.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:278.8,280.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:283.2,294.40 6 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:294.40,297.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:299.2,299.16 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:302.73,305.23 3 3
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:305.23,307.3 1 2
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:309.2,316.16 3 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:316.16,319.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:320.2,320.13 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:323.99,325.59 2 2
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:325.59,327.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:328.2,328.80 1 2
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:328.80,330.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:331.2,331.37 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:331.37,333.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:335.2,336.45 2 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:339.97,340.22 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:340.22,342.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:343.2,344.102 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:344.102,347.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:348.2,348.58 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:348.58,352.3 3 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:353.2,353.11 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:353.11,354.84 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:354.84,356.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:361.143,363.16 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:363.16,365.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:367.2,368.17 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:368.17,370.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:372.2,385.83 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:385.83,388.3 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:390.2,390.23 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:394.194,395.22 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:395.22,397.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:399.2,402.20 3 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:402.20,404.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:404.8,406.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:408.2,408.71 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:408.71,410.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:411.2,411.47 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:411.47,412.81 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:412.81,414.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:417.2,417.54 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:420.114,421.37 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:421.37,423.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:425.2,426.48 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:426.48,428.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:431.75,432.43 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:432.43,434.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:436.2,438.36 3 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:438.36,440.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:441.2,441.31 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:444.55,446.2 1 3
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:448.147,456.2 6 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:458.139,461.19 3 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:461.19,463.26 2 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:463.26,465.4 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:467.2,470.19 3 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:470.19,472.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:473.2,473.118 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:477.65,479.2 1 2
-github.com/Rain-kl/Wavelet/internal/infra/task/executor.go:482.72,484.2 1 2
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:43.38,46.38 3 14
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:46.38,47.26 1 49
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:47.26,49.4 1 7
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:51.2,51.53 1 7
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:55.40,62.2 5 1
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:65.45,68.38 3 1
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:68.38,69.25 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:69.25,72.4 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:74.2,74.12 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:78.57,81.38 3 0
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:81.38,82.31 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:82.31,85.4 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:87.2,87.12 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:91.41,93.33 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:93.33,95.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/meta.go:96.2,96.13 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/permanent_error.go:21.43,23.19 2 3
-github.com/Rain-kl/Wavelet/internal/infra/task/permanent_error.go:23.19,25.3 1 1
-github.com/Rain-kl/Wavelet/internal/infra/task/permanent_error.go:26.2,26.46 1 3
-github.com/Rain-kl/Wavelet/internal/infra/task/permanent_error.go:29.45,31.2 1 3
-github.com/Rain-kl/Wavelet/internal/infra/task/permanent_error.go:33.45,35.2 1 3
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:18.61,20.2 1 3
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:26.62,28.2 1 2
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:35.63,41.2 3 2
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:43.72,45.13 2 7
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:45.13,47.3 1 3
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:48.2,48.47 1 7
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:57.13,60.2 2 1
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:63.43,67.21 3 7
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:67.21,76.3 1 2
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:78.2,78.26 1 5
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:78.26,89.3 1 2
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:91.2,92.20 2 3
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:92.20,94.3 1 3
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:95.2,104.3 1 3
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:108.41,110.18 2 0
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:110.18,112.3 1 0
-github.com/Rain-kl/Wavelet/internal/infra/task/utils.go:113.2,113.23 1 0
-github.com/Rain-kl/Wavelet/internal/router/root/custom.go:14.47,16.2 0 0
-github.com/Rain-kl/Wavelet/internal/router/root/default.go:18.47,26.39 3 0
-github.com/Rain-kl/Wavelet/internal/router/root/default.go:26.39,28.3 1 0
-github.com/Rain-kl/Wavelet/internal/router/root/default.go:31.2,31.61 1 0
-github.com/Rain-kl/Wavelet/internal/router/root/root.go:12.45,14.2 0 0
-github.com/Rain-kl/Wavelet/internal/router/root/root.go:17.40,26.2 3 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:26.56,29.2 3 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:29.2,48.3 7 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:52.66,63.2 6 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:63.2,68.3 4 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:71.2,72.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:72.2,76.3 3 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:79.2,80.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:80.2,83.3 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:86.2,87.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:87.2,92.3 4 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:96.59,99.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:99.2,106.3 6 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:109.2,110.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:110.2,116.3 5 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:120.62,123.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:123.2,129.3 5 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:129.3,132.4 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:136.2,137.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:137.2,142.3 4 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:142.3,146.4 3 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:151.63,153.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:153.2,160.3 6 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:164.60,166.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:166.2,173.3 4 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:173.3,177.4 3 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:180.3,181.3 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:181.3,186.4 4 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:191.60,193.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:193.2,196.3 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:196.3,203.4 6 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:206.3,211.3 4 0
-github.com/Rain-kl/Wavelet/internal/router/v1/admin.go:211.3,218.4 6 0
-github.com/Rain-kl/Wavelet/internal/router/v1/custom.go:15.57,17.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/custom.go:17.2,19.3 1 0
-github.com/Rain-kl/Wavelet/internal/router/v1/message_gateway.go:12.69,14.2 1 0
-github.com/Rain-kl/Wavelet/internal/router/v1/message_gateway_admin.go:11.70,13.2 1 0
-github.com/Rain-kl/Wavelet/internal/router/v1/user.go:17.82,32.2 5 0
-github.com/Rain-kl/Wavelet/internal/router/v1/user.go:34.55,36.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/user.go:36.2,39.3 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/user.go:42.57,44.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/user.go:44.2,46.3 1 0
-github.com/Rain-kl/Wavelet/internal/router/v1/user.go:49.56,59.2 9 0
-github.com/Rain-kl/Wavelet/internal/router/v1/user.go:61.55,63.2 2 0
-github.com/Rain-kl/Wavelet/internal/router/v1/user.go:63.2,75.3 10 0
-github.com/Rain-kl/Wavelet/internal/router/v1/user.go:75.3,80.4 4 0
-github.com/Rain-kl/Wavelet/internal/router/v1/user.go:84.57,87.2 3 0
-github.com/Rain-kl/Wavelet/internal/router/v1/user.go:87.2,94.3 6 0
-github.com/Rain-kl/Wavelet/internal/router/v1/v1.go:12.80,25.2 4 0
-github.com/Rain-kl/Wavelet/internal/testhelper/cleanup.go:7.33,9.2 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/cleanup.go:13.25,14.35 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/cleanup.go:14.35,16.3 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/gin.go:12.67,16.41 4 0
-github.com/Rain-kl/Wavelet/internal/testhelper/gin.go:16.41,18.3 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/gin.go:19.2,19.10 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:31.82,36.16 2 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:36.16,38.3 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:41.2,41.45 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:41.45,43.3 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:46.2,61.16 2 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:61.16,63.3 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:66.2,70.16 3 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:70.16,72.3 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:75.2,87.20 4 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:87.20,97.3 8 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:99.2,99.30 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:102.49,189.2 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:191.49,320.2 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:322.52,325.57 2 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:325.57,327.3 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:329.2,346.30 3 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:346.30,348.3 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:349.2,351.73 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:351.73,353.3 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:357.2,357.40 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:357.40,358.42 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:358.42,360.4 1 0
-github.com/Rain-kl/Wavelet/internal/testhelper/test_helper.go:361.3,361.98 1 0
-github.com/Rain-kl/Wavelet/internal/util/custom_types.go:18.54,20.9 2 0
-github.com/Rain-kl/Wavelet/internal/util/custom_types.go:20.9,22.3 1 0
-github.com/Rain-kl/Wavelet/internal/util/custom_types.go:23.2,23.39 1 0
-github.com/Rain-kl/Wavelet/internal/util/custom_types.go:27.53,29.2 1 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:19.38,21.16 2 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:21.16,23.3 1 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:24.2,25.80 2 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:43.36,45.2 1 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:48.131,50.16 2 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:50.16,52.3 1 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:54.2,54.34 1 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:54.34,56.3 1 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:58.2,58.34 1 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:58.34,60.3 1 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:62.2,63.16 2 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:63.16,65.3 1 0
-github.com/Rain-kl/Wavelet/internal/util/http_clients.go:67.2,67.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:20.83,22.15 2 2
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:22.15,24.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:26.2,28.50 3 2
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:28.50,30.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:31.2,31.36 1 2
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:35.134,37.15 2 2
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:37.15,39.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:41.2,41.55 1 2
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:41.55,43.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:45.2,47.54 3 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:47.54,49.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:50.2,50.16 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:50.16,52.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:54.2,54.14 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:54.14,56.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:57.2,57.18 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:57.18,59.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:60.2,68.16 4 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:68.16,70.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:72.2,72.42 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:76.66,77.22 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:77.22,79.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:80.2,80.106 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:80.106,82.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:83.2,83.15 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:87.87,88.22 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:88.22,90.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:91.2,91.142 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:91.142,93.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:94.2,94.15 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:97.42,98.15 1 3
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:98.15,100.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:101.2,101.22 1 3
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:104.67,105.27 1 4
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:105.27,106.31 1 4
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:106.31,108.4 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:109.3,109.54 1 3
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:111.2,111.23 1 3
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:111.23,113.3 1 3
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:114.2,114.29 1 3
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:114.29,116.3 1 3
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:117.2,117.27 1 3
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:117.27,119.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log.go:120.2,120.14 1 3
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:37.73,38.14 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:38.14,40.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:42.2,43.15 2 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:43.15,45.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:47.2,64.67 6 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:64.67,66.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:68.2,69.28 2 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:69.28,72.3 2 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:73.2,73.27 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:73.27,76.3 2 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:78.2,79.33 2 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:79.33,85.3 2 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:86.2,86.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:90.95,92.15 2 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:92.15,94.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:96.2,110.67 5 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:110.67,112.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:114.2,115.27 2 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:115.27,118.3 2 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:120.2,121.44 2 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:121.44,126.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:127.2,127.41 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:127.41,129.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:130.2,130.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:134.96,135.15 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:135.15,137.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:139.2,140.15 2 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:140.15,142.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:144.2,155.75 4 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:155.75,157.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_stats.go:158.2,158.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_writer.go:15.82,16.20 1 2
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_writer.go:16.20,18.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_writer.go:19.2,19.22 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_writer.go:19.22,21.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_writer.go:23.2,24.16 2 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_writer.go:24.16,26.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_writer.go:28.2,28.31 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_writer.go:28.31,40.17 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_writer.go:40.17,42.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_writer.go:45.2,45.37 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_writer.go:45.37,47.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/analytics/access_log_writer.go:48.2,48.12 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:9.41,11.49 2 7
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:11.49,13.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:14.2,14.42 1 6
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:14.42,16.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:17.2,17.76 1 5
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:17.76,19.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:20.2,20.42 1 4
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:20.42,22.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:23.2,23.41 1 3
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:23.41,25.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:26.2,26.41 1 2
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:26.41,28.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/analytics/browser.go:29.2,29.16 1 1
-github.com/Rain-kl/Wavelet/internal/cmd/all.go:18.42,20.35 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/all.go:20.35,22.4 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/api.go:17.42,19.35 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/api.go:19.35,21.4 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:35.52,50.85 3 4
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:50.85,53.3 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:56.2,62.12 2 4
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:72.68,74.2 1 4
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:76.43,78.2 1 4
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:80.60,82.2 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:84.52,86.2 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:89.62,93.15 3 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:93.15,95.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:97.2,101.16 4 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:101.16,103.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:105.2,112.16 3 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:112.16,114.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:116.2,117.34 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:117.34,119.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:120.2,130.17 4 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:130.17,132.101 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:132.101,134.4 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:137.2,137.12 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:140.61,144.16 3 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:144.16,146.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:147.2,150.21 3 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:150.21,153.3 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:154.2,156.12 3 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:166.72,168.2 1 4
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:170.45,172.2 1 4
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:174.62,176.2 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:178.54,180.2 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:183.62,187.15 3 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:187.15,189.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:191.2,191.34 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:191.34,193.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:193.8,195.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:196.2,198.37 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:198.37,204.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:206.2,206.17 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:206.17,207.62 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:207.62,209.4 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:212.2,214.16 3 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:214.16,216.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:218.2,220.12 3 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:223.61,227.16 3 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:227.16,229.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:230.2,232.21 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:232.21,236.3 3 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:237.2,238.12 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:247.78,249.2 1 4
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:251.48,253.2 1 4
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:255.65,257.2 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:259.57,261.2 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:264.65,268.15 3 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:268.15,270.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:272.2,272.34 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:272.34,274.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:274.8,276.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:277.2,279.39 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:279.39,285.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:287.2,288.52 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:288.52,290.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:292.2,293.12 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:296.64,300.16 3 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:300.16,302.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/app.go:303.2,307.12 4 0
-github.com/Rain-kl/Wavelet/internal/cmd/banner.go:24.45,26.2 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/banner.go:28.53,44.26 2 1
-github.com/Rain-kl/Wavelet/internal/cmd/banner.go:44.26,46.3 1 1
-github.com/Rain-kl/Wavelet/internal/cmd/banner.go:47.2,48.34 2 1
-github.com/Rain-kl/Wavelet/internal/cmd/banner.go:51.25,52.31 1 1
-github.com/Rain-kl/Wavelet/internal/cmd/banner.go:52.31,54.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/banner.go:55.2,55.28 1 1
-github.com/Rain-kl/Wavelet/internal/cmd/banner.go:58.53,59.21 1 2
-github.com/Rain-kl/Wavelet/internal/cmd/banner.go:59.21,61.3 1 1
-github.com/Rain-kl/Wavelet/internal/cmd/banner.go:62.2,63.20 2 1
-github.com/Rain-kl/Wavelet/internal/cmd/banner.go:63.20,65.3 1 1
-github.com/Rain-kl/Wavelet/internal/cmd/banner.go:66.2,66.82 1 1
-github.com/Rain-kl/Wavelet/internal/cmd/bootstrap.go:13.43,17.2 3 3
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:36.57,38.44 2 2
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:38.44,40.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:41.2,41.26 1 2
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:41.26,43.3 1 32
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:44.2,44.27 1 2
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:50.45,52.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:53.42,58.25 4 3
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:58.25,60.4 1 2
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:60.9,64.18 4 1
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:64.18,66.5 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:67.4,68.22 2 1
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:68.22,70.5 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:73.3,74.17 2 3
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:74.17,75.46 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:75.46,77.5 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:78.4,78.47 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:81.3,82.25 2 3
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:82.25,84.4 1 1
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:84.9,86.18 2 2
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:86.18,88.5 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:91.3,91.61 1 3
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:91.61,93.4 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:95.3,95.56 1 3
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:95.56,96.82 1 3
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:96.82,98.5 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:101.4,102.79 2 3
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:102.79,103.34 1 3
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:103.34,105.6 1 1
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:108.4,108.78 1 3
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:110.3,110.17 1 3
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:110.17,112.4 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:114.3,118.42 4 3
-github.com/Rain-kl/Wavelet/internal/cmd/reset_passwd.go:122.13,126.2 3 1
-github.com/Rain-kl/Wavelet/internal/cmd/root.go:24.55,40.3 2 3
-github.com/Rain-kl/Wavelet/internal/cmd/root.go:41.45,43.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/root.go:44.56,46.3 1 3
-github.com/Rain-kl/Wavelet/internal/cmd/root.go:47.45,50.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/root.go:58.22,61.2 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/root.go:63.30,67.2 3 3
-github.com/Rain-kl/Wavelet/internal/cmd/root.go:69.13,74.54 3 1
-github.com/Rain-kl/Wavelet/internal/cmd/root.go:74.54,76.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/root.go:77.2,83.61 5 1
-github.com/Rain-kl/Wavelet/internal/cmd/root.go:87.16,88.42 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/root.go:88.42,90.3 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/scheduler.go:17.42,19.35 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/scheduler.go:19.35,21.4 1 0
-github.com/Rain-kl/Wavelet/internal/cmd/worker.go:17.42,19.35 2 0
-github.com/Rain-kl/Wavelet/internal/cmd/worker.go:19.35,21.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:31.66,33.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:33.16,35.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:36.2,40.16 4 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:40.16,42.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:43.2,44.112 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:44.112,46.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:47.2,49.80 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:49.80,51.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:52.2,53.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:53.16,55.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:56.2,57.75 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:57.75,59.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:60.2,60.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:63.71,65.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:66.20,67.46 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:68.24,69.50 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:71.2,72.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:72.16,73.47 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:73.47,75.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:76.3,76.33 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:78.2,79.30 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:79.30,82.3 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:83.2,83.13 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:86.60,90.58 4 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:90.58,98.3 5 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/cleanup.go:99.2,99.12 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:21.70,23.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:30.90,32.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:34.82,35.37 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:35.37,37.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:38.2,38.12 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:41.116,42.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:42.20,44.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:45.2,45.46 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:45.46,47.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:48.2,48.45 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:51.86,52.46 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:52.46,54.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:55.2,55.51 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:58.107,59.46 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:59.46,61.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:62.2,62.62 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:65.121,67.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:69.172,71.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:73.121,75.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:77.143,79.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:81.144,83.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:85.98,87.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:89.98,91.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:93.100,95.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:97.106,98.22 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:98.22,100.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:101.2,103.128 3 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:103.128,105.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:106.2,106.38 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:106.38,108.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:109.2,109.42 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:112.145,113.22 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:113.22,115.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:116.2,116.16 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:116.16,118.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:119.2,125.16 4 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:125.16,127.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:128.2,128.15 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:128.15,128.35 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:129.2,129.33 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:132.83,134.18 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:134.18,147.17 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:147.17,149.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:150.3,151.32 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/clickhouse.go:153.2,153.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:34.46,34.78 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:40.69,42.2 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:49.74,50.29 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:50.29,52.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:53.2,53.26 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:56.66,57.37 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:57.37,59.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:60.2,60.12 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:63.110,64.20 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:64.20,66.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:67.2,67.46 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:67.46,69.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:70.2,70.22 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:70.22,71.22 1 4
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:71.22,73.4 1 4
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:75.2,75.75 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:78.80,79.46 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:79.46,81.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:82.2,83.36 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:86.101,87.46 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:87.46,89.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:90.2,91.54 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:91.54,93.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:94.2,94.36 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:97.139,103.44 3 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:103.44,105.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:106.2,106.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:109.100,110.133 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:110.133,112.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:115.115,117.9 2 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:117.9,119.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:120.2,121.127 2 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:121.127,123.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:124.2,124.34 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:127.166,129.9 2 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:129.9,131.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:132.2,133.127 2 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:133.127,135.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:136.2,136.16 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:136.16,138.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:139.2,141.119 3 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:141.119,143.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:144.2,144.40 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:147.90,148.55 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:148.55,150.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:151.2,153.27 3 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:153.27,156.3 2 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:157.2,157.62 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:157.62,160.3 2 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:161.2,161.29 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:161.29,164.3 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:165.2,165.27 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:165.27,168.3 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:169.2,169.21 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:169.21,171.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:172.2,172.49 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:175.115,176.15 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:176.15,178.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:179.2,189.16 5 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:189.16,191.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:192.2,193.25 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:193.25,195.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:196.2,197.28 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:197.28,200.3 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:201.2,201.17 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:204.137,214.16 4 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:214.16,216.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:217.2,218.25 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:218.25,220.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:221.2,222.35 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:222.35,224.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:225.2,225.38 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:225.38,225.76 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:226.2,226.17 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:229.138,239.16 4 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:239.16,241.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:242.2,243.25 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:243.25,245.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:246.2,246.17 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:249.98,250.30 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:250.30,252.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:253.2,253.57 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:253.57,254.63 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:254.63,256.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:258.2,258.12 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:267.33,270.48 3 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:270.48,272.22 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:272.22,274.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:275.3,276.72 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:276.72,278.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:279.3,279.23 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:279.23,281.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:283.2,283.12 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:283.12,285.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:286.2,286.55 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:289.30,290.12 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:290.12,292.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:293.2,293.10 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:296.39,297.14 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:297.14,299.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:300.2,300.56 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:303.36,304.11 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:304.11,306.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:307.2,307.18 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:310.42,312.2 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:314.44,315.27 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:315.27,317.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:318.2,318.43 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:321.40,322.16 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:322.16,324.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/gorm.go:325.2,326.90 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:16.92,24.61 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:24.61,26.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:27.2,27.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:31.63,33.29 2 12
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:33.29,35.3 1 4
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:36.2,37.16 2 8
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:37.16,39.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:40.2,40.16 1 7
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:44.90,47.29 3 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:47.29,49.40 2 6
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:49.40,50.12 1 4
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:52.3,52.26 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:54.2,54.12 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:59.89,60.30 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:60.30,62.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:63.2,64.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:64.16,66.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:67.2,67.85 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:67.85,69.106 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:69.106,71.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:72.3,72.15 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:72.15,73.12 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:75.3,75.90 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:75.90,77.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:79.2,79.12 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:85.91,86.30 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:86.30,88.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:89.2,89.46 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:89.46,91.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:92.2,93.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:93.16,95.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:96.2,98.29 3 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:98.29,100.40 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:100.40,101.12 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:103.3,104.136 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:104.136,106.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:107.3,107.23 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:107.23,108.12 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:110.3,110.90 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:110.90,112.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/partition_cleanup.go:114.2,114.12 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:48.39,48.60 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:50.65,51.25 1 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:51.25,53.3 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:54.2,54.31 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:58.50,60.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:60.16,62.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:63.2,64.42 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:64.42,68.3 3 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:69.2,73.42 4 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:73.42,75.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:76.2,77.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:77.16,79.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:80.2,82.15 3 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:86.66,88.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:91.78,93.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:95.88,96.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:97.24,100.55 3 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:101.36,105.55 4 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:106.10,107.67 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:112.42,114.16 2 3
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:114.16,115.47 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:115.47,117.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:118.3,118.15 1 2
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:120.2,120.25 1 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:124.32,126.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:126.16,128.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:129.2,130.108 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:130.108,132.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:136.24,141.2 4 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:144.21,152.2 7 1
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:155.58,157.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:159.59,161.68 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:161.68,165.3 3 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:166.2,169.60 3 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:169.60,171.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:173.2,174.20 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:174.20,176.37 2 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:176.37,178.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:179.3,179.39 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:179.39,181.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/logstore/provider.go:184.2,188.22 5 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:74.39,76.2 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:78.47,80.2 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:83.36,85.44 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:85.44,86.13 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:88.2,88.34 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:91.52,100.2 6 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:102.61,104.33 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:104.33,106.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:107.2,107.30 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:107.30,109.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:111.2,117.16 6 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:117.16,119.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:121.2,121.41 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:121.41,123.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:125.2,126.16 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:126.16,128.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:130.2,130.21 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:134.37,136.33 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:136.33,138.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:139.2,140.16 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:140.16,142.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:143.2,143.37 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:147.103,148.21 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:148.21,150.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:151.2,151.20 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:151.20,153.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:154.2,154.26 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:154.26,156.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:157.2,157.23 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:157.23,159.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:161.2,175.16 5 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:175.16,177.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:179.2,189.18 6 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:193.126,195.16 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:195.16,197.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:199.2,200.63 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:200.63,202.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:204.2,204.59 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:204.59,206.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:208.2,209.27 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:209.27,211.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:213.2,213.37 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:213.37,215.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:217.2,218.37 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:218.37,229.42 9 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:229.42,231.4 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:234.2,234.22 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:238.61,241.29 3 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:241.29,248.44 6 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:248.44,252.42 4 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:252.42,254.10 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/cap.go:258.2,258.18 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/prng.go:14.31,16.32 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/prng.go:16.32,19.3 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/prng.go:20.2,20.13 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/prng.go:26.51,28.32 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/prng.go:28.32,31.3 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/prng.go:32.2,32.10 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/prng.go:38.58,41.28 3 0
-github.com/Rain-kl/Wavelet/pkg/cap/prng.go:41.28,47.3 5 0
-github.com/Rain-kl/Wavelet/pkg/cap/prng.go:48.2,48.33 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:40.65,44.25 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:44.25,46.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:47.2,47.14 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:51.80,55.2 3 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:58.67,60.12 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:60.12,62.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:63.2,63.38 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:63.38,66.3 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:67.2,67.30 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:71.95,79.2 4 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:82.67,87.2 4 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:91.105,96.12 4 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:96.12,98.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:99.2,103.18 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:107.89,112.27 4 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:112.27,114.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:115.2,116.23 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:119.64,121.21 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:121.21,123.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:126.40,130.28 4 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:130.28,131.29 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:131.29,133.4 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:143.62,147.2 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:150.81,152.22 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:152.22,154.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:155.2,155.16 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:155.16,157.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:158.2,158.23 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:162.96,164.2 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:167.68,169.2 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:172.106,174.2 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:177.90,179.22 2 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:179.22,181.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:182.2,182.16 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:182.16,184.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cap/store.go:185.2,185.23 1 0
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:26.41,27.30 1 0
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:27.30,38.16 6 0
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:38.16,40.4 1 0
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:43.3,52.39 5 0
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:52.39,65.4 1 0
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:68.3,68.49 1 0
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:68.49,71.4 2 0
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:75.63,77.34 2 4
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:77.34,79.3 1 1
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:80.2,81.41 2 3
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:81.41,83.58 2 4
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:83.58,85.4 1 2
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:87.2,87.14 1 1
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:90.39,91.30 1 3
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:91.30,93.67 2 4
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:93.67,98.4 4 2
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:100.3,100.36 1 4
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:100.36,103.4 2 0
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:105.3,105.11 1 4
-github.com/Rain-kl/Wavelet/internal/router/middlewares.go:110.47,112.2 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:35.41,37.38 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:37.38,39.3 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:42.2,49.20 7 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:49.20,51.3 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:53.2,62.16 2 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:62.16,64.3 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:67.2,67.25 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:67.25,68.84 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:68.84,70.4 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:73.2,81.15 5 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:85.30,87.16 2 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:87.16,89.3 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:91.2,98.16 3 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:98.16,100.3 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:101.2,101.22 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:101.22,103.3 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:105.2,105.17 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:105.17,107.86 2 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:107.86,109.4 1 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:112.2,120.50 6 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:120.50,125.3 4 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:126.2,129.36 3 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:132.36,137.2 3 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:137.2,140.3 2 0
-github.com/Rain-kl/Wavelet/internal/router/router.go:140.3,142.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:14.96,16.109 2 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:16.109,18.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:19.2,19.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:23.83,25.112 2 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:25.112,27.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:28.2,28.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:32.78,34.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:37.101,39.99 2 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:39.99,41.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:42.2,42.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:47.86,50.2 2 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:53.93,55.90 2 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:55.90,57.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:58.2,58.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:62.76,64.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/access_token.go:67.75,69.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:18.70,20.72 2 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:20.72,22.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:23.2,23.25 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:23.25,25.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:26.2,26.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:30.76,32.101 2 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:32.101,34.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:35.2,35.25 1 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:35.25,37.3 1 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:38.2,38.21 1 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:42.83,43.13 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:43.13,45.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:46.2,47.70 2 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:47.70,49.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:50.2,51.21 2 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:55.87,57.16 2 2
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:57.16,59.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:60.2,61.88 2 2
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:61.88,63.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:64.2,65.21 2 2
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:69.76,70.42 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:70.42,72.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:73.2,73.40 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:77.93,78.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:78.20,80.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:81.2,82.78 2 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:82.78,84.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:85.2,85.16 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:85.16,87.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:88.2,88.42 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:88.42,90.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:91.2,101.10 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:105.76,107.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:107.16,109.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:110.2,111.42 2 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:111.42,113.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:114.2,114.102 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:118.61,119.13 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:119.13,121.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:122.2,122.56 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:122.56,123.99 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:123.99,125.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:126.3,126.60 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:131.115,133.127 2 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:133.127,135.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:136.2,136.22 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:140.85,141.72 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:141.72,143.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:144.2,148.56 4 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:148.56,151.17 3 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:151.17,152.40 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:152.40,154.5 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:155.4,158.12 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:160.3,160.46 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:160.46,162.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:163.3,163.34 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:168.108,169.17 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:169.17,171.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:172.2,173.102 2 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:173.102,175.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:176.2,177.35 2 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:177.35,179.32 2 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:179.32,183.4 3 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:183.9,185.18 2 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:185.18,186.13 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:188.4,191.19 4 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:191.19,193.5 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:195.3,204.5 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:206.2,206.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:210.88,211.28 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:211.28,213.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source.go:214.2,214.102 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:55.70,56.23 1 9
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:56.23,58.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:59.2,61.15 3 9
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:64.64,66.2 1 6
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:68.50,70.2 1 13
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:72.51,74.2 1 7
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:76.77,92.2 1 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:94.77,110.2 1 1
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:112.38,113.21 1 12
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:113.21,115.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:116.2,116.69 1 12
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:119.49,124.17 4 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:124.17,129.16 4 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:129.16,131.4 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:133.3,133.18 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:133.18,136.4 2 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:138.3,138.30 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:138.30,141.4 2 5
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:145.60,146.21 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:146.21,148.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:149.2,149.73 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:152.85,155.21 3 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:155.21,157.3 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:160.96,161.19 1 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:161.19,163.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:164.2,166.21 3 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:166.21,169.3 2 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:173.82,176.81 2 5
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:176.81,178.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:180.2,180.21 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:180.21,182.77 2 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:182.77,185.4 2 1
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:188.2,189.16 2 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:189.16,191.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:192.2,193.39 2 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:197.93,201.22 3 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:201.22,203.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:205.2,205.68 1 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:205.68,208.3 2 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:210.2,210.21 1 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:210.21,212.82 2 3
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:212.82,217.4 4 1
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:220.2,221.16 2 2
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:221.16,223.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:224.2,226.21 3 2
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:230.59,236.21 4 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:236.21,238.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:240.2,240.90 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:240.90,242.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:244.2,247.21 4 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:247.21,249.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:250.2,250.35 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:250.35,252.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:253.2,253.19 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:253.19,254.58 1 1
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:254.58,256.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:259.2,260.12 2 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:264.36,265.37 1 5
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:265.37,267.36 2 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:267.36,269.4 1 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:270.3,271.31 2 4
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:273.2,273.38 1 5
-github.com/Rain-kl/Wavelet/internal/repository/auth_source_cache.go:277.39,280.2 2 10
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:18.80,19.16 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:19.16,21.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:22.2,22.36 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:26.80,28.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:31.87,33.72 2 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:33.72,35.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:36.2,36.17 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:40.79,42.70 2 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:42.70,44.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:45.2,45.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:49.65,50.56 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:50.56,51.98 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:51.98,53.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:54.3,54.94 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:54.94,56.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:57.3,57.54 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:62.79,63.15 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:63.15,65.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:66.2,66.35 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:70.127,73.16 3 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:73.16,75.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:76.2,76.16 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:80.93,82.99 2 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:82.99,84.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:85.2,85.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:89.87,91.71 2 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:91.71,93.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:94.2,94.16 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:98.65,100.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:103.148,108.16 3 2
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:108.16,110.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:111.2,111.45 1 1
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:111.45,113.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:114.2,120.53 2 1
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:120.53,122.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:123.2,123.17 1 1
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:127.90,129.77 2 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:129.77,131.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:132.2,132.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:136.64,138.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:141.59,143.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:146.86,148.80 2 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:148.80,150.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/message_gateway.go:151.2,151.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:17.73,19.82 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:19.82,21.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:22.2,22.22 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:26.84,28.77 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:28.77,30.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:31.2,31.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:35.89,37.81 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:37.81,39.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:40.2,40.22 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:44.79,46.107 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:46.107,48.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:49.2,49.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:53.79,54.57 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:54.57,56.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:57.2,58.12 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:62.77,63.55 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:63.55,65.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:66.2,67.12 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:71.79,72.57 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:72.57,74.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:75.2,76.12 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:80.95,83.21 3 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:83.21,84.61 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:84.61,86.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:89.2,89.103 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:89.103,91.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:93.2,93.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:93.21,95.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:97.2,97.22 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:101.69,102.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_channel.go:102.21,104.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:17.69,19.80 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:19.80,21.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:22.2,22.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:26.80,28.59 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:28.59,30.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:31.2,31.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:35.82,37.83 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:37.83,39.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:40.2,40.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:44.75,46.109 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:46.109,48.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:49.2,49.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:53.73,54.55 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:54.55,56.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:57.2,58.12 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:62.71,63.53 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:63.53,65.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:66.2,67.12 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:71.94,73.81 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:73.81,75.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:76.2,77.12 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:81.73,82.55 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:82.55,84.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:85.2,86.12 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:90.102,92.110 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:92.110,94.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:95.2,95.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:99.89,102.21 3 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:102.21,103.59 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:103.59,105.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:108.2,108.105 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:108.105,110.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:112.2,112.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:112.21,114.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:116.2,116.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:120.66,121.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_event.go:121.21,123.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_history.go:23.111,25.27 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_history.go:25.27,27.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_history.go:28.2,28.25 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_history.go:28.25,30.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_history.go:32.2,33.50 2 0
-github.com/Rain-kl/Wavelet/internal/repository/push_history.go:33.50,35.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_history.go:37.2,39.89 3 0
-github.com/Rain-kl/Wavelet/internal/repository/push_history.go:39.89,41.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_history.go:43.2,43.28 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_history.go:47.79,49.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/push_history.go:52.53,54.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/schedule.go:14.74,16.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/schedule.go:19.74,21.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/schedule.go:24.59,26.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/schedule.go:29.79,31.78 2 0
-github.com/Rain-kl/Wavelet/internal/repository/schedule.go:31.78,33.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/schedule.go:34.2,34.23 1 0
-github.com/Rain-kl/Wavelet/internal/repository/schedule.go:38.67,40.75 2 0
-github.com/Rain-kl/Wavelet/internal/repository/schedule.go:40.75,42.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/schedule.go:43.2,43.23 1 0
-github.com/Rain-kl/Wavelet/internal/repository/schedule.go:47.73,49.87 2 0
-github.com/Rain-kl/Wavelet/internal/repository/schedule.go:49.87,51.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/schedule.go:52.2,52.23 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:25.78,27.21 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:27.21,29.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:31.2,32.54 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:32.54,34.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:35.2,35.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:40.92,42.21 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:42.21,44.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:46.2,47.72 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:47.72,49.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:50.2,50.16 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:54.109,57.46 2 3
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:57.46,59.65 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:59.65,61.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:64.2,65.21 2 3
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:65.21,67.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:69.2,70.72 2 3
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:70.72,72.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:75.2,76.16 2 3
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:76.16,83.3 1 3
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:85.2,85.16 1 3
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:89.88,91.2 1 2
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:94.105,95.20 1 2
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:95.20,97.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:99.2,104.27 4 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:104.27,105.52 1 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:105.52,107.66 2 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:107.66,109.13 2 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:112.3,112.33 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:115.2,115.23 1 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:115.23,117.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:119.2,120.21 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:120.21,122.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:124.2,125.81 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:125.81,127.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:129.2,129.25 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:129.25,131.17 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:131.17,138.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:139.3,139.38 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:142.2,142.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:146.69,148.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:151.82,155.20 3 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:155.20,157.30 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:157.30,159.66 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:159.66,160.55 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:160.55,162.6 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:165.3,165.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:168.2,169.21 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:169.21,171.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:173.2,174.109 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:174.109,176.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:179.2,179.30 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:179.30,181.17 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:181.17,188.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:191.2,191.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:195.64,197.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:197.16,199.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:201.2,202.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:202.16,204.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:206.2,206.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:210.97,212.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:212.16,214.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:216.2,217.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:217.16,219.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:221.2,221.39 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:225.66,227.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:227.16,229.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:231.2,232.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:232.16,234.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:236.2,236.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:240.73,242.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:242.16,244.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:246.2,247.40 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:247.40,249.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:251.2,251.66 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:251.66,253.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config.go:255.2,255.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:16.99,18.22 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:18.22,20.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:21.2,22.51 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:22.51,24.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:25.2,25.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:29.93,31.78 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:31.78,33.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:34.2,34.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:38.72,41.44 3 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:41.44,43.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:44.2,44.16 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:44.16,46.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:47.2,47.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:51.80,53.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:56.110,58.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:61.77,64.59 3 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:64.59,66.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:68.2,68.44 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:68.44,75.54 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:75.54,77.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:78.8,80.52 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:80.52,82.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_admin.go:84.2,84.46 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:45.94,47.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:47.16,49.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:51.2,52.30 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:52.30,54.17 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:54.17,56.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:57.3,62.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:64.2,64.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:68.104,70.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:70.16,71.45 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:71.45,73.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:74.3,74.30 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:77.2,78.16 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:78.16,80.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:82.2,87.8 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:91.54,93.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:102.40,104.2 1 5
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:106.51,107.21 1 2
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:107.21,109.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:111.2,115.17 4 2
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:115.17,120.16 4 2
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:120.16,122.4 1 2
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:124.3,124.18 1 2
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:124.18,127.4 2 2
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:129.3,129.37 1 2
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:129.37,131.72 2 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:131.72,133.13 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:136.4,137.31 2 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:137.31,139.5 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:139.10,141.5 1 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:147.38,148.39 1 3
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:148.39,150.38 2 2
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:150.38,152.4 1 2
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:153.3,154.33 2 2
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:156.2,156.40 1 3
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:159.43,162.2 1 3
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:165.73,172.21 3 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:172.21,175.3 2 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:176.2,176.12 1 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:180.65,187.21 3 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:187.21,190.3 2 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:191.2,191.12 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:194.87,195.21 1 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:195.21,197.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:198.2,199.16 2 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:199.16,201.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:202.2,202.72 1 1
-github.com/Rain-kl/Wavelet/internal/repository/system_config_cache.go:206.41,208.2 1 5
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:30.85,33.2 2 50
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:36.85,38.2 1 4
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:41.97,43.88 2 7
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:43.88,45.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:46.2,46.62 1 6
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:46.62,48.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:49.2,49.24 1 6
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:53.89,55.79 2 2
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:55.79,57.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:58.2,58.62 1 2
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:58.62,60.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:61.2,61.24 1 2
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:66.113,72.16 3 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:72.16,73.71 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:73.71,75.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:76.3,76.31 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:78.2,78.44 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:78.44,80.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:81.2,81.24 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:85.87,86.21 1 1012
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:86.21,88.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:90.2,94.71 4 1012
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:94.71,99.3 4 1012
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:100.2,100.16 1 1012
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:100.16,102.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:103.2,103.12 1 1012
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:107.70,108.21 1 2
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:108.21,110.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:112.2,114.16 3 2
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:114.16,116.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:117.2,117.24 1 2
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:117.24,119.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:120.2,125.25 3 2
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:125.25,127.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:128.2,128.30 1 2
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:128.30,130.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:132.2,132.53 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:132.53,134.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:135.2,135.12 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:139.121,140.19 1 10
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:140.19,142.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:143.2,143.23 1 10
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:143.23,145.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:147.2,149.22 2 10
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:149.22,151.3 1 2
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:152.2,152.24 1 10
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:152.24,154.3 1 3
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:154.8,154.73 1 7
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:154.73,156.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:156.8,156.37 1 6
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:156.37,158.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:160.2,161.50 2 10
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:161.50,163.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:165.2,167.106 3 10
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:167.106,169.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:170.2,170.63 1 10
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:170.63,172.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:174.2,174.31 1 10
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:177.48,178.34 1 7
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:178.34,180.3 1 6
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:181.2,183.29 3 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:183.29,185.17 2 2
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:185.17,187.4 1 2
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:189.2,189.12 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:198.9,206.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:209.108,227.65 7 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:227.65,229.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:231.2,232.37 2 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:232.37,238.39 2 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:238.39,240.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:241.3,241.58 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:244.2,247.37 2 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:247.37,249.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:250.2,251.37 2 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:251.37,253.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:255.2,258.8 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:261.53,263.2 1 1047
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:265.86,266.21 1 8
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:266.21,268.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:270.2,271.16 2 8
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:271.16,273.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:274.2,274.24 1 8
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:274.24,276.3 1 5
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:278.2,279.12 2 3
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:282.89,283.45 1 10
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:283.45,285.3 1 1
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:287.2,288.69 2 9
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:288.69,289.29 1 9
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:289.29,291.4 1 23
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:292.3,292.13 1 9
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:294.2,294.16 1 9
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:294.16,296.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:298.2,298.28 1 9
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:298.28,300.24 2 23
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:300.24,302.4 1 4
-github.com/Rain-kl/Wavelet/internal/repository/task_execution.go:304.2,304.12 1 9
-github.com/Rain-kl/Wavelet/internal/repository/template.go:16.67,18.99 2 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:18.99,20.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:21.2,21.23 1 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:25.80,27.76 2 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:27.76,29.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:30.2,30.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:34.73,37.44 3 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:37.44,39.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:40.2,40.16 1 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:40.16,42.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:43.2,43.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:47.70,49.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:52.68,54.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/template.go:57.70,59.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:27.95,31.24 2 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:31.24,33.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:34.2,34.26 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:34.26,36.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:37.2,37.23 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:37.23,39.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:40.2,40.28 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:40.28,42.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:44.2,45.50 2 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:45.50,47.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:49.2,51.112 3 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:51.112,53.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:54.2,54.26 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:58.80,60.119 2 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:60.119,62.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:63.2,63.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:68.72,70.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:73.66,75.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:78.92,79.23 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:79.23,81.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:82.2,82.56 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:86.69,91.43 2 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:91.43,93.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:94.2,94.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:98.99,104.2 3 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:108.68,110.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:113.62,115.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:118.82,122.36 2 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:122.36,124.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:125.2,125.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload.go:129.48,131.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload_stat.go:14.71,16.54 2 0
-github.com/Rain-kl/Wavelet/internal/repository/upload_stat.go:16.54,18.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/upload_stat.go:19.2,19.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:19.70,21.74 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:21.74,23.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:24.2,24.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:28.82,30.86 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:30.86,32.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:33.2,33.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:37.52,39.94 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:39.94,41.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:42.2,46.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:50.65,52.98 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:52.98,54.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:55.2,55.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:68.99,70.26 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:70.26,72.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:73.2,73.27 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:73.27,75.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:76.2,76.24 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:76.24,78.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:80.2,81.50 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:81.50,83.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:85.2,92.34 3 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:92.34,94.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:95.2,95.26 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:99.77,104.34 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:104.34,106.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:107.2,107.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:117.80,123.35 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:123.35,125.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:126.2,126.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:130.74,132.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:135.68,136.56 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:136.56,137.88 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:137.88,139.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:140.3,140.92 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:140.92,142.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:143.3,143.60 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:148.80,150.108 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:150.108,152.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:153.2,153.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:157.74,159.102 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:159.102,161.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:162.2,162.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:166.62,168.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:171.78,172.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:172.19,174.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:175.2,176.76 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:176.76,178.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:179.2,179.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:183.92,184.20 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:184.20,186.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:187.2,190.43 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:190.43,192.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:193.2,193.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:197.62,199.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:202.106,215.21 4 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:215.21,217.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:218.2,218.58 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:218.58,220.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:221.2,222.12 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:226.84,230.47 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:230.47,232.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:233.2,233.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:237.76,239.98 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:239.98,241.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:242.2,242.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:246.86,248.103 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:248.103,250.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:251.2,251.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:255.99,257.124 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:257.124,259.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:260.2,260.19 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:264.84,266.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:269.88,271.2 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:274.74,276.113 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:276.113,278.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:279.2,279.15 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:279.15,281.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:282.2,282.22 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:282.22,284.113 2 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:284.113,286.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:287.3,287.21 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:287.21,289.4 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:291.2,291.18 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:291.18,293.3 1 0
-github.com/Rain-kl/Wavelet/internal/repository/user.go:294.2,294.38 1 0
-github.com/Rain-kl/Wavelet/internal/shared/response/abort.go:13.50,15.2 1 2
-github.com/Rain-kl/Wavelet/internal/shared/response/abort.go:18.52,20.2 1 1
-github.com/Rain-kl/Wavelet/internal/shared/response/abort.go:23.49,25.2 1 1
-github.com/Rain-kl/Wavelet/internal/shared/response/abort.go:28.48,30.2 1 1
-github.com/Rain-kl/Wavelet/internal/shared/response/abort.go:33.48,35.2 1 1
-github.com/Rain-kl/Wavelet/internal/shared/response/abort.go:38.55,40.2 1 1
-github.com/Rain-kl/Wavelet/internal/shared/response/abort.go:43.48,45.2 1 1
-github.com/Rain-kl/Wavelet/internal/shared/response/middleware.go:17.47,18.30 1 11
-github.com/Rain-kl/Wavelet/internal/shared/response/middleware.go:18.30,21.47 2 11
-github.com/Rain-kl/Wavelet/internal/shared/response/middleware.go:21.47,23.4 1 2
-github.com/Rain-kl/Wavelet/internal/shared/response/middleware.go:25.3,27.25 3 9
-github.com/Rain-kl/Wavelet/internal/shared/response/middleware.go:27.25,30.4 2 1
-github.com/Rain-kl/Wavelet/internal/shared/response/middleware.go:32.3,33.30 2 9
-github.com/Rain-kl/Wavelet/internal/shared/response/middleware.go:33.30,36.4 2 8
-github.com/Rain-kl/Wavelet/internal/shared/response/middleware.go:38.3,38.68 1 1
-github.com/Rain-kl/Wavelet/internal/shared/response/response.go:29.35,31.2 1 2
-github.com/Rain-kl/Wavelet/internal/shared/response/response.go:34.47,36.2 1 10
-github.com/Rain-kl/Wavelet/internal/shared/response/response.go:39.59,42.2 2 9
-github.com/Rain-kl/Wavelet/internal/shared/response/response.go:45.36,47.2 1 1
-github.com/Rain-kl/Wavelet/internal/shared/response/response.go:50.28,52.2 1 1
-github.com/Rain-kl/Wavelet/internal/shared/response/response.go:55.36,57.2 1 9
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:25.67,27.22 2 3
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:27.22,29.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:31.2,34.16 2 3
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:34.16,36.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:38.2,38.40 1 3
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:42.62,44.16 2 3
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:44.16,45.13 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:47.2,47.14 1 3
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:51.53,53.2 1 2
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:56.43,58.2 1 3
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:61.41,63.2 1 1
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:66.39,68.2 1 1
-github.com/Rain-kl/Wavelet/pkg/cache/ram/cache.go:71.43,73.2 1 1
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:42.13,47.2 1 1
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:49.50,53.12 4 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:53.12,56.3 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:57.2,57.13 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:62.59,64.9 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:64.9,66.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:68.2,69.12 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:69.12,71.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:74.2,74.90 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:74.90,78.3 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:80.2,80.25 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:83.76,89.9 5 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:89.9,91.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:93.2,94.12 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:94.12,96.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:99.2,99.69 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:99.69,101.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:103.2,104.31 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:104.31,105.15 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:105.15,107.4 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:109.2,109.38 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:114.26,121.8 6 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:121.8,122.32 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:122.32,124.4 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:127.2,128.20 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:128.20,130.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:132.2,136.37 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:141.44,147.9 5 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:147.9,149.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:151.2,152.31 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:152.31,153.15 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:153.15,155.4 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:157.2,157.38 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:162.60,168.29 5 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:168.29,170.21 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:170.21,172.4 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:173.3,176.4 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:178.2,178.38 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:183.50,185.9 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:185.9,187.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:189.2,190.35 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:190.35,191.91 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:191.91,193.4 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:195.2,195.13 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:199.87,200.22 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:200.22,202.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:204.2,204.15 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:204.15,207.17 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:207.17,208.35 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:208.35,211.5 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:212.4,212.14 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:214.3,215.13 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:219.2,220.16 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:220.16,222.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:223.2,224.12 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/ram/manager.go:228.21,233.2 4 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:69.34,72.41 1 6
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:72.41,72.62 1 31
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:76.2,88.10 3 6
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:94.72,98.30 3 9
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:98.30,100.3 1 4
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:102.2,103.13 2 9
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:103.13,105.3 1 7
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:108.2,110.25 3 9
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:110.25,112.3 1 7
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:113.2,117.44 3 9
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:117.44,119.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:122.2,125.34 2 9
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:125.34,131.3 5 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:131.8,140.3 4 9
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:143.2,145.12 2 9
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:149.49,152.9 3 17
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:152.9,155.3 2 3
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:157.2,158.66 2 14
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:158.66,161.3 2 3
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:162.2,166.16 3 11
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:166.16,169.50 3 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:169.50,171.4 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:172.3,172.27 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:175.2,175.28 1 11
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:175.28,178.50 3 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:178.50,180.4 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:181.3,181.27 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:184.2,190.9 5 11
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:190.9,192.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:193.2,195.21 2 11
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:198.67,203.9 4 3
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:203.9,205.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:207.2,208.66 2 3
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:208.66,211.3 2 3
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:213.2,214.16 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:214.16,217.3 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:219.2,219.28 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:219.28,222.3 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:224.2,225.31 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:229.42,233.2 3 1
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:235.50,236.34 1 4
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:236.34,241.3 4 4
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:242.2,242.23 1 4
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:246.31,255.2 6 5
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:258.33,270.2 3 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:273.82,281.2 6 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:284.25,285.19 1 9
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:285.19,287.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:289.2,289.57 1 9
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:289.57,296.3 6 1
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:300.37,305.62 3 6
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:305.62,307.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:309.2,319.28 4 6
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:319.28,322.43 2 1
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:322.43,324.12 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:327.3,329.18 3 1
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:329.18,331.4 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:334.3,336.17 3 1
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:336.17,337.12 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:340.3,345.5 1 1
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:349.2,349.46 1 6
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:349.46,351.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:354.2,354.35 1 6
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:354.35,363.3 4 1
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:365.2,365.12 1 6
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:369.60,371.21 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:371.21,373.3 1 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:377.32,382.33 4 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:382.33,384.60 2 0
-github.com/Rain-kl/Wavelet/pkg/cache/disk/cache.go:384.60,389.4 4 0
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:49.63,51.24 2 3
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:51.24,56.3 1 2
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:58.2,59.22 2 3
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:59.22,61.3 1 2
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:61.8,63.3 1 1
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:64.2,64.41 1 3
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:64.41,66.3 1 3
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:68.2,81.32 3 3
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:81.32,83.3 1 0
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:84.2,84.57 1 3
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:90.43,91.17 1 4
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:91.17,95.3 1 1
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:96.2,96.25 1 4
-github.com/Rain-kl/Wavelet/pkg/httppool/httppool.go:101.52,106.2 1 1
-github.com/Rain-kl/Wavelet/pkg/logger/logger.go:37.25,39.16 2 1
-github.com/Rain-kl/Wavelet/pkg/logger/logger.go:39.16,41.3 1 0
-github.com/Rain-kl/Wavelet/pkg/logger/logger.go:44.2,44.29 1 1
-github.com/Rain-kl/Wavelet/pkg/logger/logger.go:44.29,46.3 1 1
-github.com/Rain-kl/Wavelet/pkg/logger/logger.go:49.2,62.3 3 1
-github.com/Rain-kl/Wavelet/pkg/logger/logger.go:65.13,73.2 2 1
-github.com/Rain-kl/Wavelet/pkg/logger/logger.go:76.23,78.2 1 0
-github.com/Rain-kl/Wavelet/pkg/logger/logger.go:81.70,84.2 2 0
-github.com/Rain-kl/Wavelet/pkg/logger/logger.go:87.69,90.2 2 0
-github.com/Rain-kl/Wavelet/pkg/logger/logger.go:93.69,96.2 2 0
-github.com/Rain-kl/Wavelet/pkg/logger/logger.go:99.70,102.2 2 0
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:33.52,39.2 1 14
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:43.54,44.17 1 12
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:44.17,46.3 1 1
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:48.2,50.33 3 11
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:50.33,51.22 1 103
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:51.22,54.21 3 39
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:54.21,56.5 1 39
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:60.2,60.48 1 11
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:60.48,62.3 1 1
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:64.2,64.20 1 11
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:68.38,70.2 1 0
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:73.49,81.21 5 40
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:81.21,83.3 1 34
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:84.2,89.32 4 40
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:89.32,90.10 1 3
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:91.20,91.20 0 3
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:92.11,92.11 0 0
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:96.2,96.19 1 40
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:103.73,107.18 3 14
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:107.18,109.3 1 2
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:113.2,117.31 3 12
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:117.31,120.3 2 45
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:122.2,122.17 1 12
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:122.17,124.28 1 7
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:124.28,126.4 1 5
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:127.3,127.44 1 2
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:132.2,133.41 2 5
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:133.41,134.36 1 12
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:134.36,135.9 1 4
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:139.2,139.14 1 5
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:139.14,141.3 1 1
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:144.2,145.15 2 4
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:145.15,147.3 1 3
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:149.2,150.36 2 4
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:158.51,164.2 5 3
-github.com/Rain-kl/Wavelet/pkg/logger/ringbuffer.go:167.55,172.2 4 3
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:23.69,24.26 1 1
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:24.26,28.57 3 0
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:28.57,30.4 1 0
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:33.3,41.41 2 0
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:44.2,44.40 1 1
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:48.54,64.26 2 1
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:64.26,66.3 1 0
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:67.2,67.49 1 1
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:71.53,74.15 2 1
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:75.15,76.28 1 0
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:77.14,78.27 1 1
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:79.14,80.27 1 0
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:81.15,82.28 1 0
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:83.10,85.27 2 0
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:89.56,92.28 3 0
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:92.28,94.3 1 0
-github.com/Rain-kl/Wavelet/pkg/logger/utils.go:95.2,98.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:35.43,39.2 3 7
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:42.87,44.2 1 1
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:47.91,59.27 9 1
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:59.27,61.3 1 5
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:62.2,67.29 3 1
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:67.29,69.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:72.2,73.16 2 1
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:73.16,75.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:77.2,77.12 1 1
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:81.109,92.16 5 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:92.16,94.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:95.2,95.15 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:95.15,95.35 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:96.2,99.16 3 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:99.16,101.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:102.2,102.15 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:102.15,102.37 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:104.2,104.41 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:104.41,106.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:107.2,107.49 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:107.49,109.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:110.2,110.39 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:110.39,112.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:114.2,115.16 2 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:115.16,117.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:118.2,118.15 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:118.15,118.32 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:120.2,121.16 2 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:121.16,123.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:124.2,124.12 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:128.104,130.66 2 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:130.66,132.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:134.2,140.29 6 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:140.29,150.3 3 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:150.8,152.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:153.2,153.16 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:153.16,156.3 2 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:157.2,157.15 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:157.15,157.35 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:158.2,164.16 4 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:164.16,167.3 2 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:168.2,168.15 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:168.15,168.37 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:171.2,171.29 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:171.29,172.48 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:172.48,178.52 3 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:178.52,181.5 2 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:182.4,182.42 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:187.2,187.46 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:187.46,190.42 3 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:190.42,193.4 2 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:194.3,194.48 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:198.2,199.49 2 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:199.49,202.3 2 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:203.2,207.39 3 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:207.39,210.3 2 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:211.2,216.16 4 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:216.16,219.3 2 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:220.2,231.27 9 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:231.27,233.3 1 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:234.2,237.51 3 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:237.51,241.3 3 0
-github.com/Rain-kl/Wavelet/pkg/mail/mail.go:242.2,249.29 6 0
-github.com/Rain-kl/Wavelet/pkg/trace/propagator.go:10.52,15.2 1 0
-github.com/Rain-kl/Wavelet/pkg/trace/sampler.go:15.69,19.2 1 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace.go:19.13,26.2 3 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace.go:36.23,38.16 2 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace.go:38.16,40.3 1 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace.go:41.2,46.22 4 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace.go:46.22,48.3 1 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace.go:49.2,49.44 1 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace.go:53.36,54.35 1 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace.go:54.35,56.3 1 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace.go:60.107,62.2 1 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace_provider.go:17.70,20.16 2 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace_provider.go:20.16,22.3 1 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace_provider.go:25.2,35.16 2 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace_provider.go:35.16,37.3 1 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace_provider.go:40.2,41.16 2 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace_provider.go:41.16,43.3 1 0
-github.com/Rain-kl/Wavelet/pkg/trace/trace_provider.go:46.2,51.28 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:19.37,21.42 2 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:21.42,23.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:24.2,25.24 2 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:25.24,27.3 1 8
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:28.2,28.25 1 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:32.37,34.22 2 2
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:34.22,35.37 1 19
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:35.37,36.12 1 3
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:38.3,38.34 1 16
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:40.2,40.19 1 2
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:44.34,46.26 2 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:46.26,48.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/pairing.go:49.2,49.28 1 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/registry.go:14.39,18.2 3 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/registry.go:21.41,26.2 4 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:27.113,28.59 1 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:28.59,30.3 1 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:31.2,31.54 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:35.33,35.79 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:38.61,40.2 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:43.54,48.68 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:48.68,50.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:51.2,52.16 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:52.16,54.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:55.2,56.53 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:56.53,59.3 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:60.2,60.54 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:60.54,63.3 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:64.2,64.57 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:64.57,67.3 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:68.2,69.12 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:69.12,72.3 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:73.2,73.12 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:77.55,78.18 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:78.18,80.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:81.2,81.12 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:85.116,86.18 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:86.18,88.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:89.2,90.16 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:90.16,92.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:93.2,94.12 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:97.75,98.66 1 2
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:98.66,100.3 1 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:101.2,101.24 1 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:101.24,103.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:104.2,112.39 2 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:112.39,114.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:115.2,115.18 1 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:115.18,117.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:118.2,118.27 1 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:121.79,124.20 3 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:124.20,127.3 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:128.2,128.23 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:128.23,131.17 3 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:131.17,133.4 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:134.3,134.30 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:136.2,136.21 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:136.21,138.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:139.2,140.16 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:140.16,142.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:143.2,144.26 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:144.26,146.49 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:146.49,148.12 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:150.3,150.80 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/telegram/adapter.go:152.2,152.12 1 0
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:19.13,21.2 1 1
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:30.144,31.19 1 6
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:31.19,33.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:35.2,37.20 2 6
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:37.20,41.3 2 6
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:41.8,45.17 3 0
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:45.17,47.4 1 0
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:50.2,51.16 2 6
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:51.16,53.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:54.2,57.53 2 6
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:57.53,60.3 2 0
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:62.2,64.16 3 6
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:64.16,66.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:67.2,67.15 1 6
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:67.15,67.40 1 6
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:69.2,72.53 3 6
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:72.53,74.3 1 1
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:78.2,82.84 2 5
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:82.84,84.3 1 1
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:86.2,86.26 1 4
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:90.57,91.19 1 0
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:91.19,93.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:94.2,94.87 1 0
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:94.87,96.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/custom.go:97.2,97.12 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:17.13,19.2 1 1
-github.com/Rain-kl/Wavelet/pkg/push/email.go:26.43,30.2 3 4
-github.com/Rain-kl/Wavelet/pkg/push/email.go:33.143,34.56 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:34.56,36.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:37.2,37.18 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:37.18,39.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:41.2,42.52 2 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:42.52,44.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:46.2,47.54 2 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:47.54,49.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:49.8,52.26 2 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:52.26,54.4 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:55.3,55.36 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:59.2,64.16 4 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:64.16,65.58 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:65.58,67.4 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:70.2,82.16 8 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:82.16,85.3 2 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:87.2,91.17 3 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:91.17,93.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:95.2,95.9 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:96.20,97.23 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:98.24,99.17 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:99.17,101.4 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:104.2,104.16 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:108.56,109.19 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:109.19,111.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:112.2,112.19 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:112.19,114.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:115.2,115.22 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:115.22,117.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/email.go:118.2,118.12 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:23.13,25.2 1 1
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:79.142,80.19 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:80.19,82.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:84.2,87.20 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:87.20,95.49 5 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:95.49,97.72 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:97.72,100.5 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:100.10,103.5 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:104.9,112.107 3 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:112.107,114.20 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:114.20,116.6 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:117.5,119.20 3 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:119.20,121.6 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:123.5,124.18 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:125.22,126.28 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:127.21,128.25 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:131.5,149.6 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:150.10,154.5 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:156.8,159.53 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:159.53,161.4 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:163.3,164.55 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:164.55,166.4 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:166.9,169.27 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:169.27,171.5 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:172.4,172.39 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:175.3,176.53 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:176.53,178.4 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:181.3,182.16 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:183.20,184.26 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:185.19,186.23 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:189.3,207.4 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:211.2,211.22 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:211.22,214.17 3 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:214.17,216.4 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:217.3,218.18 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:221.2,222.16 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:222.16,224.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:227.2,228.16 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:228.16,230.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:231.2,235.16 4 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:235.16,237.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:238.2,238.15 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:238.15,238.40 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:240.2,240.38 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:240.38,242.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:244.2,245.64 2 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:245.64,247.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:249.2,249.19 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:249.19,251.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:253.2,253.16 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:257.55,258.19 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:258.19,260.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:261.2,261.87 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:261.87,263.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:264.2,264.12 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:267.63,271.16 4 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:271.16,273.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/lark.go:274.2,274.59 1 0
-github.com/Rain-kl/Wavelet/pkg/push/push.go:49.50,52.19 3 4
-github.com/Rain-kl/Wavelet/pkg/push/push.go:52.19,53.40 1 0
-github.com/Rain-kl/Wavelet/pkg/push/push.go:55.2,55.31 1 4
-github.com/Rain-kl/Wavelet/pkg/push/push.go:59.52,63.9 4 0
-github.com/Rain-kl/Wavelet/pkg/push/push.go:63.9,65.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/push.go:66.2,66.20 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:18.13,20.2 1 1
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:40.151,41.22 1 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:41.22,43.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:45.2,46.18 2 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:46.18,48.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:49.2,49.18 1 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:49.18,51.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:53.2,54.19 2 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:54.19,56.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:57.2,60.52 3 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:60.52,62.3 1 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:63.2,64.54 2 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:64.54,66.3 1 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:66.8,68.26 2 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:68.26,70.4 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:71.3,71.38 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:73.2,74.52 2 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:74.52,76.3 1 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:78.2,79.20 2 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:79.20,81.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:81.8,83.3 1 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:86.2,87.16 2 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:87.16,90.21 2 1
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:90.21,92.4 1 1
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:93.3,94.25 2 1
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:94.25,96.4 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:99.2,99.16 1 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:103.59,104.22 1 3
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:104.22,106.3 1 1
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:107.2,107.19 1 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:107.19,108.88 1 1
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:108.88,110.4 1 1
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:112.2,112.12 1 1
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:115.113,125.16 4 3
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:125.16,127.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:129.2,130.16 2 3
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:130.16,132.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:133.2,137.16 4 3
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:137.16,139.3 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:140.2,140.15 1 3
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:140.15,140.40 1 3
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:142.2,142.38 1 3
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:142.38,144.80 2 1
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:144.80,146.4 1 1
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:147.3,147.51 1 0
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:150.2,150.12 1 2
-github.com/Rain-kl/Wavelet/pkg/push/telegram.go:153.34,158.2 4 6
-github.com/Rain-kl/Wavelet/pkg/push/template.go:15.65,20.6 4 14
-github.com/Rain-kl/Wavelet/pkg/push/template.go:20.6,22.16 2 25
-github.com/Rain-kl/Wavelet/pkg/push/template.go:22.16,24.9 2 13
-github.com/Rain-kl/Wavelet/pkg/push/template.go:27.3,31.19 4 12
-github.com/Rain-kl/Wavelet/pkg/push/template.go:31.19,35.9 3 1
-github.com/Rain-kl/Wavelet/pkg/push/template.go:37.3,38.31 2 11
-github.com/Rain-kl/Wavelet/pkg/push/template.go:38.31,40.4 1 10
-github.com/Rain-kl/Wavelet/pkg/push/template.go:40.9,45.4 3 1
-github.com/Rain-kl/Wavelet/pkg/push/template.go:46.3,46.18 1 11
-github.com/Rain-kl/Wavelet/pkg/push/template.go:48.2,48.21 1 14
-github.com/Rain-kl/Wavelet/pkg/push/template.go:51.32,52.14 1 10
-github.com/Rain-kl/Wavelet/pkg/push/template.go:52.14,54.3 1 1
-github.com/Rain-kl/Wavelet/pkg/push/template.go:55.2,55.25 1 9
-github.com/Rain-kl/Wavelet/pkg/push/template.go:56.14,57.13 1 4
-github.com/Rain-kl/Wavelet/pkg/push/template.go:58.14,59.21 1 0
-github.com/Rain-kl/Wavelet/pkg/push/template.go:60.11,61.27 1 1
-github.com/Rain-kl/Wavelet/pkg/push/template.go:62.13,63.43 1 0
-github.com/Rain-kl/Wavelet/pkg/push/template.go:64.13,65.36 1 0
-github.com/Rain-kl/Wavelet/pkg/push/template.go:66.15,67.47 1 1
-github.com/Rain-kl/Wavelet/pkg/push/template.go:68.12,69.33 1 1
-github.com/Rain-kl/Wavelet/pkg/push/template.go:70.10,73.17 2 2
-github.com/Rain-kl/Wavelet/pkg/push/template.go:73.17,75.4 1 2
-github.com/Rain-kl/Wavelet/pkg/push/template.go:76.3,76.30 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:41.39,46.16 4 3
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:46.16,49.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:51.2,51.44 1 3
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:65.40,70.47 4 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:70.47,73.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:75.2,76.20 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:76.20,79.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:82.2,82.38 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:82.38,85.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:88.2,89.91 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:89.91,91.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:93.2,94.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:94.16,97.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:99.2,99.28 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:99.28,102.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:105.2,106.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:106.16,109.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:111.2,122.66 4 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:122.66,125.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:127.2,130.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:143.40,149.16 5 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:149.16,152.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:154.2,154.69 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:154.69,157.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:159.2,159.52 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:172.40,178.16 5 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:178.16,181.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:183.2,184.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:184.16,187.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/access_tokens.go:189.2,192.5 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:61.42,63.2 1 8
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:65.64,66.21 1 5
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:66.21,68.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:69.2,70.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:70.16,72.3 1 5
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:73.2,73.31 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:76.56,77.21 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:77.21,79.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:80.2,82.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:82.16,84.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:85.2,85.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:85.12,87.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:90.56,91.21 1 3
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:91.21,93.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:94.2,94.68 1 3
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:97.55,99.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:99.16,101.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:102.2,102.16 1 5
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:105.58,107.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:107.16,109.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:110.2,110.16 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:113.54,115.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:115.16,117.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:118.2,118.16 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:121.64,123.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:123.16,125.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:126.2,126.16 1 5
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:129.67,131.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:131.16,133.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:134.2,134.16 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:137.49,142.74 5 8
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:142.74,144.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:145.2,145.93 1 8
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:148.49,150.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:150.16,152.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:153.2,153.67 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:156.50,158.2 1 12
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:160.54,162.2 1 2
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:164.94,165.28 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:165.28,167.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:169.2,170.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:170.16,172.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:173.2,177.16 4 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:177.16,179.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:180.2,181.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:181.16,183.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:185.2,185.72 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:185.72,187.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:188.2,197.16 5 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:197.16,199.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:200.2,200.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:203.75,206.62 3 4
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:206.62,208.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:209.2,211.60 3 4
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:211.60,213.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:214.2,215.13 2 3
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:218.126,219.16 1 8
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:219.16,220.55 1 4
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:220.55,225.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:226.3,226.81 1 3
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:230.2,230.48 1 4
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:230.48,232.77 2 4
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:232.77,234.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:235.3,236.29 2 4
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:236.29,238.4 1 2
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:238.9,240.4 1 2
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:241.3,244.9 1 4
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:247.2,249.60 3 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:249.60,250.92 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:250.92,252.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:255.2,259.8 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:262.69,264.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:264.17,266.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:268.2,269.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:269.16,271.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:272.2,272.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:272.15,274.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:276.2,278.60 3 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:278.60,280.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:282.2,282.76 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:285.87,286.46 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:286.46,288.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:289.2,289.31 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:289.31,291.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:292.2,292.52 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:292.52,294.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:295.2,295.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:298.107,300.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:300.16,302.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:304.2,305.54 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:305.54,306.81 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:306.81,308.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:310.3,311.17 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:311.17,313.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:314.3,314.16 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:314.16,316.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:319.2,320.27 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:320.27,322.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:323.2,331.60 8 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:331.60,333.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:334.2,334.21 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:337.87,339.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:339.16,341.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:342.2,342.19 1 5
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:345.67,347.2 1 3
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:349.66,350.66 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:350.66,351.96 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:351.96,353.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:354.3,354.54 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:356.2,356.12 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:359.93,361.16 2 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:361.16,363.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:365.2,365.36 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:365.36,367.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:369.2,369.61 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:369.61,371.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:373.2,373.87 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:373.87,375.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:378.2,378.84 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:378.84,379.32 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:379.32,381.4 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:383.2,383.78 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:383.78,385.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:387.2,388.12 2 1
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:391.93,393.16 2 3
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:393.16,395.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:396.2,396.20 1 3
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:399.80,401.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:401.16,403.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:404.2,404.19 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:407.83,408.66 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:408.66,410.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:411.2,412.12 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:415.75,417.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:417.16,419.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:420.2,423.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:423.16,425.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:426.2,426.15 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:426.15,428.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:429.2,429.12 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:432.105,434.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:434.16,436.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:438.2,441.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:441.16,443.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:445.2,451.70 5 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:451.70,453.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/logics.go:455.2,457.39 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:64.28,66.34 2 5
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:66.34,69.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:70.2,70.45 1 5
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:70.45,73.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:74.2,75.47 2 5
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:75.47,78.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:79.2,80.46 2 5
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:80.46,83.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:85.2,86.16 2 5
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:86.16,92.3 5 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:93.2,93.20 1 5
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:93.20,98.3 4 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:101.2,103.39 2 5
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:103.39,108.3 4 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:110.2,110.42 1 5
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:110.42,112.17 2 4
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:112.17,115.4 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:116.3,116.52 1 4
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:116.52,119.4 2 2
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:122.2,125.51 3 3
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:125.51,128.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:129.2,130.17 2 3
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:130.17,132.3 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:133.2,134.68 2 3
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:134.68,137.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:139.2,145.88 4 3
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:159.31,161.68 2 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:161.68,164.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:166.2,167.47 2 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:167.47,170.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:172.2,179.46 7 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:179.46,182.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:183.2,183.21 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:183.21,186.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:187.2,187.43 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:187.43,190.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:193.2,193.84 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:193.84,196.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:198.2,208.25 2 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:208.25,210.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:211.2,211.25 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:211.25,213.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:214.2,214.64 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:214.64,217.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:219.2,219.54 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:219.54,222.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:224.2,224.61 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:224.61,227.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:229.2,229.76 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:241.29,245.19 4 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:245.19,247.36 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:247.36,249.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:249.9,249.49 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:249.49,251.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:251.9,251.57 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:251.57,253.4 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:255.2,257.39 3 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:257.39,260.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:261.2,261.40 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:280.37,282.47 2 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:282.47,285.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:287.2,290.52 3 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:290.52,293.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:294.2,294.46 1 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:294.46,297.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:299.2,300.20 2 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:300.20,303.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:305.2,306.95 2 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:306.95,309.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:312.2,316.58 4 1
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:329.36,331.47 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:331.47,334.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:336.2,337.21 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:337.21,340.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:342.2,342.29 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:342.29,345.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:347.2,348.62 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:348.62,351.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:353.2,353.41 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:367.36,369.47 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:369.47,372.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:374.2,375.20 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:375.20,378.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:380.2,382.16 3 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:382.16,385.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/routers.go:386.2,391.82 4 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:78.76,79.23 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:79.23,81.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:83.2,84.54 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:84.54,86.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:88.2,92.57 4 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:92.57,94.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:96.2,96.26 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:100.99,102.54 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:102.54,105.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:107.2,115.90 6 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:115.90,117.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:118.2,118.90 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:118.90,120.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:121.2,121.94 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:121.94,123.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:124.2,124.94 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:124.94,126.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:128.2,128.63 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:128.63,132.3 3 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:134.2,135.16 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:135.16,137.3 1 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:139.2,150.16 4 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:150.16,153.3 2 0
-github.com/Rain-kl/Wavelet/internal/apps/user/tasks.go:155.2,160.8 3 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:44.113,45.114 1 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:45.114,47.3 1 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:48.2,48.54 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:52.33,52.73 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:55.61,57.2 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:60.54,67.70 4 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:67.70,70.3 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:72.2,74.74 3 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:74.74,76.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:76.8,78.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:80.2,81.16 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:81.16,84.3 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:86.2,86.121 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:86.121,88.40 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:88.40,90.4 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:91.3,93.18 3 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:93.18,96.4 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:97.3,98.13 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:101.2,108.12 7 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:108.12,109.80 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:109.80,111.4 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:113.2,113.12 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:117.55,121.21 4 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:121.21,124.3 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:125.2,125.12 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:129.118,133.16 4 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:133.16,135.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:136.2,140.12 2 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:143.64,144.22 1 2
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:144.22,146.3 1 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:147.2,150.40 4 1
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:150.40,152.3 1 0
-github.com/Rain-kl/Wavelet/pkg/message_gateway/channel/qq/adapter.go:153.2,160.4 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:33.34,35.27 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:35.27,36.17 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:36.17,38.4 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:40.2,40.10 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:44.32,46.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:49.43,56.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:59.49,62.2 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:62.2,71.3 6 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:71.3,76.4 4 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:79.3,80.3 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:80.3,84.4 3 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:87.3,88.3 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:88.3,91.4 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:94.3,95.3 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:95.3,100.4 4 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:103.3,104.3 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:104.3,111.4 6 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:114.3,115.3 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:115.3,121.4 5 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:124.3,125.3 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:125.3,131.4 5 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:131.4,134.5 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:138.3,139.3 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:139.3,144.4 4 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:144.4,148.5 3 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:152.3,153.3 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:153.3,160.4 6 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:163.3,164.3 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:164.3,169.4 4 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:169.4,173.5 3 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:175.4,176.4 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:176.4,181.5 4 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:185.3,186.3 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:186.3,188.4 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:188.4,195.5 6 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:197.4,201.4 4 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:201.4,208.5 6 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:213.2,213.91 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:213.91,215.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/admin/plugin.go:218.2,229.12 3 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:20.56,21.25 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:21.25,23.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:27.58,28.25 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:28.25,30.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:40.34,42.27 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:42.27,43.17 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:43.17,45.4 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:47.2,47.10 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:51.32,53.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:56.43,63.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:66.49,71.22 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:71.22,73.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:74.2,74.27 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:74.27,76.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:78.2,83.2 4 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:83.2,92.3 8 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/plugin.go:93.2,111.12 4 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:17.50,18.14 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:18.14,20.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:21.2,37.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:42.45,44.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:46.55,48.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:50.56,52.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:54.91,55.42 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:55.42,56.91 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:56.91,58.4 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:61.2,61.48 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:61.48,62.47 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:62.47,64.4 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:65.3,65.54 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:65.54,67.4 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:70.2,70.59 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:73.102,74.17 1 2
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:74.17,76.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:78.2,80.16 3 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:80.16,82.17 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:82.17,84.4 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:85.3,85.25 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:88.2,89.34 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:89.34,91.17 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:91.17,93.4 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:94.3,94.17 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:97.2,97.31 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:97.31,99.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:101.2,101.29 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:104.104,107.2 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:109.88,112.2 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:119.47,123.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:125.97,129.2 3 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:131.90,136.2 4 1
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:138.58,142.32 4 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:142.32,144.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/auth/service.go:145.2,145.12 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:20.50,21.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:21.25,23.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:27.46,28.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:28.25,30.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:34.58,35.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:35.25,37.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:41.51,42.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:42.25,44.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:59.34,65.27 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:65.27,66.17 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:66.17,68.4 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:71.2,71.10 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:75.32,77.2 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:80.49,85.29 4 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:85.29,87.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:89.2,89.30 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:93.41,95.2 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:98.49,102.15 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:102.15,104.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:106.2,106.24 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:106.24,108.18 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:108.18,112.4 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:112.9,112.55 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:112.55,114.4 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:116.3,116.53 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:119.2,119.54 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:119.54,120.56 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:120.56,122.18 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:122.18,124.5 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:126.4,129.79 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:129.79,131.5 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:135.2,135.44 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:135.44,137.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:139.2,140.12 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:144.48,148.16 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:148.16,150.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:152.2,154.24 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:154.24,157.3 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:159.2,159.12 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:163.35,167.2 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:170.47,174.2 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:176.49,177.20 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:177.20,179.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:181.2,181.31 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:182.14,183.18 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:184.14,185.26 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:186.10,187.27 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:191.60,192.20 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:192.20,194.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:196.2,198.52 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:198.52,200.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:202.2,202.42 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:202.42,204.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:204.8,204.56 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:204.56,206.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:208.2,208.56 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:208.56,210.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:212.2,212.60 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:212.60,214.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron/plugin.go:216.2,216.12 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:25.50,26.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:26.25,28.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:32.46,33.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:33.25,35.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:39.47,40.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:40.25,42.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:46.45,47.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:47.25,49.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:53.50,54.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:54.25,56.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:60.43,61.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:61.25,63.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:81.34,89.27 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:89.27,90.17 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:90.17,92.4 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:95.2,95.10 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:99.32,101.2 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:104.49,109.29 4 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:109.29,113.3 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:115.2,115.30 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:119.41,121.2 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:124.49,128.15 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:128.15,130.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:132.2,134.50 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:134.50,135.48 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:135.48,137.18 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:137.18,139.5 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:140.4,140.35 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:144.2,144.21 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:144.21,154.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:156.2,156.44 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:156.44,158.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:160.2,162.12 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:166.48,170.16 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:170.16,172.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:174.2,176.21 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:176.21,180.3 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:182.2,182.12 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:186.35,190.2 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:193.41,197.2 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:200.40,204.2 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:206.51,207.14 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:207.14,209.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:211.2,211.24 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:212.25,213.17 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:214.21,215.17 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:216.48,217.36 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:218.43,219.73 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:219.73,221.4 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:222.35,223.73 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:223.73,225.4 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:226.26,227.73 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:227.73,229.4 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:230.20,231.73 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:231.73,233.4 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker/plugin.go:234.10,235.65 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:29.35,30.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:30.25,32.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:36.44,37.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:37.25,39.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:43.52,44.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:44.25,46.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:50.50,51.25 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:51.25,53.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:70.34,77.27 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:77.27,78.17 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:78.17,80.4 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:83.2,83.10 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:87.32,89.2 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:92.49,97.29 4 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:97.29,101.3 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:103.2,103.30 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:107.41,109.2 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:112.51,116.15 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:116.15,118.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:120.2,120.21 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:120.21,122.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:125.2,125.51 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:125.51,126.50 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:126.50,129.37 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:129.37,131.19 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:131.19,133.6 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:134.5,134.42 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:137.4,137.34 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:137.34,139.19 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:139.19,141.6 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:142.5,142.42 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:145.4,145.55 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:149.2,157.16 4 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:157.16,159.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:161.2,166.17 5 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:166.17,167.101 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:167.101,169.4 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:172.2,172.12 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:178.50,182.16 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:182.16,184.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:186.2,189.21 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:189.21,190.17 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:190.17,194.4 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:195.3,195.31 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:198.2,198.23 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:198.23,201.3 2 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:203.2,203.12 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:207.32,211.2 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:214.39,218.2 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:221.35,225.2 3 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:227.51,228.14 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:228.14,230.3 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:232.2,232.24 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:233.23,234.17 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:235.26,236.34 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:237.24,238.28 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:239.48,240.28 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:241.20,242.28 1 0
-github.com/Rain-kl/Wavelet/plugins/drivers/driver_http/plugin.go:243.10,244.60 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:25.34,27.27 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:27.27,28.17 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:28.17,30.4 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:32.2,32.10 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:36.32,38.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:41.43,48.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:60.49,66.2 3 1
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:66.2,71.3 4 1
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:73.2,76.104 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:76.104,78.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:80.2,80.103 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:80.103,82.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:85.2,88.94 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:88.94,91.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/plugin.go:94.2,109.12 3 1
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:17.48,18.25 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:18.25,20.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:29.34,31.27 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:31.27,32.17 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:32.17,34.4 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:36.2,36.10 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:40.32,42.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:45.43,52.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:55.49,61.15 3 1
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:61.15,63.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:64.2,83.29 4 1
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:83.29,85.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/risk_control/plugin.go:87.2,87.12 1 1
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:37.64,39.2 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:45.65,47.16 2 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:47.16,49.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:50.2,50.31 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:54.69,57.16 2 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:57.16,59.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:60.2,60.30 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:60.30,62.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:65.2,66.16 2 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:66.16,68.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:71.2,72.16 2 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:72.16,74.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:77.2,78.59 2 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:78.59,80.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:83.2,86.38 2 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:90.70,93.16 2 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:93.16,95.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:96.2,96.30 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:96.30,98.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:101.2,102.16 2 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:102.16,104.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:107.2,108.16 2 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:108.16,110.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:113.2,114.16 2 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:114.16,116.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:119.2,120.27 2 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:120.27,122.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:124.2,128.16 3 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:128.16,130.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:132.2,132.23 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:136.39,138.2 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:141.51,143.2 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:150.63,151.45 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:151.45,153.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:155.2,155.45 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:155.45,157.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/crypto.go:159.2,159.54 1 0
-github.com/Rain-kl/Wavelet/pkg/util/goroutine.go:16.20,18.12 2 2
-github.com/Rain-kl/Wavelet/pkg/util/goroutine.go:18.12,19.16 1 2
-github.com/Rain-kl/Wavelet/pkg/util/goroutine.go:19.16,20.32 1 2
-github.com/Rain-kl/Wavelet/pkg/util/goroutine.go:20.32,27.5 1 1
-github.com/Rain-kl/Wavelet/pkg/util/goroutine.go:29.3,29.7 1 2
-github.com/Rain-kl/Wavelet/pkg/util/like.go:14.38,16.2 1 6
-github.com/Rain-kl/Wavelet/pkg/util/password.go:13.52,15.16 2 1
-github.com/Rain-kl/Wavelet/pkg/util/password.go:15.16,17.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/password.go:18.2,18.26 1 1
-github.com/Rain-kl/Wavelet/pkg/util/password.go:24.25,25.34 1 1
-github.com/Rain-kl/Wavelet/pkg/util/password.go:25.34,27.17 2 1
-github.com/Rain-kl/Wavelet/pkg/util/password.go:27.17,29.4 1 0
-github.com/Rain-kl/Wavelet/pkg/util/password.go:30.3,30.35 1 1
-github.com/Rain-kl/Wavelet/pkg/util/password.go:32.2,32.26 1 1
-github.com/Rain-kl/Wavelet/pkg/util/password.go:36.52,38.2 1 3
-github.com/Rain-kl/Wavelet/pkg/util/password.go:42.42,44.16 2 1
-github.com/Rain-kl/Wavelet/pkg/util/password.go:44.16,46.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/password.go:47.2,47.39 1 1
-github.com/Rain-kl/Wavelet/pkg/util/strings.go:16.36,17.14 1 0
-github.com/Rain-kl/Wavelet/pkg/util/strings.go:17.14,19.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/strings.go:20.2,20.11 1 0
-github.com/Rain-kl/Wavelet/pkg/util/strings.go:24.37,26.35 2 0
-github.com/Rain-kl/Wavelet/pkg/util/strings.go:26.35,28.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/strings.go:29.2,31.38 3 0
-github.com/Rain-kl/Wavelet/pkg/util/strings.go:31.38,33.3 1 0
-github.com/Rain-kl/Wavelet/pkg/util/strings.go:34.2,34.64 1 0
-github.com/Rain-kl/Wavelet/pkg/util/uuid.go:20.38,22.65 2 0
-github.com/Rain-kl/Wavelet/pkg/util/uuid.go:22.65,27.3 3 0
-github.com/Rain-kl/Wavelet/pkg/util/uuid.go:28.2,28.40 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:33.53,34.25 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:34.25,36.3 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:40.42,41.25 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:41.25,43.3 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:47.43,48.25 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:48.25,50.3 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:61.34,65.27 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:65.27,66.17 1 3
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:66.17,68.4 1 3
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:70.2,70.10 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:74.32,76.2 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:79.49,81.24 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:81.24,83.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:85.2,88.16 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:88.16,90.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:92.2,100.24 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:100.24,102.30 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:102.30,105.4 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:108.2,109.12 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:124.59,125.23 1 6
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:125.23,127.3 1 6
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:128.2,128.28 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:131.50,132.26 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:132.26,134.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:136.2,136.22 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:136.22,140.18 3 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:140.18,142.8 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:142.8,143.12 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:144.21,145.12 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:146.26,147.13 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:147.13,149.7 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:150.6,150.41 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:150.41,152.7 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:159.49,160.23 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:160.23,162.22 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:162.22,164.4 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:168.83,170.51 1 5
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:170.51,171.67 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:171.67,173.4 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:175.3,175.29 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:179.2,179.26 1 3
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:179.26,181.17 2 3
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:181.17,187.4 2 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:187.9,187.40 1 3
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:187.40,189.4 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:192.2,192.31 1 3
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:195.101,197.16 2 2
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:197.16,199.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:201.2,202.13 2 2
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:202.13,204.3 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:207.2,213.26 2 2
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:213.26,214.85 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:214.85,216.4 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:219.2,219.12 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:222.74,227.26 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:227.26,228.104 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:228.104,230.4 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:231.3,231.61 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:234.2,234.12 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:237.78,239.2 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:241.135,243.16 2 2
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:243.16,245.3 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:246.2,246.45 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:246.45,248.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:250.2,251.16 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:251.16,253.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:255.2,255.50 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:255.50,257.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:259.2,260.16 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:260.16,262.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/cache/plugin.go:264.2,264.37 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:17.32,18.25 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:18.25,20.3 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:24.50,25.25 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:25.25,26.24 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:26.24,28.4 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:29.3,29.23 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:40.34,44.27 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:44.27,45.17 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:45.17,47.4 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:49.2,49.10 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:53.32,55.2 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:58.49,60.21 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:60.21,62.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:64.2,70.12 3 1
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:78.41,79.22 1 3
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:79.22,81.3 1 3
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:82.2,82.36 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:85.58,86.22 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:86.22,88.3 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:89.2,89.19 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:92.53,93.23 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:93.23,94.48 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:94.48,96.4 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/database/plugin.go:98.2,98.17 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:18.20,20.2 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:23.32,25.2 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:28.49,32.2 3 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:38.80,43.25 4 9
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:43.25,45.3 1 5
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:47.2,50.41 4 4
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:50.41,51.12 1 5
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:51.12,53.4 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:54.3,54.27 1 5
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:54.27,56.4 1 4
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:56.9,58.4 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:60.2,61.20 2 4
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:64.90,66.2 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:68.89,70.2 1 2
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:72.89,74.2 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:76.90,78.2 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:80.85,83.2 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:85.84,88.2 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:90.84,93.2 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:95.85,98.2 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/logger/plugin.go:100.80,107.2 4 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:20.48,21.25 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:21.25,23.3 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:32.34,34.27 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:34.27,35.17 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:35.17,37.4 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:39.2,39.10 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:43.32,45.2 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:48.49,54.2 3 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:60.91,61.22 1 4
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:61.22,63.3 1 4
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:64.2,65.16 2 0
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:65.16,67.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:68.2,68.15 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:71.151,73.16 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:73.16,75.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:77.2,78.16 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:78.16,80.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:82.2,85.8 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:88.101,90.16 2 2
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:90.16,92.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:94.2,95.16 2 2
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:95.16,97.3 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:99.2,105.8 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:108.76,110.16 2 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:110.16,112.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:113.2,113.27 1 1
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:116.139,134.16 4 0
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:134.16,136.3 1 0
-github.com/Rain-kl/Wavelet/plugins/infra/storage/plugin.go:138.2,144.8 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:23.56,24.25 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:24.25,26.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:35.34,37.27 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:37.27,38.17 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:38.17,40.4 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:42.2,42.10 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:46.32,48.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:51.43,58.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:61.49,66.22 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:66.22,68.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:69.2,73.2 3 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:73.2,83.3 8 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:83.3,88.4 4 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:91.2,94.91 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:94.91,97.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:99.2,99.92 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:99.92,101.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/plugin.go:104.2,131.12 5 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:17.50,18.14 1 3
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:18.14,20.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:21.2,37.3 1 3
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:42.45,44.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:46.99,48.16 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:48.16,50.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:51.2,51.27 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:54.111,56.16 2 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:56.16,58.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:59.2,59.27 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:62.105,64.77 2 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:64.77,66.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:67.2,67.27 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:70.120,71.24 1 2
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:71.24,73.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:75.2,87.25 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:87.25,89.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:91.2,91.24 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:91.24,92.65 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:92.65,94.4 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:97.2,97.58 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:97.58,99.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:101.2,101.30 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:104.141,106.25 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:106.25,108.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:109.2,109.22 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:109.22,111.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:112.2,112.26 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:112.26,114.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:115.2,115.20 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:115.20,117.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:118.2,118.22 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:118.22,120.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:121.2,121.23 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:121.23,123.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:124.2,124.24 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:124.24,126.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:127.2,127.25 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:127.25,129.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:130.2,132.99 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:132.99,134.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:136.2,136.31 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:139.113,141.74 2 2
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:141.74,143.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:145.2,145.38 1 2
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:145.38,147.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:149.2,149.63 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:149.63,151.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:153.2,157.11 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:160.96,162.74 2 3
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:162.74,165.3 2 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:166.2,166.37 1 3
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:169.91,175.2 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:177.131,178.15 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:178.15,180.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:181.2,181.19 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:181.19,183.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:185.2,192.16 3 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:192.16,194.3 1 0
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:196.2,197.23 2 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:197.23,199.3 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:201.2,201.25 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:204.92,206.2 1 1
-github.com/Rain-kl/Wavelet/plugins/domain/user/service.go:208.90,210.2 1 1
diff --git a/docs/WAVELET_WHITE_PAPER.md b/docs/WAVELET_WHITE_PAPER.md
index c45c21ad..b1e6aed9 100644
--- a/docs/WAVELET_WHITE_PAPER.md
+++ b/docs/WAVELET_WHITE_PAPER.md
@@ -141,8 +141,7 @@ Wavelet 是面向未来 5 年生产级云原生与高并发业务中台的 **微
| `w_uploads`
`w_upload_stats` | `plugins/domain/upload` | `models/models.go`
`repository/repository.go` | `core/contracts.StorageService`
`upload.Ingest` 流水线 |
| `w_system_configs`
`w_templates` | `plugins/domain/admin` | `models.go`
`repository.go` | `ctx.Settings()` / `contracts.ConfigService`
Redis Pub/Sub 广播 |
| `w_message_channels`
`w_message_bindings`
`w_message_pairing_codes`
`w_push_events`
`w_push_channels`
`w_push_histories` | `plugins/domain/message_gateway` | `models.go`
`repository.go` | `EventBus` 强类型事件广播订阅 |
-| `w_user_access_logs` (分析库/日志库) | `plugins/domain/risk_control` | 委托 `pkg/persistence/logstore` | `logstore.UserAccessLog` 抽象门面 |
-| `w_task_executions`
`w_schedules` | `pkg/task` & `plugins/drivers` | `pkg/task/types.go` | `ctx.Task()` 与 `ctx.Schedule()` 扩展点 |
+| `w_task_executions`
`w_schedules` | `plugins/drivers/driver_asynq_*` | `types.go`
`schedule.go` | `ctx.Task()` 与 `ctx.Schedule()` 扩展点 |
### 5.3 架构防线与单向依赖保障
1. **测试脚手架绝对解耦**:底层通用的 `pkg/testhelper` 严禁反向引用任何上层业务插件。`testhelper` 维护轻量自包含的测试表脚手架,彻底杜绝包导入循环(Import Cycle)。
diff --git a/docs/superpowers/plans/2026-08-16-message-gateway.md b/docs/superpowers/plans/2026-08-16-message-gateway.md
deleted file mode 100644
index 1f3d7cad..00000000
--- a/docs/superpowers/plans/2026-08-16-message-gateway.md
+++ /dev/null
@@ -1,650 +0,0 @@
-# Message Gateway Implementation Plan
-
-> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
-
-**Goal:** Ship Wavelet’s inbound message gateway (Telegram + QQ private chat), admin channel cards, profile pairing, and `message_gateway.inbound` events — no Clipper clip ingest.
-
-**Architecture:** `pkg/message_gateway` defines Channel/Registry/pairing with zero Gin/GORM. Worker runs adapters (telebot long poll, official botgo C2C). API does CRUD and bind/unbind. Bound inbound messages emit `listener.EmitMessageGatewayInbound`.
-
-**Tech Stack:** Go 1.25, Gin, GORM, goose, `gopkg.in/telebot.v4`, official QQ `botgo`, Next.js, next-intl.
-
-**Spec:** `docs/superpowers/specs/2026-08-16-message-gateway-design.md`
-
-## Global Constraints
-
-- Wavelet repo only. Do not edit Clipper.
-- `pkg/message_gateway` must not import Gin, GORM, sessions, or `internal/apps`.
-- Tables `w_*`. No physical FKs. Dual PG + SQLite goose.
-- API errors only `response.Abort*`.
-- No `init()` cross-module registration; wire in `internal/platform/bootstrap` and `internal/cmd`.
-- Routes only via `internal/router/v1`.
-- v1: private chat / C2C only; groups logged and dropped.
-- Pairing: alphabet `ABCDEFGHJKLMNPQRSTUVWXYZ23456789`, length 8, display `XXXX-XXXX`, TTL 15 minutes, one-time.
-- Event name string is exactly `message_gateway.inbound`.
-- Channel types: `telegram`, `qq`. `owner_scope` always `system` in v1.
-- Encrypt credentials with `pkg/util.Encrypt` using `hex.EncodeToString(sha256(session_secret))` as the 64-char key.
-- After handlers: `make swagger`. After code: `make format` and `make code-check`.
-- Commits: Conventional Commits.
-- Tests: `t.TempDir()` only.
-- Execution: `superpowers:using-git-worktrees` in Wavelet.
-
-## File map
-
-| Path | Responsibility |
-| --- | --- |
-| `pkg/message_gateway/types.go` | Capability, Attachment, InboundMessage, OutboundMessage, Recipient |
-| `pkg/message_gateway/channel.go` | `Channel` interface, `Handler` |
-| `pkg/message_gateway/registry.go` | Register / Lookup factories |
-| `pkg/message_gateway/pairing.go` | `GenerateCode`, `NormalizeCode`, `FormatCode` |
-| `pkg/message_gateway/channel/telegram` | telebot private-chat adapter |
-| `pkg/message_gateway/channel/qq` | botgo C2C adapter |
-| `internal/model/message_gateway.go` | GORM models |
-| goose `202608160003_create_message_gateway.sql` | PG + SQLite |
-| `internal/repository/message_gateway.go` | persistence |
-| `internal/listener/message_gateway.go` | event + emit |
-| `internal/apps/message_gateway` | user bind logics + handlers |
-| `internal/apps/admin/message_gateway` | admin CRUD |
-| `internal/apps/message_gateway/runner` | Worker Start / reload / inbound handler |
-| `internal/cmd/worker.go` | start runner before Asynq |
-| `internal/router/v1/admin.go` + new files | HTTP routes |
-| frontend admin + profile + i18n | UI |
-
----
-
-### Task 1: Pairing helpers and Channel types
-
-**Files:**
-- Create: `pkg/message_gateway/types.go`
-- Create: `pkg/message_gateway/channel.go`
-- Create: `pkg/message_gateway/registry.go`
-- Create: `pkg/message_gateway/pairing.go`
-- Test: `pkg/message_gateway/pairing_test.go`
-- Test: `pkg/message_gateway/registry_test.go`
-
-**Interfaces:**
-- Produces: `GenerateCode() (string, error)` returns 8 chars from the alphabet; `NormalizeCode(s string) string` strips `-` and uppercases; `FormatCode(s string) string` → `XXXX-XXXX`; `Register(typ string, fn Factory)`; `Lookup(typ string) (Factory, bool)`; types `Channel`, `Capability`, `InboundMessage`, `OutboundMessage`, `Recipient`, `Attachment`, `Handler`
-
-- [ ] **Step 1: Write pairing tests**
-
-```go
-func TestGenerateCode_AlphabetAndLength(t *testing.T) {
- code, err := GenerateCode()
- if err != nil {
- t.Fatal(err)
- }
- if len(code) != 8 {
- t.Fatalf("len=%d", len(code))
- }
- for _, r := range code {
- if !strings.ContainsRune(CodeAlphabet, r) {
- t.Fatalf("bad rune %q", r)
- }
- }
-}
-
-func TestNormalizeAndFormat(t *testing.T) {
- if got := NormalizeCode("ab-cd-ef-gh"); got != "ABCDEFGH" {
- t.Fatalf("got %q", got)
- }
- if got := FormatCode("ABCDEFGH"); got != "ABCD-EFGH" {
- t.Fatalf("got %q", got)
- }
-}
-```
-
-- [ ] **Step 2: Run — must fail compile**
-
-```bash
-go test ./pkg/message_gateway -count=1
-```
-
-Expected: undefined `GenerateCode`.
-
-- [ ] **Step 3: Implement types, pairing, registry**
-
-`pairing.go`: `const CodeAlphabet = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"`, `CodeLength = 8`. `GenerateCode` reads `crypto/rand` indexes.
-
-`channel.go`:
-
-```go
-type Channel interface {
- Type() string
- Connect(ctx context.Context) error
- Disconnect(ctx context.Context) error
- Send(ctx context.Context, to Recipient, msg OutboundMessage) error
- Capabilities() Capability
-}
-
-type Handler func(ctx context.Context, msg InboundMessage) error
-type Factory func(cfg ChannelConfig, onInbound Handler) (Channel, error)
-```
-
-`ChannelConfig` in types: `ID uint64`, `Type string`, `Name string`, `Credentials map[string]string`, `Extra map[string]string`.
-
-`Attachment`: `Path, FileName, MIME, Error string`.
-
-Registry: mutex map[string]Factory.
-
-- [ ] **Step 4: Tests pass**
-
-```bash
-go test ./pkg/message_gateway -count=1
-```
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add pkg/message_gateway
-git commit -m "feat(message-gateway): add channel types, registry, and pairing codes"
-```
-
----
-
-### Task 2: Models and goose migrations
-
-**Files:**
-- Create: `internal/model/message_gateway.go`
-- Create: `internal/infra/persistence/migrator/goose/postgres/202608160003_create_message_gateway.sql`
-- Create: `internal/infra/persistence/migrator/goose/sqlite/202608160003_create_message_gateway.sql`
-- Modify: `internal/testhelper/test_helper.go` AutoMigrate list
-- Modify: `internal/infra/persistence/migrator/migrator_test.go` only if it asserts table counts that break (do not change `w_system_configs` count)
-
-**Interfaces:**
-- Produces: `model.MessageChannel`, `model.MessageBinding`, `model.MessagePairingCode` with `TableName()` `w_message_channels`, `w_message_bindings`, `w_message_pairing_codes`
-- Constants: `MessageChannelTypeTelegram = "telegram"`, `MessageChannelTypeQQ = "qq"`, `MessageOwnerScopeSystem = "system"`
-
-- [ ] **Step 1: Add models**
-
-```go
-type MessageChannel struct {
- ID uint64 `json:"id,string" gorm:"primaryKey"`
- Name string `json:"name" gorm:"size:128;not null"`
- Type string `json:"type" gorm:"size:32;not null;index"`
- OwnerScope string `json:"owner_scope" gorm:"size:16;not null;default:system"`
- OwnerID *uint64 `json:"owner_id,string"`
- Enabled bool `json:"enabled" gorm:"not null;default:true"`
- Credentials string `json:"-" gorm:"type:text"`
- Extra string `json:"extra" gorm:"type:text"`
- CreatedAt time.Time
- UpdatedAt time.Time
-}
-```
-
-Binding: `UserID`, `ChannelID`, `PlatformUserID`. Pairing: `Code` PK, `ChannelID`, `PlatformUserID`, `ExpiresAt`.
-
-- [ ] **Step 2: Goose SQL (both dialects)**
-
-Postgres up:
-
-```sql
-CREATE TABLE IF NOT EXISTS w_message_channels (
- id BIGINT PRIMARY KEY,
- name VARCHAR(128) NOT NULL,
- type VARCHAR(32) NOT NULL,
- owner_scope VARCHAR(16) NOT NULL DEFAULT 'system',
- owner_id BIGINT NULL,
- enabled BOOLEAN NOT NULL DEFAULT TRUE,
- credentials TEXT NOT NULL DEFAULT '',
- extra TEXT NOT NULL DEFAULT '',
- created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
- updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
-);
-CREATE INDEX IF NOT EXISTS idx_w_message_channels_type ON w_message_channels (type);
-
-CREATE TABLE IF NOT EXISTS w_message_bindings (
- id BIGINT PRIMARY KEY,
- user_id BIGINT NOT NULL,
- channel_id BIGINT NOT NULL,
- platform_user_id VARCHAR(128) NOT NULL,
- created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
-);
-CREATE UNIQUE INDEX IF NOT EXISTS uniq_w_message_bindings_channel_platform
- ON w_message_bindings (channel_id, platform_user_id);
-CREATE INDEX IF NOT EXISTS idx_w_message_bindings_user ON w_message_bindings (user_id);
-
-CREATE TABLE IF NOT EXISTS w_message_pairing_codes (
- code VARCHAR(16) PRIMARY KEY,
- channel_id BIGINT NOT NULL,
- platform_user_id VARCHAR(128) NOT NULL,
- expires_at TIMESTAMPTZ NOT NULL,
- created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
-);
-CREATE INDEX IF NOT EXISTS idx_w_message_pairing_lookup
- ON w_message_pairing_codes (channel_id, platform_user_id);
-```
-
-SQLite twin: `INTEGER`/`TEXT`/`DATETIME` as in existing Wavelet sqlite migrations. Down: drop the three tables.
-
-- [ ] **Step 3: AutoMigrate the three models in testhelper**
-
-- [ ] **Step 4:**
-
-```bash
-go test ./internal/model ./internal/infra/persistence/migrator ./internal/testhelper -count=1
-```
-
-Expected: PASS (migrator applies `202608160003`).
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add internal/model/message_gateway.go \
- internal/infra/persistence/migrator/goose \
- internal/testhelper/test_helper.go
-git commit -m "feat(message-gateway): add w_message_* models and goose migrations"
-```
-
----
-
-### Task 3: Repository
-
-**Files:**
-- Create: `internal/repository/message_gateway.go`
-- Test: `internal/repository/message_gateway_test.go`
-
-**Interfaces:**
-- Consumes: models from Task 2, `db.DB(ctx)` from `internal/infra/persistence`
-- Produces:
- - `CreateMessageChannel`, `UpdateMessageChannel`, `GetMessageChannel`, `ListMessageChannels`, `DeleteMessageChannel`
- - `CreateMessageBinding`, `GetBindingByChannelPlatform(ctx, channelID, platformUserID)`, `ListBindingsByUser`, `DeleteMessageBinding`
- - `UpsertPairingCode` (reuse unexpired row for same channel+platform user), `GetPairingCode`, `DeletePairingCode`, `DeleteExpiredPairingCodes`
-
-- [ ] **Step 1: Test upsert reuses unexpired code**
-
-```go
-func TestUpsertPairingCode_ReusesUnexpired(t *testing.T) {
- _, _, cleanup := testhelper.SetupTestEnvironment(t)
- defer cleanup()
- ctx := context.Background()
- first, err := repository.UpsertPairingCode(ctx, 1, "tg-1", "ABCD1234", time.Now().Add(15*time.Minute))
- if err != nil { t.Fatal(err) }
- second, err := repository.UpsertPairingCode(ctx, 1, "tg-1", "ZZZZ9999", time.Now().Add(15*time.Minute))
- if err != nil { t.Fatal(err) }
- if first.Code != second.Code || first.Code != "ABCD1234" {
- t.Fatalf("reuse failed: %+v %+v", first, second)
- }
-}
-```
-
-- [ ] **Step 2: Run — fail (undefined)**
-
-```bash
-go test ./internal/repository -count=1 -run Pairing
-```
-
-- [ ] **Step 3: Implement repository using `db.DB(ctx)` only**
-
-`UpsertPairingCode`: `First` where `channel_id` and `platform_user_id` and `expires_at > now`; if found return it; else create with provided code.
-
-`DeleteMessageChannel`: delete pairings and bindings for that channel then the channel (transaction).
-
-- [ ] **Step 4: Tests pass**
-
-- [ ] **Step 5: Commit**
-
-```bash
-git add internal/repository/message_gateway.go internal/repository/message_gateway_test.go
-git commit -m "feat(message-gateway): add channel, binding, and pairing repositories"
-```
-
----
-
-### Task 4: Domain event
-
-**Files:**
-- Create: `internal/listener/message_gateway.go`
-- Test: `internal/listener/message_gateway_test.go`
-- Modify: `internal/platform/bootstrap/bootstrap.go` — register a log-only handler in `RegisterPushDomainEvents` sibling `RegisterMessageGatewayListeners` (`sync.Once`)
-
-**Interfaces:**
-- Produces: `const EventMessageGatewayInbound = "message_gateway.inbound"`
-- `type MessageGatewayInbound struct { Msg message_gateway.InboundMessage }`
-- `OnMessageGatewayInbound(fn)`
-- `EmitMessageGatewayInbound(ctx, msg)` — skip if `msg.BindingUserID == nil`
-
-- [ ] **Step 1: Write emit test**
-
-```go
-func TestEmitMessageGatewayInbound_SkipsUnbound(t *testing.T) {
- called := 0
- OnMessageGatewayInbound(func(ctx context.Context, ev MessageGatewayInbound) { called++ })
- EmitMessageGatewayInbound(context.Background(), message_gateway.InboundMessage{Text: "x"})
- if called != 0 {
- t.Fatal("unbound must not emit")
- }
- uid := uint64(9)
- EmitMessageGatewayInbound(context.Background(), message_gateway.InboundMessage{BindingUserID: &uid, Text: "x"})
- if called != 1 {
- t.Fatalf("called=%d", called)
- }
-}
-```
-
-- [ ] **Step 2: Run — fail compile**
-- [ ] **Step 3: Implement listener + bootstrap log-only handler**
-- [ ] **Step 4: Test pass**
-- [ ] **Step 5: Commit**
-
-```bash
-git commit -m "feat(message-gateway): emit message_gateway.inbound domain events"
-```
-
----
-
-### Task 5: Telegram adapter (private chat)
-
-**Files:**
-- Create: `pkg/message_gateway/channel/telegram/adapter.go`
-- Test: `pkg/message_gateway/channel/telegram/adapter_test.go`
-
-**Interfaces:**
-- Consumes: `ChannelConfig`, `Handler`
-- Produces: `func New(cfg ChannelConfig, onInbound Handler) (message_gateway.Channel, error)`
-- Credentials key `bot_token`; extra key `base_url`
-- `Type() == "telegram"`
-- `Capabilities`: Text, Image, File, Reply true; Group false
-
-- [ ] **Step 1: Test group updates are dropped (inject a `handleUpdate` method)**
-
-Export `HandlePrivate` for tests:
-
-```go
-func TestHandleUpdate_DropsGroups(t *testing.T) {
- var got int
- a := &Adapter{onInbound: func(ctx context.Context, msg message_gateway.InboundMessage) error {
- got++
- return nil
- }}
- a.handleTeleMessage(fakeGroupMessage())
- if got != 0 {
- t.Fatalf("group must be ignored")
- }
-}
-
-func TestHandleUpdate_PrivateText(t *testing.T) {
- var got message_gateway.InboundMessage
- a := &Adapter{cfg: message_gateway.ChannelConfig{ID: 7, Type: "telegram"}, onInbound: func(ctx context.Context, msg message_gateway.InboundMessage) error {
- got = msg
- return nil
- }}
- a.handleTeleMessage(fakePrivateText("hi", 42))
- if got.Text != "hi" || got.PlatformUserID != "42" || got.ChannelID != 7 {
- t.Fatalf("%+v", got)
- }
-}
-```
-
-Build fakes as small structs / telebot.Message with `Chat.Type = telebot.ChatPrivate` vs `ChatGroup`.
-
-- [ ] **Step 2: Run — fail**
-
-- [ ] **Step 3: Implement with `gopkg.in/telebot.v4`**
-
-`Connect`: `telebot.NewBot(Settings{Token, URL: extra base_url, Poller: &telebot.LongPoller{Timeout: 10s}})`, handle `OnText`, `OnPhoto`, `OnDocument` only if private. Download media to `os.MkdirTemp("wg-tg-*")`. `Disconnect`: `bot.Stop()`.
-
-Register factory in `New` via `message_gateway.Register("telegram", New)` from **apps runner**, not `init()` in pkg if that violates bootstrap rule. Spec said no `init()` for **cross-module** integration. Registering a factory in `telegram` package `init` is OK **or** register explicitly in runner. Prefer **explicit register in runner** to keep pkg side-effect free.
-
-- [ ] **Step 4: `go test ./pkg/message_gateway/channel/telegram -count=1`**
-
-- [ ] **Step 5: Commit**
-
-```bash
-git commit -m "feat(message-gateway): add Telegram private-chat telebot adapter"
-```
-
-Add `gopkg.in/telebot.v4` with `go get`.
-
----
-
-### Task 6: QQ adapter (C2C only)
-
-**Files:**
-- Create: `pkg/message_gateway/channel/qq/adapter.go`
-- Test: `pkg/message_gateway/channel/qq/adapter_test.go`
-
-**Interfaces:**
-- Same `New(cfg, onInbound)`
-- Credentials: `app_id`, `app_secret`
-- Extra: `portal_host` default `q.qq.com`
-- Drop non-C2C events in a testable `handleC2C` function
-
-- [ ] **Step 1: Write C2C-only tests**
-
-```go
-func TestHandleEvent_DropsNonC2C(t *testing.T) {
- var got int
- a := &Adapter{onInbound: func(ctx context.Context, msg message_gateway.InboundMessage) error {
- got++
- return nil
- }}
- a.handleEvent(qqEvent{Kind: "group", UserID: "u1", Text: "hi"})
- if got != 0 {
- t.Fatal("non-C2C must be ignored")
- }
-}
-
-func TestHandleEvent_C2CText(t *testing.T) {
- var got message_gateway.InboundMessage
- a := &Adapter{cfg: message_gateway.ChannelConfig{ID: 3}, onInbound: func(ctx context.Context, msg message_gateway.InboundMessage) error {
- got = msg
- return nil
- }}
- a.handleEvent(qqEvent{Kind: "c2c", UserID: "openid-1", Text: "hello", MessageID: "m1"})
- if got.Text != "hello" || got.PlatformUserID != "openid-1" || got.ChannelID != 3 {
- t.Fatalf("%+v", got)
- }
-}
-```
-
-Define a local `qqEvent` in the adapter file so tests do not need a live gateway. `Connect` uses official `github.com/tencent-connect/botgo` (or the module path from https://bot.q.qq.com/wiki/develop/gosdk/); pin the resolved module in `go.mod` and name it in the commit body. `Connect` enables C2C intent only. `Send` uses C2C REST.
-
-- [ ] **Step 2: `go test ./pkg/message_gateway/channel/qq -count=1` — fail compile**
-- [ ] **Step 3: Implement adapter + `New`**
-- [ ] **Step 4: Tests pass**
-- [ ] **Step 5: Commit**
-
-```bash
-git commit -m "feat(message-gateway): add QQ official C2C botgo adapter"
-```
-
----
-
-### Task 7: Worker gateway runner
-
-**Files:**
-- Create: `internal/apps/message_gateway/runner/runner.go`
-- Create: `internal/apps/message_gateway/runner/inbound.go`
-- Test: `internal/apps/message_gateway/runner/inbound_test.go`
-- Modify: `internal/cmd/worker.go` start `runner.Start` in a goroutine **before** `worker.StartWorker()`
-- Modify: `internal/platform/bootstrap` if needed to register factories
-
-**Interfaces:**
-- Consumes: repository, listener, telegram.New, qq.New, pairing.GenerateCode
-- Produces: `Start(ctx context.Context) error` — load enabled channels, lock, Connect; poll `updated_at` every 5s and reload changed IDs
-- Inbound handler:
- 1. Lookup binding by channel+platform user
- 2. If none: `UpsertPairingCode` + `ch.Send` formatted code + bind instructions
- 3. If bound: set `BindingUserID`, `EmitMessageGatewayInbound`; on emit error send “could not save”; on success send “received”
-
-- [ ] **Step 1: Test inbound unbound mints/reuses code and does not emit**
-
-Use a `fakeChannel` implementing `Channel` that records `Send` calls, and stub repository via a small `inboundService` struct with function fields so the test does not need a live bot.
-
-```go
-type inboundDeps struct {
- LookupBinding func(...) (*model.MessageBinding, error)
- UpsertCode func(...) (*model.MessagePairingCode, error)
- Emit func(context.Context, message_gateway.InboundMessage)
- Send func(context.Context, Recipient, OutboundMessage) error
-}
-
-func (d inboundDeps) Handle(ctx context.Context, msg message_gateway.InboundMessage) error
-```
-
-- [ ] **Step 2–4: Implement Handle + Start**
-
-Credential decrypt: `key := hex.EncodeToString(sum[:])` where `sum := sha256.Sum256([]byte(config.Config.App.SessionSecret))`. If decrypt fails, skip channel and log.
-
-Lock: Redis `SET wg:channel:{id} {node} NX EX 30` refreshed while running; if Redis disabled, start anyway (single-process dev).
-
-- [ ] **Step 5: Commit**
-
-```bash
-git commit -m "feat(message-gateway): run adapters on worker and handle pairing inbound"
-```
-
----
-
-### Task 8: Admin HTTP API
-
-**Files:**
-- Create: `internal/apps/admin/message_gateway/errs.go`
-- Create: `internal/apps/admin/message_gateway/logics.go`
-- Create: `internal/apps/admin/message_gateway/handlers.go`
-- Create: `internal/apps/admin/message_gateway/routers.go`
-- Test: `internal/apps/admin/message_gateway/logics_test.go`
-- Modify: `internal/router/v1/admin.go` — `registerAdminMessageGatewayRoutes` under “Messaging”
-- Create: `internal/router/v1/message_gateway_admin.go` calling `adminmsg.RegisterRoutes`
-
-**Interfaces:**
-- `GET /api/v1/admin/message-gateway/channels`
-- `GET /api/v1/admin/message-gateway/channels/definitions`
-- `POST /api/v1/admin/message-gateway/channels` body `{name,type,enabled,bot_token|app_id,app_secret,base_url,portal_host}`
-- `PATCH /api/v1/admin/message-gateway/channels/:id` empty secrets keep previous
-- `DELETE /api/v1/admin/message-gateway/channels/:id`
-- `POST /api/v1/admin/message-gateway/channels/:id/test` optional getMe/token probe
-- List DTO masks secrets as `********` if non-empty
-
-Definitions JSON:
-
-```go
-[]Definition{
- {Type:"telegram", Name:"Telegram", Fields:[]Field{{Key:"bot_token", Type:"password", Required:true}, {Key:"base_url", Type:"text"}}},
- {Type:"qq", Name:"QQ", Fields:[]Field{{Key:"app_id", Required:true}, {Key:"app_secret", Type:"password", Required:true}, {Key:"portal_host", Type:"text"}}},
-}
-```
-
-- [ ] **Step 1: Test create telegram without token fails; create with token stores ciphertext not plaintext**
-
-- [ ] **Step 2–4: Implement logics + Abort\* handlers + swagger comments**
-
-- [ ] **Step 5:** `make swagger` then commit
-
-```bash
-git commit -m "feat(message-gateway): add admin channel CRUD APIs"
-```
-
----
-
-### Task 9: User bind/unbind API
-
-**Files:**
-- Create: `internal/apps/message_gateway/errs.go`
-- Create: `internal/apps/message_gateway/logics.go`
-- Create: `internal/apps/message_gateway/handlers.go`
-- Create: `internal/apps/message_gateway/routers.go`
-- Test: `internal/apps/message_gateway/logics_test.go`
-- Modify: `internal/router/v1/v1.go` call `RegisterMessageGatewayUserRoutes`
-- Create: `internal/router/v1/message_gateway.go`
-
-**Interfaces:**
-- `GET /api/v1/message-gateway/bindings` — current user, include channel name/type
-- `POST /api/v1/message-gateway/bindings` `{ "channel_id": "...", "code": "ABCD-EFGH" }`
-- `DELETE /api/v1/message-gateway/bindings/:id`
-- Login required. Bind: `NormalizeCode`, `GetPairingCode`, check expiry and `channel_id`, `GetBindingByChannelPlatform` → 409 if other user, insert binding, delete code.
-- Unbind: only if `binding.UserID == current`.
-
-- [ ] **Step 1–4: TDD expired code 400; happy path deletes code**
-
-- [ ] **Step 5: `make swagger` + commit**
-
-```bash
-git commit -m "feat(message-gateway): add user bind and unbind APIs"
-```
-
----
-
-### Task 10: Frontend service + admin page
-
-**Files:**
-- Create: `frontend/lib/services/message-gateway/types.ts`
-- Create: `frontend/lib/services/message-gateway/admin.service.ts`
-- Create: `frontend/lib/services/message-gateway/index.ts`
-- Modify: `frontend/lib/services/index.ts` export
-- Create: `frontend/app/(main)/admin/message-gateway/page.tsx`
-- Create: `frontend/app/(main)/admin/message-gateway/components/channel-card.tsx`
-- Create: `frontend/app/(main)/admin/message-gateway/components/add-channel-dialog.tsx`
-- Create: `frontend/app/(main)/admin/message-gateway/channels/telegram/form.tsx`
-- Create: `frontend/app/(main)/admin/message-gateway/channels/qq/form.tsx`
-- Modify: `frontend/components/layout/sidebar.tsx` admin item after push
-- Modify: `frontend/messages/zh-CN.json` + `en.json` namespace `admin.messageGateway`
-
-**Interfaces:**
-- `AdminMessageGatewayService.list/create/update/remove/definitions`
-- Empty state + add dialog: type select then `` or ``
-- Card: name, type, enabled switch, delete
-- `useTranslations('admin.messageGateway')` — no hardcoded UI strings
-
-- [ ] **Step 1: Add i18n keys to zh-CN only, run `node frontend/scripts/check-i18n-keys.mjs` — fail**
-- [ ] **Step 2: Add matching en keys — checker pass**
-- [ ] **Step 3: Implement pages (follow `/admin/push` layout: `w-full py-6`, h1 `text-2xl font-semibold tracking-tight`)**
-- [ ] **Step 4:** `cd frontend && pnpm tsc --noEmit --jsx preserve`
-- [ ] **Step 5: Commit**
-
-```bash
-git commit -m "feat(message-gateway): add admin channel cards and per-type forms"
-```
-
----
-
-### Task 11: Profile bind card
-
-**Files:**
-- Create: `frontend/lib/services/message-gateway/user.service.ts`
-- Create: `frontend/components/common/settings/bot-binding-card.tsx`
-- Modify: `frontend/components/common/settings/profile.tsx` render the card
-- Modify: i18n `settings.botBinding`
-
-**Interfaces:**
-- List bindings (channel name, type, platform_user_id) + unbind
-- Bind dialog: select enabled channel + code input
-- All copy via next-intl
-
-- [ ] **Step 1–4: keys + component + typecheck**
-- [ ] **Step 5: Commit**
-
-```bash
-git commit -m "feat(message-gateway): add profile bot pairing card"
-```
-
----
-
-### Task 12: Repo-wide gates
-
-**Files:** swagger `docs/*` if not already committed
-
-- [ ] **Step 1:** `go test ./... -count=1`
-- [ ] **Step 2:** `make swagger && make format && node frontend/scripts/check-i18n-keys.mjs && make code-check`
-- [ ] **Step 3:** Confirm `RegisterMessageGatewayUserRoutes` in `v1.go` and admin routes exist; no `init()` in apps
-- [ ] **Step 4: Commit leftover format/swagger**
-
-```bash
-git commit -m "chore(message-gateway): swagger and format"
-```
-
----
-
-## Spec coverage
-
-| Spec | Task |
-|---|---|
-| pkg types / pairing / registry | 1 |
-| tables | 2 |
-| repository | 3 |
-| domain event | 4 |
-| telegram / qq adapters | 5–6 |
-| worker runner + pairing inbound | 7 |
-| admin API + UI | 8, 10 |
-| user bind + profile | 9, 11 |
-| gates | 12 |
-| Clipper ingest | **not in this plan** |
diff --git a/docs/superpowers/specs/2026-07-24-frontend-i18n-design.md b/docs/superpowers/specs/2026-07-24-frontend-i18n-design.md
deleted file mode 100644
index e2f9c2c4..00000000
--- a/docs/superpowers/specs/2026-07-24-frontend-i18n-design.md
+++ /dev/null
@@ -1,253 +0,0 @@
-# Frontend i18n Design
-
-Date: 2026-07-24
-Status: Approved for implementation planning
-Scope: Frontend UI only
-
-## 1. Goals
-
-Add bilingual UI support for Wavelet frontend:
-
-- Languages: `zh-CN` and `en`
-- Default locale: `zh-CN`
-- Locale resolution: explicit user choice → browser language → default
-- Phase 1: infrastructure + core paths only (layout / auth / settings)
-- Must remain compatible with `NEXT_STANDALONE_EXPORT` static export
-
-### Non-goals (Phase 1)
-
-- Backend API error / message localization
-- Email / push notification localization
-- URL locale prefixes (`/en/...`, `/zh-CN/...`) and SEO hreflang
-- Full translation of all admin business pages
-
-## 2. Context
-
-Current state:
-
-- Root layout hardcodes `lang='zh-CN'`
-- UI copy is mostly Chinese string literals across many TSX files
-- Date formatting often hardcodes `zh-CN` / `date-fns/locale` `zhCN`
-- No i18n library is installed
-- Frontend supports both normal Next rewrites mode and static export embed mode
-
-## 3. Approach
-
-Use **next-intl in non-routing / provider mode**.
-
-Why this approach:
-
-- Mature App Router integration and clear `useTranslations` API
-- ICU message format ready when needed
-- Avoids locale-prefixed routing, which conflicts with static-export simplicity and current route structure
-- Cookie + browser detection matches product preference without SEO path requirements
-
-Rejected alternatives:
-
-- Fully custom Context + JSON: lower dependency cost, but reimplements interpolation/plurals/type safety poorly
-- `i18next` + `react-i18next`: powerful, but heavier and less natural for this Next App Router setup
-
-## 4. Architecture
-
-```
-RootLayout
- html lang={locale}
- ThemeProvider
- CustomThemeProvider
- AppQueryProvider
- NextIntlClientProvider(locale, messages)
- existing User / Notification / Bell providers
- pages + components
-```
-
-### Key files
-
-| Path | Responsibility |
-| --- | --- |
-| `frontend/i18n/config.ts` | Supported locales, default locale, cookie name, normalize helpers |
-| `frontend/i18n/request.ts` | `getRequestConfig` for server-side locale/messages resolution when not in export mode |
-| `frontend/i18n/client.ts` | Client helpers to read/write locale preference |
-| `frontend/messages/zh-CN.json` | Chinese messages |
-| `frontend/messages/en.json` | English messages |
-| `frontend/components/common/language-switcher.tsx` (or under `layout/`) | Language switch UI |
-| `frontend/lib/i18n-format.ts` (optional location under `i18n/`) | Locale-aware date/number formatting helpers |
-
-### Runtime flow
-
-1. Resolve locale: cookie `NEXT_LOCALE` → browser languages → `zh-CN`
-2. Load `messages/{locale}.json`
-3. Provide locale + messages through `NextIntlClientProvider`
-4. Components call `useTranslations('')`
-5. Language switcher writes cookie and refreshes locale/messages
-6. Update `document.documentElement.lang`
-
-## 5. Locale Resolution
-
-Supported locales: `zh-CN`, `en`
-
-Normalization:
-
-- `zh`, `zh-CN`, `zh-Hans*` → `zh-CN`
-- `en`, `en-US`, `en-GB`, other `en-*` → `en`
-- anything else → `zh-CN`
-
-Priority:
-
-1. User explicit choice stored in cookie `NEXT_LOCALE`
-2. Browser language (`Accept-Language` on server, `navigator.languages` on client)
-3. Default `zh-CN`
-
-Invalid cookie values are normalized to a supported locale and may be rewritten to a valid value.
-
-## 6. Static Export Compatibility
-
-Constraints:
-
-- No locale-segment routes
-- No middleware-based locale rewriting required for correctness
-- `build:embed` (`NEXT_STANDALONE_EXPORT=true`) must continue to work
-
-Behavior:
-
-- **Normal SSR/dev**: resolve locale on server when possible to reduce first-paint language flash
-- **Static export**: ship both message catalogs; resolve on client from cookie/browser; accept a brief default-language flash similar to theme hydration, using existing `suppressHydrationWarning` patterns where needed
-
-## 7. Message Organization
-
-Single catalog files with nested namespaces:
-
-```json
-{
- "common": {
- "save": "保存",
- "cancel": "取消",
- "loading": "加载中..."
- },
- "layout": {
- "nav": {
- "home": "首页",
- "myFiles": "我的文件"
- },
- "userMenu": {
- "settings": "设置",
- "logout": "退出登录"
- }
- },
- "auth": {
- "login": {
- "title": "登录",
- "submit": "登录"
- }
- },
- "settings": {
- "appearance": {
- "language": "语言",
- "languageDesc": "选择界面显示语言"
- }
- }
-}
-```
-
-Conventions:
-
-- Keys use camelCase and hierarchical grouping
-- Prefer complete phrases as values; avoid assembling sentences in components
-- Use ICU only when needed (`{name}`, plural forms)
-- Backend `error_msg` values are shown as-is in Phase 1
-- Frontend-owned toast / validation copy is translated
-
-Both locale files must keep the same key tree. A key-alignment check script is recommended.
-
-## 8. Language Switcher UX
-
-Placement:
-
-- Header toolbar near theme controls
-- Appearance settings page as an explicit preference row
-
-UI labels for language options use native names and do not themselves translate:
-
-- `中文`
-- `English`
-
-On change:
-
-1. Persist `NEXT_LOCALE`
-2. Apply new locale/messages (via refresh or controlled provider update)
-3. Sync `document.documentElement.lang`
-4. Preserve unrelated UI state where practical (theme, auth session, sidebar collapse)
-
-## 9. Phase 1 Migration Scope
-
-### In scope
-
-- Install and wire `next-intl`
-- Message catalogs for core namespaces
-- Locale resolution + persistence
-- `LanguageSwitcher`
-- Translate:
- - layout shell: sidebar nav/user menu, header accessible labels / titles
- - auth: login / register / OTP labels, buttons, validation messages
- - settings: appearance (including language preference), profile, security, notifications, access-token visible copy
-- Replace date/number hardcoding only where touched by the above paths
-- Ensure `html lang` reflects active locale
-
-### Out of scope
-
-- Remaining admin pages and deep business modules
-- Backend localization
-- Route prefixing / SEO alternate links
-
-Unmigrated pages may remain Chinese hard-coded; mixed-language UI is acceptable during incremental rollout.
-
-## 10. Formatting Helpers
-
-Introduce locale-aware helpers for dates/numbers used by migrated surfaces, e.g.:
-
-- `formatDateTime(value, locale)`
-- `formatNumber(value, locale)`
-
-`date-fns` locale objects should follow active locale (`zhCN` / `enUS`) when a migrated component uses them.
-
-## 11. Error Handling & Fallbacks
-
-| Case | Behavior |
-| --- | --- |
-| Missing message key | Dev warning; do not crash; show key or fallback language value |
-| Unsupported cookie locale | Normalize to supported locale / default |
-| Partial migration | Keep hard-coded Chinese on unmigrated screens |
-| Backend error strings | Display raw `error_msg` |
-
-## 12. Testing & Acceptance
-
-Manual:
-
-1. No cookie + browser Chinese → Chinese UI
-2. No cookie + browser English → English UI
-3. Manual switch to English survives refresh
-4. Manual switch back to Chinese survives refresh
-5. Core paths (layout/auth/settings) have no major residual hard-coded Chinese UI copy
-6. `pnpm build` and `pnpm build:embed` both succeed
-7. Language switch does not break theme, session, or sidebar state
-
-Automated (recommended):
-
-- Unit tests for `normalizeLocale` / resolution priority
-- Script or test asserting `zh-CN.json` and `en.json` key parity
-
-## 13. Rollout Plan (high level)
-
-1. Add i18n infrastructure and empty/core message files
-2. Mount provider and language switcher
-3. Migrate layout shell copy
-4. Migrate auth copy
-5. Migrate settings copy + appearance language control
-6. Verify SSR and static-export builds
-7. Document how later pages should adopt `useTranslations`
-
-## 14. Open Implementation Notes
-
-- Prefer cookie name `NEXT_LOCALE` unless an existing project cookie convention conflicts during implementation
-- Prefer minimal surface-area integration with next-intl; avoid introducing locale-based routing APIs that break static export
-- Keep `internal/util` and backend packages untouched
-- After implementation, follow repo frontend conventions and existing provider composition style
diff --git a/docs/superpowers/specs/2026-08-16-message-gateway-design.md b/docs/superpowers/specs/2026-08-16-message-gateway-design.md
deleted file mode 100644
index cd249f3b..00000000
--- a/docs/superpowers/specs/2026-08-16-message-gateway-design.md
+++ /dev/null
@@ -1,268 +0,0 @@
-# Message Gateway Design (Wavelet)
-
-**Date:** 2026-08-16
-**Status:** Approved for implementation planning
-**Scope:** Wavelet framework only (sub-project 1 of 3)
-**Product:** Wavelet scaffold — reusable inbound/outbound messaging channels
-
-## 1. Goal
-
-Give Wavelet a Hermes-style **message gateway**: admins configure Telegram and QQ bots in the admin UI; end users bind their private-chat identity with a one-time short code on the profile page. Inbound private messages become **domain events**. Products (Clipper later) subscribe and decide what to persist.
-
-This spec does **not** write Clipper `c_items`. That is sub-project 3 after Wavelet is merged into Clipper.
-
-### In scope (Wavelet)
-
-- `pkg/message_gateway` + `channel/telegram` + `channel/qq`
-- Admin UI `/admin/message-gateway` (empty state, add channel, per-type forms, cards)
-- User profile card: bind / list / unbind
-- Worker-hosted connections (Telegram long poll, QQ official WebSocket)
-- Pairing codes, bindings, encrypted credentials
-- Domain event on authorized inbound messages
-- Text + image + file inbound/outbound at the adapter layer (v1 private chat only)
-
-### Out of scope
-
-- Group / guild / channel / @mention routing
-- Hermes sessions, slash commands, STT, cron, circuit-breaker fleet, 20 platforms
-- Telegram webhook mode (long poll only)
-- Writing business tables (`c_*`) or calling `upload.Ingest` from `pkg/`
-- Changing `pkg/push` (outbound notification remains a separate system)
-- Multi-tenant hosted bots (`owner_scope=user`) — column exists, v1 only inserts `system`
-
-### Later sub-projects (not this spec)
-
-2. Clipper `git fetch upstream && git merge upstream/main`
-3. Clipper listener: inbound event → `upload.Ingest` + `c_items` with `source=telegram|qq`
-
-## 2. Decisions (locked)
-
-| Topic | Choice |
-|---|---|
-| Ownership | Instance-level shared bots; users pair to them |
-| Pairing | 8-char one-time code, 15 minutes, consumed on success |
-| Profile | Show bound platform user ID; user can unbind |
-| Surface | Private chat / C2C only; groups ignored + logged |
-| Runtime | Worker process starts the gateway; API does not poll |
-| Events | Bound inbound → `internal/listener` domain event |
-| Telegram SDK | `gopkg.in/telebot.v4` (tucnak/telebot current module) |
-| QQ SDK | Official QQ Bot Go SDK (`botgo` / [docs](https://bot.q.qq.com/wiki/develop/gosdk/)) |
-| Hermes | Adapter shape only (`Connect`/`Disconnect`/`Send`/inbound event/capabilities) |
-
-## 3. Architecture
-
-```
-Admin UI ──CRUD──► API ──w_message_channels──► Worker Gateway
- │
-User DM ──telebot / botgo──► Channel adapter ─────────┤
- ▼
- unbound? mint pairing code, reply
- bound? emit InboundMessage event
- │
-User profile ──bind/unbind──► API ──w_message_bindings / pairing_codes
- │
- product listener (Clipper later)
-```
-
-`pkg/message_gateway` has **no** Gin, GORM, sessions, or `internal/apps` imports. Persistence lives in `internal/repository`. Encryption of credentials uses existing Wavelet secret helpers from apps/repository, not from `pkg`.
-
-### 3.1 Packages
-
-```
-pkg/message_gateway/
- types.go # Message, Attachment, Capability, ChannelType
- channel.go # Channel interface
- registry.go # Register / Lookup
- pairing.go # GenerateCode (alphabet, length) — no storage
- channel/telegram/ # telebot private chat
- channel/qq/ # official botgo C2C
-internal/apps/admin/message_gateway/
-internal/apps/message_gateway/ # user bind/unbind
-internal/listener/ # InboundMessage event type + dispatch
-internal/model/ # channel, binding, pairing row types
-internal/repository/ # CRUD
-```
-
-Frontend:
-
-```
-frontend/lib/services/message-gateway/
-frontend/app/(main)/admin/message-gateway/
- page.tsx
- components/channel-card.tsx
- components/add-channel-dialog.tsx
- channels/telegram/form.tsx
- channels/qq/form.tsx
-frontend/components/common/settings/ # profile bind card
-```
-
-Sidebar admin item: `titleKey: 'messageGateway'`, url `/admin/message-gateway`, placed next to push.
-
-### 3.2 Channel interface
-
-```go
-type Channel interface {
- Type() string
- Connect(ctx context.Context) error
- Disconnect(ctx context.Context) error
- Send(ctx context.Context, to Recipient, msg OutboundMessage) error
- Capabilities() Capability
-}
-
-type Capability struct {
- Text, Image, File, Reply bool
- Group bool // always false in v1 adapters
-}
-
-type InboundMessage struct {
- ChannelID uint64
- ChannelType string
- PlatformUserID string
- ChatID string
- MessageID string
- Text string
- Attachments []Attachment // local temp paths + mime; no upload package
- BindingUserID *uint64 // nil if unbound
-}
-
-type Handler func(ctx context.Context, msg InboundMessage) error
-```
-
-Gateway runner (Worker) constructs adapters from DB rows, calls `Connect`, and registers one `Handler` that implements pairing + event emit.
-
-### 3.3 Process model
-
-- `internal/cmd` Worker path: after bootstrap, `messagegateway.Start(ctx)`.
-- API process never starts adapters.
-- Enable / disable / credential change: Worker watches DB (poll every few seconds or Redis pub/sub already used by the platform). v1 may poll `updated_at` every 5s. Hot-reload only the changed channel.
-- Single Worker assumed. If a second Worker starts, it tries a Redis/DB lock keyed by `channel_id` + token fingerprint; failure → skip that channel and log.
-- Per-channel reconnect with exponential backoff; one channel crash must not stop others.
-
-## 4. Data model
-
-All tables `w_*`. Dual goose SQL (Postgres + SQLite). No physical FKs.
-
-### 4.1 `w_message_channels`
-
-| Column | Type | Notes |
-|---|---|---|
-| id | snowflake | PK |
-| name | string | admin display name |
-| type | string | `telegram` \| `qq` |
-| owner_scope | string | v1 always `system` |
-| owner_id | bigint null | reserved; null in v1 |
-| enabled | bool | |
-| credentials | text | encrypted JSON; never returned raw |
-| extra | text | optional JSON (base URL, sandbox host) |
-| created_at, updated_at | timestamptz | |
-
-### 4.2 `w_message_bindings`
-
-| Column | Type | Notes |
-|---|---|---|
-| id | snowflake | PK |
-| user_id | bigint | Wavelet user |
-| channel_id | bigint | |
-| platform_user_id | string | Telegram user id / QQ OpenID |
-| created_at | timestamptz | |
-
-Unique `(channel_id, platform_user_id)`. A user may bind many channels; a platform identity binds to at most one user per channel.
-
-### 4.3 `w_message_pairing_codes`
-
-| Column | Type | Notes |
-|---|---|---|
-| code | string | PK, 8 chars |
-| channel_id | bigint | |
-| platform_user_id | string | |
-| expires_at | timestamptz | now + 15m |
-| created_at | timestamptz | |
-
-Delete row on successful bind. Expired rows ignored and cleaned by a small periodic delete (may live in the Worker loop).
-
-**Code alphabet:** `ABCDEFGHJKLMNPQRSTUVWXYZ23456789` (no `0O1I`). Format displayed as `XXXX-XXXX`.
-
-## 5. Pairing and profile
-
-1. Unbound private message arrives.
-2. Worker upserts a pairing row (if an unexpired code already exists for that pair, reuse it).
-3. Bot replies with the code and “Settings → Profile → Bind a bot”.
-4. User opens profile card, picks an **enabled** channel, submits the code.
-5. API validates, inserts binding, deletes the code.
-6. Profile lists bindings: channel name, type, **platform user ID**, unbind button.
-
-Unauthorized/unbound never emit `InboundMessage` to product listeners.
-
-## 6. Admin UI and credentials
-
-Empty state + “Add channel”. Dialog: choose `telegram` | `qq`, then that type’s form.
-
-| Type | Required | Optional |
-|---|---|---|
-| telegram | name, bot token | API base URL (default `https://api.telegram.org`) |
-| qq | name, App ID, App Secret | sandbox / portal host (default `q.qq.com`) |
-
-Cards: name, type, enabled toggle, connected/disconnected (best-effort from Worker), edit, delete. Edit never echoes raw secrets; empty secret field means “keep current”.
-
-Create: validate field shape, optional SDK probe (`getMe` / token), then insert. Probe failure → 400, no row.
-
-## 7. HTTP API
-
-Admin (admin middleware), prefix `/api/v1/admin/message-gateway`:
-
-- `GET /channels` — list (secrets masked)
-- `GET /channels/definitions` — form schema per type
-- `POST /channels` — create
-- `PATCH /channels/:id` — update
-- `DELETE /channels/:id` — delete (cascade bindings + pairing rows in logics)
-- `POST /channels/:id/test` — optional probe
-
-User (login required), prefix `/api/v1/message-gateway`:
-
-- `GET /bindings` — current user’s bindings
-- `POST /bindings` — `{ channel_id, code }`
-- `DELETE /bindings/:id` — unbind own row only
-
-Errors via `response.Abort*`. Invalid/expired code → 400. Platform identity already bound → 409.
-
-## 8. Inbound media and reply
-
-Adapters accept private-chat **text, images, files**. Voice/STT is out of scope; a voice message is treated as a file attachment if the SDK delivers bytes, otherwise ignored with a log.
-
-Attachments are written under `t.TempDir()`-equivalent process temp (`os.MkdirTemp`) and passed as filesystem paths on `InboundMessage`. The product listener (Clipper later) must `upload.Ingest` and then delete the temp file. Gateway deletes leftovers older than 1 hour.
-
-If the product handler returns an error, the bot sends a generic “could not save your message” (no internal error text). Success ACK is a single short reply when `Capabilities().Reply` is true. ACK can be disabled later via extra JSON; v1 always ACKs.
-
-Group / non-C2C updates: log and drop. Do not mint pairing codes.
-
-## 9. Domain event
-
-Name: `message_gateway.inbound` (exact string in `internal/listener`).
-
-Payload: `InboundMessage` plus `BindingUserID` set. Register in `internal/platform/bootstrap` (no `init()`). Wavelet ships a no-op or log-only listener. Clipper will register the clip writer in sub-project 3.
-
-## 10. Error handling
-
-- Adapter panics: recover in the gateway runner, mark channel disconnected, backoff reconnect.
-- Media download failure: keep text; attachment entry has `Error` string; still emit if bound.
-- Encrypt/decrypt failure: treat channel as disabled, log, do not start adapter.
-- i18n: all new UI strings in `zh-CN.json` + `en.json` (`admin.messageGateway`, `settings.botBinding`).
-
-## 11. Testing and done criteria
-
-| Gate | Pass |
-|---|---|
-| Fake channel + pairing | generate, reuse unexpired, expire, consume, conflict 409 |
-| Telegram adapter unit | mock telebot updates: text, photo, document; groups dropped |
-| QQ adapter unit | mock C2C event; non-C2C dropped |
-| API tests | admin CRUD, bind/unbind, bad code |
-| `go test ./...` | pass |
-| Frontend | `pnpm tsc --noEmit --jsx preserve`, `check-i18n-keys.mjs` |
-| Manual | add TG channel → DM gets code → profile bind → second DM emits event in logs |
-
-## 12. Risks
-
-- **Official QQ Bot** requires a published/sandbox app at q.qq.com; local dev may only test Telegram.
-- **telebot v4 module path** is `gopkg.in/telebot.v4`; pin a version in `go.mod`.
-- **One poller per token:** documented; second Worker skips the channel.
-- **Token leak in logs:** never log raw credentials or pairing codes at info level (debug only, redacted).
diff --git a/go.mod b/go.mod
index bddbc9ac..dca975d1 100644
--- a/go.mod
+++ b/go.mod
@@ -19,6 +19,7 @@ require (
github.com/go-jose/go-jose/v4 v4.1.4
github.com/google/go-cmp v0.7.0
github.com/google/uuid v1.6.0
+ github.com/gorilla/sessions v1.4.0
github.com/gorilla/websocket v1.5.3
github.com/hibiken/asynq v0.26.0
github.com/maypok86/otter/v2 v2.3.0
@@ -118,7 +119,6 @@ require (
github.com/google/btree v1.0.0 // indirect
github.com/gorilla/context v1.1.2 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
- github.com/gorilla/sessions v1.4.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect
github.com/hashicorp/go-version v1.9.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
diff --git a/pkg/persistence/batchwriter/config.go b/pkg/batchwriter/config.go
similarity index 100%
rename from pkg/persistence/batchwriter/config.go
rename to pkg/batchwriter/config.go
diff --git a/pkg/persistence/batchwriter/errs.go b/pkg/batchwriter/errs.go
similarity index 100%
rename from pkg/persistence/batchwriter/errs.go
rename to pkg/batchwriter/errs.go
diff --git a/pkg/persistence/batchwriter/writer.go b/pkg/batchwriter/writer.go
similarity index 100%
rename from pkg/persistence/batchwriter/writer.go
rename to pkg/batchwriter/writer.go
diff --git a/pkg/batchwriter/writer_test.go b/pkg/batchwriter/writer_test.go
new file mode 100644
index 00000000..8ad68bb4
--- /dev/null
+++ b/pkg/batchwriter/writer_test.go
@@ -0,0 +1,309 @@
+// Copyright 2026 Arctel.net
+// SPDX-License-Identifier: Apache-2.0
+
+package batchwriter
+
+import (
+ "context"
+ "errors"
+ "sync"
+ "sync/atomic"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+type testEvent struct {
+ ID int
+ Data string
+}
+
+func testConfig() Config {
+ return Config{
+ Name: "test-writer",
+ QueueSize: 100,
+ MaxBatchSize: 5,
+ FlushInterval: 20 * time.Millisecond,
+ }
+}
+
+func TestWriter_BatchSizeFlush(t *testing.T) {
+ var (
+ mu sync.Mutex
+ batches [][]testEvent
+ flushWg sync.WaitGroup
+ )
+ flushWg.Add(1)
+
+ cfg := testConfig()
+ cfg.FlushInterval = time.Hour
+
+ w, err := New(cfg, func(_ context.Context, items []testEvent) error {
+ mu.Lock()
+ defer mu.Unlock()
+ batches = append(batches, items)
+ if len(items) == 5 {
+ flushWg.Done()
+ }
+ return nil
+ })
+ require.NoError(t, err)
+
+ w.Start(context.Background())
+ defer func() { _ = w.Stop(context.Background()) }()
+
+ for i := 1; i <= 5; i++ {
+ ok := w.TryEnqueue(testEvent{ID: i, Data: "payload"})
+ assert.True(t, ok)
+ }
+
+ done := make(chan struct{})
+ go func() {
+ flushWg.Wait()
+ close(done)
+ }()
+
+ select {
+ case <-done:
+ case <-time.After(2 * time.Second):
+ t.Fatal("timed out waiting for batch flush")
+ }
+
+ mu.Lock()
+ defer mu.Unlock()
+ require.Len(t, batches, 1)
+ assert.Len(t, batches[0], 5)
+ for i, item := range batches[0] {
+ assert.Equal(t, i+1, item.ID)
+ }
+}
+
+func TestWriter_IntervalFlush(t *testing.T) {
+ var (
+ mu sync.Mutex
+ flushed []testEvent
+ done = make(chan struct{})
+ )
+
+ cfg := testConfig()
+ cfg.MaxBatchSize = 100
+ cfg.FlushInterval = 30 * time.Millisecond
+
+ w, err := New(cfg, func(_ context.Context, items []testEvent) error {
+ mu.Lock()
+ defer mu.Unlock()
+ flushed = append(flushed, items...)
+ if len(flushed) == 2 {
+ select {
+ case <-done:
+ default:
+ close(done)
+ }
+ }
+ return nil
+ })
+ require.NoError(t, err)
+
+ w.Start(context.Background())
+ defer func() { _ = w.Stop(context.Background()) }()
+
+ assert.True(t, w.TryEnqueue(testEvent{ID: 1}))
+ assert.True(t, w.TryEnqueue(testEvent{ID: 2}))
+
+ select {
+ case <-done:
+ case <-time.After(2 * time.Second):
+ t.Fatal("timed out waiting for interval flush")
+ }
+
+ mu.Lock()
+ defer mu.Unlock()
+ assert.Len(t, flushed, 2)
+}
+
+func TestWriter_MinBatchSizeThreshold(t *testing.T) {
+ var (
+ mu sync.Mutex
+ flushed []testEvent
+ done = make(chan struct{})
+ )
+
+ cfg := testConfig()
+ cfg.MaxBatchSize = 100
+ cfg.MinBatchSize = 3
+ cfg.FlushInterval = 20 * time.Millisecond
+ cfg.MaxFlushWait = 60 * time.Millisecond
+
+ w, err := New(cfg, func(_ context.Context, items []testEvent) error {
+ mu.Lock()
+ defer mu.Unlock()
+ flushed = append(flushed, items...)
+ if len(flushed) == 2 {
+ select {
+ case <-done:
+ default:
+ close(done)
+ }
+ }
+ return nil
+ })
+ require.NoError(t, err)
+
+ w.Start(context.Background())
+ defer func() { _ = w.Stop(context.Background()) }()
+
+ assert.True(t, w.TryEnqueue(testEvent{ID: 1}))
+ assert.True(t, w.TryEnqueue(testEvent{ID: 2}))
+
+ time.Sleep(30 * time.Millisecond)
+ mu.Lock()
+ assert.Empty(t, flushed, "items should wait until MinBatchSize or MaxFlushWait")
+ mu.Unlock()
+
+ select {
+ case <-done:
+ case <-time.After(2 * time.Second):
+ t.Fatal("timed out waiting for forced max wait flush")
+ }
+
+ mu.Lock()
+ defer mu.Unlock()
+ assert.Len(t, flushed, 2)
+}
+
+func TestWriter_StopDrainsRemaining(t *testing.T) {
+ var (
+ mu sync.Mutex
+ flushed []testEvent
+ )
+
+ cfg := testConfig()
+ cfg.FlushInterval = time.Hour
+
+ w, err := New(cfg, func(_ context.Context, items []testEvent) error {
+ mu.Lock()
+ defer mu.Unlock()
+ flushed = append(flushed, items...)
+ return nil
+ })
+ require.NoError(t, err)
+
+ w.Start(context.Background())
+ for i := 1; i <= 3; i++ {
+ assert.True(t, w.TryEnqueue(testEvent{ID: i}))
+ }
+
+ ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
+ defer cancel()
+ require.NoError(t, w.Stop(ctx))
+
+ assert.False(t, w.Running())
+ mu.Lock()
+ defer mu.Unlock()
+ assert.Len(t, flushed, 3)
+}
+
+func TestWriter_DropWhenFull(t *testing.T) {
+ var (
+ dropped atomic.Int64
+ blockCh = make(chan struct{})
+ )
+
+ cfg := Config{
+ QueueSize: 2,
+ MaxBatchSize: 10,
+ FlushInterval: time.Hour,
+ }
+
+ w, err := New(cfg, func(_ context.Context, _ []testEvent) error {
+ <-blockCh
+ return nil
+ }, WithDropHandler(func(_ testEvent) {
+ dropped.Add(1)
+ }))
+ require.NoError(t, err)
+
+ w.Start(context.Background())
+ defer func() {
+ close(blockCh)
+ _ = w.Stop(context.Background())
+ }()
+
+ time.Sleep(10 * time.Millisecond)
+
+ w.ch <- testEvent{ID: 1}
+ w.ch <- testEvent{ID: 2}
+
+ assert.False(t, w.TryEnqueue(testEvent{ID: 3}))
+ assert.Equal(t, int64(1), dropped.Load())
+ assert.Equal(t, int64(1), w.Stats().Drops)
+}
+
+func TestWriter_FlushErrorCallback(t *testing.T) {
+ var (
+ called atomic.Bool
+ flushErr = errors.New("clickhouse write timeout")
+ done = make(chan struct{})
+ )
+
+ cfg := testConfig()
+ cfg.MaxBatchSize = 1
+ cfg.FlushInterval = time.Hour
+
+ w, err := New(cfg, func(_ context.Context, _ []testEvent) error {
+ return flushErr
+ }, WithFlushErrorHandler(func(_ context.Context, items []testEvent, err error) {
+ called.Store(true)
+ assert.Equal(t, flushErr, err)
+ assert.Len(t, items, 1)
+ close(done)
+ }))
+ require.NoError(t, err)
+
+ w.Start(context.Background())
+ defer func() { _ = w.Stop(context.Background()) }()
+
+ assert.True(t, w.TryEnqueue(testEvent{ID: 1}))
+
+ select {
+ case <-done:
+ case <-time.After(2 * time.Second):
+ t.Fatal("timed out waiting for error callback")
+ }
+
+ assert.True(t, called.Load())
+ assert.Equal(t, int64(1), w.Stats().FlushErrors)
+}
+
+func TestWriter_ValidateConfig(t *testing.T) {
+ tests := []struct {
+ name string
+ cfg Config
+ wantErr bool
+ }{
+ {"valid", DefaultConfig(), false},
+ {"zero queue", Config{QueueSize: 0, MaxBatchSize: 10, FlushInterval: time.Second}, true},
+ {"zero max batch", Config{QueueSize: 10, MaxBatchSize: 0, FlushInterval: time.Second}, true},
+ {"negative min batch", Config{QueueSize: 10, MaxBatchSize: 10, MinBatchSize: -1, FlushInterval: time.Second}, true},
+ {"zero flush interval", Config{QueueSize: 10, MaxBatchSize: 10, FlushInterval: 0}, true},
+ {"negative max flush wait", Config{QueueSize: 10, MaxBatchSize: 10, FlushInterval: time.Second, MaxFlushWait: -1}, true},
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ _, err := New(tt.cfg, func(_ context.Context, _ []testEvent) error { return nil })
+ if tt.wantErr {
+ assert.Error(t, err)
+ } else {
+ assert.NoError(t, err)
+ }
+ })
+ }
+}
+
+func TestWriter_NilFlushFunc(t *testing.T) {
+ _, err := New[testEvent](DefaultConfig(), nil)
+ assert.ErrorIs(t, err, errNilFlushFunc)
+}
diff --git a/pkg/persistence/idgen/snowflake.go b/pkg/idgen/snowflake.go
similarity index 100%
rename from pkg/persistence/idgen/snowflake.go
rename to pkg/idgen/snowflake.go
diff --git a/pkg/persistence/idgen/snowflake_test.go b/pkg/idgen/snowflake_test.go
similarity index 100%
rename from pkg/persistence/idgen/snowflake_test.go
rename to pkg/idgen/snowflake_test.go
diff --git a/pkg/persistence/migrator/clickhouse.go b/pkg/migrator/clickhouse.go
similarity index 100%
rename from pkg/persistence/migrator/clickhouse.go
rename to pkg/migrator/clickhouse.go
diff --git a/pkg/persistence/migrator/clickhouse_test.go b/pkg/migrator/clickhouse_test.go
similarity index 100%
rename from pkg/persistence/migrator/clickhouse_test.go
rename to pkg/migrator/clickhouse_test.go
diff --git a/pkg/persistence/migrator/goose/clickhouse/202606190001_create_user_access_logs.sql b/pkg/migrator/goose/clickhouse/202606190001_create_user_access_logs.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/clickhouse/202606190001_create_user_access_logs.sql
rename to pkg/migrator/goose/clickhouse/202606190001_create_user_access_logs.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606090001_initial_schema.sql b/pkg/migrator/goose/postgres/202606090001_initial_schema.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606090001_initial_schema.sql
rename to pkg/migrator/goose/postgres/202606090001_initial_schema.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606100001_create_schedules.sql b/pkg/migrator/goose/postgres/202606100001_create_schedules.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606100001_create_schedules.sql
rename to pkg/migrator/goose/postgres/202606100001_create_schedules.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606100002_access_token_is_admin.sql b/pkg/migrator/goose/postgres/202606100002_access_token_is_admin.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606100002_access_token_is_admin.sql
rename to pkg/migrator/goose/postgres/202606100002_access_token_is_admin.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606110001_remove_access_token_last_used_at.sql b/pkg/migrator/goose/postgres/202606110001_remove_access_token_last_used_at.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606110001_remove_access_token_last_used_at.sql
rename to pkg/migrator/goose/postgres/202606110001_remove_access_token_last_used_at.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606110002_alter_schedules_id_auto_increment.sql b/pkg/migrator/goose/postgres/202606110002_alter_schedules_id_auto_increment.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606110002_alter_schedules_id_auto_increment.sql
rename to pkg/migrator/goose/postgres/202606110002_alter_schedules_id_auto_increment.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606110003_rename_tables_to_w_prefix.sql b/pkg/migrator/goose/postgres/202606110003_rename_tables_to_w_prefix.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606110003_rename_tables_to_w_prefix.sql
rename to pkg/migrator/goose/postgres/202606110003_rename_tables_to_w_prefix.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606110004_add_file_access_whitelist_config.sql b/pkg/migrator/goose/postgres/202606110004_add_file_access_whitelist_config.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606110004_add_file_access_whitelist_config.sql
rename to pkg/migrator/goose/postgres/202606110004_add_file_access_whitelist_config.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606110005_add_disk_cache_configs.sql b/pkg/migrator/goose/postgres/202606110005_add_disk_cache_configs.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606110005_add_disk_cache_configs.sql
rename to pkg/migrator/goose/postgres/202606110005_add_disk_cache_configs.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606120001_add_login_session_ttl_config.sql b/pkg/migrator/goose/postgres/202606120001_add_login_session_ttl_config.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606120001_add_login_session_ttl_config.sql
rename to pkg/migrator/goose/postgres/202606120001_add_login_session_ttl_config.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606120002_add_update_upstream_repository_config.sql b/pkg/migrator/goose/postgres/202606120002_add_update_upstream_repository_config.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606120002_add_update_upstream_repository_config.sql
rename to pkg/migrator/goose/postgres/202606120002_add_update_upstream_repository_config.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606130001_add_upload_access_mode.sql b/pkg/migrator/goose/postgres/202606130001_add_upload_access_mode.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606130001_add_upload_access_mode.sql
rename to pkg/migrator/goose/postgres/202606130001_add_upload_access_mode.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606130002_expand_system_config_value.sql b/pkg/migrator/goose/postgres/202606130002_expand_system_config_value.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606130002_expand_system_config_value.sql
rename to pkg/migrator/goose/postgres/202606130002_expand_system_config_value.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606130003_add_storage_config.sql b/pkg/migrator/goose/postgres/202606130003_add_storage_config.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606130003_add_storage_config.sql
rename to pkg/migrator/goose/postgres/202606130003_add_storage_config.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606140001_create_push_tables.sql b/pkg/migrator/goose/postgres/202606140001_create_push_tables.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606140001_create_push_tables.sql
rename to pkg/migrator/goose/postgres/202606140001_create_push_tables.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606140003_add_system_user.sql b/pkg/migrator/goose/postgres/202606140003_add_system_user.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606140003_add_system_user.sql
rename to pkg/migrator/goose/postgres/202606140003_add_system_user.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606140004_create_push_channels.sql b/pkg/migrator/goose/postgres/202606140004_create_push_channels.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606140004_create_push_channels.sql
rename to pkg/migrator/goose/postgres/202606140004_create_push_channels.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606140005_update_system_cleanup_schedule.sql b/pkg/migrator/goose/postgres/202606140005_update_system_cleanup_schedule.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606140005_update_system_cleanup_schedule.sql
rename to pkg/migrator/goose/postgres/202606140005_update_system_cleanup_schedule.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606150001_add_task_type_to_push_events.sql b/pkg/migrator/goose/postgres/202606150001_add_task_type_to_push_events.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606150001_add_task_type_to_push_events.sql
rename to pkg/migrator/goose/postgres/202606150001_add_task_type_to_push_events.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606160001_remove_push_config.sql b/pkg/migrator/goose/postgres/202606160001_remove_push_config.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606160001_remove_push_config.sql
rename to pkg/migrator/goose/postgres/202606160001_remove_push_config.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606170001_add_upload_composite_indexes.sql b/pkg/migrator/goose/postgres/202606170001_add_upload_composite_indexes.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606170001_add_upload_composite_indexes.sql
rename to pkg/migrator/goose/postgres/202606170001_add_upload_composite_indexes.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606170002_create_upload_stats_table.sql b/pkg/migrator/goose/postgres/202606170002_create_upload_stats_table.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606170002_create_upload_stats_table.sql
rename to pkg/migrator/goose/postgres/202606170002_create_upload_stats_table.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606170003_backfill_upload_stats.sql b/pkg/migrator/goose/postgres/202606170003_backfill_upload_stats.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606170003_backfill_upload_stats.sql
rename to pkg/migrator/goose/postgres/202606170003_backfill_upload_stats.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202606180001_drop_upload_storage_driver.sql b/pkg/migrator/goose/postgres/202606180001_drop_upload_storage_driver.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202606180001_drop_upload_storage_driver.sql
rename to pkg/migrator/goose/postgres/202606180001_drop_upload_storage_driver.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202608160001_create_user_access_logs.sql b/pkg/migrator/goose/postgres/202608160001_create_user_access_logs.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202608160001_create_user_access_logs.sql
rename to pkg/migrator/goose/postgres/202608160001_create_user_access_logs.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202608160002_log_database_configs.sql b/pkg/migrator/goose/postgres/202608160002_log_database_configs.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202608160002_log_database_configs.sql
rename to pkg/migrator/goose/postgres/202608160002_log_database_configs.sql
diff --git a/pkg/persistence/migrator/goose/postgres/202608160003_create_message_gateway.sql b/pkg/migrator/goose/postgres/202608160003_create_message_gateway.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/postgres/202608160003_create_message_gateway.sql
rename to pkg/migrator/goose/postgres/202608160003_create_message_gateway.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606090001_initial_schema.sql b/pkg/migrator/goose/sqlite/202606090001_initial_schema.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606090001_initial_schema.sql
rename to pkg/migrator/goose/sqlite/202606090001_initial_schema.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606100001_create_schedules.sql b/pkg/migrator/goose/sqlite/202606100001_create_schedules.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606100001_create_schedules.sql
rename to pkg/migrator/goose/sqlite/202606100001_create_schedules.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606100002_access_token_is_admin.sql b/pkg/migrator/goose/sqlite/202606100002_access_token_is_admin.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606100002_access_token_is_admin.sql
rename to pkg/migrator/goose/sqlite/202606100002_access_token_is_admin.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606110001_remove_access_token_last_used_at.sql b/pkg/migrator/goose/sqlite/202606110001_remove_access_token_last_used_at.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606110001_remove_access_token_last_used_at.sql
rename to pkg/migrator/goose/sqlite/202606110001_remove_access_token_last_used_at.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606110002_alter_schedules_id_auto_increment.sql b/pkg/migrator/goose/sqlite/202606110002_alter_schedules_id_auto_increment.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606110002_alter_schedules_id_auto_increment.sql
rename to pkg/migrator/goose/sqlite/202606110002_alter_schedules_id_auto_increment.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606110003_rename_tables_to_w_prefix.sql b/pkg/migrator/goose/sqlite/202606110003_rename_tables_to_w_prefix.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606110003_rename_tables_to_w_prefix.sql
rename to pkg/migrator/goose/sqlite/202606110003_rename_tables_to_w_prefix.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606110004_add_file_access_whitelist_config.sql b/pkg/migrator/goose/sqlite/202606110004_add_file_access_whitelist_config.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606110004_add_file_access_whitelist_config.sql
rename to pkg/migrator/goose/sqlite/202606110004_add_file_access_whitelist_config.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606110005_add_disk_cache_configs.sql b/pkg/migrator/goose/sqlite/202606110005_add_disk_cache_configs.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606110005_add_disk_cache_configs.sql
rename to pkg/migrator/goose/sqlite/202606110005_add_disk_cache_configs.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606120001_add_login_session_ttl_config.sql b/pkg/migrator/goose/sqlite/202606120001_add_login_session_ttl_config.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606120001_add_login_session_ttl_config.sql
rename to pkg/migrator/goose/sqlite/202606120001_add_login_session_ttl_config.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606120002_add_update_upstream_repository_config.sql b/pkg/migrator/goose/sqlite/202606120002_add_update_upstream_repository_config.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606120002_add_update_upstream_repository_config.sql
rename to pkg/migrator/goose/sqlite/202606120002_add_update_upstream_repository_config.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606130001_add_upload_access_mode.sql b/pkg/migrator/goose/sqlite/202606130001_add_upload_access_mode.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606130001_add_upload_access_mode.sql
rename to pkg/migrator/goose/sqlite/202606130001_add_upload_access_mode.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606130002_expand_system_config_value.sql b/pkg/migrator/goose/sqlite/202606130002_expand_system_config_value.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606130002_expand_system_config_value.sql
rename to pkg/migrator/goose/sqlite/202606130002_expand_system_config_value.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606130003_add_storage_config.sql b/pkg/migrator/goose/sqlite/202606130003_add_storage_config.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606130003_add_storage_config.sql
rename to pkg/migrator/goose/sqlite/202606130003_add_storage_config.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606140001_create_push_tables.sql b/pkg/migrator/goose/sqlite/202606140001_create_push_tables.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606140001_create_push_tables.sql
rename to pkg/migrator/goose/sqlite/202606140001_create_push_tables.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606140003_add_system_user.sql b/pkg/migrator/goose/sqlite/202606140003_add_system_user.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606140003_add_system_user.sql
rename to pkg/migrator/goose/sqlite/202606140003_add_system_user.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606140004_create_push_channels.sql b/pkg/migrator/goose/sqlite/202606140004_create_push_channels.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606140004_create_push_channels.sql
rename to pkg/migrator/goose/sqlite/202606140004_create_push_channels.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606140005_update_system_cleanup_schedule.sql b/pkg/migrator/goose/sqlite/202606140005_update_system_cleanup_schedule.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606140005_update_system_cleanup_schedule.sql
rename to pkg/migrator/goose/sqlite/202606140005_update_system_cleanup_schedule.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606150001_add_task_type_to_push_events.sql b/pkg/migrator/goose/sqlite/202606150001_add_task_type_to_push_events.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606150001_add_task_type_to_push_events.sql
rename to pkg/migrator/goose/sqlite/202606150001_add_task_type_to_push_events.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606160001_remove_push_config.sql b/pkg/migrator/goose/sqlite/202606160001_remove_push_config.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606160001_remove_push_config.sql
rename to pkg/migrator/goose/sqlite/202606160001_remove_push_config.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606170001_add_upload_composite_indexes.sql b/pkg/migrator/goose/sqlite/202606170001_add_upload_composite_indexes.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606170001_add_upload_composite_indexes.sql
rename to pkg/migrator/goose/sqlite/202606170001_add_upload_composite_indexes.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606170002_create_upload_stats_table.sql b/pkg/migrator/goose/sqlite/202606170002_create_upload_stats_table.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606170002_create_upload_stats_table.sql
rename to pkg/migrator/goose/sqlite/202606170002_create_upload_stats_table.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606170003_backfill_upload_stats.sql b/pkg/migrator/goose/sqlite/202606170003_backfill_upload_stats.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606170003_backfill_upload_stats.sql
rename to pkg/migrator/goose/sqlite/202606170003_backfill_upload_stats.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202606180001_drop_upload_storage_driver.sql b/pkg/migrator/goose/sqlite/202606180001_drop_upload_storage_driver.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202606180001_drop_upload_storage_driver.sql
rename to pkg/migrator/goose/sqlite/202606180001_drop_upload_storage_driver.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202608160001_create_user_access_logs.sql b/pkg/migrator/goose/sqlite/202608160001_create_user_access_logs.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202608160001_create_user_access_logs.sql
rename to pkg/migrator/goose/sqlite/202608160001_create_user_access_logs.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202608160002_log_database_configs.sql b/pkg/migrator/goose/sqlite/202608160002_log_database_configs.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202608160002_log_database_configs.sql
rename to pkg/migrator/goose/sqlite/202608160002_log_database_configs.sql
diff --git a/pkg/persistence/migrator/goose/sqlite/202608160003_create_message_gateway.sql b/pkg/migrator/goose/sqlite/202608160003_create_message_gateway.sql
similarity index 100%
rename from pkg/persistence/migrator/goose/sqlite/202608160003_create_message_gateway.sql
rename to pkg/migrator/goose/sqlite/202608160003_create_message_gateway.sql
diff --git a/pkg/persistence/migrator/migrator.go b/pkg/migrator/migrator.go
similarity index 95%
rename from pkg/persistence/migrator/migrator.go
rename to pkg/migrator/migrator.go
index 228d6796..25b2d5db 100644
--- a/pkg/persistence/migrator/migrator.go
+++ b/pkg/migrator/migrator.go
@@ -11,8 +11,7 @@ import (
"log"
"github.com/Rain-kl/Wavelet/pkg/config"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
-
+ "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/pressly/goose/v3"
)
@@ -59,7 +58,7 @@ func migrationDir() string {
// Migrate 执行数据库迁移
func Migrate() Report {
- gormDB := db.DB(context.Background())
+ gormDB := database.DB(context.Background())
if gormDB == nil {
log.Fatalf("[%s] database not initialized\n", dbType())
}
diff --git a/pkg/persistence/migrator/migrator_test.go b/pkg/migrator/migrator_test.go
similarity index 97%
rename from pkg/persistence/migrator/migrator_test.go
rename to pkg/migrator/migrator_test.go
index 43feffd9..9770eda8 100644
--- a/pkg/persistence/migrator/migrator_test.go
+++ b/pkg/migrator/migrator_test.go
@@ -7,7 +7,7 @@ import (
"testing"
"github.com/Rain-kl/Wavelet/pkg/config"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/alicebob/miniredis/v2"
"github.com/glebarez/sqlite"
"github.com/redis/go-redis/v9"
diff --git a/pkg/persistence/batchwriter/writer_test.go b/pkg/persistence/batchwriter/writer_test.go
deleted file mode 100644
index cd05bb25..00000000
--- a/pkg/persistence/batchwriter/writer_test.go
+++ /dev/null
@@ -1,491 +0,0 @@
-// Copyright 2026 Arctel.net
-// SPDX-License-Identifier: Apache-2.0
-
-package batchwriter
-
-import (
- "context"
- "errors"
- "sync"
- "testing"
- "time"
-
- "github.com/google/go-cmp/cmp"
-)
-
-func TestNewRejectsInvalidConfig(t *testing.T) {
- t.Parallel()
-
- _, err := New[int](Config{}, func(context.Context, []int) error { return nil })
- if err == nil {
- t.Fatal("New() = nil, want validation error")
- }
-}
-
-func TestNewRejectsNilFlushFunc(t *testing.T) {
- t.Parallel()
-
- cfg := DefaultConfig()
- _, err := New[int](cfg, nil)
- if !errors.Is(err, errNilFlushFunc) {
- t.Fatalf("New() error = %v, want %v", err, errNilFlushFunc)
- }
-}
-
-func TestWriterFlushesOnMaxBatchSize(t *testing.T) {
- t.Parallel()
-
- var (
- mu sync.Mutex
- batches [][]int
- )
- cfg := DefaultConfig()
- cfg.MaxBatchSize = 3
- cfg.FlushInterval = time.Hour
-
- writer, err := New[int](cfg, func(_ context.Context, items []int) error {
- mu.Lock()
- defer mu.Unlock()
- batches = append(batches, append([]int(nil), items...))
- return nil
- })
- if err != nil {
- t.Fatalf("New() error = %v", err)
- }
-
- writer.Start(context.Background())
- t.Cleanup(func() {
- stopCtx, cancel := context.WithTimeout(context.Background(), time.Second)
- defer cancel()
- if err := writer.Stop(stopCtx); err != nil {
- t.Fatalf("Stop() error = %v", err)
- }
- })
-
- for i := range 3 {
- if !writer.TryEnqueue(i + 1) {
- t.Fatalf("TryEnqueue(%d) = false, want true", i+1)
- }
- }
-
- deadline := time.Now().Add(time.Second)
- for {
- mu.Lock()
- ready := len(batches) == 1
- mu.Unlock()
- if ready || time.Now().After(deadline) {
- break
- }
- time.Sleep(10 * time.Millisecond)
- }
-
- mu.Lock()
- got := batches
- mu.Unlock()
-
- want := [][]int{{1, 2, 3}}
- if diff := cmp.Diff(want, got); diff != "" {
- t.Fatalf("flush batches mismatch (-want +got):\n%s", diff)
- }
-}
-
-func TestWriterFlushesOnInterval(t *testing.T) {
- t.Parallel()
-
- var (
- mu sync.Mutex
- batch []int
- )
- cfg := DefaultConfig()
- cfg.MaxBatchSize = 100
- cfg.MinBatchSize = 0
- cfg.FlushInterval = 20 * time.Millisecond
-
- writer, err := New[int](cfg, func(_ context.Context, items []int) error {
- mu.Lock()
- defer mu.Unlock()
- batch = append([]int(nil), items...)
- return nil
- })
- if err != nil {
- t.Fatalf("New() error = %v", err)
- }
-
- writer.Start(context.Background())
- t.Cleanup(func() {
- stopCtx, cancel := context.WithTimeout(context.Background(), time.Second)
- defer cancel()
- if err := writer.Stop(stopCtx); err != nil {
- t.Fatalf("Stop() error = %v", err)
- }
- })
-
- if !writer.TryEnqueue(42) {
- t.Fatal("TryEnqueue() = false, want true")
- }
-
- deadline := time.Now().Add(time.Second)
- for {
- mu.Lock()
- ready := len(batch) == 1
- mu.Unlock()
- if ready || time.Now().After(deadline) {
- break
- }
- time.Sleep(5 * time.Millisecond)
- }
-
- mu.Lock()
- got := batch
- mu.Unlock()
-
- want := []int{42}
- if diff := cmp.Diff(want, got); diff != "" {
- t.Fatalf("interval flush mismatch (-want +got):\n%s", diff)
- }
-}
-
-func TestWriterTryEnqueueDropsWhenFull(t *testing.T) {
- t.Parallel()
-
- cfg := DefaultConfig()
- cfg.QueueSize = 1
- cfg.MaxBatchSize = 10
- cfg.FlushInterval = time.Hour
-
- var dropped int
- writer, err := New[int](cfg, func(context.Context, []int) error { return nil }, WithDropHandler[int](func(int) {
- dropped++
- }))
- if err != nil {
- t.Fatalf("New() error = %v", err)
- }
-
- writer.Start(context.Background())
- t.Cleanup(func() {
- stopCtx, cancel := context.WithTimeout(context.Background(), time.Second)
- defer cancel()
- _ = writer.Stop(stopCtx)
- })
-
- if !writer.TryEnqueue(1) {
- t.Fatal("TryEnqueue(1) = false, want true")
- }
- if writer.TryEnqueue(2) {
- t.Fatal("TryEnqueue(2) = true, want false")
- }
- if !writer.IsFull() {
- t.Fatal("IsFull() = false, want true")
- }
- if dropped != 1 {
- t.Fatalf("dropped = %d, want 1", dropped)
- }
-}
-
-func TestWriterStopDrainsQueuedItems(t *testing.T) {
- t.Parallel()
-
- cfg := DefaultConfig()
- cfg.MaxBatchSize = 10
- cfg.FlushInterval = time.Hour
-
- var flushed []int
- writer, err := New[int](cfg, func(_ context.Context, items []int) error {
- flushed = append(flushed, items...)
- return nil
- })
- if err != nil {
- t.Fatalf("New() error = %v", err)
- }
-
- writer.Start(context.Background())
- for i := range 2 {
- if !writer.TryEnqueue(i + 1) {
- t.Fatalf("TryEnqueue(%d) = false, want true", i+1)
- }
- }
-
- stopCtx, cancel := context.WithTimeout(context.Background(), time.Second)
- defer cancel()
- if err := writer.Stop(stopCtx); err != nil {
- t.Fatalf("Stop() error = %v", err)
- }
-
- want := []int{1, 2}
- if diff := cmp.Diff(want, flushed); diff != "" {
- t.Fatalf("Stop() drain mismatch (-want +got):\n%s", diff)
- }
- if writer.Running() {
- t.Fatal("Running() = true after Stop(), want false")
- }
-}
-
-func TestWriterInvokesFlushErrorHandler(t *testing.T) {
- t.Parallel()
-
- cfg := DefaultConfig()
- cfg.MaxBatchSize = 1
- cfg.FlushInterval = time.Hour
-
- flushErr := errors.New("flush failed")
- var (
- mu sync.Mutex
- errCount int
- gotItems []int
- )
-
- writer, err := New[int](cfg, func(context.Context, []int) error {
- return flushErr
- }, WithFlushErrorHandler[int](func(_ context.Context, items []int, err error) {
- mu.Lock()
- defer mu.Unlock()
- errCount++
- gotItems = append([]int(nil), items...)
- if !errors.Is(err, flushErr) {
- t.Errorf("flush error = %v, want %v", err, flushErr)
- }
- }))
- if err != nil {
- t.Fatalf("New() error = %v", err)
- }
-
- writer.Start(context.Background())
- t.Cleanup(func() {
- stopCtx, cancel := context.WithTimeout(context.Background(), time.Second)
- defer cancel()
- _ = writer.Stop(stopCtx)
- })
-
- if !writer.TryEnqueue(7) {
- t.Fatal("TryEnqueue() = false, want true")
- }
-
- deadline := time.Now().Add(time.Second)
- for {
- mu.Lock()
- ready := errCount == 1
- mu.Unlock()
- if ready || time.Now().After(deadline) {
- break
- }
- time.Sleep(5 * time.Millisecond)
- }
-
- mu.Lock()
- gotCount := errCount
- items := gotItems
- mu.Unlock()
-
- if gotCount != 1 {
- t.Fatalf("flush error handler count = %d, want 1", gotCount)
- }
- if diff := cmp.Diff([]int{7}, items); diff != "" {
- t.Fatalf("flush error handler items mismatch (-want +got):\n%s", diff)
- }
-
- stats := writer.Stats()
- if stats.FlushErrors != 1 {
- t.Fatalf("Stats().FlushErrors = %d, want 1", stats.FlushErrors)
- }
-}
-
-func TestWriterSkipsIntervalFlushBelowMinBatchSize(t *testing.T) {
- t.Parallel()
-
- var (
- mu sync.Mutex
- batch []int
- )
- cfg := DefaultConfig()
- cfg.MaxBatchSize = 100
- cfg.MinBatchSize = 5
- cfg.FlushInterval = 20 * time.Millisecond
-
- writer, err := New[int](cfg, func(_ context.Context, items []int) error {
- mu.Lock()
- defer mu.Unlock()
- batch = append([]int(nil), items...)
- return nil
- })
- if err != nil {
- t.Fatalf("New() error = %v", err)
- }
-
- writer.Start(context.Background())
- t.Cleanup(func() {
- stopCtx, cancel := context.WithTimeout(context.Background(), time.Second)
- defer cancel()
- if err := writer.Stop(stopCtx); err != nil {
- t.Fatalf("Stop() error = %v", err)
- }
- })
-
- for i := range 3 {
- if !writer.TryEnqueue(i + 1) {
- t.Fatalf("TryEnqueue(%d) = false, want true", i+1)
- }
- }
-
- time.Sleep(100 * time.Millisecond)
-
- mu.Lock()
- got := batch
- mu.Unlock()
-
- if len(got) != 0 {
- t.Fatalf("interval flush with below-min batch = %v, want no flush", got)
- }
-}
-
-func TestWriterFlushesOnIntervalWhenMinBatchSizeReached(t *testing.T) {
- t.Parallel()
-
- var (
- mu sync.Mutex
- batch []int
- )
- cfg := DefaultConfig()
- cfg.MaxBatchSize = 100
- cfg.MinBatchSize = 3
- cfg.FlushInterval = 20 * time.Millisecond
-
- writer, err := New[int](cfg, func(_ context.Context, items []int) error {
- mu.Lock()
- defer mu.Unlock()
- batch = append([]int(nil), items...)
- return nil
- })
- if err != nil {
- t.Fatalf("New() error = %v", err)
- }
-
- writer.Start(context.Background())
- t.Cleanup(func() {
- stopCtx, cancel := context.WithTimeout(context.Background(), time.Second)
- defer cancel()
- if err := writer.Stop(stopCtx); err != nil {
- t.Fatalf("Stop() error = %v", err)
- }
- })
-
- for i := range 3 {
- if !writer.TryEnqueue(i + 1) {
- t.Fatalf("TryEnqueue(%d) = false, want true", i+1)
- }
- }
-
- deadline := time.Now().Add(time.Second)
- for {
- mu.Lock()
- ready := len(batch) == 3
- mu.Unlock()
- if ready || time.Now().After(deadline) {
- break
- }
- time.Sleep(5 * time.Millisecond)
- }
-
- mu.Lock()
- got := batch
- mu.Unlock()
-
- want := []int{1, 2, 3}
- if diff := cmp.Diff(want, got); diff != "" {
- t.Fatalf("interval flush at min batch size mismatch (-want +got):\n%s", diff)
- }
-}
-
-func TestWriterForcesFlushAfterMaxFlushWait(t *testing.T) {
- t.Parallel()
-
- var (
- mu sync.Mutex
- batch []int
- )
- cfg := DefaultConfig()
- cfg.MaxBatchSize = 100
- cfg.MinBatchSize = 50
- cfg.FlushInterval = 20 * time.Millisecond
- cfg.MaxFlushWait = 80 * time.Millisecond
-
- writer, err := New[int](cfg, func(_ context.Context, items []int) error {
- mu.Lock()
- defer mu.Unlock()
- batch = append([]int(nil), items...)
- return nil
- })
- if err != nil {
- t.Fatalf("New() error = %v", err)
- }
-
- writer.Start(context.Background())
- t.Cleanup(func() {
- stopCtx, cancel := context.WithTimeout(context.Background(), time.Second)
- defer cancel()
- if err := writer.Stop(stopCtx); err != nil {
- t.Fatalf("Stop() error = %v", err)
- }
- })
-
- if !writer.TryEnqueue(1) {
- t.Fatal("TryEnqueue(1) = false, want true")
- }
-
- deadline := time.Now().Add(time.Second)
- for {
- mu.Lock()
- ready := len(batch) == 1
- mu.Unlock()
- if ready || time.Now().After(deadline) {
- break
- }
- time.Sleep(5 * time.Millisecond)
- }
-
- mu.Lock()
- got := batch
- mu.Unlock()
- if diff := cmp.Diff([]int{1}, got); diff != "" {
- t.Fatalf("max flush wait mismatch (-want +got):\n%s", diff)
- }
-}
-
-func TestWriterStatsTracksDrops(t *testing.T) {
- t.Parallel()
-
- cfg := DefaultConfig()
- cfg.Name = "test-drops"
- cfg.QueueSize = 1
- cfg.MaxBatchSize = 10
- cfg.FlushInterval = time.Hour
-
- writer, err := New[int](cfg, func(context.Context, []int) error { return nil })
- if err != nil {
- t.Fatalf("New() error = %v", err)
- }
-
- writer.Start(context.Background())
- t.Cleanup(func() {
- stopCtx, cancel := context.WithTimeout(context.Background(), time.Second)
- defer cancel()
- _ = writer.Stop(stopCtx)
- })
-
- if !writer.TryEnqueue(1) {
- t.Fatal("TryEnqueue(1) = false, want true")
- }
- if writer.TryEnqueue(2) {
- t.Fatal("TryEnqueue(2) = true, want false")
- }
-
- stats := writer.Stats()
- if stats.Drops != 1 {
- t.Fatalf("Stats().Drops = %d, want 1", stats.Drops)
- }
- if stats.Cap != 1 {
- t.Fatalf("Stats().Cap = %d, want 1", stats.Cap)
- }
- if !stats.Running {
- t.Fatal("Stats().Running = false, want true")
- }
-}
diff --git a/pkg/shared/constants.go b/pkg/shared/constants.go
deleted file mode 100644
index d2793f58..00000000
--- a/pkg/shared/constants.go
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright 2025 linux.do
-// Copyright 2026 Arctel.net
-// SPDX-License-Identifier: Apache-2.0
-
-// Package shared 提供跨模块共享的常量、错误定义和通用类型。
-package shared
diff --git a/pkg/shared/errs.go b/pkg/shared/errs.go
deleted file mode 100644
index c5c61b8c..00000000
--- a/pkg/shared/errs.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2025 linux.do
-// Copyright 2026 Arctel.net
-// SPDX-License-Identifier: Apache-2.0
-
-package shared
-
-// 通用业务错误消息常量
-const (
- BannedAccount = "账号已被封禁"
- UnAuthorized = "未登录"
-)
diff --git a/pkg/task/meta_test.go b/pkg/task/meta_test.go
deleted file mode 100644
index ce6ac5d4..00000000
--- a/pkg/task/meta_test.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2026 Arctel.net
-// SPDX-License-Identifier: Apache-2.0
-
-package task_test
-
-import (
- "testing"
-
- "github.com/Rain-kl/Wavelet/pkg/task"
-)
-
-func TestDuplicateTaskMeta(t *testing.T) {
- dummyMeta := task.TaskMeta{
- Type: "test_duplicate_task",
- AsynqTask: "test:duplicate_task",
- Name: "Test Duplicate Task",
- }
-
- task.RegisterTaskMeta(dummyMeta)
- task.RegisterTaskMeta(dummyMeta)
-
- metas := task.GetDispatchableTasks()
-
- // Check if we have duplicates by checking if a Type appears more than once
- seen := make(map[string]int)
- for _, m := range metas {
- seen[m.Type]++
- }
-
- for taskType, count := range seen {
- if count > 1 {
- t.Errorf("Task type %q registered %d times, expected at most 1", taskType, count)
- }
- }
-}
diff --git a/pkg/task/permanent_error_test.go b/pkg/task/permanent_error_test.go
deleted file mode 100644
index f8ae9300..00000000
--- a/pkg/task/permanent_error_test.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2026 Arctel.net
-// SPDX-License-Identifier: Apache-2.0
-
-package task
-
-import (
- "errors"
- "testing"
-
- "github.com/hibiken/asynq"
- "github.com/stretchr/testify/assert"
-)
-
-func TestPermanentErrorSkipsRetryWithoutExposingAsynqMessage(t *testing.T) {
- err := PermanentError(" 来源配置无效 ")
-
- assert.True(t, errors.Is(err, asynq.SkipRetry))
- assert.Equal(t, "来源配置无效", err.Error())
- assert.NotContains(t, err.Error(), asynq.SkipRetry.Error())
-}
-
-func TestPermanentErrorUsesSafeFallbackForBlankMessage(t *testing.T) {
- err := PermanentError(" ")
-
- assert.True(t, errors.Is(err, asynq.SkipRetry))
- assert.Equal(t, defaultPermanentErrorMessage, err.Error())
-}
diff --git a/pkg/task/utils_test.go b/pkg/task/utils_test.go
deleted file mode 100644
index 28a091b3..00000000
--- a/pkg/task/utils_test.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2026 Arctel.net
-// SPDX-License-Identifier: Apache-2.0
-
-package task
-
-import (
- "testing"
-
- "github.com/Rain-kl/Wavelet/pkg/config"
- "github.com/redis/go-redis/v9"
- "github.com/redis/go-redis/v9/maintnotifications"
-)
-
-func TestNewRedisConnOptConfiguresMaintenanceNotifications(t *testing.T) {
- previous := config.Config.Redis
- t.Cleanup(func() { config.Config.Redis = previous })
-
- for _, test := range []struct {
- name string
- enabled bool
- want maintnotifications.Mode
- }{
- {name: "disabled by default", enabled: false, want: maintnotifications.ModeDisabled},
- {name: "auto when enabled", enabled: true, want: maintnotifications.ModeAuto},
- } {
- t.Run(test.name, func(t *testing.T) {
- config.Config.Redis.MaintNotifications = test.enabled
-
- t.Run("standalone", func(t *testing.T) {
- config.Config.Redis.ClusterMode = false
- config.Config.Redis.MasterName = ""
- config.Config.Redis.Addrs = []string{"127.0.0.1:6379"}
-
- client, ok := NewRedisConnOpt().MakeRedisClient().(*redis.Client)
- if !ok {
- t.Fatal("standalone option did not create *redis.Client")
- }
- defer func() { _ = client.Close() }()
- assertMaintenanceNotificationsMode(t, client.Options().MaintNotificationsConfig, test.want)
- })
-
- t.Run("cluster", func(t *testing.T) {
- config.Config.Redis.ClusterMode = true
- config.Config.Redis.MasterName = ""
- config.Config.Redis.Addrs = []string{"127.0.0.1:6379"}
-
- client, ok := NewRedisConnOpt().MakeRedisClient().(*redis.ClusterClient)
- if !ok {
- t.Fatal("cluster option did not create *redis.ClusterClient")
- }
- defer func() { _ = client.Close() }()
- assertMaintenanceNotificationsMode(t, client.Options().MaintNotificationsConfig, test.want)
- })
-
- t.Run("sentinel", func(t *testing.T) {
- config.Config.Redis.ClusterMode = false
- config.Config.Redis.MasterName = "openflare"
- config.Config.Redis.Addrs = []string{"127.0.0.1:26379"}
-
- client, ok := NewRedisConnOpt().MakeRedisClient().(*redis.Client)
- if !ok {
- t.Fatal("sentinel option did not create *redis.Client")
- }
- defer func() { _ = client.Close() }()
- assertMaintenanceNotificationsMode(t, client.Options().MaintNotificationsConfig, test.want)
- })
- })
- }
-}
-
-func assertMaintenanceNotificationsMode(t *testing.T, cfg *maintnotifications.Config, want maintnotifications.Mode) {
- t.Helper()
- if cfg == nil || cfg.Mode != want {
- t.Fatalf("maintenance notifications mode = %v, want %v", cfg, want)
- }
-}
diff --git a/pkg/task/worker/middlewares.go b/pkg/task/worker/middlewares.go
deleted file mode 100644
index 587bb323..00000000
--- a/pkg/task/worker/middlewares.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2025 linux.do
-// Copyright 2026 Arctel.net
-// SPDX-License-Identifier: Apache-2.0
-
-// Package worker 提供 Asynq 任务处理服务器与中间件
-package worker
-
-import (
- "context"
-
- "github.com/hibiken/asynq"
-)
-
-// taskLoggingMiddleware 任务处理中间件
-// 注意:OTel Span 创建、日志记录、TaskExecution 状态管理
-// 已由 task.ProcessTask 统一处理,此中间件保留用于未来扩展(如限流、监控等)
-func taskLoggingMiddleware(h asynq.Handler) asynq.Handler {
- return asynq.HandlerFunc(func(ctx context.Context, t *asynq.Task) error {
- return h.ProcessTask(ctx, t)
- })
-}
diff --git a/pkg/task/worker/worker.go b/pkg/task/worker/worker.go
deleted file mode 100644
index 920c7f17..00000000
--- a/pkg/task/worker/worker.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2025 linux.do
-// Copyright 2026 Arctel.net
-// SPDX-License-Identifier: Apache-2.0
-
-package worker
-
-import (
- "time"
-
- "github.com/Rain-kl/Wavelet/pkg/config"
- "github.com/Rain-kl/Wavelet/pkg/task"
-
- "github.com/hibiken/asynq"
-)
-
-// workerShutdownTimeout Worker 优雅关闭超时时间
-const workerShutdownTimeout = 3 * time.Minute
-
-// StartWorker 启动任务处理服务器
-func StartWorker() error {
-
- asynqServer := asynq.NewServer(
- task.RedisOpt,
- asynq.Config{
- Concurrency: config.Config.Worker.Concurrency,
- ShutdownTimeout: workerShutdownTimeout,
- Queues: BuildQueuesFromConfig(),
- StrictPriority: config.Config.Worker.StrictPriority,
- },
- )
-
- // 注册 Asynq 任务路由
- mux := asynq.NewServeMux()
- mux.Use(taskLoggingMiddleware)
-
- // 统一使用 task.ProcessTask 处理所有任务类型
- // 框架内部自动分发到对应的 TaskHandler 实现
- // 动态注册所有已注册的任务处理器路由,框架内部自动分发到对应的 TaskHandler 实现
- for _, taskName := range task.GetRegisteredAsynqTasks() {
- mux.HandleFunc(taskName, task.ProcessTask)
- }
-
- // 启动服务器
- return asynqServer.Run(mux)
-}
-
-// StartWorkerServer 异步启动 Asynq 工作器服务并返回 Server 实例以支持平滑停机
-func StartWorkerServer() (*asynq.Server, error) {
-
- asynqServer := asynq.NewServer(
- task.RedisOpt,
- asynq.Config{
- Concurrency: config.Config.Worker.Concurrency,
- ShutdownTimeout: workerShutdownTimeout,
- Queues: BuildQueuesFromConfig(),
- StrictPriority: config.Config.Worker.StrictPriority,
- },
- )
-
- mux := asynq.NewServeMux()
- mux.Use(taskLoggingMiddleware)
-
- for _, taskName := range task.GetRegisteredAsynqTasks() {
- mux.HandleFunc(taskName, task.ProcessTask)
- }
-
- if err := asynqServer.Start(mux); err != nil {
- return nil, err
- }
- return asynqServer, nil
-}
-
-// BuildQueuesFromConfig 从配置构建队列映射
-func BuildQueuesFromConfig() map[string]int {
- queues := make(map[string]int)
-
- // 从配置读取队列
- if len(config.Config.Worker.Queues) > 0 {
- for _, q := range config.Config.Worker.Queues {
- if q.Name != "" && q.Priority > 0 {
- queues[q.Name] = q.Priority
- }
- }
- }
-
- // 如果配置为空,使用默认队列
- if len(queues) == 0 {
- queues = map[string]int{
- task.QueueDefault: 1,
- }
- }
-
- return queues
-}
diff --git a/pkg/testhelper/test_helper.go b/pkg/testhelper/test_helper.go
index b51008d7..74ca3ac6 100644
--- a/pkg/testhelper/test_helper.go
+++ b/pkg/testhelper/test_helper.go
@@ -10,7 +10,8 @@ import (
"testing"
"time"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ cachepkg "github.com/Rain-kl/Wavelet/plugins/infra/cache"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/alicebob/miniredis/v2"
"github.com/glebarez/sqlite"
"github.com/redis/go-redis/v9"
@@ -249,7 +250,7 @@ func SetupTestEnvironment(t *testing.T) (*gorm.DB, *miniredis.Miniredis, func())
})
db.SetDB(sqliteDB)
- db.Redis = redisClient
+ cachepkg.Redis = redisClient
seedDefaultConfigs(t, sqliteDB)
@@ -258,7 +259,7 @@ func SetupTestEnvironment(t *testing.T) (*gorm.DB, *miniredis.Miniredis, func())
_ = redisClient.Close()
mr.Close()
db.SetDB(nil)
- db.Redis = nil
+ cachepkg.Redis = nil
}
return sqliteDB, mr, cleanup
@@ -327,6 +328,6 @@ func seedDefaultConfigs(t *testing.T, tx *gorm.DB) {
if _, ok := publicKeys[config.Key]; ok {
config.Visibility = "visible"
}
- _ = db.HSetJSON(context.Background(), "system_configs", config.Key, &config)
+ _ = cachepkg.HSetJSON(context.Background(), "system_configs", config.Key, &config)
}
}
diff --git a/plugins/domain/admin/handlers_auth_source.go b/plugins/domain/admin/handlers_auth_source.go
index e94d37d8..f0121862 100644
--- a/plugins/domain/admin/handlers_auth_source.go
+++ b/plugins/domain/admin/handlers_auth_source.go
@@ -7,16 +7,16 @@ import (
"net/http"
"strconv"
- persistence "github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/response"
"github.com/Rain-kl/Wavelet/plugins/domain/auth"
+ "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/gin-gonic/gin"
)
// ListAuthSources lists all configured authentication sources.
func ListAuthSources(c *gin.Context) {
var sources []auth.AuthSource
- gormDB := persistence.DB(c.Request.Context())
+ gormDB := database.DB(c.Request.Context())
if err := gormDB.Order("id ASC").Find(&sources).Error; err != nil {
response.AbortInternal(c, "获取认证源列表失败")
return
@@ -51,7 +51,7 @@ func CreateAuthSource(c *gin.Context) {
return
}
- gormDB := persistence.DB(c.Request.Context())
+ gormDB := database.DB(c.Request.Context())
if err := gormDB.Create(&source).Error; err != nil {
response.AbortBadRequest(c, "创建认证源失败: "+err.Error())
return
@@ -70,7 +70,7 @@ func UpdateAuthSource(c *gin.Context) {
return
}
- gormDB := persistence.DB(c.Request.Context())
+ gormDB := database.DB(c.Request.Context())
var existing auth.AuthSource
if err := gormDB.First(&existing, id).Error; err != nil {
response.AbortNotFound(c, "认证源不存在")
@@ -115,7 +115,7 @@ func ToggleAuthSource(c *gin.Context) {
return
}
- gormDB := persistence.DB(c.Request.Context())
+ gormDB := database.DB(c.Request.Context())
var existing auth.AuthSource
if err := gormDB.First(&existing, id).Error; err != nil {
response.AbortNotFound(c, "认证源不存在")
@@ -147,7 +147,7 @@ func DeleteAuthSource(c *gin.Context) {
return
}
- gormDB := persistence.DB(c.Request.Context())
+ gormDB := database.DB(c.Request.Context())
if err := gormDB.Delete(&auth.AuthSource{}, id).Error; err != nil {
response.AbortInternal(c, "删除认证源失败")
return
diff --git a/plugins/domain/admin/handlers_config.go b/plugins/domain/admin/handlers_config.go
index 13fedc6f..39cc32d2 100644
--- a/plugins/domain/admin/handlers_config.go
+++ b/plugins/domain/admin/handlers_config.go
@@ -15,9 +15,10 @@ import (
"github.com/Rain-kl/Wavelet/pkg/logger"
mail "github.com/Rain-kl/Wavelet/pkg/mail"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/response"
"github.com/Rain-kl/Wavelet/plugins/domain/cap"
+ cachepkg "github.com/Rain-kl/Wavelet/plugins/infra/cache"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/objectstore"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
@@ -350,15 +351,15 @@ func invalidateCachesAfterConfigUpdate(ctx context.Context, key string) {
invalidateSystemConfigCaches(ctx, key)
if key == ConfigKeyStorageConfig {
- if db.Redis != nil {
- _ = db.Redis.Publish(ctx, "upload:access_cache:invalidate", "reset").Err()
+ if cachepkg.Redis != nil {
+ _ = cachepkg.Redis.Publish(ctx, "upload:access_cache:invalidate", "reset").Err()
}
objectstore.ResetCache()
objectstore.PublishCacheInvalidation(ctx)
}
if key == ConfigKeyFileAccessWhitelist {
- if db.Redis != nil {
- _ = db.Redis.Publish(ctx, "upload:access_cache:invalidate", "reset").Err()
+ if cachepkg.Redis != nil {
+ _ = cachepkg.Redis.Publish(ctx, "upload:access_cache:invalidate", "reset").Err()
}
}
diff --git a/plugins/domain/admin/handlers_db.go b/plugins/domain/admin/handlers_db.go
index 630b9dc7..089c5f8e 100644
--- a/plugins/domain/admin/handlers_db.go
+++ b/plugins/domain/admin/handlers_db.go
@@ -20,8 +20,8 @@ import (
"gorm.io/gorm"
"github.com/Rain-kl/Wavelet/pkg/config"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/response"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
const (
diff --git a/plugins/domain/admin/handlers_logs.go b/plugins/domain/admin/handlers_logs.go
index 6999cebf..68f63705 100644
--- a/plugins/domain/admin/handlers_logs.go
+++ b/plugins/domain/admin/handlers_logs.go
@@ -17,12 +17,12 @@ import (
"github.com/Rain-kl/Wavelet/pkg/config"
"github.com/Rain-kl/Wavelet/pkg/logger"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/persistence/logstore"
"github.com/Rain-kl/Wavelet/pkg/response"
- "github.com/Rain-kl/Wavelet/pkg/task"
"github.com/Rain-kl/Wavelet/pkg/util"
"github.com/Rain-kl/Wavelet/plugins/domain/risk_control"
+ "github.com/Rain-kl/Wavelet/plugins/domain/risk_control/logstore"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
)
@@ -497,16 +497,16 @@ const (
)
// LogDBSwitchMeta 描述切换日志数据库任务。
-var LogDBSwitchMeta = task.TaskMeta{
+var LogDBSwitchMeta = driver_asynq_worker.TaskMeta{
Type: TaskTypeLogDBSwitch,
AsynqTask: LogDBSwitchTask,
Name: "切换日志数据库",
Description: "复制迁移用户访问日志并在成功后切换日志主库(期间禁止日志写入)",
SupportsTime: false,
- MaxRetry: task.DefaultMaxRetry,
- Queue: task.QueueDefault,
+ MaxRetry: driver_asynq_worker.DefaultMaxRetry,
+ Queue: driver_asynq_worker.QueueDefault,
Retryable: true,
- Params: []task.TaskParam{
+ Params: []driver_asynq_worker.TaskParam{
{Name: "target", Label: "目标日志库", Type: "string", Required: true,
Placeholder: "postgres|sqlite|clickhouse", Description: "迁移目标:postgres(主库为 PG 时)、sqlite(主库为 SQLite 时)或 clickhouse"},
},
@@ -553,7 +553,7 @@ func validTarget(v string) bool {
}
// Execute 执行迁移。
-func (h *LogDBSwitchHandler) Execute(ctx context.Context, payload []byte) (*task.TaskResult, error) {
+func (h *LogDBSwitchHandler) Execute(ctx context.Context, payload []byte) (*driver_asynq_worker.TaskResult, error) {
var p logDBSwitchPayload
if err := json.Unmarshal(payload, &p); err != nil {
return nil, fmt.Errorf("参数解析失败: %w", err)
@@ -565,10 +565,10 @@ func (h *LogDBSwitchHandler) Execute(ctx context.Context, payload []byte) (*task
source, err := currentLogDatabase(ctx)
if err != nil {
- task.AppendLog(ctx, "读取日志主库失败: %v", err)
+ driver_asynq_worker.AppendLog(ctx, "读取日志主库失败: %v", err)
return nil, err
}
- task.AppendLog(ctx, "开始切换日志数据库:%s -> %s", source, p.Target)
+ driver_asynq_worker.AppendLog(ctx, "开始切换日志数据库:%s -> %s", source, p.Target)
if err := setMigrationFlag(ctx, "migrating"); err != nil {
return nil, err
@@ -612,8 +612,8 @@ func (h *LogDBSwitchHandler) Execute(ctx context.Context, payload []byte) (*task
return nil, err
}
logstore.InvalidateCache()
- task.AppendLog(ctx, "日志数据库已切换为 %s,写入恢复", p.Target)
- return &task.TaskResult{Message: fmt.Sprintf("日志数据库已从 %s 切换为 %s", source, p.Target)}, nil
+ driver_asynq_worker.AppendLog(ctx, "日志数据库已切换为 %s,写入恢复", p.Target)
+ return &driver_asynq_worker.TaskResult{Message: fmt.Sprintf("日志数据库已从 %s 切换为 %s", source, p.Target)}, nil
}
func validateSwitch(ctx context.Context, target string) error {
@@ -676,7 +676,7 @@ func copyUserAccessLogs(ctx context.Context, src, dst *logstore.Store) error {
}
afterID = rows[len(rows)-1].ID
copied += len(rows)
- task.AppendLog(ctx, "已复制用户访问日志 %d 条", copied)
+ driver_asynq_worker.AppendLog(ctx, "已复制用户访问日志 %d 条", copied)
if len(rows) < copyBatchSize {
break
}
diff --git a/plugins/domain/admin/handlers_status.go b/plugins/domain/admin/handlers_status.go
index 7af31a51..f3b459f6 100644
--- a/plugins/domain/admin/handlers_status.go
+++ b/plugins/domain/admin/handlers_status.go
@@ -18,8 +18,8 @@ import (
"github.com/Rain-kl/Wavelet/pkg/config"
"github.com/Rain-kl/Wavelet/pkg/logger"
- "github.com/Rain-kl/Wavelet/pkg/persistence/logstore"
"github.com/Rain-kl/Wavelet/pkg/response"
+ "github.com/Rain-kl/Wavelet/plugins/domain/risk_control/logstore"
)
var startTime = time.Now()
diff --git a/plugins/domain/admin/handlers_tasks.go b/plugins/domain/admin/handlers_tasks.go
index b8ef9e7c..63373e10 100644
--- a/plugins/domain/admin/handlers_tasks.go
+++ b/plugins/domain/admin/handlers_tasks.go
@@ -16,8 +16,8 @@ import (
"github.com/Rain-kl/Wavelet/pkg/logger"
"github.com/Rain-kl/Wavelet/pkg/response"
- "github.com/Rain-kl/Wavelet/pkg/task"
- "github.com/Rain-kl/Wavelet/pkg/task/scheduler"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_cron"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
)
// ListTaskTypes 获取支持的任务类型列表
@@ -26,12 +26,12 @@ import (
// @Tags admin
// @Produce json
// @Security SessionCookie
-// @Success 200 {object} response.Any{data=[]task.TaskMeta} "任务类型列表"
+// @Success 200 {object} response.Any{data=[]driver_asynq_worker.TaskMeta} "任务类型列表"
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Router /api/v1/admin/tasks/types [get]
func ListTaskTypes(c *gin.Context) {
- c.JSON(http.StatusOK, response.OK(task.GetDispatchableTasks()))
+ c.JSON(http.StatusOK, response.OK(driver_asynq_worker.GetDispatchableTasks()))
}
// DispatchTaskRequest 下发任务请求
@@ -64,7 +64,7 @@ func DispatchTask(c *gin.Context) {
return
}
- meta := task.GetTaskMeta(req.TaskType)
+ meta := driver_asynq_worker.GetTaskMeta(req.TaskType)
if meta == nil {
response.AbortBadRequest(c, InvalidTaskType)
return
@@ -75,13 +75,13 @@ func DispatchTask(c *gin.Context) {
payloadBytes = []byte(req.Payload)
}
- validated, err := task.ValidateAndNormalizePayload(meta.AsynqTask, payloadBytes)
+ validated, err := driver_asynq_worker.ValidateAndNormalizePayload(meta.AsynqTask, payloadBytes)
if err != nil {
response.AbortBadRequest(c, err.Error())
return
}
- taskID, err := task.DispatchTask(c.Request.Context(), req.TaskType, validated, "manual")
+ taskID, err := driver_asynq_worker.DispatchTask(c.Request.Context(), req.TaskType, validated, "manual")
if err != nil {
response.AbortInternal(c, fmt.Sprintf("%s: %v", TaskDispatchFailed, err))
return
@@ -112,7 +112,7 @@ func ListTaskExecutions(c *gin.Context) {
}
if req.TaskType != "" {
- if meta := task.GetTaskMeta(req.TaskType); meta != nil {
+ if meta := driver_asynq_worker.GetTaskMeta(req.TaskType); meta != nil {
req.TaskType = meta.AsynqTask
}
}
@@ -181,7 +181,7 @@ func RetryTask(c *gin.Context) {
return
}
- newTaskID, err := task.RetryTask(c.Request.Context(), id)
+ newTaskID, err := driver_asynq_worker.RetryTask(c.Request.Context(), id)
if err != nil {
errMsg := err.Error()
switch {
@@ -254,7 +254,7 @@ func CreateSchedule(c *gin.Context) {
}
// 校验关联的异步任务类型
- meta := task.GetTaskMeta(req.TaskType)
+ meta := driver_asynq_worker.GetTaskMeta(req.TaskType)
if meta == nil {
response.AbortBadRequest(c, InvalidTaskType)
return
@@ -265,7 +265,7 @@ func CreateSchedule(c *gin.Context) {
if strings.TrimSpace(req.Payload) != "" {
payloadBytes = []byte(req.Payload)
}
- validated, err := task.ValidateAndNormalizePayload(meta.AsynqTask, payloadBytes)
+ validated, err := driver_asynq_worker.ValidateAndNormalizePayload(meta.AsynqTask, payloadBytes)
if err != nil {
response.AbortBadRequest(c, err.Error())
return
@@ -285,7 +285,7 @@ func CreateSchedule(c *gin.Context) {
}
// 触发调度服务重载
- if err := scheduler.ReloadScheduler(); err != nil {
+ if err := driver_asynq_cron.ReloadScheduler(); err != nil {
logger.ErrorF(c.Request.Context(), "[TaskAdmin] 重载调度器失败: %v", err)
}
@@ -343,7 +343,7 @@ func UpdateSchedule(c *gin.Context) {
}
// 校验关联的异步任务类型
- meta := task.GetTaskMeta(req.TaskType)
+ meta := driver_asynq_worker.GetTaskMeta(req.TaskType)
if meta == nil {
response.AbortBadRequest(c, InvalidTaskType)
return
@@ -354,7 +354,7 @@ func UpdateSchedule(c *gin.Context) {
if strings.TrimSpace(req.Payload) != "" {
payloadBytes = []byte(req.Payload)
}
- validated, err := task.ValidateAndNormalizePayload(meta.AsynqTask, payloadBytes)
+ validated, err := driver_asynq_worker.ValidateAndNormalizePayload(meta.AsynqTask, payloadBytes)
if err != nil {
response.AbortBadRequest(c, err.Error())
return
@@ -372,7 +372,7 @@ func UpdateSchedule(c *gin.Context) {
}
// 触发调度服务重载
- if err := scheduler.ReloadScheduler(); err != nil {
+ if err := driver_asynq_cron.ReloadScheduler(); err != nil {
logger.ErrorF(c.Request.Context(), "[TaskAdmin] 重载调度器失败: %v", err)
}
@@ -405,7 +405,7 @@ func DeleteSchedule(c *gin.Context) {
}
// 触发调度服务重载
- if err := scheduler.ReloadScheduler(); err != nil {
+ if err := driver_asynq_cron.ReloadScheduler(); err != nil {
logger.ErrorF(c.Request.Context(), "[TaskAdmin] 重载调度器失败: %v", err)
}
diff --git a/plugins/domain/admin/handlers_user.go b/plugins/domain/admin/handlers_user.go
index 92896805..84572d6c 100644
--- a/plugins/domain/admin/handlers_user.go
+++ b/plugins/domain/admin/handlers_user.go
@@ -16,12 +16,12 @@ import (
"gorm.io/gorm"
"github.com/Rain-kl/Wavelet/core/contracts"
+ "github.com/Rain-kl/Wavelet/pkg/idgen"
"github.com/Rain-kl/Wavelet/pkg/logger"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/persistence/idgen"
"github.com/Rain-kl/Wavelet/pkg/response"
"github.com/Rain-kl/Wavelet/pkg/util"
"github.com/Rain-kl/Wavelet/plugins/domain/auth"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
const minPasswordLength = 8
diff --git a/plugins/domain/admin/repository.go b/plugins/domain/admin/repository.go
index 856e89ff..7652a0dd 100644
--- a/plugins/domain/admin/repository.go
+++ b/plugins/domain/admin/repository.go
@@ -17,9 +17,10 @@ import (
"gorm.io/gorm"
"github.com/Rain-kl/Wavelet/pkg/cache/ram"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/persistence/idgen"
+ "github.com/Rain-kl/Wavelet/pkg/idgen"
"github.com/Rain-kl/Wavelet/pkg/util"
+ cachepkg "github.com/Rain-kl/Wavelet/plugins/infra/cache"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
const (
@@ -482,7 +483,7 @@ func GetLatestTaskExecutionByTaskType(ctx context.Context, taskType string) (*Ta
// AppendTaskExecutionLog 将日志追加到 Redis 缓冲,任务完成后再持久化到数据库。
func AppendTaskExecutionLog(ctx context.Context, taskID string, logLine string) error {
- if db.Redis == nil {
+ if cachepkg.Redis == nil {
return errors.New("redis client is not initialized")
}
@@ -490,7 +491,7 @@ func AppendTaskExecutionLog(ctx context.Context, taskID string, logLine string)
line := fmt.Sprintf("[%s] %s\n", now, logLine)
key := taskExecutionLogRedisKey(taskID)
- _, err := db.Redis.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
+ _, err := cachepkg.Redis.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.RPush(ctx, key, line)
pipe.LTrim(ctx, key, -taskExecutionLogMaxLines, -1)
pipe.Expire(ctx, key, taskExecutionLogExpiration)
@@ -504,12 +505,12 @@ func AppendTaskExecutionLog(ctx context.Context, taskID string, logLine string)
// FlushTaskExecutionLog 将 Redis 中的完整任务日志写入数据库,并在成功后清理缓存。
func FlushTaskExecutionLog(ctx context.Context, taskID string) error {
- if db.Redis == nil {
+ if cachepkg.Redis == nil {
return errors.New("redis client is not initialized")
}
key := taskExecutionLogRedisKey(taskID)
- logLines, err := db.Redis.LRange(ctx, key, 0, -1).Result()
+ logLines, err := cachepkg.Redis.LRange(ctx, key, 0, -1).Result()
if err != nil {
return fmt.Errorf("get task execution log from redis: %w", err)
}
@@ -528,7 +529,7 @@ func FlushTaskExecutionLog(ctx context.Context, taskID string) error {
return fmt.Errorf("persist task execution log: task %q not found", taskID)
}
- if err := db.Redis.Del(ctx, key).Err(); err != nil {
+ if err := cachepkg.Redis.Del(ctx, key).Err(); err != nil {
return fmt.Errorf("delete persisted task execution log from redis: %w", err)
}
return nil
@@ -658,15 +659,15 @@ func CleanupTaskExecutionLogs(ctx context.Context, now time.Time) (TaskExecution
}
func taskExecutionLogRedisKey(taskID string) string {
- return db.PrefixedKey(taskExecutionLogRedisKeyPrefix + taskID)
+ return cachepkg.PrefixedKey(taskExecutionLogRedisKeyPrefix + taskID)
}
func loadTaskExecutionLog(ctx context.Context, execution *TaskExecution) error {
- if db.Redis == nil {
+ if cachepkg.Redis == nil {
return nil
}
- logLines, err := db.Redis.LRange(ctx, taskExecutionLogRedisKey(execution.TaskID), 0, -1).Result()
+ logLines, err := cachepkg.Redis.LRange(ctx, taskExecutionLogRedisKey(execution.TaskID), 0, -1).Result()
if err != nil {
return fmt.Errorf("get task execution log from redis: %w", err)
}
@@ -679,12 +680,12 @@ func loadTaskExecutionLog(ctx context.Context, execution *TaskExecution) error {
}
func loadTaskExecutionLogs(ctx context.Context, executions []TaskExecution) error {
- if db.Redis == nil || len(executions) == 0 {
+ if cachepkg.Redis == nil || len(executions) == 0 {
return nil
}
commands := make([]*redis.StringSliceCmd, len(executions))
- _, err := db.Redis.Pipelined(ctx, func(pipe redis.Pipeliner) error {
+ _, err := cachepkg.Redis.Pipelined(ctx, func(pipe redis.Pipeliner) error {
for i := range executions {
commands[i] = pipe.LRange(ctx, taskExecutionLogRedisKey(executions[i].TaskID), 0, -1)
}
diff --git a/plugins/domain/admin/system_config_cache.go b/plugins/domain/admin/system_config_cache.go
index 981f3949..6978095e 100644
--- a/plugins/domain/admin/system_config_cache.go
+++ b/plugins/domain/admin/system_config_cache.go
@@ -13,8 +13,8 @@ import (
"gorm.io/gorm"
"github.com/Rain-kl/Wavelet/pkg/cache/ram"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/util"
+ cachepkg "github.com/Rain-kl/Wavelet/plugins/infra/cache"
)
const (
@@ -104,14 +104,14 @@ func ensureSystemConfigCacheListener() {
}
func startSystemConfigCacheInvalidationListener() {
- if db.Redis == nil {
+ if cachepkg.Redis == nil {
return
}
systemConfigListenerCtx, systemConfigListenerCancel = context.WithCancel(context.Background())
systemConfigListenerDone = make(chan struct{})
- redisClient := db.Redis // 捕获当前客户端:goroutine 不读可变全局,避免与测试置空 db.Redis 竞争
+ redisClient := cachepkg.Redis // 捕获当前客户端:goroutine 不读可变全局,避免与测试置空 cachepkg.Redis 竞争
util.Go(func() {
listenerCtx := systemConfigListenerCtx
defer close(systemConfigListenerDone)
@@ -169,8 +169,8 @@ func InvalidateSystemConfigCache(ctx context.Context, key string) error {
ram.Delete(ConfigCacheType, key)
// Broadcast to other nodes and clean legacy Redis cache key
- if db.Redis != nil {
- _ = db.HDel(ctx, SystemConfigRedisHashKey, key)
+ if cachepkg.Redis != nil {
+ _ = cachepkg.HDel(ctx, SystemConfigRedisHashKey, key)
publishSystemConfigBroadcast(ctx, ConfigCacheType, key)
}
return nil
@@ -184,22 +184,22 @@ func InvalidateAllSystemConfigCaches(ctx context.Context) error {
ram.UpdateTypeItems(ConfigCacheType, nil)
// Broadcast to other nodes and clean legacy Redis cache keys
- if db.Redis != nil {
- _ = db.Redis.Del(ctx, db.PrefixedKey(SystemConfigRedisHashKey), db.PrefixedKey(SystemConfigVisibleListRedisKey)).Err()
+ if cachepkg.Redis != nil {
+ _ = cachepkg.Redis.Del(ctx, cachepkg.PrefixedKey(SystemConfigRedisHashKey), cachepkg.PrefixedKey(SystemConfigVisibleListRedisKey)).Err()
publishSystemConfigBroadcast(ctx, ConfigCacheType, "*")
}
return nil
}
func publishSystemConfigBroadcast(ctx context.Context, configType string, key string) {
- if db.Redis == nil {
+ if cachepkg.Redis == nil {
return
}
payload, err := json.Marshal(systemConfigBroadcastMessage{Type: configType, Key: key})
if err != nil {
return
}
- _ = db.Redis.Publish(ctx, SystemConfigBroadcastChannel, payload).Err()
+ _ = cachepkg.Redis.Publish(ctx, SystemConfigBroadcastChannel, payload).Err()
}
// ResetSystemConfigRAMCacheForTest clears only the process-local RAM cache.
diff --git a/plugins/domain/admin/system_config_test.go b/plugins/domain/admin/system_config_test.go
index 6beadce7..95acb2a3 100644
--- a/plugins/domain/admin/system_config_test.go
+++ b/plugins/domain/admin/system_config_test.go
@@ -14,7 +14,8 @@ import (
"github.com/redis/go-redis/v9/maintnotifications"
"gorm.io/gorm"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ "github.com/Rain-kl/Wavelet/plugins/infra/cache"
+ "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
func setupSystemConfigTest(t *testing.T) (*gorm.DB, func()) {
@@ -51,15 +52,15 @@ func setupSystemConfigTest(t *testing.T) (*gorm.DB, func()) {
},
})
- previousRedis := db.Redis
- db.SetDB(sqliteDB)
- db.Redis = redisClient
+ previousRedis := cache.Redis
+ database.SetDB(sqliteDB)
+ cache.Redis = redisClient
cleanup := func() {
StopSystemConfigCacheListener()
ResetSystemConfigRAMCacheForTest()
- db.SetDB(nil)
- db.Redis = previousRedis
+ database.SetDB(nil)
+ cache.Redis = previousRedis
_ = redisClient.Close()
mr.Close()
}
diff --git a/plugins/domain/auth/auth_source_resolver.go b/plugins/domain/auth/auth_source_resolver.go
index 9a4fcd17..a7ce5c91 100644
--- a/plugins/domain/auth/auth_source_resolver.go
+++ b/plugins/domain/auth/auth_source_resolver.go
@@ -11,8 +11,7 @@ import (
"strings"
"github.com/Rain-kl/Wavelet/core/contracts"
-
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/coreos/go-oidc/v3/oidc"
"golang.org/x/oauth2"
diff --git a/plugins/domain/auth/cache.go b/plugins/domain/auth/cache.go
index f6736d11..76db1efe 100644
--- a/plugins/domain/auth/cache.go
+++ b/plugins/domain/auth/cache.go
@@ -12,8 +12,8 @@ import (
"github.com/Rain-kl/Wavelet/core/contracts"
"github.com/Rain-kl/Wavelet/pkg/cache/ram"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/util"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/cache"
)
const (
diff --git a/plugins/domain/auth/cache_test.go b/plugins/domain/auth/cache_test.go
index e4d67127..38472e9a 100644
--- a/plugins/domain/auth/cache_test.go
+++ b/plugins/domain/auth/cache_test.go
@@ -12,8 +12,8 @@ import (
"github.com/redis/go-redis/v9/maintnotifications"
"github.com/Rain-kl/Wavelet/core/contracts"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/plugins/domain/auth"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/cache"
)
func setupOauthCacheTest(t *testing.T) (*miniredis.Miniredis, func()) {
diff --git a/plugins/domain/auth/errs.go b/plugins/domain/auth/errs.go
index efcf33ba..5f17d4cc 100644
--- a/plugins/domain/auth/errs.go
+++ b/plugins/domain/auth/errs.go
@@ -34,4 +34,6 @@ const (
errAdminRequired = "无权访问"
//nolint:gosec // error message, not hardcoded credentials
errTokenAdminRequired = "令牌无管理员权限"
+ errBannedAccount = "账号已被封禁"
+ errUnAuthorized = "未登录"
)
diff --git a/plugins/domain/auth/handlers.go b/plugins/domain/auth/handlers.go
index 8678ab00..48518741 100644
--- a/plugins/domain/auth/handlers.go
+++ b/plugins/domain/auth/handlers.go
@@ -15,14 +15,12 @@ import (
"github.com/Rain-kl/Wavelet/core/contracts"
+ "github.com/Rain-kl/Wavelet/pkg/idgen"
"github.com/Rain-kl/Wavelet/pkg/logger"
-
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/persistence/idgen"
-
"github.com/Rain-kl/Wavelet/pkg/response"
- "github.com/Rain-kl/Wavelet/pkg/shared"
"github.com/Rain-kl/Wavelet/pkg/util"
+ cachepkg "github.com/Rain-kl/Wavelet/plugins/infra/cache"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
@@ -81,7 +79,7 @@ func GetLoginURL(c *gin.Context) {
response.AbortInternal(c, err.Error())
return
}
- if err := db.Redis.Set(ctx, db.PrefixedKey(fmt.Sprintf(OAuthStateCacheKeyFormat, state)), payloadValue, OAuthStateCacheKeyExpiration).Err(); err != nil {
+ if err := cachepkg.Redis.Set(ctx, cachepkg.PrefixedKey(fmt.Sprintf(OAuthStateCacheKeyFormat, state)), payloadValue, OAuthStateCacheKeyExpiration).Err(); err != nil {
response.AbortInternal(c, err.Error())
return
}
@@ -110,16 +108,16 @@ func buildAuthorizeURL(ctx context.Context, source *AuthSource, state string) (s
}
func reserveOAuthStateSlot(ctx context.Context, sessionHash string) error {
- if db.Redis == nil || sessionHash == "" {
+ if cachepkg.Redis == nil || sessionHash == "" {
return nil
}
- key := db.PrefixedKey(fmt.Sprintf(oauthStateLimitKeyFormat, sessionHash))
- n, err := db.Redis.Incr(ctx, key).Result()
+ key := cachepkg.PrefixedKey(fmt.Sprintf(oauthStateLimitKeyFormat, sessionHash))
+ n, err := cachepkg.Redis.Incr(ctx, key).Result()
if err != nil {
return err
}
if n == 1 {
- _ = db.Redis.Expire(ctx, key, OAuthStateCacheKeyExpiration).Err()
+ _ = cachepkg.Redis.Expire(ctx, key, OAuthStateCacheKeyExpiration).Err()
}
if n > oauthStateLimitMax {
return errors.New(errOAuthStateRateLimited)
@@ -153,7 +151,7 @@ func Authorize(c *gin.Context) {
session := sessions.Default(c)
userID := GetUserIDFromSession(session)
if purpose == OAuthPurposeBind && userID == 0 {
- response.AbortUnauthorized(c, shared.UnAuthorized)
+ response.AbortUnauthorized(c, errUnAuthorized)
return
}
@@ -182,7 +180,7 @@ func Authorize(c *gin.Context) {
response.AbortInternal(c, err.Error())
return
}
- if err := db.Redis.Set(ctx, db.PrefixedKey(fmt.Sprintf(OAuthStateCacheKeyFormat, state)), payloadValue, OAuthStateCacheKeyExpiration).Err(); err != nil {
+ if err := cachepkg.Redis.Set(ctx, cachepkg.PrefixedKey(fmt.Sprintf(OAuthStateCacheKeyFormat, state)), payloadValue, OAuthStateCacheKeyExpiration).Err(); err != nil {
response.AbortInternal(c, err.Error())
return
}
@@ -204,13 +202,13 @@ func Callback(c *gin.Context) {
}
ctx := c.Request.Context()
- stateKey := db.PrefixedKey(fmt.Sprintf(OAuthStateCacheKeyFormat, req.State))
- payloadRaw, err := db.Redis.Get(ctx, stateKey).Result()
+ stateKey := cachepkg.PrefixedKey(fmt.Sprintf(OAuthStateCacheKeyFormat, req.State))
+ payloadRaw, err := cachepkg.Redis.Get(ctx, stateKey).Result()
if err != nil {
response.AbortBadRequest(c, errInvalidState)
return
}
- _ = db.Redis.Del(ctx, stateKey)
+ _ = cachepkg.Redis.Del(ctx, stateKey)
payload, err := decodeOAuthStatePayload(payloadRaw)
if err != nil {
@@ -222,7 +220,7 @@ func Callback(c *gin.Context) {
currentUserID := GetUserIDFromSession(session)
if payload.Purpose == OAuthPurposeBind && currentUserID == 0 {
- response.AbortUnauthorized(c, shared.UnAuthorized)
+ response.AbortUnauthorized(c, errUnAuthorized)
return
}
@@ -288,7 +286,7 @@ func Callback(c *gin.Context) {
func handleCallbackBind(ctx context.Context, c *gin.Context, source *AuthSource, userInfo *contracts.OAuthUserInfoDTO) {
userID := GetUserIDFromContext(c)
if userID == 0 {
- response.AbortUnauthorized(c, shared.UnAuthorized)
+ response.AbortUnauthorized(c, errUnAuthorized)
return
}
var user contracts.UserDTO
@@ -477,7 +475,7 @@ func ListExternalAccounts(c *gin.Context) {
func DeleteExternalAccount(c *gin.Context) {
userID := GetUserIDFromContext(c)
if userID == 0 {
- response.AbortUnauthorized(c, shared.UnAuthorized)
+ response.AbortUnauthorized(c, errUnAuthorized)
return
}
rawID := strings.TrimSpace(c.Param("id"))
diff --git a/plugins/domain/auth/middleware.go b/plugins/domain/auth/middleware.go
index 184da390..19f1cfaa 100644
--- a/plugins/domain/auth/middleware.go
+++ b/plugins/domain/auth/middleware.go
@@ -11,10 +11,9 @@ import (
"errors"
"github.com/Rain-kl/Wavelet/core/contracts"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/response"
- "github.com/Rain-kl/Wavelet/pkg/shared"
otel_trace "github.com/Rain-kl/Wavelet/pkg/trace"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/gin-gonic/gin"
)
@@ -132,7 +131,7 @@ func LoginRequired() gin.HandlerFunc {
user, err := GetUserFromRequest(c)
if err != nil {
- response.AbortUnauthorized(c, shared.UnAuthorized)
+ response.AbortUnauthorized(c, errUnAuthorized)
return
}
@@ -150,7 +149,7 @@ func AdminRequired() gin.HandlerFunc {
user, err := GetUserFromRequest(c)
if err != nil {
- response.AbortUnauthorized(c, shared.UnAuthorized)
+ response.AbortUnauthorized(c, errUnAuthorized)
return
}
diff --git a/plugins/domain/auth/plugin_test.go b/plugins/domain/auth/plugin_test.go
index 7f38d9aa..92e5bd8e 100644
--- a/plugins/domain/auth/plugin_test.go
+++ b/plugins/domain/auth/plugin_test.go
@@ -18,8 +18,8 @@ import (
"github.com/Rain-kl/Wavelet/core"
"github.com/Rain-kl/Wavelet/core/contracts"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/plugins/domain/auth"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
type testUser struct {
diff --git a/plugins/domain/auth/repository.go b/plugins/domain/auth/repository.go
index 74bdd224..df8ebafd 100644
--- a/plugins/domain/auth/repository.go
+++ b/plugins/domain/auth/repository.go
@@ -7,7 +7,7 @@ package auth
import (
"context"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
// GetAuthSourceByID 根据 ID 获取认证源
diff --git a/plugins/domain/auth/service.go b/plugins/domain/auth/service.go
index 22e7a877..6aab5cf0 100644
--- a/plugins/domain/auth/service.go
+++ b/plugins/domain/auth/service.go
@@ -9,7 +9,7 @@ import (
"sync"
"github.com/Rain-kl/Wavelet/core/contracts"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/gin-gonic/gin"
)
diff --git a/plugins/domain/auth/session.go b/plugins/domain/auth/session.go
index f575ae07..c1a18051 100644
--- a/plugins/domain/auth/session.go
+++ b/plugins/domain/auth/session.go
@@ -13,7 +13,7 @@ import (
"github.com/Rain-kl/Wavelet/core/contracts"
"github.com/Rain-kl/Wavelet/pkg/config"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
diff --git a/plugins/domain/cap/handlers.go b/plugins/domain/cap/handlers.go
index 63aca708..12f921e9 100644
--- a/plugins/domain/cap/handlers.go
+++ b/plugins/domain/cap/handlers.go
@@ -6,14 +6,14 @@ package cap
import (
"net/http"
- pkgcap "github.com/Rain-kl/Wavelet/pkg/cap"
"github.com/Rain-kl/Wavelet/pkg/logger"
"github.com/Rain-kl/Wavelet/pkg/response"
+ "github.com/Rain-kl/Wavelet/plugins/domain/cap/pow"
"github.com/gin-gonic/gin"
)
-// ChallengeResponse is a local type alias for the pkg/cap.ChallengeResponse struct
-type ChallengeResponse = pkgcap.ChallengeResponse
+// ChallengeResponse is a local type alias for the pow.ChallengeResponse struct
+type ChallengeResponse = pow.ChallengeResponse
type challengeRequest struct {
Scope string `json:"scope" form:"scope"`
diff --git a/plugins/domain/cap/manager.go b/plugins/domain/cap/manager.go
index 1d843744..fe0ff173 100644
--- a/plugins/domain/cap/manager.go
+++ b/plugins/domain/cap/manager.go
@@ -13,9 +13,9 @@ import (
"sync"
"time"
- pkgcap "github.com/Rain-kl/Wavelet/pkg/cap"
"github.com/Rain-kl/Wavelet/pkg/config"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/cache"
+ "github.com/Rain-kl/Wavelet/plugins/domain/cap/pow"
)
const (
@@ -28,11 +28,11 @@ const (
// Manager orchestrates challenge generation and solution validation.
type Manager struct {
secret []byte
- store pkgcap.Store
+ store pow.Store
}
// NewManager creates a new CAPTCHA Manager.
-func NewManager(secret []byte, store pkgcap.Store) *Manager {
+func NewManager(secret []byte, store pow.Store) *Manager {
return &Manager{
secret: secret,
store: store,
@@ -40,19 +40,19 @@ func NewManager(secret []byte, store pkgcap.Store) *Manager {
}
// Generate creates a challenge response.
-func (m *Manager) Generate(ctx context.Context, scope string) (*pkgcap.ChallengeResponse, error) {
+func (m *Manager) Generate(ctx context.Context, scope string) (*pow.ChallengeResponse, error) {
settings, err := CurrentSettings(ctx)
if err != nil {
return nil, err
}
- challengeConfig := pkgcap.ChallengeConfig{
+ challengeConfig := pow.ChallengeConfig{
Count: settings.ChallengeCount,
Size: settings.ChallengeSize,
Difficulty: settings.ChallengeDifficulty,
Expires: settings.ChallengeTTL,
}
- return pkgcap.GenerateChallenge(m.secret, challengeConfig, scope)
+ return pow.GenerateChallenge(m.secret, challengeConfig, scope)
}
// RedeemResponse is returned to the client on redeem.
@@ -65,14 +65,14 @@ type RedeemResponse struct {
// Redeem verifies PoW solutions and returns a one-time redeem token.
func (m *Manager) Redeem(ctx context.Context, token string, solutions []int, scope string) (*RedeemResponse, error) {
- sigHex := pkgcap.JwtSigHex(token)
+ sigHex := pow.JwtSigHex(token)
if sigHex == "" {
return &RedeemResponse{Success: false, Error: "invalid_token"}, nil
}
nonceKey := "cap:nonce:" + sigHex
- payload, err := pkgcap.VerifyChallengeSolutions(token, solutions, m.secret, scope)
+ payload, err := pow.VerifyChallengeSolutions(token, solutions, m.secret, scope)
if err != nil {
return &RedeemResponse{Success: false, Error: err.Error()}, nil //nolint:nilerr // validation errors are returned as response, not system errors
}
@@ -96,8 +96,8 @@ func (m *Manager) Redeem(ctx context.Context, token string, solutions []int, sco
return &RedeemResponse{Success: false, Error: "settings_load_error"}, err
}
- id := pkgcap.RandomHex(redeemTokenIDLength)
- verToken := pkgcap.RandomHex(redeemVerTokenLength)
+ id := pow.RandomHex(redeemTokenIDLength)
+ verToken := pow.RandomHex(redeemVerTokenLength)
verHashBytes := sha256.Sum256([]byte(verToken))
verHashHex := hex.EncodeToString(verHashBytes[:])
@@ -163,7 +163,7 @@ func (m *Manager) VerifyToken(ctx context.Context, token string, expectedScope s
return true, nil
}
-func sGetAndDelete(ctx context.Context, store pkgcap.Store, key string) (string, bool, error) {
+func sGetAndDelete(ctx context.Context, store pow.Store, key string) (string, bool, error) {
if store == nil {
return "", false, nil
}
@@ -186,11 +186,11 @@ func GetDefaultManager() *Manager {
return
}
- var store pkgcap.Store
+ var store pow.Store
if config.Config != nil && config.Config.Redis.Enabled && db.Redis != nil {
- store = pkgcap.NewRedisStore(db.Redis)
+ store = pow.NewRedisStore(db.Redis)
} else {
- store = pkgcap.NewMemoryStore(1 * time.Minute)
+ store = pow.NewMemoryStore(1 * time.Minute)
}
defaultManager = NewManager(secret, store)
diff --git a/pkg/cap/cap.go b/plugins/domain/cap/pow/cap.go
similarity index 98%
rename from pkg/cap/cap.go
rename to plugins/domain/cap/pow/cap.go
index 0d3727f0..1d45d066 100644
--- a/pkg/cap/cap.go
+++ b/plugins/domain/cap/pow/cap.go
@@ -1,8 +1,8 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-// Package cap 提供人机验证(CAPTCHA)功能
-package cap
+// Package pow provides proof-of-work challenge generation and verification.
+package pow
import (
"crypto/hmac"
diff --git a/pkg/cap/errs.go b/plugins/domain/cap/pow/errs.go
similarity index 97%
rename from pkg/cap/errs.go
rename to plugins/domain/cap/pow/errs.go
index 9a3b85d2..3433e42b 100644
--- a/pkg/cap/errs.go
+++ b/plugins/domain/cap/pow/errs.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package cap
+package pow
const (
errInvalidTokenFormat = "invalid token format"
diff --git a/plugins/domain/cap/pow/pow_test.go b/plugins/domain/cap/pow/pow_test.go
new file mode 100644
index 00000000..1277c12b
--- /dev/null
+++ b/plugins/domain/cap/pow/pow_test.go
@@ -0,0 +1,111 @@
+// Copyright 2026 Arctel.net
+// SPDX-License-Identifier: Apache-2.0
+
+package pow
+
+import (
+ "context"
+ "testing"
+ "time"
+)
+
+func TestPowChallengeFlow(t *testing.T) {
+ secret := []byte("test-secret-key-1234567890123456")
+ conf := ChallengeConfig{
+ Count: 2,
+ Size: 16,
+ Difficulty: 1,
+ Expires: 1 * time.Minute,
+ }
+ scope := "login"
+
+ resp, err := GenerateChallenge(secret, conf, scope)
+ if err != nil {
+ t.Fatalf("GenerateChallenge failed: %v", err)
+ }
+ if resp.Token == "" {
+ t.Fatal("expected non-empty token")
+ }
+ if resp.Challenge.C != 2 {
+ t.Fatalf("expected count 2, got %d", resp.Challenge.C)
+ }
+
+ sigHex := JwtSigHex(resp.Token)
+ if sigHex == "" {
+ t.Fatal("expected non-empty sigHex")
+ }
+
+ solutions := Solve(resp.Token, resp.Challenge.C, resp.Challenge.S, resp.Challenge.D)
+ if len(solutions) != 2 {
+ t.Fatalf("expected 2 solutions, got %d", len(solutions))
+ }
+
+ payload, err := VerifyChallengeSolutions(resp.Token, solutions, secret, scope)
+ if err != nil {
+ t.Fatalf("VerifyChallengeSolutions failed: %v", err)
+ }
+ if payload.Scope != scope {
+ t.Fatalf("expected scope %s, got %s", scope, payload.Scope)
+ }
+
+ // Scope mismatch test
+ _, err = VerifyChallengeSolutions(resp.Token, solutions, secret, "other_scope")
+ if err == nil {
+ t.Fatal("expected scope mismatch error")
+ }
+
+ // Invalid solutions test
+ _, err = VerifyChallengeSolutions(resp.Token, []int{9999999, 9999999}, secret, scope)
+ if err == nil {
+ t.Fatal("expected invalid solution error")
+ }
+
+ // Invalid token test
+ _, err = VerifyChallengeSolutions("invalid.jwt.token", solutions, secret, scope)
+ if err == nil {
+ t.Fatal("expected invalid token error")
+ }
+}
+
+func TestMemoryStore(t *testing.T) {
+ ctx := context.Background()
+ store := NewMemoryStore(100 * time.Millisecond)
+
+ // Set and Get
+ err := store.Set(ctx, "k1", "v1", 200*time.Millisecond)
+ if err != nil {
+ t.Fatalf("Set failed: %v", err)
+ }
+ val, ok, err := store.Get(ctx, "k1")
+ if err != nil || !ok || val != "v1" {
+ t.Fatalf("Get failed: val=%s, ok=%v, err=%v", val, ok, err)
+ }
+
+ // SetNX
+ set, err := store.SetNX(ctx, "k1", "v2", 200*time.Millisecond)
+ if err != nil || set {
+ t.Fatalf("SetNX should have failed because key exists: set=%v, err=%v", set, err)
+ }
+
+ set, err = store.SetNX(ctx, "k2", "v2", 200*time.Millisecond)
+ if err != nil || !set {
+ t.Fatalf("SetNX should have succeeded: set=%v, err=%v", set, err)
+ }
+
+ // GetAndDelete
+ val, ok, err = store.GetAndDelete(ctx, "k2")
+ if err != nil || !ok || val != "v2" {
+ t.Fatalf("GetAndDelete failed: val=%s, ok=%v, err=%v", val, ok, err)
+ }
+ _, ok, _ = store.Get(ctx, "k2")
+ if ok {
+ t.Fatal("k2 should be deleted")
+ }
+
+ // Delete
+ _ = store.Delete(ctx, "k1")
+ _, ok, _ = store.Get(ctx, "k1")
+ if ok {
+ t.Fatal("k1 should be deleted")
+ }
+}
diff --git a/pkg/cap/prng.go b/plugins/domain/cap/pow/prng.go
similarity index 85%
rename from pkg/cap/prng.go
rename to plugins/domain/cap/pow/prng.go
index 46df81dc..e6ebf263 100644
--- a/pkg/cap/prng.go
+++ b/plugins/domain/cap/pow/prng.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package cap
+package pow
import (
"fmt"
@@ -27,11 +27,18 @@ func fnv1aResume(state uint32, str string) uint32 {
h := state
for i := 0; i < len(str); i++ {
h ^= uint32(str[i])
- h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24)
+ h += (hashShift(h))
}
return h
}
+// hashShift computes FNV-1a mix additions
+//
+//nolint:mnd
+func hashShift(h uint32) uint32 {
+ return (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24)
+}
+
// prngFromHash generates a hex string of specified length using an initial hash state
//
//nolint:mnd // xorshift 算法位移常量
diff --git a/pkg/cap/store.go b/plugins/domain/cap/pow/store.go
similarity index 99%
rename from pkg/cap/store.go
rename to plugins/domain/cap/pow/store.go
index 4e7b61f0..4a4de699 100644
--- a/pkg/cap/store.go
+++ b/plugins/domain/cap/pow/store.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package cap
+package pow
import (
"context"
diff --git a/plugins/domain/cap/runtime_settings.go b/plugins/domain/cap/runtime_settings.go
index a594d2f4..869e52bb 100644
--- a/plugins/domain/cap/runtime_settings.go
+++ b/plugins/domain/cap/runtime_settings.go
@@ -14,9 +14,9 @@ import (
"golang.org/x/sync/singleflight"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
-
"github.com/Rain-kl/Wavelet/pkg/util"
+ cachepkg "github.com/Rain-kl/Wavelet/plugins/infra/cache"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
const (
@@ -148,7 +148,7 @@ func loadRuntimeSettings(ctx context.Context) (RuntimeSettings, error) {
Value string `gorm:"column:value"`
}
var records []configRecord
- if err := db.DB(ctx).Table("w_system_configs").Where("key IN ?", runtimeConfigKeys).Find(&records).Error; err != nil {
+ if err := database.DB(ctx).Table("w_system_configs").Where("key IN ?", runtimeConfigKeys).Find(&records).Error; err != nil {
return RuntimeSettings{}, err
}
configs := make(map[string]string, len(records))
@@ -209,7 +209,7 @@ func (s *runtimeSettingsStore) ensureInvalidationListener() {
const SystemConfigInvalidationChannel = "system_config:invalidation"
func startRuntimeSettingsInvalidationListener() {
- rdb := db.Redis
+ rdb := cachepkg.Redis
if rdb == nil {
return
}
diff --git a/plugins/domain/domain_test.go b/plugins/domain/domain_test.go
index 11ca8b7a..3473a50a 100644
--- a/plugins/domain/domain_test.go
+++ b/plugins/domain/domain_test.go
@@ -18,15 +18,13 @@ import (
"github.com/Rain-kl/Wavelet/core"
"github.com/Rain-kl/Wavelet/core/contracts"
-
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/plugins/domain/admin"
"github.com/Rain-kl/Wavelet/plugins/domain/auth"
"github.com/Rain-kl/Wavelet/plugins/domain/message_gateway"
"github.com/Rain-kl/Wavelet/plugins/domain/risk_control"
"github.com/Rain-kl/Wavelet/plugins/domain/user"
"github.com/Rain-kl/Wavelet/plugins/infra/cache"
- "github.com/Rain-kl/Wavelet/plugins/infra/database"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/plugins/infra/logger"
"github.com/Rain-kl/Wavelet/plugins/infra/storage"
)
@@ -80,7 +78,7 @@ func TestAuthPlugin(t *testing.T) {
ctx := core.NewContext(context.Background())
testDB := setupTestDB(t)
- require.NoError(t, database.New(database.WithDB(testDB)).Apply(ctx))
+ require.NoError(t, db.New(db.WithDB(testDB)).Apply(ctx))
require.NoError(t, cache.New().Apply(ctx))
require.NoError(t, logger.New().Apply(ctx))
@@ -144,7 +142,7 @@ func TestUserPlugin(t *testing.T) {
ctx := core.NewContext(context.Background())
testDB := setupTestDB(t)
- require.NoError(t, database.New(database.WithDB(testDB)).Apply(ctx))
+ require.NoError(t, db.New(db.WithDB(testDB)).Apply(ctx))
require.NoError(t, cache.New().Apply(ctx))
require.NoError(t, logger.New().Apply(ctx))
@@ -250,7 +248,7 @@ func TestMessageGatewayPlugin(t *testing.T) {
ctx := core.NewContext(context.Background())
testDB := setupTestDB(t)
- require.NoError(t, database.New(database.WithDB(testDB)).Apply(ctx))
+ require.NoError(t, db.New(db.WithDB(testDB)).Apply(ctx))
require.NoError(t, cache.New().Apply(ctx))
require.NoError(t, logger.New().Apply(ctx))
@@ -338,7 +336,7 @@ func TestAdminPlugin(t *testing.T) {
ctx := core.NewContext(context.Background())
testDB := setupTestDB(t)
- require.NoError(t, database.New(database.WithDB(testDB)).Apply(ctx))
+ require.NoError(t, db.New(db.WithDB(testDB)).Apply(ctx))
require.NoError(t, cache.New().Apply(ctx))
require.NoError(t, logger.New().Apply(ctx))
@@ -398,7 +396,7 @@ func TestAllDomainPluginsCombined(t *testing.T) {
testDB := setupTestDB(t)
// Apply Infra plugins
- require.NoError(t, database.New(database.WithDB(testDB)).Apply(ctx))
+ require.NoError(t, db.New(db.WithDB(testDB)).Apply(ctx))
require.NoError(t, cache.New(cache.WithRedis(rdb)).Apply(ctx))
require.NoError(t, logger.New().Apply(ctx))
require.NoError(t, storage.New().Apply(ctx))
diff --git a/pkg/message_gateway/channel.go b/plugins/domain/message_gateway/channel.go
similarity index 100%
rename from pkg/message_gateway/channel.go
rename to plugins/domain/message_gateway/channel.go
diff --git a/pkg/message_gateway/channel/qq/adapter.go b/plugins/domain/message_gateway/channels/qq/adapter.go
similarity index 98%
rename from pkg/message_gateway/channel/qq/adapter.go
rename to plugins/domain/message_gateway/channels/qq/adapter.go
index a8591b1d..f84947b8 100644
--- a/pkg/message_gateway/channel/qq/adapter.go
+++ b/plugins/domain/message_gateway/channels/qq/adapter.go
@@ -12,7 +12,7 @@ import (
"time"
"github.com/Rain-kl/Wavelet/pkg/logger"
- "github.com/Rain-kl/Wavelet/pkg/message_gateway"
+ "github.com/Rain-kl/Wavelet/plugins/domain/message_gateway"
"github.com/tencent-connect/botgo"
"github.com/tencent-connect/botgo/dto"
"github.com/tencent-connect/botgo/event"
diff --git a/pkg/message_gateway/channel/qq/adapter_test.go b/plugins/domain/message_gateway/channels/qq/adapter_test.go
similarity index 94%
rename from pkg/message_gateway/channel/qq/adapter_test.go
rename to plugins/domain/message_gateway/channels/qq/adapter_test.go
index 55c5b994..68bbecd9 100644
--- a/pkg/message_gateway/channel/qq/adapter_test.go
+++ b/plugins/domain/message_gateway/channels/qq/adapter_test.go
@@ -7,7 +7,7 @@ import (
"context"
"testing"
- "github.com/Rain-kl/Wavelet/pkg/message_gateway"
+ "github.com/Rain-kl/Wavelet/plugins/domain/message_gateway"
)
func TestHandleEvent_DropsNonC2C(t *testing.T) {
diff --git a/pkg/message_gateway/channel/telegram/adapter.go b/plugins/domain/message_gateway/channels/telegram/adapter.go
similarity index 98%
rename from pkg/message_gateway/channel/telegram/adapter.go
rename to plugins/domain/message_gateway/channels/telegram/adapter.go
index d15bae89..3d2359b2 100644
--- a/pkg/message_gateway/channel/telegram/adapter.go
+++ b/plugins/domain/message_gateway/channels/telegram/adapter.go
@@ -12,7 +12,7 @@ import (
"strconv"
"strings"
- "github.com/Rain-kl/Wavelet/pkg/message_gateway"
+ "github.com/Rain-kl/Wavelet/plugins/domain/message_gateway"
tele "gopkg.in/telebot.v4"
)
diff --git a/pkg/message_gateway/channel/telegram/adapter_test.go b/plugins/domain/message_gateway/channels/telegram/adapter_test.go
similarity index 95%
rename from pkg/message_gateway/channel/telegram/adapter_test.go
rename to plugins/domain/message_gateway/channels/telegram/adapter_test.go
index 135874e8..f0d67039 100644
--- a/pkg/message_gateway/channel/telegram/adapter_test.go
+++ b/plugins/domain/message_gateway/channels/telegram/adapter_test.go
@@ -7,7 +7,7 @@ import (
"context"
"testing"
- "github.com/Rain-kl/Wavelet/pkg/message_gateway"
+ "github.com/Rain-kl/Wavelet/plugins/domain/message_gateway"
tele "gopkg.in/telebot.v4"
)
diff --git a/pkg/message_gateway/types.go b/plugins/domain/message_gateway/gateway_types.go
similarity index 100%
rename from pkg/message_gateway/types.go
rename to plugins/domain/message_gateway/gateway_types.go
diff --git a/plugins/domain/message_gateway/logics.go b/plugins/domain/message_gateway/logics.go
index 57b1c36c..b70a7283 100644
--- a/plugins/domain/message_gateway/logics.go
+++ b/plugins/domain/message_gateway/logics.go
@@ -10,8 +10,6 @@ import (
"strings"
"time"
- pkgmg "github.com/Rain-kl/Wavelet/pkg/message_gateway"
-
"gorm.io/gorm"
)
@@ -37,7 +35,7 @@ func bindChannel(ctx context.Context, userID uint64, req BindRequest) (BindingDT
if err != nil || channelID == 0 {
return BindingDTO{}, errChannelIDRequired
}
- code := pkgmg.NormalizeCode(req.Code)
+ code := NormalizeCode(req.Code)
if code == "" {
return BindingDTO{}, errCodeInvalid
}
diff --git a/pkg/message_gateway/pairing.go b/plugins/domain/message_gateway/pairing.go
similarity index 100%
rename from pkg/message_gateway/pairing.go
rename to plugins/domain/message_gateway/pairing.go
diff --git a/pkg/message_gateway/pairing_test.go b/plugins/domain/message_gateway/pairing_test.go
similarity index 100%
rename from pkg/message_gateway/pairing_test.go
rename to plugins/domain/message_gateway/pairing_test.go
diff --git a/pkg/push/custom.go b/plugins/domain/message_gateway/push/custom.go
similarity index 100%
rename from pkg/push/custom.go
rename to plugins/domain/message_gateway/push/custom.go
diff --git a/pkg/push/custom_test.go b/plugins/domain/message_gateway/push/custom_test.go
similarity index 100%
rename from pkg/push/custom_test.go
rename to plugins/domain/message_gateway/push/custom_test.go
diff --git a/pkg/push/email.go b/plugins/domain/message_gateway/push/email.go
similarity index 100%
rename from pkg/push/email.go
rename to plugins/domain/message_gateway/push/email.go
diff --git a/pkg/push/email_test.go b/plugins/domain/message_gateway/push/email_test.go
similarity index 100%
rename from pkg/push/email_test.go
rename to plugins/domain/message_gateway/push/email_test.go
diff --git a/pkg/push/lark.go b/plugins/domain/message_gateway/push/lark.go
similarity index 100%
rename from pkg/push/lark.go
rename to plugins/domain/message_gateway/push/lark.go
diff --git a/pkg/push/push.go b/plugins/domain/message_gateway/push/push.go
similarity index 100%
rename from pkg/push/push.go
rename to plugins/domain/message_gateway/push/push.go
diff --git a/pkg/push/telegram.go b/plugins/domain/message_gateway/push/telegram.go
similarity index 100%
rename from pkg/push/telegram.go
rename to plugins/domain/message_gateway/push/telegram.go
diff --git a/pkg/push/telegram_test.go b/plugins/domain/message_gateway/push/telegram_test.go
similarity index 100%
rename from pkg/push/telegram_test.go
rename to plugins/domain/message_gateway/push/telegram_test.go
diff --git a/pkg/push/template.go b/plugins/domain/message_gateway/push/template.go
similarity index 100%
rename from pkg/push/template.go
rename to plugins/domain/message_gateway/push/template.go
diff --git a/pkg/push/template_test.go b/plugins/domain/message_gateway/push/template_test.go
similarity index 100%
rename from pkg/push/template_test.go
rename to plugins/domain/message_gateway/push/template_test.go
diff --git a/plugins/domain/message_gateway/push_channels.go b/plugins/domain/message_gateway/push_channels.go
index 1cc405ee..0509ec3b 100644
--- a/plugins/domain/message_gateway/push_channels.go
+++ b/plugins/domain/message_gateway/push_channels.go
@@ -11,8 +11,8 @@ import (
"strings"
"sync"
- pkgpush "github.com/Rain-kl/Wavelet/pkg/push"
"github.com/Rain-kl/Wavelet/pkg/response"
+ pkgpush "github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/push"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
diff --git a/plugins/domain/message_gateway/push_events.go b/plugins/domain/message_gateway/push_events.go
index 3162f148..6ddec299 100644
--- a/plugins/domain/message_gateway/push_events.go
+++ b/plugins/domain/message_gateway/push_events.go
@@ -11,7 +11,7 @@ import (
"github.com/Rain-kl/Wavelet/pkg/logger"
- pkgpush "github.com/Rain-kl/Wavelet/pkg/push"
+ pkgpush "github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/push"
"github.com/Rain-kl/Wavelet/pkg/util"
"gorm.io/gorm"
diff --git a/plugins/domain/message_gateway/push_handlers.go b/plugins/domain/message_gateway/push_handlers.go
index 5a53d96d..5dd14831 100644
--- a/plugins/domain/message_gateway/push_handlers.go
+++ b/plugins/domain/message_gateway/push_handlers.go
@@ -9,7 +9,7 @@ import (
"net/http"
"strconv"
- pkgpush "github.com/Rain-kl/Wavelet/pkg/push"
+ pkgpush "github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/push"
"github.com/Rain-kl/Wavelet/pkg/response"
"github.com/gin-gonic/gin"
diff --git a/plugins/domain/message_gateway/push_logics.go b/plugins/domain/message_gateway/push_logics.go
index a5de0358..f6ff7a26 100644
--- a/plugins/domain/message_gateway/push_logics.go
+++ b/plugins/domain/message_gateway/push_logics.go
@@ -12,9 +12,9 @@ import (
"strings"
"github.com/Rain-kl/Wavelet/core/contracts"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
- pkgpush "github.com/Rain-kl/Wavelet/pkg/push"
- "github.com/Rain-kl/Wavelet/pkg/task"
+ pkgpush "github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/push"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
"gorm.io/gorm"
)
@@ -445,7 +445,7 @@ func findBuiltInEvent(key string) (EventMetadata, bool) {
func getEventInfo(req CreatePushEventRequest) (string, string, []byte, error) {
if req.TaskType != "" {
- meta := task.GetTaskMetaByAsynqTask(req.TaskType)
+ meta := driver_asynq_worker.GetTaskMetaByAsynqTask(req.TaskType)
if meta == nil {
return "", "", nil, errors.New("unsupported task type")
}
@@ -484,7 +484,7 @@ func enqueuePushTask(ctx context.Context, payload SendPayload) error {
if err != nil {
return err
}
- _, err = task.DispatchTask(ctx, "send_notification", payloadBytes, "system")
+ _, err = driver_asynq_worker.DispatchTask(ctx, "send_notification", payloadBytes, "system")
return err
}
diff --git a/plugins/domain/message_gateway/push_task_listener.go b/plugins/domain/message_gateway/push_task_listener.go
index c7db8e1d..79e94b76 100644
--- a/plugins/domain/message_gateway/push_task_listener.go
+++ b/plugins/domain/message_gateway/push_task_listener.go
@@ -10,15 +10,15 @@ import (
"time"
"github.com/Rain-kl/Wavelet/pkg/logger"
- "github.com/Rain-kl/Wavelet/pkg/task"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
)
// RegisterTaskListeners subscribes push notification handlers to task completion events.
func RegisterTaskListeners() {
- task.OnTaskCompleted(handleTaskCompleted)
+ driver_asynq_worker.OnTaskCompleted(handleTaskCompleted)
}
-func handleTaskCompleted(ctx context.Context, execution *task.TaskExecution, result *task.TaskResult, execErr error) {
+func handleTaskCompleted(ctx context.Context, execution *driver_asynq_worker.TaskExecution, result *driver_asynq_worker.TaskResult, execErr error) {
events, err := listActivePushEventsByTaskType(ctx, execution.TaskType)
if err != nil {
logger.ErrorF(ctx, "push_task_completed_listener: failed to query push events for task type %s: %v", execution.TaskType, err)
diff --git a/plugins/domain/message_gateway/push_tasks.go b/plugins/domain/message_gateway/push_tasks.go
index 19e6a9f6..53981f7d 100644
--- a/plugins/domain/message_gateway/push_tasks.go
+++ b/plugins/domain/message_gateway/push_tasks.go
@@ -9,8 +9,8 @@ import (
"errors"
"fmt"
- "github.com/Rain-kl/Wavelet/pkg/push"
- "github.com/Rain-kl/Wavelet/pkg/task"
+ "github.com/Rain-kl/Wavelet/plugins/domain/message_gateway/push"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
)
const (
@@ -21,16 +21,16 @@ const (
)
// SendNotificationMeta represents the task metadata.
-var SendNotificationMeta = task.TaskMeta{
+var SendNotificationMeta = driver_asynq_worker.TaskMeta{
Type: TaskTypeSendNotification,
AsynqTask: SendNotificationTask,
Name: "推送通知",
Description: "异步执行系统通知的多渠道派发与推送",
SupportsTime: false,
- MaxRetry: task.DefaultMaxRetry,
- Queue: task.QueueDefault,
+ MaxRetry: driver_asynq_worker.DefaultMaxRetry,
+ Queue: driver_asynq_worker.QueueDefault,
Retryable: true,
- Params: []task.TaskParam{
+ Params: []driver_asynq_worker.TaskParam{
{
Name: "event_key",
Label: "事件标识",
@@ -69,20 +69,20 @@ func (h *PushHandler) ValidatePayload(payload []byte) ([]byte, error) {
}
// Execute performs the push send and logs delivery history audit.
-func (h *PushHandler) Execute(ctx context.Context, payload []byte) (*task.TaskResult, error) {
+func (h *PushHandler) Execute(ctx context.Context, payload []byte) (*driver_asynq_worker.TaskResult, error) {
var req SendPayload
if err := json.Unmarshal(payload, &req); err != nil {
- task.AppendLog(ctx, "解析推送参数失败: %v", err)
+ driver_asynq_worker.AppendLog(ctx, "解析推送参数失败: %v", err)
return nil, fmt.Errorf("parse payload failed: %w", err)
}
- task.AppendLog(ctx, "开始推送通知: 事件 = %s, 渠道 = %s, 接收目标 = %s", req.EventKey, req.Config.Channel, req.Target)
+ driver_asynq_worker.AppendLog(ctx, "开始推送通知: 事件 = %s, 渠道 = %s, 接收目标 = %s", req.EventKey, req.Config.Channel, req.Target)
pusher, err := push.GetPusher(req.Config.Channel)
if err != nil {
errWrap := fmt.Errorf("get pusher failed: %w", err)
- task.AppendLog(ctx, "推送失败: %v", errWrap)
- if task.IsFinalAttempt(ctx) {
+ driver_asynq_worker.AppendLog(ctx, "推送失败: %v", errWrap)
+ if driver_asynq_worker.IsFinalAttempt(ctx) {
h.recordHistory(ctx, req, "failed", errWrap.Error())
}
return nil, errWrap
@@ -95,29 +95,29 @@ func (h *PushHandler) Execute(ctx context.Context, payload []byte) (*task.TaskRe
content := req.Body.Content
if err != nil {
- task.AppendLog(ctx, "消息推送失败 (标题: %s): %v", title, err)
+ driver_asynq_worker.AppendLog(ctx, "消息推送失败 (标题: %s): %v", title, err)
if upstreamResp != "" {
- task.AppendLog(ctx, "上游返回: %s", upstreamResp)
+ driver_asynq_worker.AppendLog(ctx, "上游返回: %s", upstreamResp)
}
- if task.IsFinalAttempt(ctx) {
+ if driver_asynq_worker.IsFinalAttempt(ctx) {
h.recordHistory(ctx, req, "failed", err.Error())
}
return nil, fmt.Errorf("pusher.Send failed: %w", err)
}
- task.AppendLog(ctx, "消息推送成功 (标题: %s, 内容摘要: %s)", title, content)
+ driver_asynq_worker.AppendLog(ctx, "消息推送成功 (标题: %s, 内容摘要: %s)", title, content)
if upstreamResp != "" {
- task.AppendLog(ctx, "上游返回: %s", upstreamResp)
+ driver_asynq_worker.AppendLog(ctx, "上游返回: %s", upstreamResp)
}
h.recordHistory(ctx, req, "success", "")
- return &task.TaskResult{
+ return &driver_asynq_worker.TaskResult{
Message: fmt.Sprintf("推送成功: [%s] -> %s", req.Config.Channel, req.Target),
}, nil
}
func (h *PushHandler) recordHistory(ctx context.Context, req SendPayload, status string, errMsg string) {
if dbErr := recordPushHistory(ctx, req, status, errMsg); dbErr != nil {
- task.AppendLog(ctx, "写入推送历史审计记录失败: %v", dbErr)
+ driver_asynq_worker.AppendLog(ctx, "写入推送历史审计记录失败: %v", dbErr)
}
}
diff --git a/pkg/message_gateway/registry.go b/plugins/domain/message_gateway/registry.go
similarity index 100%
rename from pkg/message_gateway/registry.go
rename to plugins/domain/message_gateway/registry.go
diff --git a/pkg/message_gateway/registry_test.go b/plugins/domain/message_gateway/registry_test.go
similarity index 100%
rename from pkg/message_gateway/registry_test.go
rename to plugins/domain/message_gateway/registry_test.go
diff --git a/plugins/domain/message_gateway/repository.go b/plugins/domain/message_gateway/repository.go
index e9fb73c6..da143499 100644
--- a/plugins/domain/message_gateway/repository.go
+++ b/plugins/domain/message_gateway/repository.go
@@ -10,8 +10,9 @@ import (
"gorm.io/gorm"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/persistence/idgen"
+ "github.com/Rain-kl/Wavelet/pkg/idgen"
+ cachepkg "github.com/Rain-kl/Wavelet/plugins/infra/cache"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
const (
@@ -223,8 +224,8 @@ func DeletePushChannelRecord(ctx context.Context, channel *PushChannel) error {
func GetActivePushChannelByName(ctx context.Context, name string) (*PushChannel, error) {
cacheKey := "push:channel:active:" + name
var channel PushChannel
- if db.Redis != nil {
- if err := db.GetJSON(ctx, cacheKey, &channel); err == nil {
+ if cachepkg.Redis != nil {
+ if err := cachepkg.GetJSON(ctx, cacheKey, &channel); err == nil {
return &channel, nil
}
}
@@ -233,8 +234,8 @@ func GetActivePushChannelByName(ctx context.Context, name string) (*PushChannel,
return nil, err
}
- if db.Redis != nil {
- _ = db.SetJSON(ctx, cacheKey, channel, activePushChannelCacheTTL)
+ if cachepkg.Redis != nil {
+ _ = cachepkg.SetJSON(ctx, cacheKey, channel, activePushChannelCacheTTL)
}
return &channel, nil
@@ -242,8 +243,8 @@ func GetActivePushChannelByName(ctx context.Context, name string) (*PushChannel,
// DeleteActivePushChannelCache 清理启用消息通道的缓存。
func DeleteActivePushChannelCache(ctx context.Context, name string) {
- if db.Redis != nil {
- _ = db.Redis.Del(ctx, db.PrefixedKey("push:channel:active:"+name)).Err()
+ if cachepkg.Redis != nil {
+ _ = cachepkg.Redis.Del(ctx, cachepkg.PrefixedKey("push:channel:active:"+name)).Err()
}
}
@@ -333,8 +334,8 @@ func ListActivePushEventsByTaskTypeRecord(ctx context.Context, taskType string)
func GetActivePushEventByKey(ctx context.Context, key string) (*PushEvent, error) {
cacheKey := "push:event:active:" + key
var event PushEvent
- if db.Redis != nil {
- if err := db.GetJSON(ctx, cacheKey, &event); err == nil {
+ if cachepkg.Redis != nil {
+ if err := cachepkg.GetJSON(ctx, cacheKey, &event); err == nil {
return &event, nil
}
}
@@ -343,8 +344,8 @@ func GetActivePushEventByKey(ctx context.Context, key string) (*PushEvent, error
return nil, err
}
- if db.Redis != nil {
- _ = db.SetJSON(ctx, cacheKey, event, activePushEventCacheTTL)
+ if cachepkg.Redis != nil {
+ _ = cachepkg.SetJSON(ctx, cacheKey, event, activePushEventCacheTTL)
}
return &event, nil
@@ -352,8 +353,8 @@ func GetActivePushEventByKey(ctx context.Context, key string) (*PushEvent, error
// DeleteActivePushEventCache 清理启用通知事件的缓存。
func DeleteActivePushEventCache(ctx context.Context, key string) {
- if db.Redis != nil {
- _ = db.Redis.Del(ctx, db.PrefixedKey("push:event:active:"+key)).Err()
+ if cachepkg.Redis != nil {
+ _ = cachepkg.Redis.Del(ctx, cachepkg.PrefixedKey("push:event:active:"+key)).Err()
}
}
diff --git a/plugins/domain/risk_control/logics.go b/plugins/domain/risk_control/logics.go
index 12507795..f65ecbbe 100644
--- a/plugins/domain/risk_control/logics.go
+++ b/plugins/domain/risk_control/logics.go
@@ -8,10 +8,9 @@ import (
"sync"
"time"
+ "github.com/Rain-kl/Wavelet/pkg/batchwriter"
"github.com/Rain-kl/Wavelet/pkg/logger"
-
- "github.com/Rain-kl/Wavelet/pkg/persistence/batchwriter"
- "github.com/Rain-kl/Wavelet/pkg/persistence/logstore"
+ "github.com/Rain-kl/Wavelet/plugins/domain/risk_control/logstore"
)
var (
diff --git a/pkg/persistence/analytics/access_log.go b/plugins/domain/risk_control/logstore/access_log.go
similarity index 95%
rename from pkg/persistence/analytics/access_log.go
rename to plugins/domain/risk_control/logstore/access_log.go
index 66c2b85a..5f91596f 100644
--- a/pkg/persistence/analytics/access_log.go
+++ b/plugins/domain/risk_control/logstore/access_log.go
@@ -1,17 +1,16 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-// Package analytics provides ClickHouse data access for analytics tables.
-package analytics
+// Package logstore provides data access for analytics tables.
+package logstore
import (
"context"
"fmt"
-
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/util"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
"gorm.io/gorm"
)
diff --git a/pkg/persistence/analytics/access_log_filter.go b/plugins/domain/risk_control/logstore/access_log_filter.go
similarity index 50%
rename from pkg/persistence/analytics/access_log_filter.go
rename to plugins/domain/risk_control/logstore/access_log_filter.go
index 0d2ae948..162207c3 100644
--- a/pkg/persistence/analytics/access_log_filter.go
+++ b/plugins/domain/risk_control/logstore/access_log_filter.go
@@ -1,11 +1,11 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package analytics
+package logstore
import "time"
-// AccessLogFilter scopes ClickHouse user access log queries.
+// AccessLogFilter scopes user access log queries.
type AccessLogFilter struct {
// UserIDs filters by user IDs. nil means no user filter; an empty slice means no matches.
UserIDs []uint64
@@ -15,3 +15,21 @@ type AccessLogFilter struct {
// EndTime filters created_at <= EndTime when non-nil.
EndTime *time.Time
}
+
+// DailyTrend is a single day's access count.
+type DailyTrend struct {
+ Date string
+ Count uint64
+}
+
+// BrowserShare is a browser group's share of access logs.
+type BrowserShare struct {
+ Browser string
+ Count uint64
+}
+
+// TopUser is an active user ranked by access count.
+type TopUser struct {
+ UserID uint64
+ Count uint64
+}
diff --git a/pkg/persistence/analytics/access_log_stats.go b/plugins/domain/risk_control/logstore/access_log_stats.go
similarity index 89%
rename from pkg/persistence/analytics/access_log_stats.go
rename to plugins/domain/risk_control/logstore/access_log_stats.go
index efa0516d..2a320867 100644
--- a/pkg/persistence/analytics/access_log_stats.go
+++ b/plugins/domain/risk_control/logstore/access_log_stats.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package analytics
+package logstore
import (
"context"
@@ -9,29 +9,11 @@ import (
"sort"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
const hoursInDay = 24
-// DailyTrend is a single day's access count.
-type DailyTrend struct {
- Date string
- Count uint64
-}
-
-// BrowserShare is a browser group's share of access logs.
-type BrowserShare struct {
- Browser string
- Count uint64
-}
-
-// TopUser is an active user ranked by access count.
-type TopUser struct {
- UserID uint64
- Count uint64
-}
-
// GetDailyTrend returns per-day access counts for the last days days (inclusive of today).
func GetDailyTrend(ctx context.Context, days int) ([]DailyTrend, error) {
if days < 1 {
diff --git a/pkg/persistence/analytics/access_log_test.go b/plugins/domain/risk_control/logstore/access_log_test.go
similarity index 98%
rename from pkg/persistence/analytics/access_log_test.go
rename to plugins/domain/risk_control/logstore/access_log_test.go
index 7e2763ba..bc06db18 100644
--- a/pkg/persistence/analytics/access_log_test.go
+++ b/plugins/domain/risk_control/logstore/access_log_test.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package analytics
+package logstore
import (
"context"
@@ -12,11 +12,12 @@ import (
"github.com/ClickHouse/clickhouse-go/v2/lib/column"
"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/glebarez/sqlite"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
+
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
func setupChGormDB(t *testing.T) *gorm.DB {
diff --git a/pkg/persistence/analytics/access_log_writer.go b/plugins/domain/risk_control/logstore/access_log_writer.go
similarity index 92%
rename from pkg/persistence/analytics/access_log_writer.go
rename to plugins/domain/risk_control/logstore/access_log_writer.go
index 8ff937f2..21c500cf 100644
--- a/pkg/persistence/analytics/access_log_writer.go
+++ b/plugins/domain/risk_control/logstore/access_log_writer.go
@@ -1,13 +1,13 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package analytics
+package logstore
import (
"context"
"fmt"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
// BatchInsert writes access logs to ClickHouse using the native batch API.
diff --git a/pkg/persistence/analytics/browser.go b/plugins/domain/risk_control/logstore/browser.go
similarity index 97%
rename from pkg/persistence/analytics/browser.go
rename to plugins/domain/risk_control/logstore/browser.go
index 8ff97f7f..94634db2 100644
--- a/pkg/persistence/analytics/browser.go
+++ b/plugins/domain/risk_control/logstore/browser.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package analytics
+package logstore
import "strings"
diff --git a/pkg/persistence/logstore/cleanup.go b/plugins/domain/risk_control/logstore/cleanup.go
similarity index 100%
rename from pkg/persistence/logstore/cleanup.go
rename to plugins/domain/risk_control/logstore/cleanup.go
diff --git a/pkg/persistence/logstore/clickhouse.go b/plugins/domain/risk_control/logstore/clickhouse.go
similarity index 72%
rename from pkg/persistence/logstore/clickhouse.go
rename to plugins/domain/risk_control/logstore/clickhouse.go
index 3a198e63..51f0b415 100644
--- a/pkg/persistence/logstore/clickhouse.go
+++ b/plugins/domain/risk_control/logstore/clickhouse.go
@@ -9,8 +9,7 @@ import (
"time"
"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/persistence/analytics"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
type clickhouseUserAccessLogStore struct {
@@ -37,48 +36,48 @@ func (s *clickhouseUserAccessLogStore) ensureWritable(ctx context.Context) error
return nil
}
-func (s *clickhouseUserAccessLogStore) BatchInsert(ctx context.Context, logs []analytics.UserAccessLog) error {
+func (s *clickhouseUserAccessLogStore) BatchInsert(ctx context.Context, logs []UserAccessLog) error {
if len(logs) == 0 {
return nil
}
if err := s.ensureWritable(ctx); err != nil {
return err
}
- return analytics.BatchInsert(ctx, logs)
+ return BatchInsert(ctx, logs)
}
func (s *clickhouseUserAccessLogStore) DeleteAll(ctx context.Context) (int64, error) {
if err := s.ensureWritable(ctx); err != nil {
return 0, err
}
- return analytics.DeleteAllUserAccessLogs(ctx)
+ return DeleteAllUserAccessLogs(ctx)
}
func (s *clickhouseUserAccessLogStore) DeleteBefore(ctx context.Context, cutoff time.Time) (int64, error) {
if err := s.ensureWritable(ctx); err != nil {
return 0, err
}
- return analytics.DeleteUserAccessLogsBefore(ctx, cutoff)
+ return DeleteUserAccessLogsBefore(ctx, cutoff)
}
-func (s *clickhouseUserAccessLogStore) Count(ctx context.Context, filter analytics.AccessLogFilter) (uint64, error) {
- return analytics.CountAccessLogs(ctx, filter)
+func (s *clickhouseUserAccessLogStore) Count(ctx context.Context, filter AccessLogFilter) (uint64, error) {
+ return CountAccessLogs(ctx, filter)
}
-func (s *clickhouseUserAccessLogStore) List(ctx context.Context, filter analytics.AccessLogFilter, page, pageSize int) ([]analytics.UserAccessLog, uint64, error) {
- return analytics.ListAccessLogs(ctx, filter, page, pageSize)
+func (s *clickhouseUserAccessLogStore) List(ctx context.Context, filter AccessLogFilter, page, pageSize int) ([]UserAccessLog, uint64, error) {
+ return ListAccessLogs(ctx, filter, page, pageSize)
}
-func (s *clickhouseUserAccessLogStore) GetDailyTrend(ctx context.Context, days int) ([]analytics.DailyTrend, error) {
- return analytics.GetDailyTrend(ctx, days)
+func (s *clickhouseUserAccessLogStore) GetDailyTrend(ctx context.Context, days int) ([]DailyTrend, error) {
+ return GetDailyTrend(ctx, days)
}
-func (s *clickhouseUserAccessLogStore) GetBrowserDistribution(ctx context.Context, startTime time.Time) ([]analytics.BrowserShare, error) {
- return analytics.GetBrowserDistribution(ctx, startTime)
+func (s *clickhouseUserAccessLogStore) GetBrowserDistribution(ctx context.Context, startTime time.Time) ([]BrowserShare, error) {
+ return GetBrowserDistribution(ctx, startTime)
}
-func (s *clickhouseUserAccessLogStore) GetTopActiveUsers(ctx context.Context, startTime time.Time, limit int) ([]analytics.TopUser, error) {
- return analytics.GetTopActiveUsers(ctx, startTime, limit)
+func (s *clickhouseUserAccessLogStore) GetTopActiveUsers(ctx context.Context, startTime time.Time, limit int) ([]TopUser, error) {
+ return GetTopActiveUsers(ctx, startTime, limit)
}
func (s *clickhouseUserAccessLogStore) EnsurePartitions(_ context.Context, _, _ time.Time) error {
@@ -97,7 +96,7 @@ func (s *clickhouseUserAccessLogStore) MigrationRange(ctx context.Context) (time
if db.ChConn == nil {
return time.Time{}, time.Time{}, fmt.Errorf("clickhouse connection is not initialized")
}
- table := analytics.UserAccessLog{}.TableName()
+ table := UserAccessLog{}.TableName()
var minTime, maxTime *time.Time
if err := db.ChConn.QueryRow(ctx, "SELECT min(created_at), max(created_at) FROM "+table).Scan(&minTime, &maxTime); err != nil {
return time.Time{}, time.Time{}, fmt.Errorf("query migration range %s: %w", table, err)
@@ -108,15 +107,15 @@ func (s *clickhouseUserAccessLogStore) MigrationRange(ctx context.Context) (time
return minTime.UTC(), maxTime.UTC(), nil
}
-func (s *clickhouseUserAccessLogStore) ListForMigration(ctx context.Context, afterID uint64, limit int) ([]analytics.UserAccessLog, error) {
+func (s *clickhouseUserAccessLogStore) ListForMigration(ctx context.Context, afterID uint64, limit int) ([]UserAccessLog, error) {
if db.ChConn == nil {
return nil, fmt.Errorf("clickhouse connection is not initialized")
}
if limit <= 0 {
limit = migrationPageSize
}
- table := analytics.UserAccessLog{}.TableName()
- columns := analytics.UserAccessLog{}.InsertColumns()
+ table := UserAccessLog{}.TableName()
+ columns := UserAccessLog{}.InsertColumns()
rows, err := db.ChConn.Query(ctx, fmt.Sprintf(
"SELECT %s FROM %s WHERE id > ? ORDER BY id ASC LIMIT ?",
columns, table,
@@ -128,10 +127,10 @@ func (s *clickhouseUserAccessLogStore) ListForMigration(ctx context.Context, aft
return scanUserAccessLogs(rows)
}
-func scanUserAccessLogs(rows driver.Rows) ([]analytics.UserAccessLog, error) {
- var result []analytics.UserAccessLog
+func scanUserAccessLogs(rows driver.Rows) ([]UserAccessLog, error) {
+ var result []UserAccessLog
for rows.Next() {
- var item analytics.UserAccessLog
+ var item UserAccessLog
if err := rows.Scan(
&item.ID,
&item.UserID,
diff --git a/pkg/persistence/logstore/gorm.go b/plugins/domain/risk_control/logstore/gorm.go
similarity index 78%
rename from pkg/persistence/logstore/gorm.go
rename to plugins/domain/risk_control/logstore/gorm.go
index 0cea2dcd..5dd0c7a2 100644
--- a/pkg/persistence/logstore/gorm.go
+++ b/plugins/domain/risk_control/logstore/gorm.go
@@ -11,9 +11,7 @@ import (
"strings"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence/analytics"
- "github.com/Rain-kl/Wavelet/pkg/persistence/idgen"
-
+ "github.com/Rain-kl/Wavelet/pkg/idgen"
"gorm.io/gorm"
)
@@ -60,7 +58,7 @@ func (s *gormLogStore) ensureWritable(ctx context.Context) error {
return nil
}
-func (s *userAccessLogGormStore) BatchInsert(ctx context.Context, logs []analytics.UserAccessLog) error {
+func (s *userAccessLogGormStore) BatchInsert(ctx context.Context, logs []UserAccessLog) error {
if len(logs) == 0 {
return nil
}
@@ -79,7 +77,7 @@ func (s *userAccessLogGormStore) DeleteAll(ctx context.Context) (int64, error) {
if err := s.ensureWritable(ctx); err != nil {
return 0, err
}
- res := s.db.WithContext(ctx).Where("1 = 1").Delete(&analytics.UserAccessLog{})
+ res := s.db.WithContext(ctx).Where("1 = 1").Delete(&UserAccessLog{})
return res.RowsAffected, res.Error
}
@@ -87,16 +85,16 @@ func (s *userAccessLogGormStore) DeleteBefore(ctx context.Context, cutoff time.T
if err := s.ensureWritable(ctx); err != nil {
return 0, err
}
- res := s.db.WithContext(ctx).Where("created_at < ?", cutoff).Delete(&analytics.UserAccessLog{})
+ res := s.db.WithContext(ctx).Where("created_at < ?", cutoff).Delete(&UserAccessLog{})
if res.Error != nil && isMissingRelation(res.Error) {
return 0, nil
}
return res.RowsAffected, res.Error
}
-func (s *userAccessLogGormStore) ListForMigration(ctx context.Context, afterID uint64, limit int) ([]analytics.UserAccessLog, error) {
- var rows []analytics.UserAccessLog
- q := s.db.WithContext(ctx).Model(&analytics.UserAccessLog{}).
+func (s *userAccessLogGormStore) ListForMigration(ctx context.Context, afterID uint64, limit int) ([]UserAccessLog, error) {
+ var rows []UserAccessLog
+ q := s.db.WithContext(ctx).Model(&UserAccessLog{}).
Where("id > ?", afterID).
Order("id ASC").
Limit(limitOr(limit, migrationPageSize))
@@ -107,36 +105,36 @@ func (s *userAccessLogGormStore) ListForMigration(ctx context.Context, afterID u
}
func (s *userAccessLogGormStore) MigrationRange(ctx context.Context) (time.Time, time.Time, error) {
- return gormMigrationRange(ctx, s.db, "created_at", analytics.UserAccessLog{}, func(v *analytics.UserAccessLog) time.Time {
+ return gormMigrationRange(ctx, s.db, "created_at", UserAccessLog{}, func(v *UserAccessLog) time.Time {
return v.CreatedAt
})
}
-func (s *userAccessLogGormStore) Count(ctx context.Context, filter analytics.AccessLogFilter) (uint64, error) {
+func (s *userAccessLogGormStore) Count(ctx context.Context, filter AccessLogFilter) (uint64, error) {
where, args, ok := buildUserAccessLogWhere(filter)
if !ok {
return 0, nil
}
var total int64
- if err := s.db.WithContext(ctx).Model(&analytics.UserAccessLog{}).Where(where, args...).Count(&total).Error; err != nil {
+ if err := s.db.WithContext(ctx).Model(&UserAccessLog{}).Where(where, args...).Count(&total).Error; err != nil {
return 0, err
}
return countToUint64(total), nil
}
-func (s *userAccessLogGormStore) List(ctx context.Context, filter analytics.AccessLogFilter, page, pageSize int) ([]analytics.UserAccessLog, uint64, error) {
+func (s *userAccessLogGormStore) List(ctx context.Context, filter AccessLogFilter, page, pageSize int) ([]UserAccessLog, uint64, error) {
where, args, ok := buildUserAccessLogWhere(filter)
if !ok {
- return []analytics.UserAccessLog{}, 0, nil
+ return []UserAccessLog{}, 0, nil
}
var total int64
- if err := s.db.WithContext(ctx).Model(&analytics.UserAccessLog{}).Where(where, args...).Count(&total).Error; err != nil {
+ if err := s.db.WithContext(ctx).Model(&UserAccessLog{}).Where(where, args...).Count(&total).Error; err != nil {
return nil, 0, err
}
if total == 0 {
- return []analytics.UserAccessLog{}, 0, nil
+ return []UserAccessLog{}, 0, nil
}
- var rows []analytics.UserAccessLog
+ var rows []UserAccessLog
q := s.db.WithContext(ctx).Where(where, args...).Order("created_at DESC, id DESC")
if err := q.Limit(limitOr(pageSize, defaultPageSize)).Offset(offsetOf(page, pageSize)).Find(&rows).Error; err != nil {
return nil, 0, err
@@ -144,7 +142,7 @@ func (s *userAccessLogGormStore) List(ctx context.Context, filter analytics.Acce
return rows, countToUint64(total), nil
}
-func buildUserAccessLogWhere(filter analytics.AccessLogFilter) (string, []any, bool) {
+func buildUserAccessLogWhere(filter AccessLogFilter) (string, []any, bool) {
if filter.UserIDs != nil && len(filter.UserIDs) == 0 {
return "", nil, false
}
@@ -172,7 +170,7 @@ func buildUserAccessLogWhere(filter analytics.AccessLogFilter) (string, []any, b
return strings.Join(parts, " AND "), args, true
}
-func (s *userAccessLogGormStore) GetDailyTrend(ctx context.Context, days int) ([]analytics.DailyTrend, error) {
+func (s *userAccessLogGormStore) GetDailyTrend(ctx context.Context, days int) ([]DailyTrend, error) {
if days <= 0 {
days = 7
}
@@ -182,7 +180,7 @@ func (s *userAccessLogGormStore) GetDailyTrend(ctx context.Context, days int) ([
Cnt uint64
}
var rows []row
- err := s.db.WithContext(ctx).Model(&analytics.UserAccessLog{}).
+ err := s.db.WithContext(ctx).Model(&UserAccessLog{}).
Select(dailyTrendDateSQL(s.db)+" AS date, COUNT(*) AS cnt").
Where("created_at >= ?", start).
Group("date").Order("date ASC").Scan(&rows).Error
@@ -193,21 +191,21 @@ func (s *userAccessLogGormStore) GetDailyTrend(ctx context.Context, days int) ([
for _, r := range rows {
counts[r.Date] = r.Cnt
}
- out := make([]analytics.DailyTrend, 0, days)
+ out := make([]DailyTrend, 0, days)
for i := 0; i < days; i++ {
d := start.AddDate(0, 0, i).Format("2006-01-02")
- out = append(out, analytics.DailyTrend{Date: d, Count: counts[d]})
+ out = append(out, DailyTrend{Date: d, Count: counts[d]})
}
return out, nil
}
-func (s *userAccessLogGormStore) GetBrowserDistribution(ctx context.Context, startTime time.Time) ([]analytics.BrowserShare, error) {
+func (s *userAccessLogGormStore) GetBrowserDistribution(ctx context.Context, startTime time.Time) ([]BrowserShare, error) {
type row struct {
UserAgent string
Cnt uint64
}
var rows []row
- err := s.db.WithContext(ctx).Model(&analytics.UserAccessLog{}).
+ err := s.db.WithContext(ctx).Model(&UserAccessLog{}).
Select("user_agent, COUNT(*) AS cnt").
Where("created_at >= ?", startTime).
Group("user_agent").Order("cnt DESC").Limit(topUserAgents).Scan(&rows).Error
@@ -216,32 +214,32 @@ func (s *userAccessLogGormStore) GetBrowserDistribution(ctx context.Context, sta
}
counts := make(map[string]uint64)
for _, r := range rows {
- counts[analytics.ParseBrowserName(r.UserAgent)] += r.Cnt
+ counts[ParseBrowserName(r.UserAgent)] += r.Cnt
}
- out := make([]analytics.BrowserShare, 0, len(counts))
+ out := make([]BrowserShare, 0, len(counts))
for label, count := range counts {
- out = append(out, analytics.BrowserShare{Browser: label, Count: count})
+ out = append(out, BrowserShare{Browser: label, Count: count})
}
sort.Slice(out, func(i, j int) bool { return out[i].Count > out[j].Count })
return out, nil
}
-func (s *userAccessLogGormStore) GetTopActiveUsers(ctx context.Context, startTime time.Time, limit int) ([]analytics.TopUser, error) {
+func (s *userAccessLogGormStore) GetTopActiveUsers(ctx context.Context, startTime time.Time, limit int) ([]TopUser, error) {
type row struct {
UserID uint64
Cnt uint64
}
var rows []row
- err := s.db.WithContext(ctx).Model(&analytics.UserAccessLog{}).
+ err := s.db.WithContext(ctx).Model(&UserAccessLog{}).
Select("user_id, COUNT(*) AS cnt").
Where("user_id <> 0 AND created_at >= ?", startTime).
Group("user_id").Order("cnt DESC").Limit(limitOr(limit, defaultTopN)).Scan(&rows).Error
if err != nil {
return nil, err
}
- out := make([]analytics.TopUser, len(rows))
+ out := make([]TopUser, len(rows))
for i, r := range rows {
- out[i] = analytics.TopUser{UserID: r.UserID, Count: r.Cnt}
+ out[i] = TopUser{UserID: r.UserID, Count: r.Cnt}
}
return out, nil
}
diff --git a/pkg/persistence/logstore/gorm_test.go b/plugins/domain/risk_control/logstore/gorm_test.go
similarity index 74%
rename from pkg/persistence/logstore/gorm_test.go
rename to plugins/domain/risk_control/logstore/gorm_test.go
index 3e6fbde4..725d2a6f 100644
--- a/pkg/persistence/logstore/gorm_test.go
+++ b/plugins/domain/risk_control/logstore/gorm_test.go
@@ -8,8 +8,6 @@ import (
"testing"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence/analytics"
-
"github.com/glebarez/sqlite"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
@@ -19,7 +17,7 @@ func newTestUserAccessStore(t *testing.T) *userAccessLogGormStore {
t.Helper()
gdb, err := gorm.Open(sqlite.Open("file:logstore-"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
require.NoError(t, err)
- require.NoError(t, gdb.AutoMigrate(&analytics.UserAccessLog{}))
+ require.NoError(t, gdb.AutoMigrate(&UserAccessLog{}))
return newUserAccessLogGormStore(gdb)
}
@@ -27,17 +25,17 @@ func TestGormUserAccessLogCountList(t *testing.T) {
ua := newTestUserAccessStore(t)
ctx := context.Background()
now := time.Now().UTC().Truncate(time.Second)
- require.NoError(t, ua.BatchInsert(ctx, []analytics.UserAccessLog{
+ require.NoError(t, ua.BatchInsert(ctx, []UserAccessLog{
{UserID: 10, Path: "/api/v1/users", Method: "GET", Status: 200, CreatedAt: now},
{UserID: 20, Path: "/api/v1/admin", Method: "GET", Status: 200, CreatedAt: now},
{UserID: 10, Path: "/api/v1/other", Method: "POST", Status: 201, CreatedAt: now},
}))
- count, err := ua.Count(ctx, analytics.AccessLogFilter{UserIDs: []uint64{10}, Path: "users"})
+ count, err := ua.Count(ctx, AccessLogFilter{UserIDs: []uint64{10}, Path: "users"})
require.NoError(t, err)
require.Equal(t, uint64(1), count)
- rows, total, err := ua.List(ctx, analytics.AccessLogFilter{UserIDs: []uint64{10}, Path: "users"}, 1, 10)
+ rows, total, err := ua.List(ctx, AccessLogFilter{UserIDs: []uint64{10}, Path: "users"}, 1, 10)
require.NoError(t, err)
require.Equal(t, uint64(1), total)
require.Len(t, rows, 1)
@@ -55,6 +53,6 @@ func TestGormUserAccessLogFreeze(t *testing.T) {
})
t.Cleanup(ResetForTest)
- err := ua.BatchInsert(context.Background(), []analytics.UserAccessLog{{UserID: 1, CreatedAt: time.Now()}})
+ err := ua.BatchInsert(context.Background(), []UserAccessLog{{UserID: 1, CreatedAt: time.Now()}})
require.ErrorIs(t, err, ErrMigrating)
}
diff --git a/pkg/persistence/logstore/imports_test.go b/plugins/domain/risk_control/logstore/imports_test.go
similarity index 55%
rename from pkg/persistence/logstore/imports_test.go
rename to plugins/domain/risk_control/logstore/imports_test.go
index 9f72f11a..8376dd3e 100644
--- a/pkg/persistence/logstore/imports_test.go
+++ b/plugins/domain/risk_control/logstore/imports_test.go
@@ -9,18 +9,14 @@ import (
"testing"
)
-// apps 禁止直连 analytics 做日志读写;查询过滤器请用 logstore.AccessLogFilter。
+// plugins/domain 不得直接 import 已废弃的 pkg/persistence。
var forbiddenImports = []string{
- "github.com/Rain-kl/Wavelet/pkg/persistence/analytics",
+ "github.com/Rain-kl/Wavelet/pkg/idgen",
+ "github.com/Rain-kl/Wavelet/plugins/domain/risk_control/logstore",
}
-// logstore 的 CH 实现按设计委托 analyticsrepo。
-var allowedAnalyticsDelegation = map[string]bool{
- "github.com/Rain-kl/Wavelet/pkg/persistence/logstore": true,
-}
-
-func TestAppsMustNotImportLogBackendDirectly(t *testing.T) {
- t.Chdir("../../..")
+func TestAppsMustNotImportPersistenceDirectly(t *testing.T) {
+ t.Chdir("../../../..")
out, err := exec.Command("go", "list", "-test", "-f", `{{.ImportPath}} {{join .Imports " "}}`, "./plugins/domain/...").Output()
if err != nil {
t.Fatalf("go list: %v", err)
@@ -36,8 +32,8 @@ func TestAppsMustNotImportLogBackendDirectly(t *testing.T) {
}
for _, imp := range fields[1:] {
for _, forbidden := range forbiddenImports {
- if imp == forbidden && !allowedAnalyticsDelegation[pkg] {
- t.Errorf("%s must not import forbidden log backend %s", pkg, forbidden)
+ if imp == forbidden {
+ t.Errorf("%s must not import forbidden package %s", pkg, forbidden)
}
}
}
diff --git a/pkg/persistence/logstore/logstore.go b/plugins/domain/risk_control/logstore/logstore.go
similarity index 63%
rename from pkg/persistence/logstore/logstore.go
rename to plugins/domain/risk_control/logstore/logstore.go
index a55e7ef0..21804def 100644
--- a/pkg/persistence/logstore/logstore.go
+++ b/plugins/domain/risk_control/logstore/logstore.go
@@ -8,8 +8,6 @@ import (
"context"
"errors"
"time"
-
- "github.com/Rain-kl/Wavelet/pkg/persistence/analytics"
)
// ErrMigrating 表示日志数据库正在迁移,当前禁止写入。
@@ -17,15 +15,15 @@ var ErrMigrating = errors.New("log database is migrating, writes are disabled")
// UserAccessLogStore 用户访问日志(w_user_access_logs)。
type UserAccessLogStore interface {
- BatchInsert(ctx context.Context, logs []analytics.UserAccessLog) error
+ BatchInsert(ctx context.Context, logs []UserAccessLog) error
DeleteAll(ctx context.Context) (int64, error)
DeleteBefore(ctx context.Context, cutoff time.Time) (int64, error)
- Count(ctx context.Context, filter analytics.AccessLogFilter) (uint64, error)
- List(ctx context.Context, filter analytics.AccessLogFilter, page, pageSize int) ([]analytics.UserAccessLog, uint64, error)
- GetDailyTrend(ctx context.Context, days int) ([]analytics.DailyTrend, error)
- GetBrowserDistribution(ctx context.Context, startTime time.Time) ([]analytics.BrowserShare, error)
- GetTopActiveUsers(ctx context.Context, startTime time.Time, limit int) ([]analytics.TopUser, error)
- ListForMigration(ctx context.Context, afterID uint64, limit int) ([]analytics.UserAccessLog, error)
+ Count(ctx context.Context, filter AccessLogFilter) (uint64, error)
+ List(ctx context.Context, filter AccessLogFilter, page, pageSize int) ([]UserAccessLog, uint64, error)
+ GetDailyTrend(ctx context.Context, days int) ([]DailyTrend, error)
+ GetBrowserDistribution(ctx context.Context, startTime time.Time) ([]BrowserShare, error)
+ GetTopActiveUsers(ctx context.Context, startTime time.Time, limit int) ([]TopUser, error)
+ ListForMigration(ctx context.Context, afterID uint64, limit int) ([]UserAccessLog, error)
MigrationRange(ctx context.Context) (from, to time.Time, err error)
EnsurePartitions(ctx context.Context, from, to time.Time) error
// DropEmptyPartitions 幂等清理 PG 空分区表:删除 before 月份之前、且无任何数据的按月分区;
@@ -36,21 +34,6 @@ type UserAccessLogStore interface {
DropExpiredPartitions(ctx context.Context, cutoff time.Time) error
}
-// UserAccessLog 用户访问日志实体类型别名
-type UserAccessLog = analytics.UserAccessLog
-
-// AccessLogFilter 访问日志查询过滤条件类型别名
-type AccessLogFilter = analytics.AccessLogFilter
-
-// DailyTrend 每日趋势数据类型别名
-type DailyTrend = analytics.DailyTrend
-
-// BrowserShare 浏览器分布数据类型别名
-type BrowserShare = analytics.BrowserShare
-
-// TopUser Top 用户活跃统计类型别名
-type TopUser = analytics.TopUser
-
// StatusStore 日志库状态。
type StatusStore interface {
ActiveDatabase(ctx context.Context) (string, error)
diff --git a/pkg/persistence/analytics/models.go b/plugins/domain/risk_control/logstore/models.go
similarity index 83%
rename from pkg/persistence/analytics/models.go
rename to plugins/domain/risk_control/logstore/models.go
index ac6dbca1..2aa8079b 100644
--- a/pkg/persistence/analytics/models.go
+++ b/plugins/domain/risk_control/logstore/models.go
@@ -1,8 +1,8 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-// Package analytics defines ClickHouse analytics domain models.
-package analytics
+// Package logstore abstracts user access-log storage across ClickHouse, PostgreSQL and SQLite.
+package logstore
import (
"fmt"
@@ -14,7 +14,7 @@ const (
userAccessLogInsertColumns = "id, user_id, path, method, ip, user_agent, headers, status, latency, created_at"
)
-// UserAccessLog stores HTTP access records in ClickHouse.
+// UserAccessLog stores HTTP access records in ClickHouse, PostgreSQL and SQLite.
type UserAccessLog struct {
ID uint64 `gorm:"column:id"`
UserID uint64 `gorm:"column:user_id"`
@@ -28,7 +28,7 @@ type UserAccessLog struct {
CreatedAt time.Time `gorm:"column:created_at"`
}
-// TableName returns the ClickHouse table name.
+// TableName returns the table name.
func (UserAccessLog) TableName() string {
return userAccessLogTableName
}
diff --git a/pkg/persistence/logstore/partition_cleanup.go b/plugins/domain/risk_control/logstore/partition_cleanup.go
similarity index 100%
rename from pkg/persistence/logstore/partition_cleanup.go
rename to plugins/domain/risk_control/logstore/partition_cleanup.go
diff --git a/pkg/persistence/logstore/partition_cleanup_test.go b/plugins/domain/risk_control/logstore/partition_cleanup_test.go
similarity index 94%
rename from pkg/persistence/logstore/partition_cleanup_test.go
rename to plugins/domain/risk_control/logstore/partition_cleanup_test.go
index 150184fe..50d6de81 100644
--- a/pkg/persistence/logstore/partition_cleanup_test.go
+++ b/plugins/domain/risk_control/logstore/partition_cleanup_test.go
@@ -8,7 +8,6 @@ import (
"testing"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence/analytics"
"github.com/stretchr/testify/require"
)
@@ -59,7 +58,7 @@ func TestDropEligiblePartitionNames(t *testing.T) {
func TestDropPartitionHelpersSQLiteNoop(t *testing.T) {
ua := newTestUserAccessStore(t)
ctx := context.Background()
- require.NoError(t, ua.BatchInsert(ctx, []analytics.UserAccessLog{
+ require.NoError(t, ua.BatchInsert(ctx, []UserAccessLog{
{UserID: 1, Path: "/x", CreatedAt: time.Now().UTC()},
}))
require.NoError(t, ua.DropExpiredPartitions(ctx, time.Now().AddDate(0, 0, -90)))
diff --git a/pkg/persistence/logstore/provider.go b/plugins/domain/risk_control/logstore/provider.go
similarity index 98%
rename from pkg/persistence/logstore/provider.go
rename to plugins/domain/risk_control/logstore/provider.go
index a1a219d0..1e30897d 100644
--- a/pkg/persistence/logstore/provider.go
+++ b/plugins/domain/risk_control/logstore/provider.go
@@ -12,8 +12,7 @@ import (
"github.com/Rain-kl/Wavelet/pkg/config"
"github.com/Rain-kl/Wavelet/pkg/logger"
-
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
const (
diff --git a/plugins/domain/risk_control/middleware.go b/plugins/domain/risk_control/middleware.go
index d03330c9..eeac946f 100644
--- a/plugins/domain/risk_control/middleware.go
+++ b/plugins/domain/risk_control/middleware.go
@@ -11,10 +11,10 @@ import (
"github.com/Rain-kl/Wavelet/core/contracts"
"github.com/Rain-kl/Wavelet/pkg/config"
- "github.com/Rain-kl/Wavelet/pkg/persistence/idgen"
- "github.com/Rain-kl/Wavelet/pkg/persistence/logstore"
+ "github.com/Rain-kl/Wavelet/pkg/idgen"
"github.com/Rain-kl/Wavelet/pkg/response"
"github.com/Rain-kl/Wavelet/plugins/domain/auth"
+ "github.com/Rain-kl/Wavelet/plugins/domain/risk_control/logstore"
"github.com/gin-gonic/gin"
)
diff --git a/plugins/domain/risk_control/middleware_test.go b/plugins/domain/risk_control/middleware_test.go
index d25b4b48..dd36ccdd 100644
--- a/plugins/domain/risk_control/middleware_test.go
+++ b/plugins/domain/risk_control/middleware_test.go
@@ -13,12 +13,12 @@ import (
"time"
"github.com/Rain-kl/Wavelet/core/contracts"
+ "github.com/Rain-kl/Wavelet/pkg/batchwriter"
"github.com/Rain-kl/Wavelet/pkg/config"
- "github.com/Rain-kl/Wavelet/pkg/persistence/batchwriter"
- "github.com/Rain-kl/Wavelet/pkg/persistence/logstore"
"github.com/Rain-kl/Wavelet/pkg/testhelper"
"github.com/Rain-kl/Wavelet/plugins/domain/auth"
"github.com/Rain-kl/Wavelet/plugins/domain/risk_control"
+ "github.com/Rain-kl/Wavelet/plugins/domain/risk_control/logstore"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
)
diff --git a/plugins/domain/system/plugin.go b/plugins/domain/system/plugin.go
index 469d7b96..2b89ed0d 100644
--- a/plugins/domain/system/plugin.go
+++ b/plugins/domain/system/plugin.go
@@ -9,7 +9,7 @@ import (
"github.com/Rain-kl/Wavelet/core"
"github.com/Rain-kl/Wavelet/pkg/config"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/pkg/response"
"github.com/gin-gonic/gin"
)
@@ -54,7 +54,7 @@ func (p *Plugin) Apply(ctx *core.Context) error {
Value string `json:"value"`
}
var configs []configItem
- _ = db.DB(c.Request.Context()).Table("w_system_configs").Where("visibility = ?", "visible").Find(&configs).Error
+ _ = database.DB(c.Request.Context()).Table("w_system_configs").Where("visibility = ?", "visible").Find(&configs).Error
c.JSON(http.StatusOK, response.OK(gin.H{
"configs": configs,
"app": gin.H{
diff --git a/plugins/domain/upload/cache/access_cache.go b/plugins/domain/upload/cache/access_cache.go
index 3e339f07..2b5bf649 100644
--- a/plugins/domain/upload/cache/access_cache.go
+++ b/plugins/domain/upload/cache/access_cache.go
@@ -11,7 +11,8 @@ import (
"sync"
"time"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ cachepkg "github.com/Rain-kl/Wavelet/plugins/infra/cache"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/pkg/util"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/shared"
uploadstorage "github.com/Rain-kl/Wavelet/plugins/domain/upload/storage"
@@ -41,8 +42,8 @@ func ResetAccessCaches() {
// PublishAccessCacheInvalidation broadcasts upload access cache eviction to all nodes.
func PublishAccessCacheInvalidation(ctx context.Context) {
- if db.Redis != nil {
- _ = db.Redis.Publish(ctx, fileAccessInvalidationChannel, "reset").Err()
+ if cachepkg.Redis != nil {
+ _ = cachepkg.Redis.Publish(ctx, fileAccessInvalidationChannel, "reset").Err()
}
}
@@ -51,7 +52,7 @@ func ensureAccessCacheListener() {
}
func startAccessCacheInvalidationListener() {
- rdb := db.Redis
+ rdb := cachepkg.Redis
if rdb == nil {
return
}
@@ -114,7 +115,7 @@ func fetchFileAccessWhitelist(ctx context.Context) map[string]struct{} {
func parseFileAccessWhitelist(ctx context.Context) []string {
var sc struct{ Value string }
- err := db.DB(ctx).Table("w_system_configs").Where("key = ?", "file_access_whitelist").First(&sc).Error
+ err := database.DB(ctx).Table("w_system_configs").Where("key = ?", "file_access_whitelist").First(&sc).Error
if err != nil || sc.Value == "" {
return []string{shared.DefaultPublicUploadType}
}
diff --git a/plugins/domain/upload/cache/meta_cache.go b/plugins/domain/upload/cache/meta_cache.go
index a9692c5e..daf74faa 100644
--- a/plugins/domain/upload/cache/meta_cache.go
+++ b/plugins/domain/upload/cache/meta_cache.go
@@ -10,7 +10,8 @@ import (
"sync"
"github.com/Rain-kl/Wavelet/pkg/cache/ram"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
+ cachepkg "github.com/Rain-kl/Wavelet/plugins/infra/cache"
"github.com/Rain-kl/Wavelet/pkg/util"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
)
@@ -42,7 +43,7 @@ func cloneUpload(u models.Upload) models.Upload {
}
func ensureUploadMetaCacheListener() {
- if db.Redis == nil {
+ if cachepkg.Redis == nil {
return
}
uploadMetaListenerOnce.Do(startUploadMetaCacheInvalidationListener)
@@ -52,7 +53,7 @@ func startUploadMetaCacheInvalidationListener() {
uploadMetaListenerCtx, uploadMetaListenerCancel = context.WithCancel(context.Background())
uploadMetaListenerDone = make(chan struct{})
- redisClient := db.Redis // 捕获当前客户端:goroutine 不读可变全局,避免与测试置空 db.Redis 竞争
+ redisClient := cachepkg.Redis // 捕获当前客户端:goroutine 不读可变全局,避免与测试置空 cachepkg.Redis 竞争
util.Go(func() {
defer close(uploadMetaListenerDone)
pubsub := redisClient.Subscribe(uploadMetaListenerCtx, uploadMetaInvalidationChan)
@@ -77,14 +78,14 @@ func startUploadMetaCacheInvalidationListener() {
}
func publishUploadMetaRAMInvalidation(ctx context.Context, id uint64) {
- if db.Redis == nil {
+ if cachepkg.Redis == nil {
return
}
payload, err := json.Marshal(uploadMetaInvalidationMessage{ID: id})
if err != nil {
return
}
- _ = db.Redis.Publish(ctx, uploadMetaInvalidationChan, payload).Err()
+ _ = cachepkg.Redis.Publish(ctx, uploadMetaInvalidationChan, payload).Err()
}
// GetUploadByID loads upload metadata from RAM, Redis, or the database.
@@ -96,16 +97,16 @@ func GetUploadByID(ctx context.Context, id uint64) (models.Upload, error) {
}
key := uploadMetaRedisKey(id)
- if db.Redis != nil {
+ if cachepkg.Redis != nil {
var u models.Upload
- if err := db.GetJSON(ctx, key, &u); err == nil {
+ if err := cachepkg.GetJSON(ctx, key, &u); err == nil {
uploadMetaRAM.Set(id, cloneUpload(u))
return u, nil
}
}
var u models.Upload
- if err := db.DB(ctx).
+ if err := database.DB(ctx).
Where("id = ? AND status IN (?, ?)", id, models.UploadStatusPending, models.UploadStatusUsed).
First(&u).Error; err != nil {
return models.Upload{}, err
@@ -125,8 +126,8 @@ func SetUploadMetaCache(ctx context.Context, u *models.Upload) {
cloned := cloneUpload(*u)
uploadMetaRAM.Set(u.ID, cloned)
- if db.Redis != nil {
- _ = db.SetJSON(ctx, uploadMetaRedisKey(u.ID), cloned, uploadMetaRedisCacheTTL)
+ if cachepkg.Redis != nil {
+ _ = cachepkg.SetJSON(ctx, uploadMetaRedisKey(u.ID), cloned, uploadMetaRedisCacheTTL)
}
}
@@ -135,8 +136,8 @@ func InvalidateUploadMetaCache(ctx context.Context, id uint64) {
ensureUploadMetaCacheListener()
uploadMetaRAM.Invalidate(id)
- if db.Redis != nil {
- _ = db.Redis.Del(ctx, db.PrefixedKey(uploadMetaRedisKey(id))).Err()
+ if cachepkg.Redis != nil {
+ _ = cachepkg.Redis.Del(ctx, cachepkg.PrefixedKey(uploadMetaRedisKey(id))).Err()
publishUploadMetaRAMInvalidation(ctx, id)
}
}
@@ -151,7 +152,7 @@ func StopUploadMetaCacheListener() {
if uploadMetaListenerCancel != nil {
uploadMetaListenerCancel()
if uploadMetaListenerDone != nil {
- <-uploadMetaListenerDone // 等待 goroutine 退出,保证之后置空 db.Redis 不再竞争
+ <-uploadMetaListenerDone // 等待 goroutine 退出,保证之后置空 cachepkg.Redis 不再竞争
}
uploadMetaListenerCancel = nil
uploadMetaListenerDone = nil
diff --git a/plugins/domain/upload/cache/meta_cache_test.go b/plugins/domain/upload/cache/meta_cache_test.go
index 52ef2864..6a3ae297 100644
--- a/plugins/domain/upload/cache/meta_cache_test.go
+++ b/plugins/domain/upload/cache/meta_cache_test.go
@@ -9,7 +9,7 @@ import (
"testing"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ cachepkg "github.com/Rain-kl/Wavelet/plugins/infra/cache"
"github.com/Rain-kl/Wavelet/pkg/testhelper"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"gorm.io/gorm"
@@ -58,7 +58,7 @@ func TestGetUploadByIDLoadsFromDBAndPopulatesCache(t *testing.T) {
}
var redisUpload models.Upload
- if err := db.GetJSON(ctx, uploadMetaRedisKey(upload.ID), &redisUpload); err != nil {
+ if err := cachepkg.GetJSON(ctx, uploadMetaRedisKey(upload.ID), &redisUpload); err != nil {
t.Fatalf("redis cache miss after DB load: %v", err)
}
if redisUpload.ID != upload.ID {
@@ -137,7 +137,7 @@ func TestInvalidateUploadMetaCacheClearsRAMAndRedis(t *testing.T) {
InvalidateUploadMetaCache(ctx, upload.ID)
var redisUpload models.Upload
- if err := db.GetJSON(ctx, uploadMetaRedisKey(upload.ID), &redisUpload); err == nil {
+ if err := cachepkg.GetJSON(ctx, uploadMetaRedisKey(upload.ID), &redisUpload); err == nil {
t.Fatal("expected redis cache to be invalidated")
}
@@ -188,7 +188,7 @@ func TestUploadMetaInvalidationPubSubClearsPeerRAM(t *testing.T) {
if err != nil {
t.Fatalf("marshal invalidation payload: %v", err)
}
- if err := db.Redis.Publish(ctx, uploadMetaInvalidationChan, string(payload)).Err(); err != nil {
+ if err := cachepkg.Redis.Publish(ctx, uploadMetaInvalidationChan, string(payload)).Err(); err != nil {
t.Fatalf("publish invalidation: %v", err)
}
@@ -205,7 +205,7 @@ func TestUploadMetaInvalidationPubSubClearsPeerRAM(t *testing.T) {
t.Fatal("expected peer RAM cache to be cleared by pub/sub")
}
- if err := db.Redis.Del(ctx, db.PrefixedKey(uploadMetaRedisKey(upload.ID))).Err(); err != nil {
+ if err := cachepkg.Redis.Del(ctx, cachepkg.PrefixedKey(uploadMetaRedisKey(upload.ID))).Err(); err != nil {
t.Fatalf("delete redis cache: %v", err)
}
if _, err := GetUploadByID(ctx, upload.ID); err == nil {
@@ -243,10 +243,10 @@ func TestGetUploadByIDWorksWithRedisDisabled(t *testing.T) {
defer cleanup()
ResetUploadMetaCacheForTest()
- redisClient := db.Redis
- db.Redis = nil
+ redisClient := cachepkg.Redis
+ cachepkg.Redis = nil
t.Cleanup(func() {
- db.Redis = redisClient
+ cachepkg.Redis = redisClient
StopUploadMetaCacheListener()
})
diff --git a/plugins/domain/upload/errs.go b/plugins/domain/upload/errs.go
index a980dc26..996c8e6d 100644
--- a/plugins/domain/upload/errs.go
+++ b/plugins/domain/upload/errs.go
@@ -35,4 +35,5 @@ const (
ErrS3KeyStartsWithSlash = shared.ErrS3KeyStartsWithSlash
ErrS3KeyContainsNullBytes = shared.ErrS3KeyContainsNullBytes
ErrQueryUnusedUploadsFailed = shared.ErrQueryUnusedUploadsFailed
+ ErrUnauthorized = shared.ErrUnauthorized
)
diff --git a/plugins/domain/upload/exports.go b/plugins/domain/upload/exports.go
index 18673ff7..2501533a 100644
--- a/plugins/domain/upload/exports.go
+++ b/plugins/domain/upload/exports.go
@@ -4,7 +4,6 @@
package upload
import (
- "github.com/Rain-kl/Wavelet/pkg/task"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/cache"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/filesrv"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/handler"
@@ -12,6 +11,7 @@ import (
uploadstats "github.com/Rain-kl/Wavelet/plugins/domain/upload/stats"
uploadtask "github.com/Rain-kl/Wavelet/plugins/domain/upload/task"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/util"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
)
// HTTP handlers
@@ -116,11 +116,11 @@ type WarmImageCachePayload = uploadtask.WarmImageCachePayload
// Ensure task handler types implement required interfaces.
var (
- _ task.TaskHandler = (*MigrationHandler)(nil)
- _ task.TaskHandler = (*SystemCleanupHandler)(nil)
- _ task.TaskHandler = (*RebuildUploadStatsHandler)(nil)
+ _ driver_asynq_worker.TaskHandler = (*MigrationHandler)(nil)
+ _ driver_asynq_worker.TaskHandler = (*SystemCleanupHandler)(nil)
+ _ driver_asynq_worker.TaskHandler = (*RebuildUploadStatsHandler)(nil)
_ interface {
- task.TaskHandler
+ driver_asynq_worker.TaskHandler
ValidatePayload([]byte) ([]byte, error)
} = (*WarmImageCacheHandler)(nil)
)
diff --git a/plugins/domain/upload/filesrv/file_server.go b/plugins/domain/upload/filesrv/file_server.go
index cca47376..e4544864 100644
--- a/plugins/domain/upload/filesrv/file_server.go
+++ b/plugins/domain/upload/filesrv/file_server.go
@@ -17,7 +17,6 @@ import (
"github.com/Rain-kl/Wavelet/core/contracts"
"github.com/Rain-kl/Wavelet/pkg/response"
- appshared "github.com/Rain-kl/Wavelet/pkg/shared"
"github.com/Rain-kl/Wavelet/plugins/domain/auth"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/cache"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
@@ -78,7 +77,7 @@ func ServeFileByID(c *gin.Context) {
}
if err := CheckFileAccessPermission(c, upload); err != nil {
- response.AbortUnauthorized(c, appshared.UnAuthorized)
+ response.AbortUnauthorized(c, shared.ErrUnauthorized)
return
}
diff --git a/plugins/domain/upload/handler/routers.go b/plugins/domain/upload/handler/routers.go
index ca1a4833..e523d52a 100644
--- a/plugins/domain/upload/handler/routers.go
+++ b/plugins/domain/upload/handler/routers.go
@@ -25,7 +25,6 @@ import (
"github.com/Rain-kl/Wavelet/core/contracts"
"github.com/Rain-kl/Wavelet/pkg/logger"
"github.com/Rain-kl/Wavelet/pkg/response"
- appshared "github.com/Rain-kl/Wavelet/pkg/shared"
"github.com/Rain-kl/Wavelet/plugins/domain/auth"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/filesrv"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/ingest"
@@ -183,7 +182,7 @@ func DownloadFile(c *gin.Context) {
}
if err := filesrv.CheckFileAccessPermission(c, upload); err != nil {
- response.AbortUnauthorized(c, appshared.UnAuthorized)
+ response.AbortUnauthorized(c, shared.ErrUnauthorized)
return
}
diff --git a/plugins/domain/upload/ingest/helpers.go b/plugins/domain/upload/ingest/helpers.go
index a9e1239d..a2804524 100644
--- a/plugins/domain/upload/ingest/helpers.go
+++ b/plugins/domain/upload/ingest/helpers.go
@@ -13,8 +13,8 @@ import (
"time"
"github.com/Rain-kl/Wavelet/pkg/logger"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/persistence/idgen"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
+ "github.com/Rain-kl/Wavelet/pkg/idgen"
uploadcache "github.com/Rain-kl/Wavelet/plugins/domain/upload/cache"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/repository"
@@ -50,7 +50,7 @@ func resolveAccessMode(uploadType string, explicit *int) int {
func validateAllowedExtension(ctx context.Context, ext string) error {
var val string
- err := db.DB(ctx).Table("w_system_configs").Where("key = ?", "upload_allowed_extensions").Pluck("value", &val).Error
+ err := database.DB(ctx).Table("w_system_configs").Where("key = ?", "upload_allowed_extensions").Pluck("value", &val).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil
@@ -128,7 +128,7 @@ func persistUploadRecord(ctx context.Context, upload *models.Upload, objectKey s
}
func createUploadWithStats(ctx context.Context, upload *models.Upload) error {
- return db.DB(ctx).Transaction(func(tx *gorm.DB) error {
+ return database.DB(ctx).Transaction(func(tx *gorm.DB) error {
if err := repository.CreateUploadTx(tx, upload); err != nil {
return err
}
diff --git a/plugins/domain/upload/ingest/ingest_test.go b/plugins/domain/upload/ingest/ingest_test.go
index 382c5bd2..bcdb9bcb 100644
--- a/plugins/domain/upload/ingest/ingest_test.go
+++ b/plugins/domain/upload/ingest/ingest_test.go
@@ -13,7 +13,7 @@ import (
"testing"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/pkg/testhelper"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/objectstore"
@@ -276,7 +276,7 @@ type totalStatsSnapshot struct {
func loadTotalStats(ctx context.Context) (totalStatsSnapshot, error) {
var rows []models.UploadStat
- if err := db.DB(ctx).Where("dimension = ?", models.UploadStatDimensionTotal).Find(&rows).Error; err != nil {
+ if err := database.DB(ctx).Where("dimension = ?", models.UploadStatDimensionTotal).Find(&rows).Error; err != nil {
return totalStatsSnapshot{}, err
}
if len(rows) == 0 {
diff --git a/plugins/domain/upload/ingest/remove.go b/plugins/domain/upload/ingest/remove.go
index cbbfd703..161cc8ac 100644
--- a/plugins/domain/upload/ingest/remove.go
+++ b/plugins/domain/upload/ingest/remove.go
@@ -6,7 +6,7 @@ package ingest
import (
"context"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
uploadcache "github.com/Rain-kl/Wavelet/plugins/domain/upload/cache"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/repository"
@@ -45,7 +45,7 @@ func RemoveOwned(ctx context.Context, userID, uploadID uint64) (models.Upload, e
func softDeleteUploadWithStats(ctx context.Context, upload *models.Upload) error {
statsSnapshot := *upload
- if err := db.DB(ctx).Transaction(func(tx *gorm.DB) error {
+ if err := database.DB(ctx).Transaction(func(tx *gorm.DB) error {
if err := repository.SoftDeleteUploadTx(tx, upload); err != nil {
return err
}
diff --git a/plugins/domain/upload/repository.go b/plugins/domain/upload/repository.go
index b4fbca1c..6fae5726 100644
--- a/plugins/domain/upload/repository.go
+++ b/plugins/domain/upload/repository.go
@@ -9,8 +9,8 @@ import (
"gorm.io/gorm"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/persistence/idgen"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
+ "github.com/Rain-kl/Wavelet/pkg/idgen"
"github.com/Rain-kl/Wavelet/pkg/util"
)
@@ -28,7 +28,7 @@ type UploadListFilter struct {
// ListUploads returns paginated upload records matching the filter.
func ListUploads(ctx context.Context, filter UploadListFilter) (int64, []Upload, error) {
- query := db.DB(ctx).Model(&Upload{}).
+ query := database.DB(ctx).Model(&Upload{}).
Where("status != ?", UploadStatusDeleted)
if filter.UserID != 0 {
@@ -60,7 +60,7 @@ func ListUploads(ctx context.Context, filter UploadListFilter) (int64, []Upload,
// GetActiveUploadByID loads a non-deleted upload by ID.
func GetActiveUploadByID(ctx context.Context, id uint64) (Upload, error) {
var upload Upload
- if err := db.DB(ctx).Where("id = ? AND status != ?", id, UploadStatusDeleted).First(&upload).Error; err != nil {
+ if err := database.DB(ctx).Where("id = ? AND status != ?", id, UploadStatusDeleted).First(&upload).Error; err != nil {
return Upload{}, err
}
return upload, nil
@@ -69,7 +69,7 @@ func GetActiveUploadByID(ctx context.Context, id uint64) (Upload, error) {
// SoftDeleteUpload marks an upload as deleted.
// External modules must use upload.Remove or upload.RemoveOwned; only internal/apps/upload may call this.
func SoftDeleteUpload(ctx context.Context, upload *Upload) error {
- return SoftDeleteUploadTx(db.DB(ctx), upload)
+ return SoftDeleteUploadTx(database.DB(ctx), upload)
}
// SoftDeleteUploadTx marks an upload as deleted within an existing transaction.
@@ -82,13 +82,13 @@ func UpdateUpload(ctx context.Context, upload *Upload, updates map[string]any) e
if len(updates) == 0 {
return nil
}
- return db.DB(ctx).Model(upload).Updates(updates).Error
+ return database.DB(ctx).Model(upload).Updates(updates).Error
}
// ListDistinctUploadTypes returns all distinct non-empty upload business types.
func ListDistinctUploadTypes(ctx context.Context) ([]string, error) {
var types []string
- if err := db.DB(ctx).Model(&Upload{}).
+ if err := database.DB(ctx).Model(&Upload{}).
Where("type IS NOT NULL AND type != ''").
Distinct().
Pluck("type", &types).Error; err != nil {
@@ -100,7 +100,7 @@ func ListDistinctUploadTypes(ctx context.Context) ([]string, error) {
// FindReusableUploadByHash finds an existing upload with the same hash and size.
func FindReusableUploadByHash(ctx context.Context, hash string, size int64) (Upload, error) {
var existing Upload
- err := db.DB(ctx).
+ err := database.DB(ctx).
Where("hash = ? AND file_size = ? AND status IN (?, ?)", hash, size, UploadStatusPending, UploadStatusUsed).
First(&existing).Error
return existing, err
@@ -108,7 +108,7 @@ func FindReusableUploadByHash(ctx context.Context, hash string, size int64) (Upl
// CreateUpload persists a new upload record.
func CreateUpload(ctx context.Context, upload *Upload) error {
- return CreateUploadTx(db.DB(ctx), upload)
+ return CreateUploadTx(database.DB(ctx), upload)
}
// CreateUploadTx persists a new upload record within an existing transaction.
@@ -122,7 +122,7 @@ func CreateUploadTx(tx *gorm.DB, upload *Upload) error {
// ListUploadsByIDs returns active uploads matching the given IDs.
func ListUploadsByIDs(ctx context.Context, ids []uint64) ([]Upload, error) {
var uploads []Upload
- if err := db.DB(ctx).
+ if err := database.DB(ctx).
Where("id IN ? AND status IN (?, ?)", ids, UploadStatusPending, UploadStatusUsed).
Find(&uploads).Error; err != nil {
return nil, err
@@ -134,13 +134,13 @@ func ListUploadsByIDs(ctx context.Context, ids []uint64) ([]Upload, error) {
//
//nolint:revive
func UploadQuery(ctx context.Context) *gorm.DB {
- return db.DB(ctx).Model(&Upload{})
+ return database.DB(ctx).Model(&Upload{})
}
// ListUploadStats returns all upload statistics rows.
func ListUploadStats(ctx context.Context) ([]UploadStat, error) {
var stats []UploadStat
- if err := db.DB(ctx).Find(&stats).Error; err != nil {
+ if err := database.DB(ctx).Find(&stats).Error; err != nil {
return nil, err
}
return stats, nil
diff --git a/plugins/domain/upload/repository/repository.go b/plugins/domain/upload/repository/repository.go
index 2f322204..bd491d27 100644
--- a/plugins/domain/upload/repository/repository.go
+++ b/plugins/domain/upload/repository/repository.go
@@ -9,7 +9,7 @@ import (
"context"
"strings"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/pkg/util"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"gorm.io/gorm"
@@ -27,7 +27,7 @@ type UploadListFilter struct {
// ListUploads returns paginated upload records matching the filter.
func ListUploads(ctx context.Context, filter UploadListFilter) (int64, []models.Upload, error) {
- query := db.DB(ctx).Model(&models.Upload{}).
+ query := database.DB(ctx).Model(&models.Upload{}).
Where("status != ?", models.UploadStatusDeleted)
if filter.UserID != 0 {
@@ -59,7 +59,7 @@ func ListUploads(ctx context.Context, filter UploadListFilter) (int64, []models.
// GetActiveUploadByID loads a non-deleted upload by ID.
func GetActiveUploadByID(ctx context.Context, id uint64) (models.Upload, error) {
var upload models.Upload
- if err := db.DB(ctx).Where("id = ? AND status != ?", id, models.UploadStatusDeleted).First(&upload).Error; err != nil {
+ if err := database.DB(ctx).Where("id = ? AND status != ?", id, models.UploadStatusDeleted).First(&upload).Error; err != nil {
return models.Upload{}, err
}
return upload, nil
@@ -67,7 +67,7 @@ func GetActiveUploadByID(ctx context.Context, id uint64) (models.Upload, error)
// SoftDeleteUpload marks an upload as deleted.
func SoftDeleteUpload(ctx context.Context, upload *models.Upload) error {
- return SoftDeleteUploadTx(db.DB(ctx), upload)
+ return SoftDeleteUploadTx(database.DB(ctx), upload)
}
// SoftDeleteUploadTx marks an upload as deleted within an existing transaction.
@@ -80,13 +80,13 @@ func UpdateUpload(ctx context.Context, upload *models.Upload, updates map[string
if len(updates) == 0 {
return nil
}
- return db.DB(ctx).Model(upload).Updates(updates).Error
+ return database.DB(ctx).Model(upload).Updates(updates).Error
}
// ListDistinctUploadTypes returns all distinct non-empty upload business types.
func ListDistinctUploadTypes(ctx context.Context) ([]string, error) {
var types []string
- if err := db.DB(ctx).Model(&models.Upload{}).
+ if err := database.DB(ctx).Model(&models.Upload{}).
Where("type IS NOT NULL AND type != ''").
Distinct().
Pluck("type", &types).Error; err != nil {
@@ -98,7 +98,7 @@ func ListDistinctUploadTypes(ctx context.Context) ([]string, error) {
// FindReusableUploadByHash finds an existing upload with the same hash and size.
func FindReusableUploadByHash(ctx context.Context, hash string, size int64) (models.Upload, error) {
var existing models.Upload
- err := db.DB(ctx).
+ err := database.DB(ctx).
Where("hash = ? AND file_size = ? AND status IN (?, ?)", hash, size, models.UploadStatusPending, models.UploadStatusUsed).
First(&existing).Error
return existing, err
@@ -106,7 +106,7 @@ func FindReusableUploadByHash(ctx context.Context, hash string, size int64) (mod
// CreateUpload persists a new upload record.
func CreateUpload(ctx context.Context, upload *models.Upload) error {
- return CreateUploadTx(db.DB(ctx), upload)
+ return CreateUploadTx(database.DB(ctx), upload)
}
// CreateUploadTx persists a new upload record within an existing transaction.
@@ -117,7 +117,7 @@ func CreateUploadTx(tx *gorm.DB, upload *models.Upload) error {
// ListUploadsByIDs returns active uploads matching the given IDs.
func ListUploadsByIDs(ctx context.Context, ids []uint64) ([]models.Upload, error) {
var uploads []models.Upload
- if err := db.DB(ctx).
+ if err := database.DB(ctx).
Where("id IN ? AND status IN (?, ?)", ids, models.UploadStatusPending, models.UploadStatusUsed).
Find(&uploads).Error; err != nil {
return nil, err
@@ -127,13 +127,13 @@ func ListUploadsByIDs(ctx context.Context, ids []uint64) ([]models.Upload, error
// UploadQuery returns a scoped GORM query for uploads.
func UploadQuery(ctx context.Context) *gorm.DB {
- return db.DB(ctx).Model(&models.Upload{})
+ return database.DB(ctx).Model(&models.Upload{})
}
// ListUploadStats returns all upload statistics rows.
func ListUploadStats(ctx context.Context) ([]models.UploadStat, error) {
var stats []models.UploadStat
- if err := db.DB(ctx).Find(&stats).Error; err != nil {
+ if err := database.DB(ctx).Find(&stats).Error; err != nil {
return nil, err
}
return stats, nil
diff --git a/plugins/domain/upload/shared/errs.go b/plugins/domain/upload/shared/errs.go
index f552aa2c..c3918866 100644
--- a/plugins/domain/upload/shared/errs.go
+++ b/plugins/domain/upload/shared/errs.go
@@ -40,4 +40,5 @@ const (
ErrQueryImagesForCacheWarmup = "查询待预热图片失败: %w"
ErrQueryTypeListFailed = "查询文件类型列表失败"
ErrUpdateFileFailed = "更新文件失败"
+ ErrUnauthorized = "未登录"
)
diff --git a/plugins/domain/upload/stats/stats_counter.go b/plugins/domain/upload/stats/stats_counter.go
index b4fd41b2..2ed8de33 100644
--- a/plugins/domain/upload/stats/stats_counter.go
+++ b/plugins/domain/upload/stats/stats_counter.go
@@ -8,7 +8,7 @@ import (
"time"
"github.com/Rain-kl/Wavelet/pkg/logger"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"gorm.io/gorm"
"gorm.io/gorm/clause"
@@ -26,7 +26,7 @@ func ApplyUploadStatsRemove(ctx context.Context, upload *models.Upload) error {
// RebuildUploadStats rebuilds all incremental stats from current upload records.
func RebuildUploadStats(ctx context.Context) error {
- return db.DB(ctx).Transaction(func(tx *gorm.DB) error {
+ return database.DB(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Where("1 = 1").Delete(&models.UploadStat{}).Error; err != nil {
return err
}
@@ -49,7 +49,7 @@ func applyUploadStatsDelta(ctx context.Context, upload *models.Upload, sign int6
if upload == nil || !isActiveUploadStatus(upload.Status) {
return nil
}
- return db.DB(ctx).Transaction(func(tx *gorm.DB) error {
+ return database.DB(ctx).Transaction(func(tx *gorm.DB) error {
return ApplyUploadStatsDeltaTx(tx, upload, sign)
})
}
diff --git a/plugins/domain/upload/stats/stats_counter_test.go b/plugins/domain/upload/stats/stats_counter_test.go
index baf22efd..4f570810 100644
--- a/plugins/domain/upload/stats/stats_counter_test.go
+++ b/plugins/domain/upload/stats/stats_counter_test.go
@@ -8,7 +8,7 @@ import (
"testing"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/pkg/testhelper"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"gorm.io/gorm"
@@ -29,7 +29,7 @@ func TestApplyUploadStatsDeltaTxWithinTransaction(t *testing.T) {
CreatedAt: time.Now(),
}
- if err := db.DB(ctx).Transaction(func(tx *gorm.DB) error {
+ if err := database.DB(ctx).Transaction(func(tx *gorm.DB) error {
return ApplyUploadStatsDeltaTx(tx, upload, 1)
}); err != nil {
t.Fatalf("ApplyUploadStatsDeltaTx returned error: %v", err)
@@ -90,7 +90,7 @@ type uploadStatsSnapshot struct {
func loadUploadStats(ctx context.Context) (uploadStatsSnapshot, error) {
var rows []models.UploadStat
- if err := db.DB(ctx).Where("dimension = ?", models.UploadStatDimensionTotal).Find(&rows).Error; err != nil {
+ if err := database.DB(ctx).Where("dimension = ?", models.UploadStatDimensionTotal).Find(&rows).Error; err != nil {
return uploadStatsSnapshot{}, err
}
if len(rows) == 0 {
diff --git a/plugins/domain/upload/storage/access_state.go b/plugins/domain/upload/storage/access_state.go
index 0011f82e..62a3c03f 100644
--- a/plugins/domain/upload/storage/access_state.go
+++ b/plugins/domain/upload/storage/access_state.go
@@ -9,9 +9,8 @@ import (
"sync"
"time"
- "github.com/Rain-kl/Wavelet/pkg/task"
-
"github.com/Rain-kl/Wavelet/plugins/domain/upload/shared"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/objectstore"
)
@@ -71,9 +70,9 @@ func buildMigrationAccessState(ctx context.Context) MigrationAccessState {
}
state := MigrationAccessState{
- ReadOnly: execution.Status != task.TaskExecutionStatusSucceeded,
+ ReadOnly: execution.Status != driver_asynq_worker.TaskExecutionStatusSucceeded,
}
- if execution.Status == task.TaskExecutionStatusSucceeded {
+ if execution.Status == driver_asynq_worker.TaskExecutionStatusSucceeded {
return state
}
diff --git a/plugins/domain/upload/storage/migration.go b/plugins/domain/upload/storage/migration.go
index df610ef3..91af0cd7 100644
--- a/plugins/domain/upload/storage/migration.go
+++ b/plugins/domain/upload/storage/migration.go
@@ -10,8 +10,7 @@ import (
"fmt"
"strings"
- "github.com/Rain-kl/Wavelet/pkg/task"
-
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/objectstore"
)
@@ -19,8 +18,8 @@ import (
const StorageMigrationTask = "storage:migrate"
// LatestMigrationExecution returns the most recent storage migration task execution.
-func LatestMigrationExecution(ctx context.Context) (*task.TaskExecution, bool, error) {
- return task.GetLatestTaskExecutionByTaskType(ctx, StorageMigrationTask)
+func LatestMigrationExecution(ctx context.Context) (*driver_asynq_worker.TaskExecution, bool, error) {
+ return driver_asynq_worker.GetLatestTaskExecutionByTaskType(ctx, StorageMigrationTask)
}
// ParseMigrationTargetConfig parses and validates a storage migration target payload.
diff --git a/plugins/domain/upload/task/cleanup.go b/plugins/domain/upload/task/cleanup.go
index 71148b15..da57a884 100644
--- a/plugins/domain/upload/task/cleanup.go
+++ b/plugins/domain/upload/task/cleanup.go
@@ -10,18 +10,18 @@ import (
"fmt"
"time"
- "github.com/Rain-kl/Wavelet/pkg/logger"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
+ "gorm.io/gorm"
- "github.com/Rain-kl/Wavelet/pkg/persistence/logstore"
- "github.com/Rain-kl/Wavelet/pkg/task"
+ "github.com/Rain-kl/Wavelet/pkg/logger"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
+ logstore "github.com/Rain-kl/Wavelet/plugins/domain/risk_control/logstore"
uploadcache "github.com/Rain-kl/Wavelet/plugins/domain/upload/cache"
+ "github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/shared"
uploadstats "github.com/Rain-kl/Wavelet/plugins/domain/upload/stats"
uploadstorage "github.com/Rain-kl/Wavelet/plugins/domain/upload/storage"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/objectstore"
- "gorm.io/gorm"
)
const (
@@ -32,14 +32,14 @@ const (
)
// SystemCleanupMeta represents the task metadata.
-var SystemCleanupMeta = task.TaskMeta{
+var SystemCleanupMeta = driver_asynq_worker.TaskMeta{
Type: TaskTypeSystemCleanup,
AsynqTask: SystemCleanupTask,
Name: "系统垃圾清理",
Description: "定期清理未使用上传文件、历史推送记录和过期任务执行日志",
SupportsTime: false,
- MaxRetry: task.DefaultMaxRetry,
- Queue: task.QueueDefault,
+ MaxRetry: driver_asynq_worker.DefaultMaxRetry,
+ Queue: driver_asynq_worker.QueueDefault,
Retryable: true,
}
@@ -47,7 +47,7 @@ var SystemCleanupMeta = task.TaskMeta{
type SystemCleanupHandler struct{}
// Execute 执行系统清理(包含文件清理、历史推送日志和任务执行日志清理)
-func (h *SystemCleanupHandler) Execute(ctx context.Context, _ []byte) (*task.TaskResult, error) {
+func (h *SystemCleanupHandler) Execute(ctx context.Context, _ []byte) (*driver_asynq_worker.TaskResult, error) {
if uploadstorage.ReadOnly(ctx) {
return nil, errors.New(shared.ErrStorageReadOnly)
}
@@ -58,16 +58,16 @@ func (h *SystemCleanupHandler) Execute(ctx context.Context, _ []byte) (*task.Tas
oneHourAgo := time.Now().Add(-1 * time.Hour)
- task.AppendLog(ctx, "开始扫描未使用上传文件,阈值: %s", oneHourAgo.Format(time.RFC3339))
+ driver_asynq_worker.AppendLog(ctx, "开始扫描未使用上传文件,阈值: %s", oneHourAgo.Format(time.RFC3339))
for {
var unusedUploads []models.Upload
- if err := db.DB(ctx).
+ if err := database.DB(ctx).
Where("id > ? AND status = ? AND created_at < ?", lastID, models.UploadStatusPending, oneHourAgo).
Order("id ASC").
Limit(batchSize).
Find(&unusedUploads).Error; err != nil {
- task.AppendLog(ctx, "查询未使用的上传文件失败: %v", err)
+ driver_asynq_worker.AppendLog(ctx, "查询未使用的上传文件失败: %v", err)
return nil, fmt.Errorf(shared.ErrQueryUnusedUploadsFailed, err)
}
@@ -75,12 +75,12 @@ func (h *SystemCleanupHandler) Execute(ctx context.Context, _ []byte) (*task.Tas
break
}
- task.AppendLog(ctx, "本批次找到 %d 个需要清理的上传文件", len(unusedUploads))
+ driver_asynq_worker.AppendLog(ctx, "本批次找到 %d 个需要清理的上传文件", len(unusedUploads))
for _, u := range unusedUploads {
totalProcessed++
- if err := db.DB(ctx).Transaction(func(tx *gorm.DB) error {
+ if err := database.DB(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Model(&models.Upload{}).
Where("id = ? AND status = ?", u.ID, models.UploadStatusPending).
Update("status", models.UploadStatusDeleted).Error; err != nil {
@@ -97,7 +97,7 @@ func (h *SystemCleanupHandler) Execute(ctx context.Context, _ []byte) (*task.Tas
return nil
}); err != nil {
- task.AppendLog(ctx, "清理上传文件失败 [ID:%d]: %v", u.ID, err)
+ driver_asynq_worker.AppendLog(ctx, "清理上传文件失败 [ID:%d]: %v", u.ID, err)
lastID = u.ID
continue
}
@@ -109,28 +109,28 @@ func (h *SystemCleanupHandler) Execute(ctx context.Context, _ []byte) (*task.Tas
}
}
- task.AppendLog(ctx, "开始清理历史推送审计日志,只保留最近7天数据...")
+ driver_asynq_worker.AppendLog(ctx, "开始清理历史推送审计日志,只保留最近7天数据...")
cutoff := time.Now().AddDate(0, 0, -7)
var pushHistoryCount int64
- if err := db.DB(ctx).Table("w_push_histories").Where("created_at < ?", cutoff).Count(&pushHistoryCount).Error; err != nil {
- task.AppendLog(ctx, "统计待清理的历史推送记录失败: %v", err)
+ if err := database.DB(ctx).Table("w_push_histories").Where("created_at < ?", cutoff).Count(&pushHistoryCount).Error; err != nil {
+ driver_asynq_worker.AppendLog(ctx, "统计待清理的历史推送记录失败: %v", err)
} else if pushHistoryCount > 0 {
- if err := db.DB(ctx).Table("w_push_histories").Where("created_at < ?", cutoff).Delete(map[string]any{}).Error; err != nil {
- task.AppendLog(ctx, "删除历史推送记录失败: %v", err)
+ if err := database.DB(ctx).Table("w_push_histories").Where("created_at < ?", cutoff).Delete(map[string]any{}).Error; err != nil {
+ driver_asynq_worker.AppendLog(ctx, "删除历史推送记录失败: %v", err)
} else {
- task.AppendLog(ctx, "成功删除 %d 条历史推送记录 (截止时间: %s)", pushHistoryCount, cutoff.Format("2006-01-02 15:04:05"))
+ driver_asynq_worker.AppendLog(ctx, "成功删除 %d 条历史推送记录 (截止时间: %s)", pushHistoryCount, cutoff.Format("2006-01-02 15:04:05"))
}
} else {
- task.AppendLog(ctx, "没有需要清理的历史推送记录 (截止时间: %s)", cutoff.Format("2006-01-02 15:04:05"))
+ driver_asynq_worker.AppendLog(ctx, "没有需要清理的历史推送记录 (截止时间: %s)", cutoff.Format("2006-01-02 15:04:05"))
}
- task.AppendLog(ctx, "开始清理任务执行日志:高频任务保留最近3天,低频任务保留最近30天...")
- taskLogStats, err := task.CleanupTaskExecutionLogs(ctx, time.Now())
+ driver_asynq_worker.AppendLog(ctx, "开始清理任务执行日志:高频任务保留最近3天,低频任务保留最近30天...")
+ taskLogStats, err := driver_asynq_worker.CleanupTaskExecutionLogs(ctx, time.Now())
if err != nil {
- task.AppendLog(ctx, "清理任务执行日志失败: %v", err)
+ driver_asynq_worker.AppendLog(ctx, "清理任务执行日志失败: %v", err)
logger.ErrorF(ctx, "清理任务执行日志失败: %v", err)
} else {
- task.AppendLog(ctx, "成功清理任务执行日志 %d 条(高频 %d 条,低频 %d 条)",
+ driver_asynq_worker.AppendLog(ctx, "成功清理任务执行日志 %d 条(高频 %d 条,低频 %d 条)",
taskLogStats.HighFrequencyDeleted+taskLogStats.LowFrequencyDeleted,
taskLogStats.HighFrequencyDeleted,
taskLogStats.LowFrequencyDeleted,
@@ -140,11 +140,11 @@ func (h *SystemCleanupHandler) Execute(ctx context.Context, _ []byte) (*task.Tas
var logDeleted int64
logSummary, logErr := logstore.CleanupExpired(ctx)
if logErr != nil {
- task.AppendLog(ctx, "清理过期用户访问日志失败: %v", logErr)
+ driver_asynq_worker.AppendLog(ctx, "清理过期用户访问日志失败: %v", logErr)
logger.ErrorF(ctx, "清理过期用户访问日志失败: %v", logErr)
} else {
logDeleted = logSummary.Deleted
- task.AppendLog(ctx, "成功清理过期用户访问日志 %d 条(%s 保留 %d 天)",
+ driver_asynq_worker.AppendLog(ctx, "成功清理过期用户访问日志 %d 条(%s 保留 %d 天)",
logSummary.Deleted, logSummary.ActiveDatabase, logSummary.RetentionDays)
}
@@ -155,6 +155,6 @@ func (h *SystemCleanupHandler) Execute(ctx context.Context, _ []byte) (*task.Tas
taskLogStats.HighFrequencyDeleted+taskLogStats.LowFrequencyDeleted,
logDeleted,
)
- task.AppendLog(ctx, "%s", msg)
- return &task.TaskResult{Message: msg}, nil
+ driver_asynq_worker.AppendLog(ctx, "%s", msg)
+ return &driver_asynq_worker.TaskResult{Message: msg}, nil
}
diff --git a/plugins/domain/upload/task/rebuild_stats.go b/plugins/domain/upload/task/rebuild_stats.go
index 9624c2d2..8f34f2e0 100644
--- a/plugins/domain/upload/task/rebuild_stats.go
+++ b/plugins/domain/upload/task/rebuild_stats.go
@@ -7,10 +7,10 @@ import (
"context"
"fmt"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/task"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
uploadstats "github.com/Rain-kl/Wavelet/plugins/domain/upload/stats"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
)
const (
@@ -21,14 +21,14 @@ const (
)
// RebuildUploadStatsMeta describes the upload stats rebuild task.
-var RebuildUploadStatsMeta = task.TaskMeta{
+var RebuildUploadStatsMeta = driver_asynq_worker.TaskMeta{
Type: TaskTypeRebuildUploadStats,
AsynqTask: RebuildUploadStatsTask,
Name: "重算文件存储统计",
Description: "根据当前 w_uploads 活跃记录全量重建 w_upload_stats(总量、类型、分类、趋势)",
SupportsTime: false,
- MaxRetry: task.DefaultMaxRetry,
- Queue: task.QueueDefault,
+ MaxRetry: driver_asynq_worker.DefaultMaxRetry,
+ Queue: driver_asynq_worker.QueueDefault,
Retryable: true,
}
@@ -36,28 +36,28 @@ var RebuildUploadStatsMeta = task.TaskMeta{
type RebuildUploadStatsHandler struct{}
// Execute scans active uploads and rebuilds all upload stat dimensions.
-func (h *RebuildUploadStatsHandler) Execute(ctx context.Context, _ []byte) (*task.TaskResult, error) {
+func (h *RebuildUploadStatsHandler) Execute(ctx context.Context, _ []byte) (*driver_asynq_worker.TaskResult, error) {
var activeCount int64
- if err := db.DB(ctx).
+ if err := database.DB(ctx).
Model(&models.Upload{}).
Where("status != ?", models.UploadStatusDeleted).
Count(&activeCount).Error; err != nil {
- task.AppendLog(ctx, "统计活跃上传记录失败: %v", err)
+ driver_asynq_worker.AppendLog(ctx, "统计活跃上传记录失败: %v", err)
return nil, fmt.Errorf("count active uploads: %w", err)
}
- task.AppendLog(ctx, "开始重算文件存储统计,活跃记录数: %d", activeCount)
+ driver_asynq_worker.AppendLog(ctx, "开始重算文件存储统计,活跃记录数: %d", activeCount)
if err := uploadstats.RebuildUploadStats(ctx); err != nil {
- task.AppendLog(ctx, "重算文件存储统计失败: %v", err)
+ driver_asynq_worker.AppendLog(ctx, "重算文件存储统计失败: %v", err)
return nil, fmt.Errorf("rebuild upload stats: %w", err)
}
var totalStat models.UploadStat
- if err := db.DB(ctx).
+ if err := database.DB(ctx).
Where("dimension = ? AND stat_key = ?", models.UploadStatDimensionTotal, "").
First(&totalStat).Error; err != nil {
- task.AppendLog(ctx, "读取总量统计失败: %v", err)
+ driver_asynq_worker.AppendLog(ctx, "读取总量统计失败: %v", err)
return nil, fmt.Errorf("load total upload stats: %w", err)
}
@@ -67,6 +67,6 @@ func (h *RebuildUploadStatsHandler) Execute(ctx context.Context, _ []byte) (*tas
totalStat.FileCount,
totalStat.FileSize,
)
- task.AppendLog(ctx, "%s", msg)
- return &task.TaskResult{Message: msg}, nil
+ driver_asynq_worker.AppendLog(ctx, "%s", msg)
+ return &driver_asynq_worker.TaskResult{Message: msg}, nil
}
diff --git a/plugins/domain/upload/task/rebuild_stats_test.go b/plugins/domain/upload/task/rebuild_stats_test.go
index 688274c5..e634d821 100644
--- a/plugins/domain/upload/task/rebuild_stats_test.go
+++ b/plugins/domain/upload/task/rebuild_stats_test.go
@@ -8,7 +8,7 @@ import (
"testing"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/pkg/testhelper"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
)
@@ -33,13 +33,13 @@ func TestRebuildUploadStatsHandler_Execute(t *testing.T) {
},
}
for i := range uploads {
- if err := db.DB(ctx).Create(&uploads[i]).Error; err != nil {
+ if err := database.DB(ctx).Create(&uploads[i]).Error; err != nil {
t.Fatalf("seed upload failed: %v", err)
}
}
// Corrupt stats to ensure rebuild recalculates from uploads.
- if err := db.DB(ctx).Create(&models.UploadStat{
+ if err := database.DB(ctx).Create(&models.UploadStat{
Dimension: models.UploadStatDimensionTotal,
StatKey: "",
FileCount: 0,
@@ -58,7 +58,7 @@ func TestRebuildUploadStatsHandler_Execute(t *testing.T) {
}
var totalStat models.UploadStat
- if err := db.DB(ctx).
+ if err := database.DB(ctx).
Where("dimension = ? AND stat_key = ?", models.UploadStatDimensionTotal, "").
First(&totalStat).Error; err != nil {
t.Fatalf("load total stat failed: %v", err)
diff --git a/plugins/domain/upload/task/storage_migration.go b/plugins/domain/upload/task/storage_migration.go
index cb041902..eb3bd802 100644
--- a/plugins/domain/upload/task/storage_migration.go
+++ b/plugins/domain/upload/task/storage_migration.go
@@ -15,14 +15,16 @@ import (
"sync/atomic"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/task"
+ "golang.org/x/sync/errgroup"
+
+ cache "github.com/Rain-kl/Wavelet/plugins/infra/cache"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/pkg/util"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
uploadstats "github.com/Rain-kl/Wavelet/plugins/domain/upload/stats"
uploadstorage "github.com/Rain-kl/Wavelet/plugins/domain/upload/storage"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/objectstore"
- "golang.org/x/sync/errgroup"
)
const (
@@ -33,16 +35,16 @@ const (
)
// StorageMigrationMeta describes the manually dispatchable migration task.
-var StorageMigrationMeta = task.TaskMeta{
+var StorageMigrationMeta = driver_asynq_worker.TaskMeta{
Type: TaskTypeStorageMigration,
AsynqTask: StorageMigrationTask,
Name: "迁移文件存储",
Description: "将活动存储中的文件迁移到待切换的目标存储,迁移期间文件系统保持只读",
SupportsTime: false,
- MaxRetry: task.DefaultMaxRetry,
- Queue: task.QueueDefault,
+ MaxRetry: driver_asynq_worker.DefaultMaxRetry,
+ Queue: driver_asynq_worker.QueueDefault,
Retryable: true,
- Params: []task.TaskParam{
+ Params: []driver_asynq_worker.TaskParam{
{
Name: "target",
Label: "目标存储配置 (JSON)",
@@ -74,15 +76,15 @@ func (h *MigrationHandler) ValidatePayload(payload []byte) ([]byte, error) {
}
// Execute migrates all unique active-storage objects to the pending backend.
-func (h *MigrationHandler) Execute(ctx context.Context, payload []byte) (*task.TaskResult, error) {
- if db.Redis != nil {
+func (h *MigrationHandler) Execute(ctx context.Context, payload []byte) (*driver_asynq_worker.TaskResult, error) {
+ if cache.Redis != nil {
const (
cleanupTimeout = 5 * time.Second
renewalInterval = 10 * time.Minute
)
- lockKey := db.PrefixedKey("lock:storage:migrate")
- ok, err := db.Redis.SetNX(ctx, lockKey, "locked", time.Hour).Result()
+ lockKey := cache.PrefixedKey("lock:storage:migrate")
+ ok, err := cache.Redis.SetNX(ctx, lockKey, "locked", time.Hour).Result()
if err != nil {
return nil, fmt.Errorf("acquire migration lock: %w", err)
}
@@ -96,7 +98,7 @@ func (h *MigrationHandler) Execute(ctx context.Context, payload []byte) (*task.T
close(stopRenewal)
cleanupCtx, cancel := context.WithTimeout(context.Background(), cleanupTimeout)
defer cancel()
- _ = db.Redis.Del(cleanupCtx, lockKey)
+ _ = cache.Redis.Del(cleanupCtx, lockKey)
}()
//nolint:contextcheck,gosec
@@ -107,7 +109,7 @@ func (h *MigrationHandler) Execute(ctx context.Context, payload []byte) (*task.T
select {
case <-ticker.C:
renewCtx, cancel := context.WithTimeout(context.Background(), cleanupTimeout)
- _ = db.Redis.Expire(renewCtx, lockKey, time.Hour).Err()
+ _ = cache.Redis.Expire(renewCtx, lockKey, time.Hour).Err()
cancel()
case <-stopRenewal:
return
@@ -131,8 +133,8 @@ func (h *MigrationHandler) Execute(ctx context.Context, payload []byte) (*task.T
return nil, fmt.Errorf("activate same-driver storage config: %w", err)
}
message := fmt.Sprintf("存储配置已更新,活动存储保持为 %s", target.Driver)
- task.AppendLog(ctx, "%s", message)
- return &task.TaskResult{Message: message}, nil
+ driver_asynq_worker.AppendLog(ctx, "%s", message)
+ return &driver_asynq_worker.TaskResult{Message: message}, nil
}
total, err := countStorageObjects(ctx)
@@ -144,8 +146,8 @@ func (h *MigrationHandler) Execute(ctx context.Context, payload []byte) (*task.T
return nil, fmt.Errorf("activate empty storage config: %w", err)
}
message := fmt.Sprintf("当前存储没有需要迁移的对象,活动存储已切换为 %s", target.Driver)
- task.AppendLog(ctx, "%s", message)
- return &task.TaskResult{Message: message}, nil
+ driver_asynq_worker.AppendLog(ctx, "%s", message)
+ return &driver_asynq_worker.TaskResult{Message: message}, nil
}
sourceBackend, err := objectstore.NewBackend(ctx, active, active.Driver)
@@ -157,7 +159,7 @@ func (h *MigrationHandler) Execute(ctx context.Context, payload []byte) (*task.T
return nil, fmt.Errorf("create target storage: %w", err)
}
- task.AppendLog(ctx, "开始存储迁移: %s -> %s,总对象数: %d", active.Driver, target.Driver, total)
+ driver_asynq_worker.AppendLog(ctx, "开始存储迁移: %s -> %s,总对象数: %d", active.Driver, target.Driver, total)
migrated, err := migrateObjects(ctx, sourceBackend, targetBackend, total)
if err != nil {
return nil, err
@@ -167,13 +169,13 @@ func (h *MigrationHandler) Execute(ctx context.Context, payload []byte) (*task.T
return nil, fmt.Errorf("activate target storage: %w", err)
}
message := fmt.Sprintf("存储迁移完成,共迁移 %d 个对象,活动存储已切换为 %s", migrated, target.Driver)
- task.AppendLog(ctx, "%s", message)
- return &task.TaskResult{Message: message}, nil
+ driver_asynq_worker.AppendLog(ctx, "%s", message)
+ return &driver_asynq_worker.TaskResult{Message: message}, nil
}
func countStorageObjects(ctx context.Context) (int64, error) {
var count int64
- err := db.DB(ctx).Model(&models.Upload{}).
+ err := database.DB(ctx).Model(&models.Upload{}).
Where("status != ?", models.UploadStatusDeleted).
Distinct("file_path").
Count(&count).Error
@@ -185,7 +187,7 @@ func hasUnresolvedMigrationTask(ctx context.Context) (bool, error) {
if err != nil || !ok {
return false, err
}
- return execution.Status == task.TaskExecutionStatusPending || execution.Status == task.TaskExecutionStatusRunning, nil
+ return execution.Status == driver_asynq_worker.TaskExecutionStatusPending || execution.Status == driver_asynq_worker.TaskExecutionStatusRunning, nil
}
type migrationObject struct {
@@ -211,10 +213,10 @@ func migrateObjects(
return atomic.LoadInt64(&migrated), fmt.Errorf("storage migration canceled: %w", err)
}
- task.AppendLog(ctx, "正在查询待迁移对象批次,当前已完成迁移: %d/%d", atomic.LoadInt64(&migrated), total)
+ driver_asynq_worker.AppendLog(ctx, "正在查询待迁移对象批次,当前已完成迁移: %d/%d", atomic.LoadInt64(&migrated), total)
var objects []migrationObject
- query := db.DB(ctx).Model(&models.Upload{}).
+ query := database.DB(ctx).Model(&models.Upload{}).
Select("file_path, MAX(file_size) AS file_size, MAX(mime_type) AS mime_type, MAX(hash) AS hash").
Where("status != ?", models.UploadStatusDeleted)
if lastFilePath != "" {
@@ -227,12 +229,12 @@ func migrateObjects(
return atomic.LoadInt64(&migrated), fmt.Errorf("query source objects: %w", err)
}
if len(objects) == 0 {
- task.AppendLog(ctx, "所有对象迁移完毕")
+ driver_asynq_worker.AppendLog(ctx, "所有对象迁移完毕")
break
}
lastFilePath = objects[len(objects)-1].FilePath
- task.AppendLog(ctx, "获取当前批次迁移对象,批次大小: %d,实际获取对象数: %d", batchSize, len(objects))
+ driver_asynq_worker.AppendLog(ctx, "获取当前批次迁移对象,批次大小: %d,实际获取对象数: %d", batchSize, len(objects))
var g errgroup.Group
g.SetLimit(migrationConcurrency)
@@ -252,7 +254,7 @@ func migrateObjects(
return atomic.LoadInt64(&migrated), err
}
- task.AppendLog(ctx, "当前批次迁移完成。迁移进度: %d/%d", atomic.LoadInt64(&migrated), total)
+ driver_asynq_worker.AppendLog(ctx, "当前批次迁移完成。迁移进度: %d/%d", atomic.LoadInt64(&migrated), total)
}
return atomic.LoadInt64(&migrated), nil
}
@@ -265,11 +267,11 @@ func migrateSingleObject(
sha256HexLength int,
) error {
if shouldSkipMigration(ctx, targetBackend, obj) {
- task.AppendLog(ctx, "[跳过迁移] 目标存储已存在相同文件: %s", obj.FilePath)
+ driver_asynq_worker.AppendLog(ctx, "[跳过迁移] 目标存储已存在相同文件: %s", obj.FilePath)
return nil
}
- task.AppendLog(ctx, "[迁移开始] 正在从源存储读取文件: %s", obj.FilePath)
+ driver_asynq_worker.AppendLog(ctx, "[迁移开始] 正在从源存储读取文件: %s", obj.FilePath)
source, err := sourceBackend.Get(ctx, obj.FilePath)
if err != nil {
if isNotFoundError(err) {
@@ -277,7 +279,7 @@ func migrateSingleObject(
}
return fmt.Errorf("open source object %q: %w", obj.FilePath, err)
}
- task.AppendLog(ctx, "[传输中] 正在向目标存储上传文件: %s (大小: %d 字节, 类型: %s)", obj.FilePath, obj.FileSize, obj.MimeType)
+ driver_asynq_worker.AppendLog(ctx, "[传输中] 正在向目标存储上传文件: %s (大小: %d 字节, 类型: %s)", obj.FilePath, obj.FileSize, obj.MimeType)
targetResult, putErr := targetBackend.Put(ctx, obj.FilePath, source.Body, obj.FileSize, obj.MimeType)
closeErr := source.Body.Close()
if putErr != nil {
@@ -288,7 +290,7 @@ func migrateSingleObject(
}
if len(obj.Hash) == sha256HexLength {
- task.AppendLog(ctx, "[校验中] 正在对目标文件进行数据一致性校验 (SHA-256): %s", targetResult.Key)
+ driver_asynq_worker.AppendLog(ctx, "[校验中] 正在对目标文件进行数据一致性校验 (SHA-256): %s", targetResult.Key)
targetObj, getErr := targetBackend.Get(ctx, targetResult.Key)
if getErr != nil {
return fmt.Errorf("retrieve target object for verification %q: %w", obj.FilePath, getErr)
@@ -306,18 +308,18 @@ func migrateSingleObject(
if computedHash != obj.Hash {
return fmt.Errorf("integrity check failed for %q: got hash %s, want %s", obj.FilePath, computedHash, obj.Hash)
}
- task.AppendLog(ctx, "[校验通过] 文件一致性校验成功: %s", targetResult.Key)
+ driver_asynq_worker.AppendLog(ctx, "[校验通过] 文件一致性校验成功: %s", targetResult.Key)
}
if targetResult.Key != obj.FilePath {
- task.AppendLog(ctx, "[更新数据库] 正在更新文件路径: %s -> %s", obj.FilePath, targetResult.Key)
- if err := db.DB(ctx).Model(&models.Upload{}).
+ driver_asynq_worker.AppendLog(ctx, "[更新数据库] 正在更新文件路径: %s -> %s", obj.FilePath, targetResult.Key)
+ if err := database.DB(ctx).Model(&models.Upload{}).
Where("file_path = ? AND status != ?", obj.FilePath, models.UploadStatusDeleted).
Update("file_path", targetResult.Key).Error; err != nil {
return fmt.Errorf("update migrated object %q: %w", obj.FilePath, err)
}
}
- task.AppendLog(ctx, "[迁移成功] 文件已完成迁移: %s", targetResult.Key)
+ driver_asynq_worker.AppendLog(ctx, "[迁移成功] 文件已完成迁移: %s", targetResult.Key)
return nil
}
@@ -342,15 +344,15 @@ func markMissingMigrationObjectDeleted(
filePath string,
sourceErr error,
) error {
- task.AppendLog(ctx, "警告: 源存储中物理文件不存在,标记为已删除并跳过: %s (错误: %v)", filePath, sourceErr)
+ driver_asynq_worker.AppendLog(ctx, "警告: 源存储中物理文件不存在,标记为已删除并跳过: %s (错误: %v)", filePath, sourceErr)
var affectedUploads []models.Upload
- if err := db.DB(ctx).
+ if err := database.DB(ctx).
Where("file_path = ? AND status != ?", filePath, models.UploadStatusDeleted).
Find(&affectedUploads).Error; err != nil {
return fmt.Errorf("load missing object uploads %q: %w", filePath, err)
}
- if err := db.DB(ctx).Model(&models.Upload{}).
+ if err := database.DB(ctx).Model(&models.Upload{}).
Where("file_path = ?", filePath).
Update("status", models.UploadStatusDeleted).Error; err != nil {
return fmt.Errorf("update missing object %q: %w", filePath, err)
diff --git a/plugins/domain/upload/task/storage_migration_task_test.go b/plugins/domain/upload/task/storage_migration_task_test.go
index ae2be51f..e03746a6 100644
--- a/plugins/domain/upload/task/storage_migration_task_test.go
+++ b/plugins/domain/upload/task/storage_migration_task_test.go
@@ -16,7 +16,7 @@ import (
"testing"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ cache "github.com/Rain-kl/Wavelet/plugins/infra/cache"
"github.com/Rain-kl/Wavelet/pkg/testhelper"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/objectstore"
@@ -239,16 +239,16 @@ func TestMigrationHandlerExecuteWithRedisLock(t *testing.T) {
})
defer rdb.Close()
- oldRedis := db.Redis
- db.Redis = rdb
+ oldRedis := cache.Redis
+ cache.Redis = rdb
defer func() {
- db.Redis = oldRedis
+ cache.Redis = oldRedis
}()
ctx := context.Background()
// Acquire lock manually
- lockKey := db.PrefixedKey("lock:storage:migrate")
+ lockKey := cache.PrefixedKey("lock:storage:migrate")
if err := rdb.Set(ctx, lockKey, "locked", time.Hour).Err(); err != nil {
t.Fatalf("Failed to set manual lock in Redis: %v", err)
}
diff --git a/plugins/domain/upload/task/tasks.go b/plugins/domain/upload/task/tasks.go
index c28bff2b..31de72a2 100644
--- a/plugins/domain/upload/task/tasks.go
+++ b/plugins/domain/upload/task/tasks.go
@@ -12,11 +12,11 @@ import (
"strings"
"sync"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/task"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/filesrv"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/shared"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
)
const (
@@ -29,16 +29,16 @@ const (
var warmImageCacheMu sync.Mutex
// WarmImageCacheMeta represents the image cache warmup task metadata.
-var WarmImageCacheMeta = task.TaskMeta{
+var WarmImageCacheMeta = driver_asynq_worker.TaskMeta{
Type: TaskTypeWarmImageCache,
AsynqTask: WarmImageCacheTask,
Name: "预热图片压缩缓存",
Description: "串行将文件管理中的图片转换为指定质量的 WebP 并写入永久缓存",
SupportsTime: false,
- MaxRetry: task.DefaultMaxRetry,
- Queue: task.QueueDefault,
+ MaxRetry: driver_asynq_worker.DefaultMaxRetry,
+ Queue: driver_asynq_worker.QueueDefault,
Retryable: true,
- Params: []task.TaskParam{
+ Params: []driver_asynq_worker.TaskParam{
{
Name: "quality",
Label: "图片质量",
@@ -80,10 +80,10 @@ func (h *WarmImageCacheHandler) ValidatePayload(payload []byte) ([]byte, error)
}
// Execute serially converts all managed images to WebP cache entries.
-func (h *WarmImageCacheHandler) Execute(ctx context.Context, payload []byte) (*task.TaskResult, error) {
+func (h *WarmImageCacheHandler) Execute(ctx context.Context, payload []byte) (*driver_asynq_worker.TaskResult, error) {
normalizedPayload, err := h.ValidatePayload(payload)
if err != nil {
- task.AppendLog(ctx, "图片缓存预热参数无效: %v", err)
+ driver_asynq_worker.AppendLog(ctx, "图片缓存预热参数无效: %v", err)
return nil, err
}
@@ -92,7 +92,7 @@ func (h *WarmImageCacheHandler) Execute(ctx context.Context, payload []byte) (*t
return nil, fmt.Errorf(shared.ErrParseImageCacheWarmupPayload, err)
}
- task.AppendLog(ctx, "等待获取图片缓存预热执行锁,质量: %s", req.Quality)
+ driver_asynq_worker.AppendLog(ctx, "等待获取图片缓存预热执行锁,质量: %s", req.Quality)
warmImageCacheMu.Lock()
defer warmImageCacheMu.Unlock()
@@ -106,7 +106,7 @@ func (h *WarmImageCacheHandler) Execute(ctx context.Context, payload []byte) (*t
var totalGenerated int
var totalFailed int
- task.AppendLog(ctx, "开始串行预热图片压缩缓存,质量: %s,每批: %d", req.Quality, batchSize)
+ driver_asynq_worker.AppendLog(ctx, "开始串行预热图片压缩缓存,质量: %s,每批: %d", req.Quality, batchSize)
for {
if err := ctx.Err(); err != nil {
@@ -114,7 +114,7 @@ func (h *WarmImageCacheHandler) Execute(ctx context.Context, payload []byte) (*t
}
var uploads []models.Upload
- if err := db.DB(ctx).
+ if err := database.DB(ctx).
Where("id > ? AND status != ? AND (LOWER(mime_type) LIKE ? OR LOWER(extension) IN ?)",
lastID,
models.UploadStatusDeleted,
@@ -124,7 +124,7 @@ func (h *WarmImageCacheHandler) Execute(ctx context.Context, payload []byte) (*t
Order("id ASC").
Limit(batchSize).
Find(&uploads).Error; err != nil {
- task.AppendLog(ctx, "查询图片上传记录失败: %v", err)
+ driver_asynq_worker.AppendLog(ctx, "查询图片上传记录失败: %v", err)
return nil, fmt.Errorf(shared.ErrQueryImagesForCacheWarmup, err)
}
@@ -149,7 +149,7 @@ func (h *WarmImageCacheHandler) Execute(ctx context.Context, payload []byte) (*t
totalFailed++
batchFailed++
if totalFailed <= maxFailureLogs {
- task.AppendLog(ctx, "图片处理失败 [ID:%d]: %v", upload.ID, err)
+ driver_asynq_worker.AppendLog(ctx, "图片处理失败 [ID:%d]: %v", upload.ID, err)
}
continue
}
@@ -162,7 +162,7 @@ func (h *WarmImageCacheHandler) Execute(ctx context.Context, payload []byte) (*t
batchGenerated++
}
- task.AppendLog(
+ driver_asynq_worker.AppendLog(
ctx,
"批次完成,末尾 ID: %d,生成: %d,命中: %d,失败: %d",
lastID,
@@ -179,6 +179,6 @@ func (h *WarmImageCacheHandler) Execute(ctx context.Context, payload []byte) (*t
totalCached,
totalFailed,
)
- task.AppendLog(ctx, "%s", msg)
- return &task.TaskResult{Message: msg}, nil
+ driver_asynq_worker.AppendLog(ctx, "%s", msg)
+ return &driver_asynq_worker.TaskResult{Message: msg}, nil
}
diff --git a/plugins/domain/upload/task/tasks_test.go b/plugins/domain/upload/task/tasks_test.go
index 64b5c6a4..d940461a 100644
--- a/plugins/domain/upload/task/tasks_test.go
+++ b/plugins/domain/upload/task/tasks_test.go
@@ -17,13 +17,13 @@ import (
"testing"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/task"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/pkg/testhelper"
msg "github.com/Rain-kl/Wavelet/plugins/domain/message_gateway"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/filesrv"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/models"
"github.com/Rain-kl/Wavelet/plugins/domain/upload/shared"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/diskcache"
"github.com/Rain-kl/Wavelet/plugins/infra/storage/objectstore"
"github.com/stretchr/testify/assert"
@@ -48,7 +48,7 @@ func TestSystemCleanupHandler_Execute(t *testing.T) {
objectstore.ResetCache()
ctx := context.Background()
- err := db.DB(ctx).AutoMigrate(&msg.PushHistory{})
+ err := database.DB(ctx).AutoMigrate(&msg.PushHistory{})
require.NoError(t, err)
// 准备测试数据:创建一些上传记录
@@ -85,7 +85,7 @@ func TestSystemCleanupHandler_Execute(t *testing.T) {
},
}
for _, r := range records {
- err := db.DB(ctx).Create(r).Error
+ err := database.DB(ctx).Create(r).Error
require.NoError(t, err)
}
@@ -110,21 +110,21 @@ func TestSystemCleanupHandler_Execute(t *testing.T) {
Status: "success",
CreatedAt: now,
}
- err = db.DB(ctx).Create(oldPush).Error
+ err = database.DB(ctx).Create(oldPush).Error
require.NoError(t, err)
- err = db.DB(ctx).Create(newPush).Error
+ err = database.DB(ctx).Create(newPush).Error
require.NoError(t, err)
- oldTaskLog := &task.TaskExecution{
+ oldTaskLog := &driver_asynq_worker.TaskExecution{
TaskID: "old_low_frequency_task_log",
TaskType: "low:frequency",
TaskName: "低频任务",
- Status: task.TaskExecutionStatusSucceeded,
+ Status: driver_asynq_worker.TaskExecutionStatusSucceeded,
CreatedAt: now.AddDate(0, 0, -31),
UpdatedAt: now.AddDate(0, 0, -31),
TriggeredBy: "system",
}
- err = task.CreateTaskExecution(ctx, oldTaskLog)
+ err = driver_asynq_worker.CreateTaskExecution(ctx, oldTaskLog)
require.NoError(t, err)
// 执行 handler
@@ -138,29 +138,29 @@ func TestSystemCleanupHandler_Execute(t *testing.T) {
// 验证数据库状态:pending 且超过1小时的应被标记为 deleted
var pendingCount int64
- db.DB(ctx).Model(&models.Upload{}).Where("status = ?", models.UploadStatusPending).Count(&pendingCount)
+ database.DB(ctx).Model(&models.Upload{}).Where("status = ?", models.UploadStatusPending).Count(&pendingCount)
assert.Equal(t, int64(1), pendingCount, "应只剩1条 pending 记录(最近的文件)")
var deletedCount int64
- db.DB(ctx).Model(&models.Upload{}).Where("status = ?", models.UploadStatusDeleted).Count(&deletedCount)
+ database.DB(ctx).Model(&models.Upload{}).Where("status = ?", models.UploadStatusDeleted).Count(&deletedCount)
assert.Equal(t, int64(2), deletedCount, "应有2条被标记为 deleted")
var usedCount int64
- db.DB(ctx).Model(&models.Upload{}).Where("status = ?", models.UploadStatusUsed).Count(&usedCount)
+ database.DB(ctx).Model(&models.Upload{}).Where("status = ?", models.UploadStatusUsed).Count(&usedCount)
assert.Equal(t, int64(1), usedCount, "used 状态的文件不应受影响")
// 验证推送历史数据状态:10天前的应被删除,今天的应保留
var pushCount int64
- db.DB(ctx).Model(&msg.PushHistory{}).Count(&pushCount)
+ database.DB(ctx).Model(&msg.PushHistory{}).Count(&pushCount)
assert.Equal(t, int64(1), pushCount, "应只剩1条推送历史记录")
var remainingPush msg.PushHistory
- err = db.DB(ctx).First(&remainingPush).Error
+ err = database.DB(ctx).First(&remainingPush).Error
require.NoError(t, err)
assert.Equal(t, "New Login", remainingPush.Title)
var taskLogCount int64
- err = db.DB(ctx).Model(&task.TaskExecution{}).Where("task_id = ?", "old_low_frequency_task_log").Count(&taskLogCount).Error
+ err = database.DB(ctx).Model(&driver_asynq_worker.TaskExecution{}).Where("task_id = ?", "old_low_frequency_task_log").Count(&taskLogCount).Error
require.NoError(t, err)
assert.Equal(t, int64(0), taskLogCount, "过期低频任务日志应被清理")
}
@@ -180,7 +180,7 @@ func TestSystemCleanupHandler_ExecuteNoFiles(t *testing.T) {
defer storageMock()
ctx := context.Background()
- err := db.DB(ctx).AutoMigrate(&msg.PushHistory{})
+ err := database.DB(ctx).AutoMigrate(&msg.PushHistory{})
require.NoError(t, err)
// 没有任何上传记录
@@ -194,7 +194,7 @@ func TestSystemCleanupHandler_ExecuteNoFiles(t *testing.T) {
func TestSystemCleanupHandler_ImplementsTaskHandler(t *testing.T) {
// 编译期验证 SystemCleanupHandler 实现了 TaskHandler 接口
- var _ task.TaskHandler = (*SystemCleanupHandler)(nil)
+ var _ driver_asynq_worker.TaskHandler = (*SystemCleanupHandler)(nil)
}
func TestWarmImageCacheHandlerValidatePayload(t *testing.T) {
@@ -362,8 +362,8 @@ func TestWarmImageCacheHandlerExecute(t *testing.T) {
}
func TestWarmImageCacheHandlerImplementsTaskInterfaces(t *testing.T) {
- var _ task.TaskHandler = (*WarmImageCacheHandler)(nil)
- var _ task.PayloadValidator = (*WarmImageCacheHandler)(nil)
+ var _ driver_asynq_worker.TaskHandler = (*WarmImageCacheHandler)(nil)
+ var _ driver_asynq_worker.PayloadValidator = (*WarmImageCacheHandler)(nil)
}
func writeTaskTestPNG(t *testing.T, path string, fill color.RGBA) {
diff --git a/plugins/domain/user/handlers.go b/plugins/domain/user/handlers.go
index 15fcf27b..74755fe4 100644
--- a/plugins/domain/user/handlers.go
+++ b/plugins/domain/user/handlers.go
@@ -11,7 +11,7 @@ import (
"strconv"
"time"
- persistence "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/pkg/response"
"github.com/Rain-kl/Wavelet/plugins/domain/auth"
@@ -96,7 +96,7 @@ func Register(c *gin.Context) {
return
}
- gormDB := persistence.DB(c.Request.Context())
+ gormDB := database.DB(c.Request.Context())
if err := gormDB.Create(newUser).Error; err != nil {
response.AbortBadRequest(c, "创建用户失败: "+err.Error())
return
@@ -143,7 +143,7 @@ func ChangePassword(c *gin.Context) {
return
}
- gormDB := persistence.DB(c.Request.Context())
+ gormDB := database.DB(c.Request.Context())
_ = gormDB.Save(&user)
auth.InvalidateCachedUser(c.Request.Context(), user.ID)
@@ -173,7 +173,7 @@ func UpdateProfile(c *gin.Context) {
user.Website = req.Website
user.Location = req.Location
- gormDB := persistence.DB(c.Request.Context())
+ gormDB := database.DB(c.Request.Context())
_ = gormDB.Save(&user)
auth.InvalidateCachedUser(c.Request.Context(), user.ID)
@@ -184,7 +184,7 @@ func UpdateProfile(c *gin.Context) {
func ListAccessTokens(c *gin.Context) {
userID := auth.GetUserIDFromContext(c)
var tokens []AccessToken
- gormDB := persistence.DB(c.Request.Context())
+ gormDB := database.DB(c.Request.Context())
_ = gormDB.Where("user_id = ?", userID).Find(&tokens).Error
c.JSON(http.StatusOK, response.OK(tokens))
}
@@ -222,7 +222,7 @@ func CreateAccessToken(c *gin.Context) {
IsAdmin: req.IsAdmin,
}
- gormDB := persistence.DB(c.Request.Context())
+ gormDB := database.DB(c.Request.Context())
if err := gormDB.Create(&token).Error; err != nil {
response.AbortInternal(c, "创建令牌失败")
return
@@ -245,7 +245,7 @@ func DeleteAccessToken(c *gin.Context) {
userID := auth.GetUserIDFromContext(c)
var token AccessToken
- gormDB := persistence.DB(c.Request.Context())
+ gormDB := database.DB(c.Request.Context())
if err := gormDB.Where("id = ? AND user_id = ?", id, userID).First(&token).Error; err != nil {
response.AbortNotFound(c, errTokenNotFound)
return
@@ -267,7 +267,7 @@ func RotateAccessToken(c *gin.Context) {
userID := auth.GetUserIDFromContext(c)
var token AccessToken
- gormDB := persistence.DB(c.Request.Context())
+ gormDB := database.DB(c.Request.Context())
if err := gormDB.Where("id = ? AND user_id = ?", id, userID).First(&token).Error; err != nil {
response.AbortNotFound(c, errTokenNotFound)
return
diff --git a/plugins/domain/user/plugin_test.go b/plugins/domain/user/plugin_test.go
index 55ae3ec6..e0fe597d 100644
--- a/plugins/domain/user/plugin_test.go
+++ b/plugins/domain/user/plugin_test.go
@@ -15,7 +15,7 @@ import (
"github.com/Rain-kl/Wavelet/core"
"github.com/Rain-kl/Wavelet/core/contracts"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/plugins/domain/user"
)
@@ -30,7 +30,7 @@ func setupTestDB(t *testing.T) *gorm.DB {
&user.AccessToken{},
))
- db.SetDB(testDB)
+ database.SetDB(testDB)
return testDB
}
diff --git a/plugins/domain/user/repository.go b/plugins/domain/user/repository.go
index 106137b6..e8d423dd 100644
--- a/plugins/domain/user/repository.go
+++ b/plugins/domain/user/repository.go
@@ -9,7 +9,7 @@ import (
"strings"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/pkg/util"
"gorm.io/gorm"
)
@@ -17,7 +17,7 @@ import (
// GetUserByID 通过 ID 获取用户
func GetUserByID(ctx context.Context, id uint64) (*User, error) {
var u User
- if err := db.DB(ctx).First(&u, id).Error; err != nil {
+ if err := database.DB(ctx).First(&u, id).Error; err != nil {
return nil, err
}
return &u, nil
@@ -26,7 +26,7 @@ func GetUserByID(ctx context.Context, id uint64) (*User, error) {
// GetUserByUsername 通过用户名获取用户
func GetUserByUsername(ctx context.Context, username string) (*User, error) {
var u User
- if err := db.DB(ctx).Where("username = ?", username).First(&u).Error; err != nil {
+ if err := database.DB(ctx).Where("username = ?", username).First(&u).Error; err != nil {
return nil, err
}
return &u, nil
@@ -35,7 +35,7 @@ func GetUserByUsername(ctx context.Context, username string) (*User, error) {
// GetUserByEmail 通过邮箱获取用户
func GetUserByEmail(ctx context.Context, email string) (*User, error) {
var u User
- if err := db.DB(ctx).Where("email = ?", email).First(&u).Error; err != nil {
+ if err := database.DB(ctx).Where("email = ?", email).First(&u).Error; err != nil {
return nil, err
}
return &u, nil
@@ -43,17 +43,17 @@ func GetUserByEmail(ctx context.Context, email string) (*User, error) {
// CreateUser 创建用户
func CreateUser(ctx context.Context, u *User) error {
- return db.DB(ctx).Create(u).Error
+ return database.DB(ctx).Create(u).Error
}
// UpdateUser 更新用户
func UpdateUser(ctx context.Context, u *User) error {
- return db.DB(ctx).Save(u).Error
+ return database.DB(ctx).Save(u).Error
}
// ListUsers 分页查询用户
func ListUsers(ctx context.Context, page, pageSize int, keyword string) ([]*User, int64, error) {
- db := db.DB(ctx).Model(&User{})
+ db := database.DB(ctx).Model(&User{})
if keyword != "" {
escaped := util.EscapeLike(keyword)
db = db.Where("username LIKE ? ESCAPE '\\' OR nickname LIKE ? ESCAPE '\\' OR email LIKE ? ESCAPE '\\'", "%"+escaped+"%", "%"+escaped+"%", "%"+escaped+"%")
@@ -75,7 +75,7 @@ func ListUsers(ctx context.Context, page, pageSize int, keyword string) ([]*User
// GetAccessTokenByHash 通过 Hash 查询访问令牌
func GetAccessTokenByHash(ctx context.Context, tokenHash string) (*AccessToken, error) {
var token AccessToken
- if err := db.DB(ctx).Where("token_hash = ?", tokenHash).First(&token).Error; err != nil {
+ if err := database.DB(ctx).Where("token_hash = ?", tokenHash).First(&token).Error; err != nil {
return nil, err
}
return &token, nil
@@ -91,7 +91,7 @@ type AdminUserListFilter struct {
// ListAdminUsers 获取后台管理用户列表
func ListAdminUsers(ctx context.Context, filter AdminUserListFilter) (int64, []User, error) {
- query := db.DB(ctx).Model(&User{})
+ query := database.DB(ctx).Model(&User{})
if filter.Username != "" {
escaped := util.EscapeLike(strings.ToLower(filter.Username))
query = query.Where("LOWER(username) LIKE ? ESCAPE '\\'", "%"+escaped+"%")
@@ -117,13 +117,13 @@ func ListAdminUsers(ctx context.Context, filter AdminUserListFilter) (int64, []U
// UpdateUserActive 更新用户激活状态
func UpdateUserActive(ctx context.Context, id uint64, active bool) error {
- return db.DB(ctx).Model(&User{}).Where("id = ?", id).Update("is_active", active).Error
+ return database.DB(ctx).Model(&User{}).Where("id = ?", id).Update("is_active", active).Error
}
// GetActiveUserByID 获取处于激活状态的用户
func GetActiveUserByID(ctx context.Context, id uint64) (*User, error) {
var u User
- if err := db.DB(ctx).Where("id = ? AND is_active = ?", id, true).First(&u).Error; err != nil {
+ if err := database.DB(ctx).Where("id = ? AND is_active = ?", id, true).First(&u).Error; err != nil {
return nil, err
}
return &u, nil
@@ -131,7 +131,7 @@ func GetActiveUserByID(ctx context.Context, id uint64) (*User, error) {
// DeleteUserWithRelations 删除用户及其级联关系
func DeleteUserWithRelations(ctx context.Context, id uint64) error {
- return db.DB(ctx).Transaction(func(tx *gorm.DB) error {
+ return database.DB(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Where("user_id = ?", id).Delete(&AccessToken{}).Error; err != nil {
return err
}
@@ -142,7 +142,7 @@ func DeleteUserWithRelations(ctx context.Context, id uint64) error {
// GetFirstAdminUser 获取第一个管理员用户
func GetFirstAdminUser(ctx context.Context) (*User, error) {
var u User
- if err := db.DB(ctx).Where("is_admin = ?", true).Order("id ASC").First(&u).Error; err != nil {
+ if err := database.DB(ctx).Where("is_admin = ?", true).Order("id ASC").First(&u).Error; err != nil {
return nil, err
}
return &u, nil
@@ -152,7 +152,7 @@ func GetFirstAdminUser(ctx context.Context) (*User, error) {
func ListUsernamesMatchingBase(ctx context.Context, base string) ([]string, error) {
var usernames []string
escaped := util.EscapeLike(strings.ToLower(base))
- if err := db.DB(ctx).Model(&User{}).
+ if err := database.DB(ctx).Model(&User{}).
Where("LOWER(username) LIKE ? ESCAPE '\\'", escaped+"%").
Pluck("username", &usernames).Error; err != nil {
return nil, err
diff --git a/plugins/domain/user/service.go b/plugins/domain/user/service.go
index 89c62ef2..da89eb07 100644
--- a/plugins/domain/user/service.go
+++ b/plugins/domain/user/service.go
@@ -12,8 +12,8 @@ import (
"time"
"github.com/Rain-kl/Wavelet/core/contracts"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/persistence/idgen"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
+ "github.com/Rain-kl/Wavelet/pkg/idgen"
pkgu "github.com/Rain-kl/Wavelet/pkg/util"
)
@@ -65,7 +65,7 @@ func (s *userServiceImpl) GetUserByUsername(ctx context.Context, username string
func (s *userServiceImpl) GetUserByEmail(ctx context.Context, email string) (*contracts.UserDTO, error) {
var u User
- if err := db.DB(ctx).Where("email = ?", email).First(&u).Error; err != nil {
+ if err := database.DB(ctx).Where("email = ?", email).First(&u).Error; err != nil {
return nil, err
}
return toUserDTO(&u), nil
@@ -133,7 +133,7 @@ func (s *userServiceImpl) UpdateProfile(ctx context.Context, id uint64, req cont
}
updates["updated_at"] = time.Now()
- if err := db.DB(ctx).Model(&User{}).Where("id = ?", id).Updates(updates).Error; err != nil {
+ if err := database.DB(ctx).Model(&User{}).Where("id = ?", id).Updates(updates).Error; err != nil {
return nil, err
}
@@ -142,7 +142,7 @@ func (s *userServiceImpl) UpdateProfile(ctx context.Context, id uint64, req cont
func (s *userServiceImpl) UpdatePassword(ctx context.Context, id uint64, oldPassword, newPassword string) error {
var user User
- if err := db.DB(ctx).Where("id = ?", id).First(&user).Error; err != nil {
+ if err := database.DB(ctx).Where("id = ?", id).First(&user).Error; err != nil {
return err
}
@@ -154,7 +154,7 @@ func (s *userServiceImpl) UpdatePassword(ctx context.Context, id uint64, oldPass
return err
}
- return db.DB(ctx).Model(&User{}).Where("id = ?", id).
+ return database.DB(ctx).Model(&User{}).Where("id = ?", id).
Updates(map[string]any{
"password": user.Password,
"updated_at": time.Now(),
@@ -163,7 +163,7 @@ func (s *userServiceImpl) UpdatePassword(ctx context.Context, id uint64, oldPass
func (s *userServiceImpl) VerifyPassword(ctx context.Context, id uint64, password string) bool {
var user User
- if err := db.DB(ctx).Where("id = ?", id).First(&user).Error; err != nil {
+ if err := database.DB(ctx).Where("id = ?", id).First(&user).Error; err != nil {
pkgu.DummyCheckPassword(password)
return false
}
@@ -171,7 +171,7 @@ func (s *userServiceImpl) VerifyPassword(ctx context.Context, id uint64, passwor
}
func (s *userServiceImpl) UpdateLastLogin(ctx context.Context, id uint64, _ string) error {
- return db.DB(ctx).Model(&User{}).Where("id = ?", id).
+ return database.DB(ctx).Model(&User{}).Where("id = ?", id).
Updates(map[string]any{
"last_login_at": time.Now(),
"updated_at": time.Now(),
@@ -210,7 +210,7 @@ func (s *userServiceImpl) SetUserActive(ctx context.Context, id uint64, active b
}
func (s *userServiceImpl) SetUserAdmin(ctx context.Context, id uint64, admin bool) error {
- return db.DB(ctx).Model(&User{}).Where("id = ?", id).Update("is_admin", admin).Error
+ return database.DB(ctx).Model(&User{}).Where("id = ?", id).Update("is_admin", admin).Error
}
func (s *userServiceImpl) VerifyAccessToken(ctx context.Context, tokenHash string) (*contracts.UserDTO, bool, error) {
@@ -233,13 +233,13 @@ func (s *userServiceImpl) DeleteUser(ctx context.Context, id uint64) error {
func (s *userServiceImpl) CountUsers(ctx context.Context) (int64, error) {
var count int64
- err := db.DB(ctx).Model(&User{}).Count(&count).Error
+ err := database.DB(ctx).Model(&User{}).Count(&count).Error
return count, err
}
func (s *userServiceImpl) CountActiveUsers(ctx context.Context) (int64, error) {
var count int64
- err := db.DB(ctx).Model(&User{}).Where("is_active = ?", true).Count(&count).Error
+ err := database.DB(ctx).Model(&User{}).Where("is_active = ?", true).Count(&count).Error
return count, err
}
diff --git a/pkg/task/scheduler/errs.go b/plugins/drivers/driver_asynq_cron/errs.go
similarity index 55%
rename from pkg/task/scheduler/errs.go
rename to plugins/drivers/driver_asynq_cron/errs.go
index ccb41465..1e820ecf 100644
--- a/pkg/task/scheduler/errs.go
+++ b/plugins/drivers/driver_asynq_cron/errs.go
@@ -1,8 +1,8 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-// Package scheduler 提供定时任务调度功能
-package scheduler
+// Package driver_asynq_cron provides Asynq cron schedule driver plugin for Cordis.
+package driver_asynq_cron
const (
errLoadLocationFailed = "failed to load location: %w"
diff --git a/plugins/drivers/driver_asynq_cron/plugin.go b/plugins/drivers/driver_asynq_cron/plugin.go
index bc532516..42ced9ef 100644
--- a/plugins/drivers/driver_asynq_cron/plugin.go
+++ b/plugins/drivers/driver_asynq_cron/plugin.go
@@ -14,6 +14,7 @@ import (
"github.com/hibiken/asynq"
"github.com/Rain-kl/Wavelet/core"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
)
// Option configures the Asynq cron scheduler driver plugin.
@@ -61,7 +62,7 @@ type Plugin struct {
// New creates a new Asynq Cron Scheduler driver plugin.
func New(opts ...Option) *Plugin {
p := &Plugin{
- redisOpt: asynq.RedisClientOpt{Addr: "127.0.0.1:6379"},
+ redisOpt: driver_asynq_worker.RedisOpt,
location: time.Local,
}
diff --git a/pkg/task/schedule.go b/plugins/drivers/driver_asynq_cron/schedule.go
similarity index 92%
rename from pkg/task/schedule.go
rename to plugins/drivers/driver_asynq_cron/schedule.go
index 90b7100b..1685a918 100644
--- a/pkg/task/schedule.go
+++ b/plugins/drivers/driver_asynq_cron/schedule.go
@@ -1,13 +1,13 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package task
+package driver_asynq_cron
import (
"context"
"time"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
// Schedule 定时任务配置表
diff --git a/pkg/task/scheduler/scheduler.go b/plugins/drivers/driver_asynq_cron/scheduler.go
similarity index 91%
rename from pkg/task/scheduler/scheduler.go
rename to plugins/drivers/driver_asynq_cron/scheduler.go
index 77435d16..124684e9 100644
--- a/pkg/task/scheduler/scheduler.go
+++ b/plugins/drivers/driver_asynq_cron/scheduler.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package scheduler
+package driver_asynq_cron
import (
"context"
@@ -11,11 +11,10 @@ import (
"syscall"
"time"
- "github.com/Rain-kl/Wavelet/pkg/task"
+ "github.com/hibiken/asynq"
"github.com/Rain-kl/Wavelet/pkg/logger"
-
- "github.com/hibiken/asynq"
+ "github.com/Rain-kl/Wavelet/plugins/drivers/driver_asynq_worker"
)
var (
@@ -27,12 +26,11 @@ var (
// GetAsynqClient 获取全局 AsynqClient
func GetAsynqClient() *asynq.Client {
- return task.AsynqClient
+ return driver_asynq_worker.AsynqClient
}
// StartScheduler 启动调度器 (该函数阻塞,直到调度器退出)
func StartScheduler() error {
-
var err error
schedulerOnce.Do(func() {
quitChan = make(chan struct{})
@@ -82,7 +80,7 @@ func ReloadScheduler() error {
}
// 2. 从数据库载入启用的定时任务配置
- schedules, err := task.ListActiveSchedules(context.Background())
+ schedules, err := ListActiveSchedules(context.Background())
if err != nil {
return fmt.Errorf("load schedules from db failed: %w", err)
}
@@ -94,7 +92,7 @@ func ReloadScheduler() error {
// 3. 实例化新的调度器
newScheduler := asynq.NewScheduler(
- task.RedisOpt,
+ driver_asynq_worker.RedisOpt,
&asynq.SchedulerOpts{
Location: location,
},
@@ -102,7 +100,7 @@ func ReloadScheduler() error {
// 4. 遍历并注册任务
for _, s := range schedules {
- meta := task.GetTaskMeta(s.TaskType)
+ meta := driver_asynq_worker.GetTaskMeta(s.TaskType)
if meta == nil {
continue // 忽略排程配置中无效的任务类型
}
diff --git a/pkg/task/scheduler/scheduler_test.go b/plugins/drivers/driver_asynq_cron/scheduler_test.go
similarity index 96%
rename from pkg/task/scheduler/scheduler_test.go
rename to plugins/drivers/driver_asynq_cron/scheduler_test.go
index c9c2307e..f591a625 100644
--- a/pkg/task/scheduler/scheduler_test.go
+++ b/plugins/drivers/driver_asynq_cron/scheduler_test.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package scheduler
+package driver_asynq_cron
import "testing"
diff --git a/pkg/task/constants.go b/plugins/drivers/driver_asynq_worker/constants.go
similarity index 77%
rename from pkg/task/constants.go
rename to plugins/drivers/driver_asynq_worker/constants.go
index 4ad07259..876291fd 100644
--- a/pkg/task/constants.go
+++ b/plugins/drivers/driver_asynq_worker/constants.go
@@ -2,8 +2,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-// Package task 定义异步任务类型与调度常量
-package task
+package driver_asynq_worker
// 任务队列名称
const (
diff --git a/pkg/task/errs.go b/plugins/drivers/driver_asynq_worker/errs.go
similarity index 96%
rename from pkg/task/errs.go
rename to plugins/drivers/driver_asynq_worker/errs.go
index 6e020ef3..f73967c0 100644
--- a/pkg/task/errs.go
+++ b/plugins/drivers/driver_asynq_worker/errs.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package task
+package driver_asynq_worker
const (
errUnknownTaskType = "未知的任务类型: %s"
diff --git a/pkg/task/executor.go b/plugins/drivers/driver_asynq_worker/executor.go
similarity index 95%
rename from pkg/task/executor.go
rename to plugins/drivers/driver_asynq_worker/executor.go
index 77251b9b..928e2156 100644
--- a/pkg/task/executor.go
+++ b/plugins/drivers/driver_asynq_worker/executor.go
@@ -2,48 +2,60 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package task
+package driver_asynq_worker
import (
"context"
"encoding/json"
"errors"
"fmt"
+ "sync"
"time"
- "github.com/Rain-kl/Wavelet/pkg/logger"
- "github.com/Rain-kl/Wavelet/pkg/persistence/idgen"
- otel_trace "github.com/Rain-kl/Wavelet/pkg/trace"
"github.com/hibiken/asynq"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/trace"
+
+ "github.com/Rain-kl/Wavelet/pkg/idgen"
+ "github.com/Rain-kl/Wavelet/pkg/logger"
+ otel_trace "github.com/Rain-kl/Wavelet/pkg/trace"
+ "github.com/Rain-kl/Wavelet/pkg/util"
)
-// handlerRegistry 已注册的任务处理器
-var handlerRegistry = make(map[string]TaskHandler)
+var (
+ handlerRegistryMutex sync.RWMutex
+ handlerRegistry = make(map[string]TaskHandler)
+
+ completedHandlersMutex sync.RWMutex
+ taskCompletedHandlers []CompletedHandler
+)
// CompletedHandler is called when a task execution completes.
type CompletedHandler func(ctx context.Context, execution *TaskExecution, result *TaskResult, execErr error)
-var taskCompletedHandlers []CompletedHandler
-
// OnTaskCompleted registers a handler for task completion events.
// Handlers must be registered during application bootstrap before processing tasks.
func OnTaskCompleted(handler CompletedHandler) {
+ completedHandlersMutex.Lock()
+ defer completedHandlersMutex.Unlock()
taskCompletedHandlers = append(taskCompletedHandlers, handler)
}
// RegisterHandler 注册任务处理器
-// 传入任务类型标识(对应 constants.go 中的 AsynqTask 常量)和 TaskHandler 实现
+// 传入任务类型标识(对应 AsynqTask 常量)和 TaskHandler 实现
func RegisterHandler(asynqTaskType string, handler TaskHandler) {
+ handlerRegistryMutex.Lock()
+ defer handlerRegistryMutex.Unlock()
handlerRegistry[asynqTaskType] = handler
}
// getHandler 获取已注册的处理器
func getHandler(asynqTaskType string) (TaskHandler, bool) {
+ handlerRegistryMutex.RLock()
+ defer handlerRegistryMutex.RUnlock()
h, ok := handlerRegistry[asynqTaskType]
return h, ok
}
@@ -416,13 +428,19 @@ func completeTaskExecution(ctx context.Context, execution *TaskExecution, t *asy
}
func notifyTaskCompleted(ctx context.Context, execution *TaskExecution, result *TaskResult, execErr error) {
+ completedHandlersMutex.RLock()
+ defer completedHandlersMutex.RUnlock()
+
if len(taskCompletedHandlers) == 0 {
return
}
asyncCtx := context.WithoutCancel(ctx)
for _, handler := range taskCompletedHandlers {
- go handler(asyncCtx, execution, result, execErr)
+ h := handler
+ util.Go(func() {
+ h(asyncCtx, execution, result, execErr)
+ })
}
}
diff --git a/pkg/task/executor_test.go b/plugins/drivers/driver_asynq_worker/executor_test.go
similarity index 96%
rename from pkg/task/executor_test.go
rename to plugins/drivers/driver_asynq_worker/executor_test.go
index 86118211..cd03f550 100644
--- a/pkg/task/executor_test.go
+++ b/plugins/drivers/driver_asynq_worker/executor_test.go
@@ -2,7 +2,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package task
+package driver_asynq_worker
import (
"context"
@@ -11,13 +11,14 @@ import (
"testing"
"time"
- "github.com/Rain-kl/Wavelet/pkg/testhelper"
"github.com/hibiken/asynq"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/trace"
+
+ "github.com/Rain-kl/Wavelet/pkg/testhelper"
)
// mockHandler 用于测试的模拟任务处理器
@@ -191,11 +192,6 @@ func TestProcessTaskSuccess(t *testing.T) {
err := CreateTaskExecution(ctx, execution)
require.NoError(t, err)
- // 通过 asynq 的 Task 不能直接设置 taskID,ProcessTask 通过 t.ResultWriter().TaskID() 获取
- // 但 asynq.Task 在没有经过 asynq server 的情况下 ResultWriter 可能为 nil
- // 我们需要在 ProcessTask 内部改用 taskID 注入的方式测试
- // 为了测试 ProcessTask,我们直接模拟调用 handler
-
// 直接通过 handler 测试
handler, ok := getHandler(testTaskType)
require.True(t, ok)
diff --git a/pkg/task/handler.go b/plugins/drivers/driver_asynq_worker/handler.go
similarity index 93%
rename from pkg/task/handler.go
rename to plugins/drivers/driver_asynq_worker/handler.go
index 2b9c628d..5087fca9 100644
--- a/pkg/task/handler.go
+++ b/plugins/drivers/driver_asynq_worker/handler.go
@@ -2,7 +2,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package task
+package driver_asynq_worker
import "context"
@@ -24,7 +24,7 @@ type PayloadValidator interface {
// TaskHandler 异步任务处理器接口
// 所有异步任务必须实现此接口,框架将自动管理任务执行记录的创建、状态流转和日志写入。
//
-// 开发者只需实现 Execute 方法编写业务逻辑,在方法内通过 task.AppendLog(ctx, ...) 追加执行日志。
+// 开发者只需实现 Execute 方法编写业务逻辑,在方法内通过 driver_asynq_worker.AppendLog(ctx, ...) 追加执行日志。
// 任务的创建、状态更新、错误记录、重试计数全部由框架透明处理。
//
//nolint:revive // TaskHandler 保留完整名称以避免与通用 Handler 混淆
diff --git a/pkg/task/meta.go b/plugins/drivers/driver_asynq_worker/meta.go
similarity index 94%
rename from pkg/task/meta.go
rename to plugins/drivers/driver_asynq_worker/meta.go
index 019fc637..853cfd09 100644
--- a/pkg/task/meta.go
+++ b/plugins/drivers/driver_asynq_worker/meta.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package task
+package driver_asynq_worker
import (
"sync"
@@ -51,7 +51,7 @@ func RegisterTaskMeta(meta TaskMeta) {
dispatchableTasks = append(dispatchableTasks, meta)
}
-// GetDispatchableTasks 获取所有已注册的元数据列表(返回副本以避免并发并发读写冲突)
+// GetDispatchableTasks 获取所有已注册的元数据列表(返回副本以避免并发读写冲突)
func GetDispatchableTasks() []TaskMeta {
dispatchableTasksMutex.RLock()
defer dispatchableTasksMutex.RUnlock()
@@ -89,6 +89,9 @@ func GetTaskMetaByAsynqTask(asynqTask string) *TaskMeta {
// GetRegisteredAsynqTasks 返回所有已注册的 Asynq 任务名称,以便动态注册路由
func GetRegisteredAsynqTasks() []string {
+ handlerRegistryMutex.RLock()
+ defer handlerRegistryMutex.RUnlock()
+
keys := make([]string, 0, len(handlerRegistry))
for k := range handlerRegistry {
keys = append(keys, k)
diff --git a/plugins/drivers/driver_asynq_worker/meta_test.go b/plugins/drivers/driver_asynq_worker/meta_test.go
new file mode 100644
index 00000000..9c05c0cd
--- /dev/null
+++ b/plugins/drivers/driver_asynq_worker/meta_test.go
@@ -0,0 +1,98 @@
+// Copyright 2026 Arctel.net
+// SPDX-License-Identifier: Apache-2.0
+
+package driver_asynq_worker
+
+import (
+ "sync"
+ "testing"
+)
+
+func resetDispatchableTasks() {
+ dispatchableTasksMutex.Lock()
+ defer dispatchableTasksMutex.Unlock()
+ dispatchableTasks = nil
+}
+
+func TestRegisterTaskMeta_ThreadSafe(t *testing.T) {
+ resetDispatchableTasks()
+ defer resetDispatchableTasks()
+
+ var wg sync.WaitGroup
+ workers := 20
+ iterations := 100
+
+ for i := 0; i < workers; i++ {
+ wg.Add(1)
+ go func(id int) {
+ defer wg.Done()
+ for j := 0; j < iterations; j++ {
+ RegisterTaskMeta(TaskMeta{
+ Type: "task_type_a",
+ AsynqTask: "asynq_task_a",
+ Name: "Task A",
+ })
+ RegisterTaskMeta(TaskMeta{
+ Type: "task_type_b",
+ AsynqTask: "asynq_task_b",
+ Name: "Task B",
+ })
+ }
+ }(i)
+ }
+
+ wg.Wait()
+
+ tasks := GetDispatchableTasks()
+ if len(tasks) != 2 {
+ t.Fatalf("expected 2 unique tasks, got %d", len(tasks))
+ }
+}
+
+func TestGetTaskMeta_Isolation(t *testing.T) {
+ resetDispatchableTasks()
+ defer resetDispatchableTasks()
+
+ RegisterTaskMeta(TaskMeta{
+ Type: "task_isolated",
+ AsynqTask: "asynq_isolated",
+ Name: "Original Name",
+ })
+
+ meta := GetTaskMeta("task_isolated")
+ if meta == nil {
+ t.Fatal("expected task to be found")
+ }
+
+ // Modify returned struct
+ meta.Name = "Modified Name"
+
+ // Fetch again and verify original data is unaffected
+ meta2 := GetTaskMeta("task_isolated")
+ if meta2.Name != "Original Name" {
+ t.Fatalf("expected name to be 'Original Name', got %s", meta2.Name)
+ }
+}
+
+func TestGetTaskMetaByAsynqTask_Isolation(t *testing.T) {
+ resetDispatchableTasks()
+ defer resetDispatchableTasks()
+
+ RegisterTaskMeta(TaskMeta{
+ Type: "task_isolated",
+ AsynqTask: "asynq_isolated",
+ Name: "Original Name",
+ })
+
+ meta := GetTaskMetaByAsynqTask("asynq_isolated")
+ if meta == nil {
+ t.Fatal("expected task to be found")
+ }
+
+ meta.Name = "Modified Name"
+
+ meta2 := GetTaskMetaByAsynqTask("asynq_isolated")
+ if meta2.Name != "Original Name" {
+ t.Fatalf("expected name to be 'Original Name', got %s", meta2.Name)
+ }
+}
diff --git a/pkg/task/permanent_error.go b/plugins/drivers/driver_asynq_worker/permanent_error.go
similarity index 96%
rename from pkg/task/permanent_error.go
rename to plugins/drivers/driver_asynq_worker/permanent_error.go
index a0dad4f3..03dc77b8 100644
--- a/pkg/task/permanent_error.go
+++ b/plugins/drivers/driver_asynq_worker/permanent_error.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package task
+package driver_asynq_worker
import (
"strings"
diff --git a/plugins/drivers/driver_asynq_worker/permanent_error_test.go b/plugins/drivers/driver_asynq_worker/permanent_error_test.go
new file mode 100644
index 00000000..19d9a977
--- /dev/null
+++ b/plugins/drivers/driver_asynq_worker/permanent_error_test.go
@@ -0,0 +1,37 @@
+// Copyright 2026 Arctel.net
+// SPDX-License-Identifier: Apache-2.0
+
+package driver_asynq_worker
+
+import (
+ "errors"
+ "testing"
+
+ "github.com/hibiken/asynq"
+)
+
+func TestPermanentError(t *testing.T) {
+ err := PermanentError("自定义永久错误")
+ if err == nil {
+ t.Fatal("PermanentError returned nil")
+ }
+ if err.Error() != "自定义永久错误" {
+ t.Fatalf("Error() = %q, want %q", err.Error(), "自定义永久错误")
+ }
+ if !errors.Is(err, asynq.SkipRetry) {
+ t.Fatal("PermanentError does not unwrap to asynq.SkipRetry")
+ }
+}
+
+func TestPermanentErrorDefaultMessage(t *testing.T) {
+ err := PermanentError(" ")
+ if err == nil {
+ t.Fatal("PermanentError returned nil")
+ }
+ if err.Error() != defaultPermanentErrorMessage {
+ t.Fatalf("Error() = %q, want default %q", err.Error(), defaultPermanentErrorMessage)
+ }
+ if !errors.Is(err, asynq.SkipRetry) {
+ t.Fatal("PermanentError does not unwrap to asynq.SkipRetry")
+ }
+}
diff --git a/plugins/drivers/driver_asynq_worker/plugin.go b/plugins/drivers/driver_asynq_worker/plugin.go
index 36a9aa37..51c4abc4 100644
--- a/plugins/drivers/driver_asynq_worker/plugin.go
+++ b/plugins/drivers/driver_asynq_worker/plugin.go
@@ -83,7 +83,7 @@ type Plugin struct {
// New creates a new Asynq Worker driver plugin.
func New(opts ...Option) *Plugin {
p := &Plugin{
- redisOpt: asynq.RedisClientOpt{Addr: "127.0.0.1:6379"},
+ redisOpt: RedisOpt,
concurrency: defaultConcurrency,
shutdownTimeout: defaultShutdownTimeout,
queues: map[string]int{"default": 1},
@@ -144,6 +144,10 @@ func (p *Plugin) Start(_ context.Context) error {
}
}
+ for _, taskName := range GetRegisteredAsynqTasks() {
+ mux.HandleFunc(taskName, ProcessTask)
+ }
+
if p.server == nil {
p.server = asynq.NewServer(
p.redisOpt,
@@ -216,6 +220,11 @@ func toAsynqHandler(h any) (asynq.Handler, error) {
return fn, nil
case asynq.Handler:
return fn, nil
+ case TaskHandler:
+ return asynq.HandlerFunc(func(c context.Context, t *asynq.Task) error {
+ RegisterHandler(t.Type(), fn)
+ return ProcessTask(c, t)
+ }), nil
case func(context.Context, *asynq.Task) error:
return asynq.HandlerFunc(fn), nil
case func(context.Context, []byte) error:
diff --git a/pkg/task/task_repo.go b/plugins/drivers/driver_asynq_worker/task_repo.go
similarity index 81%
rename from pkg/task/task_repo.go
rename to plugins/drivers/driver_asynq_worker/task_repo.go
index 87b7c235..f6c3064d 100644
--- a/pkg/task/task_repo.go
+++ b/plugins/drivers/driver_asynq_worker/task_repo.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package task
+package driver_asynq_worker
import (
"context"
@@ -12,8 +12,9 @@ import (
"github.com/redis/go-redis/v9"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
- "github.com/Rain-kl/Wavelet/pkg/persistence/idgen"
+ "github.com/Rain-kl/Wavelet/pkg/idgen"
+ cachepkg "github.com/Rain-kl/Wavelet/plugins/infra/cache"
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
const (
@@ -23,7 +24,7 @@ const (
)
func taskExecutionLogRedisKey(taskID string) string {
- return db.PrefixedKey(taskExecutionLogRedisKeyPrefix + taskID)
+ return cachepkg.PrefixedKey(taskExecutionLogRedisKeyPrefix + taskID)
}
func createTaskExecution(ctx context.Context, execution *TaskExecution) error {
@@ -56,7 +57,7 @@ func getTaskExecutionByTaskID(ctx context.Context, taskID string) (*TaskExecutio
}
func appendTaskExecutionLog(ctx context.Context, taskID string, logLine string) error {
- if db.Redis == nil {
+ if cachepkg.Redis == nil {
return errors.New("redis client is not initialized")
}
@@ -64,7 +65,7 @@ func appendTaskExecutionLog(ctx context.Context, taskID string, logLine string)
line := fmt.Sprintf("[%s] %s\n", now, logLine)
key := taskExecutionLogRedisKey(taskID)
- _, err := db.Redis.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
+ _, err := cachepkg.Redis.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.RPush(ctx, key, line)
pipe.LTrim(ctx, key, -taskExecutionLogMaxLines, -1)
pipe.Expire(ctx, key, taskExecutionLogExpiration)
@@ -77,12 +78,12 @@ func appendTaskExecutionLog(ctx context.Context, taskID string, logLine string)
}
func flushTaskExecutionLog(ctx context.Context, taskID string) error {
- if db.Redis == nil {
+ if cachepkg.Redis == nil {
return errors.New("redis client is not initialized")
}
key := taskExecutionLogRedisKey(taskID)
- logLines, err := db.Redis.LRange(ctx, key, 0, -1).Result()
+ logLines, err := cachepkg.Redis.LRange(ctx, key, 0, -1).Result()
if err != nil {
return fmt.Errorf("get task execution log from redis: %w", err)
}
@@ -101,18 +102,18 @@ func flushTaskExecutionLog(ctx context.Context, taskID string) error {
return fmt.Errorf("persist task execution log: task %q not found", taskID)
}
- if err := db.Redis.Del(ctx, key).Err(); err != nil {
+ if err := cachepkg.Redis.Del(ctx, key).Err(); err != nil {
return fmt.Errorf("delete persisted task execution log from redis: %w", err)
}
return nil
}
func loadTaskExecutionLog(ctx context.Context, execution *TaskExecution) error {
- if db.Redis == nil {
+ if cachepkg.Redis == nil {
return nil
}
- logLines, err := db.Redis.LRange(ctx, taskExecutionLogRedisKey(execution.TaskID), 0, -1).Result()
+ logLines, err := cachepkg.Redis.LRange(ctx, taskExecutionLogRedisKey(execution.TaskID), 0, -1).Result()
if err != nil {
return fmt.Errorf("get task execution log from redis: %w", err)
}
diff --git a/pkg/task/types.go b/plugins/drivers/driver_asynq_worker/types.go
similarity index 98%
rename from pkg/task/types.go
rename to plugins/drivers/driver_asynq_worker/types.go
index 703b9149..03a9fe68 100644
--- a/pkg/task/types.go
+++ b/plugins/drivers/driver_asynq_worker/types.go
@@ -1,15 +1,16 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package task
+package driver_asynq_worker
import (
"context"
"errors"
"time"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
"gorm.io/gorm"
+
+ db "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
// TaskExecutionStatus 任务执行状态
diff --git a/pkg/task/utils.go b/plugins/drivers/driver_asynq_worker/utils.go
similarity index 99%
rename from pkg/task/utils.go
rename to plugins/drivers/driver_asynq_worker/utils.go
index 3c075735..41d5b208 100644
--- a/pkg/task/utils.go
+++ b/plugins/drivers/driver_asynq_worker/utils.go
@@ -2,13 +2,14 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package task
+package driver_asynq_worker
import (
- "github.com/Rain-kl/Wavelet/pkg/config"
"github.com/hibiken/asynq"
"github.com/redis/go-redis/v9"
"github.com/redis/go-redis/v9/maintnotifications"
+
+ "github.com/Rain-kl/Wavelet/pkg/config"
)
type redisClientConnOpt struct {
diff --git a/plugins/drivers/driver_asynq_worker/utils_test.go b/plugins/drivers/driver_asynq_worker/utils_test.go
new file mode 100644
index 00000000..1ab5bf5f
--- /dev/null
+++ b/plugins/drivers/driver_asynq_worker/utils_test.go
@@ -0,0 +1,59 @@
+// Copyright 2026 Arctel.net
+// SPDX-License-Identifier: Apache-2.0
+
+package driver_asynq_worker
+
+import (
+ "testing"
+
+ "github.com/Rain-kl/Wavelet/pkg/config"
+ "github.com/redis/go-redis/v9/maintnotifications"
+)
+
+func TestMaintNotificationsConfig(t *testing.T) {
+ tests := []struct {
+ name string
+ enabled bool
+ wantMode maintnotifications.Mode
+ }{
+ {
+ name: "disabled mode when flag is false",
+ enabled: false,
+ wantMode: maintnotifications.ModeDisabled,
+ },
+ {
+ name: "auto mode when flag is true",
+ enabled: true,
+ wantMode: maintnotifications.ModeAuto,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ cfg := maintNotificationsConfig(tt.enabled)
+ if cfg == nil {
+ t.Fatalf("maintNotificationsConfig(%v) = nil, want non-nil", tt.enabled)
+ }
+ if cfg.Mode != tt.wantMode {
+ t.Fatalf("maintNotificationsConfig(%v).Mode = %v, want %v", tt.enabled, cfg.Mode, tt.wantMode)
+ }
+ })
+ }
+}
+
+func TestPrefixedQueue(t *testing.T) {
+ oldPrefix := config.Config.Redis.KeyPrefix
+ defer func() {
+ config.Config.Redis.KeyPrefix = oldPrefix
+ }()
+
+ config.Config.Redis.KeyPrefix = "test:"
+ if got := PrefixedQueue("default"); got != "test:default" {
+ t.Fatalf("PrefixedQueue() = %q, want %q", got, "test:default")
+ }
+
+ config.Config.Redis.KeyPrefix = ""
+ if got := PrefixedQueue("default"); got != "default" {
+ t.Fatalf("PrefixedQueue() = %q, want %q", got, "default")
+ }
+}
diff --git a/plugins/drivers/driver_http/middlewares.go b/plugins/drivers/driver_http/middlewares.go
index ce3e8896..8544b158 100644
--- a/plugins/drivers/driver_http/middlewares.go
+++ b/plugins/drivers/driver_http/middlewares.go
@@ -14,7 +14,7 @@ import (
"github.com/Rain-kl/Wavelet/pkg/config"
"github.com/Rain-kl/Wavelet/pkg/logger"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/pkg/response"
otel_trace "github.com/Rain-kl/Wavelet/pkg/trace"
"github.com/gin-gonic/gin"
@@ -73,7 +73,7 @@ func loggerMiddleware() gin.HandlerFunc {
func isOriginAllowed(ctx context.Context, origin string) bool {
var val string
- if err := db.DB(ctx).Table("w_system_configs").Where("key = ?", "server_address").Pluck("value", &val).Error; err != nil || val == "" {
+ if err := database.DB(ctx).Table("w_system_configs").Where("key = ?", "server_address").Pluck("value", &val).Error; err != nil || val == "" {
return false
}
allowedOrigins := strings.Split(val, ",")
diff --git a/pkg/persistence/errs.go b/plugins/infra/cache/errs.go
similarity index 96%
rename from pkg/persistence/errs.go
rename to plugins/infra/cache/errs.go
index 46aac911..f653d6fe 100644
--- a/pkg/persistence/errs.go
+++ b/plugins/infra/cache/errs.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package db
+package cache
const (
errRedisHashSetFailed = "failed to set redis hash: %w"
diff --git a/plugins/infra/cache/plugin.go b/plugins/infra/cache/plugin.go
index b7dc40c3..33498a57 100644
--- a/plugins/infra/cache/plugin.go
+++ b/plugins/infra/cache/plugin.go
@@ -14,7 +14,6 @@ import (
"github.com/Rain-kl/Wavelet/core"
"github.com/Rain-kl/Wavelet/core/contracts"
"github.com/Rain-kl/Wavelet/pkg/cache/ram"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
"github.com/Rain-kl/Wavelet/pkg/util"
"github.com/redis/go-redis/v9"
)
@@ -82,7 +81,7 @@ func (p *Plugin) Name() string {
func (p *Plugin) Apply(ctx *core.Context) error {
redisClient := p.redisClient
if redisClient == nil {
- redisClient = db.Redis
+ redisClient = Redis
}
ramCache, err := ram.New[string, ramEntry](ram.Options{
@@ -128,7 +127,7 @@ func (s *cacheServiceImpl) prefixedKey(key string) string {
if s.keyPrefix != "" {
return s.keyPrefix + key
}
- return db.PrefixedKey(key)
+ return PrefixedKey(key)
}
func (s *cacheServiceImpl) startPubSubListener() {
diff --git a/pkg/persistence/redis.go b/plugins/infra/cache/redis.go
similarity index 99%
rename from pkg/persistence/redis.go
rename to plugins/infra/cache/redis.go
index 7617e0f2..5acc7e6c 100644
--- a/pkg/persistence/redis.go
+++ b/plugins/infra/cache/redis.go
@@ -2,7 +2,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package db
+package cache
import (
"context"
diff --git a/pkg/persistence/redis_test.go b/plugins/infra/cache/redis_test.go
similarity index 98%
rename from pkg/persistence/redis_test.go
rename to plugins/infra/cache/redis_test.go
index 55ec55e2..0b91041e 100644
--- a/pkg/persistence/redis_test.go
+++ b/plugins/infra/cache/redis_test.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package db
+package cache
import (
"testing"
diff --git a/pkg/persistence/clickhouse.go b/plugins/infra/database/clickhouse.go
similarity index 98%
rename from pkg/persistence/clickhouse.go
rename to plugins/infra/database/clickhouse.go
index c59b1c85..fc613222 100644
--- a/pkg/persistence/clickhouse.go
+++ b/plugins/infra/database/clickhouse.go
@@ -2,8 +2,8 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-// Package db 提供数据库连接与基础设施
-package db
+// Package database 提供数据库连接与基础设施
+package database
import (
"context"
diff --git a/plugins/infra/database/plugin.go b/plugins/infra/database/plugin.go
index c3ee26ca..4a768377 100644
--- a/plugins/infra/database/plugin.go
+++ b/plugins/infra/database/plugin.go
@@ -9,7 +9,6 @@ import (
"github.com/Rain-kl/Wavelet/core"
"github.com/Rain-kl/Wavelet/core/contracts"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
"gorm.io/gorm"
)
@@ -61,7 +60,7 @@ func (p *Plugin) Name() string {
func (p *Plugin) Apply(ctx *core.Context) error {
targetDB := p.db
if targetDB == nil {
- targetDB = db.DB(context.Background())
+ targetDB = DB(context.Background())
}
svc := &dbServiceImpl{
@@ -82,14 +81,14 @@ func (s *dbServiceImpl) GORM() *gorm.DB {
if s.primary != nil {
return s.primary
}
- return db.DB(context.Background())
+ return DB(context.Background())
}
func (s *dbServiceImpl) DB(ctx context.Context) *gorm.DB {
if s.primary != nil {
return s.primary.WithContext(ctx)
}
- return db.DB(ctx)
+ return DB(ctx)
}
func (s *dbServiceImpl) Named(name string) *gorm.DB {
diff --git a/pkg/persistence/postgres.go b/plugins/infra/database/postgres.go
similarity index 99%
rename from pkg/persistence/postgres.go
rename to plugins/infra/database/postgres.go
index 8c71425b..25816982 100644
--- a/pkg/persistence/postgres.go
+++ b/plugins/infra/database/postgres.go
@@ -2,7 +2,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package db
+package database
import (
"context"
@@ -157,7 +157,6 @@ func initPostgres() {
sqlDB.SetMaxOpenConns(dbConfig.MaxOpenConn)
sqlDB.SetConnMaxLifetime(time.Duration(dbConfig.ConnMaxLifetime) * time.Second)
sqlDB.SetConnMaxIdleTime(time.Duration(dbConfig.ConnMaxIdleTime) * time.Second)
-
}
// buildDSN 构建 PostgreSQL DSN
diff --git a/pkg/persistence/postgres_logger.go b/plugins/infra/database/postgres_logger.go
similarity index 99%
rename from pkg/persistence/postgres_logger.go
rename to plugins/infra/database/postgres_logger.go
index 0bfd0f7a..61b74666 100644
--- a/pkg/persistence/postgres_logger.go
+++ b/plugins/infra/database/postgres_logger.go
@@ -2,7 +2,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package db
+package database
import (
"context"
diff --git a/pkg/persistence/postgres_logger_test.go b/plugins/infra/database/postgres_logger_test.go
similarity index 97%
rename from pkg/persistence/postgres_logger_test.go
rename to plugins/infra/database/postgres_logger_test.go
index 20539a5b..bfcd1a7b 100644
--- a/pkg/persistence/postgres_logger_test.go
+++ b/plugins/infra/database/postgres_logger_test.go
@@ -1,7 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
-package db
+package database
import (
"testing"
diff --git a/plugins/infra/storage/diskcache/cache.go b/plugins/infra/storage/diskcache/cache.go
index 15d95b8f..7c7b0bca 100644
--- a/plugins/infra/storage/diskcache/cache.go
+++ b/plugins/infra/storage/diskcache/cache.go
@@ -11,7 +11,7 @@ import (
"time"
pkgcache "github.com/Rain-kl/Wavelet/pkg/cache/disk"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
)
// Status represents the runtime cache statistics.
@@ -63,14 +63,14 @@ func New(basePath string) *DiskCache {
// ReloadConfig reloads policies from database configs dynamically.
func (c *DiskCache) ReloadConfig(ctx context.Context) {
// Ensure DB is initialized before querying
- if db.DB(ctx) == nil {
+ if database.DB(ctx) == nil {
return
}
// 1. Max Size
maxSizeMB := int64(defaultMaxSizeMB)
var maxVal string
- if err := db.DB(ctx).Table("w_system_configs").Where("key = ?", "disk_cache_max_size_mb").Pluck("value", &maxVal).Error; err == nil && maxVal != "" {
+ if err := database.DB(ctx).Table("w_system_configs").Where("key = ?", "disk_cache_max_size_mb").Pluck("value", &maxVal).Error; err == nil && maxVal != "" {
if val, err := strconv.ParseInt(maxVal, 10, 64); err == nil && val > 0 {
maxSizeMB = val
}
@@ -79,7 +79,7 @@ func (c *DiskCache) ReloadConfig(ctx context.Context) {
// 2. Default TTL
ttlMinutes := int64(defaultTTLMinutes)
var ttlVal string
- if err := db.DB(ctx).Table("w_system_configs").Where("key = ?", "disk_cache_ttl_minutes").Pluck("value", &ttlVal).Error; err == nil && ttlVal != "" {
+ if err := database.DB(ctx).Table("w_system_configs").Where("key = ?", "disk_cache_ttl_minutes").Pluck("value", &ttlVal).Error; err == nil && ttlVal != "" {
if val, err := strconv.ParseInt(ttlVal, 10, 64); err == nil && val >= 0 {
ttlMinutes = val
}
@@ -88,7 +88,7 @@ func (c *DiskCache) ReloadConfig(ctx context.Context) {
// 3. LRU Enabled
lruEnabled := true
var lruVal string
- if err := db.DB(ctx).Table("w_system_configs").Where("key = ?", "disk_cache_lru_enabled").Pluck("value", &lruVal).Error; err == nil && lruVal != "" {
+ if err := database.DB(ctx).Table("w_system_configs").Where("key = ?", "disk_cache_lru_enabled").Pluck("value", &lruVal).Error; err == nil && lruVal != "" {
if val, err := strconv.ParseBool(lruVal); err == nil {
lruEnabled = val
}
diff --git a/plugins/infra/storage/diskcache/cache_test.go b/plugins/infra/storage/diskcache/cache_test.go
index 1155a395..ac6dba79 100644
--- a/plugins/infra/storage/diskcache/cache_test.go
+++ b/plugins/infra/storage/diskcache/cache_test.go
@@ -8,7 +8,7 @@ import (
"os"
"testing"
- db "github.com/Rain-kl/Wavelet/pkg/persistence"
+ cache "github.com/Rain-kl/Wavelet/plugins/infra/cache"
"github.com/Rain-kl/Wavelet/pkg/testhelper"
)
@@ -29,8 +29,8 @@ func TestDiskCacheReloadConfig(t *testing.T) {
dbConn.Table("w_system_configs").Where("key = ?", "disk_cache_lru_enabled").Update("value", "false")
// Invalidate Redis config cache to force DB reload
- if db.Redis != nil {
- db.Redis.Del(context.Background(), db.PrefixedKey("system_configs"))
+ if cache.Redis != nil {
+ cache.Redis.Del(context.Background(), cache.PrefixedKey("system_configs"))
}
// Reload config
diff --git a/plugins/infra/storage/objectstore/config.go b/plugins/infra/storage/objectstore/config.go
index a7e38c53..88ef9ca6 100644
--- a/plugins/infra/storage/objectstore/config.go
+++ b/plugins/infra/storage/objectstore/config.go
@@ -12,7 +12,7 @@ import (
"strings"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"gorm.io/gorm"
)
@@ -110,7 +110,7 @@ func LoadConfig(ctx context.Context) (Config, error) {
func loadConfigByKey(ctx context.Context, key string, fallback Config) (Config, error) {
var val string
- err := db.DB(ctx).Table("w_system_configs").Where("key = ?", key).Pluck("value", &val).Error
+ err := database.DB(ctx).Table("w_system_configs").Where("key = ?", key).Pluck("value", &val).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return fallback, nil
@@ -182,7 +182,7 @@ func SaveActiveConfig(ctx context.Context, cfg Config) error {
}
func saveSystemConfig(ctx context.Context, key string, value any, description string) error {
- err := db.DB(ctx).Transaction(func(tx *gorm.DB) error {
+ err := database.DB(ctx).Transaction(func(tx *gorm.DB) error {
return upsertSystemConfig(ctx, tx, key, value, description)
})
if err == nil && key == "storage_config" {
diff --git a/plugins/infra/storage/objectstore/storage.go b/plugins/infra/storage/objectstore/storage.go
index 5c83ccd8..c2c512f4 100644
--- a/plugins/infra/storage/objectstore/storage.go
+++ b/plugins/infra/storage/objectstore/storage.go
@@ -13,7 +13,8 @@ import (
"sync"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ cache "github.com/Rain-kl/Wavelet/plugins/infra/cache"
+ database "github.com/Rain-kl/Wavelet/plugins/infra/database"
"github.com/Rain-kl/Wavelet/pkg/util"
"gorm.io/gorm"
@@ -76,14 +77,14 @@ func ResetCache() {
// PublishCacheInvalidation broadcasts cache eviction to all nodes in the cluster via Redis.
func PublishCacheInvalidation(ctx context.Context) {
- if db.Redis != nil {
- _ = db.Redis.Publish(ctx, ConfigInvalidationChannel, "reset").Err()
+ if cache.Redis != nil {
+ _ = cache.Redis.Publish(ctx, ConfigInvalidationChannel, "reset").Err()
}
}
// startPubSubListener starts the background subscriber for cache invalidations.
func startPubSubListener() {
- rdb := db.Redis
+ rdb := cache.Redis
if rdb == nil {
return
}
@@ -126,7 +127,7 @@ func Active(ctx context.Context) (Driver, Backend, error) {
}
var val string
- err := db.DB(ctx).Table("w_system_configs").Where("key = ?", "storage_config").Pluck("value", &val).Error
+ err := database.DB(ctx).Table("w_system_configs").Where("key = ?", "storage_config").Pluck("value", &val).Error
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return "", nil, err
}
diff --git a/plugins/infra/storage/objectstore/storage_test.go b/plugins/infra/storage/objectstore/storage_test.go
index ad38b3c6..5c919f9e 100644
--- a/plugins/infra/storage/objectstore/storage_test.go
+++ b/plugins/infra/storage/objectstore/storage_test.go
@@ -11,7 +11,7 @@ import (
"testing"
"time"
- "github.com/Rain-kl/Wavelet/pkg/persistence"
+ cache "github.com/Rain-kl/Wavelet/plugins/infra/cache"
"github.com/alicebob/miniredis/v2"
"github.com/redis/go-redis/v9"
)
@@ -91,11 +91,11 @@ func TestStorageCachePubSub(t *testing.T) {
})
defer rdb.Close()
- // 3. Set db.Redis to our client
- oldRedis := db.Redis
- db.Redis = rdb
+ // 3. Set cache.Redis to our client
+ oldRedis := cache.Redis
+ cache.Redis = rdb
defer func() {
- db.Redis = oldRedis
+ cache.Redis = oldRedis
}()
// Reset cache and set some cached config