From 665397ede7b1152167f25f412e3d3f7eb6faa7dd Mon Sep 17 00:00:00 2001 From: yangy Date: Sun, 31 May 2026 09:52:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(ota):=20=E5=A2=9E=E5=BC=BA=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E7=AE=A1=E7=90=86=E4=B8=8EOTA=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增OTA固件升级处理器,支持固件升级请求及黑名单过滤 - 引入设备持久化仓储,支持设备信息上报与活动记录 - 扩展数据模型,新增UserDevice与UserActive,支持设备版本跟踪 - 实现Redis到MySQL的异步数据同步任务 - 更新路由配置,集成新的API端点以支持OTA功能 - 优化架构图,反映新增的数据流与处理流程 --- .../zh/content/API 接口文档/设备管理接口.md | 305 +++++++- .../repowiki/zh/content/基础设施/缓存系统.md | 32 + .qoder/repowiki/zh/content/数据库设计.md | 380 +++++++++- .../zh/content/核心模块/业务处理器.md | 212 +++++- .../repowiki/zh/content/核心模块/数据模型.md | 658 +++++++++++++++--- .../zh/content/核心模块/数据访问层.md | 468 +++++++++++-- .../repowiki/zh/meta/repowiki-metadata.json | 2 +- 7 files changed, 1764 insertions(+), 293 deletions(-) diff --git a/.qoder/repowiki/zh/content/API 接口文档/设备管理接口.md b/.qoder/repowiki/zh/content/API 接口文档/设备管理接口.md index 72a972b..6c499d5 100644 --- a/.qoder/repowiki/zh/content/API 接口文档/设备管理接口.md +++ b/.qoder/repowiki/zh/content/API 接口文档/设备管理接口.md @@ -6,27 +6,46 @@ - [internal/router/router.go](file://internal/router/router.go) - [internal/cache/redis.go](file://internal/cache/redis.go) - [internal/config/redis.go](file://internal/config/redis.go) +- [internal/config/database.go](file://internal/config/database.go) +- [internal/database/mysql.go](file://internal/database/mysql.go) +- [internal/model/user_device.go](file://internal/model/user_device.go) +- [internal/model/user_active.go](file://internal/model/user_active.go) +- [internal/repository/device.go](file://internal/repository/device.go) +- [internal/task/device_persist.go](file://internal/task/device_persist.go) - [internal/response/response.go](file://internal/response/response.go) - [internal/middleware/logger.go](file://internal/middleware/logger.go) - [internal/middleware/cors.go](file://internal/middleware/cors.go) - [cmd/server/main.go](file://cmd/server/main.go) +- [sql/user_device.sql](file://sql/user_device.sql) +- [sql/user_active.sql](file://sql/user_active.sql) - [README.md](file://README.md) +## 更新摘要 +**变更内容** +- 新增设备信息持久化系统,实现Redis到数据库的定时同步 +- 添加DevicePersistTask组件,支持设备注册和活动跟踪的数据库持久化 +- 新增数据库表user_device和user_active的完整数据结构 +- 实现每5分钟的批量数据同步机制 +- 增强数据一致性保证和错误处理机制 + ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构概览](#架构概览) 5. [详细组件分析](#详细组件分析) -6. [依赖关系分析](#依赖关系分析) -7. [性能考虑](#性能考虑) -8. [故障排除指南](#故障排除指南) -9. [结论](#结论) +6. [数据库持久化系统](#数据库持久化系统) +7. [依赖关系分析](#依赖关系分析) +8. [性能考虑](#性能考虑) +9. [故障排除指南](#故障排除指南) +10. [结论](#结论) ## 简介 -本文档详细描述了设备管理接口的完整规范,特别是设备信息上报接口。该接口允许设备向服务器上报其基本信息,包括 MAC 地址、型号、版本号等,并将数据存储在 Redis 缓存中。文档涵盖了 HTTP 方法、URL 模式、请求参数结构、响应格式、错误处理、数据验证规则、重复上报处理和数据一致性保证等方面。 +本文档详细描述了设备管理接口的完整规范,特别是设备信息上报接口。该接口允许设备向服务器上报其基本信息,包括 MAC 地址、型号、版本号等,并将数据存储在 Redis 缓存中。系统现已集成设备信息持久化系统,通过DevicePersistTask组件实现Redis到数据库的定时同步,支持设备注册和活动跟踪的数据库持久化。 + +文档涵盖了 HTTP 方法、URL 模式、请求参数结构、响应格式、错误处理、数据验证规则、重复上报处理和数据一致性保证等方面。 ## 项目结构 @@ -34,7 +53,11 @@ - **入口层**: `cmd/server/main.go` - 应用程序入口点,负责初始化配置、数据库连接、搜索引擎和缓存客户端 - **路由层**: `internal/router/router.go` - 路由定义和中间件配置 - **处理器层**: `internal/handler/device.go` - 设备信息上报业务逻辑 +- **任务层**: `internal/task/device_persist.go` - 设备信息持久化任务 - **缓存层**: `internal/cache/redis.go` 和 `internal/config/redis.go` - Redis 客户端配置和连接管理 +- **数据库层**: `internal/config/database.go`、`internal/database/mysql.go` - 数据库配置和连接管理 +- **模型层**: `internal/model/user_device.go`、`internal/model/user_active.go` - 数据库模型定义 +- **仓库层**: `internal/repository/device.go` - 数据访问层 - **响应层**: `internal/response/response.go` - 统一响应格式 - **中间件层**: `internal/middleware/logger.go` 和 `internal/middleware/cors.go` - 日志记录和跨域支持 @@ -50,29 +73,42 @@ Middleware[中间件层] end subgraph "业务处理" DeviceHandler[设备处理器] +DevicePersistTask[设备持久化任务] Response[响应层] end subgraph "数据存储" Redis[Redis缓存] +MySQL[MySQL数据库] Config[配置管理] end +subgraph "数据模型" +UserDevice[用户设备模型] +UserActive[用户活跃模型] +Repository[数据访问层] +end Main --> Gin Gin --> Router Router --> Middleware Router --> DeviceHandler DeviceHandler --> Response DeviceHandler --> Redis +DevicePersistTask --> MySQL +DevicePersistTask --> Redis +DevicePersistTask --> Repository +Repository --> UserDevice +Repository --> UserActive Main --> Config Main --> Redis +Main --> MySQL ``` **图表来源** -- [cmd/server/main.go:22-64](file://cmd/server/main.go#L22-L64) -- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41) -- [internal/handler/device.go:14-24](file://internal/handler/device.go#L14-L24) +- [cmd/server/main.go:27-76](file://cmd/server/main.go#L27-L76) +- [internal/handler/device.go:15-25](file://internal/handler/device.go#L15-L25) +- [internal/task/device_persist.go:14-22](file://internal/task/device_persist.go#L14-L22) **章节来源** -- [cmd/server/main.go:1-96](file://cmd/server/main.go#L1-L96) +- [cmd/server/main.go:1-156](file://cmd/server/main.go#L1-L156) - [internal/router/router.go:1-42](file://internal/router/router.go#L1-L42) ## 核心组件 @@ -86,6 +122,15 @@ Main --> Redis - **缓存存储**: 使用 Redis Hash 结构存储设备信息 - **错误处理**: 提供统一的错误响应格式 +### 设备持久化任务 + +新增的设备持久化任务组件负责将Redis中的设备信息定期同步到数据库中,实现数据的长期持久化存储。该组件具有以下特点: + +- **定时同步**: 每5分钟自动执行一次数据同步 +- **批量处理**: 支持批量读取和处理Redis中的设备数据 +- **事务保证**: 确保数据库操作的一致性 +- **错误恢复**: 具备完善的错误处理和日志记录机制 + ### 接口规范 #### HTTP 请求规范 @@ -130,7 +175,7 @@ Main --> Redis | 200 | 500 | 系统错误 | `{"code": 500, "msg": "系统错误"}` | **章节来源** -- [internal/handler/device.go:26-84](file://internal/handler/device.go#L26-L84) +- [internal/handler/device.go:27-83](file://internal/handler/device.go#L27-L83) - [internal/router/router.go:32-38](file://internal/router/router.go#L32-L38) ## 架构概览 @@ -143,6 +188,8 @@ participant Client as 设备客户端 participant API as API网关 participant Handler as 设备处理器 participant Redis as Redis缓存 +participant Task as 持久化任务 +participant DB as MySQL数据库 participant Logger as 日志系统 Client->>API : GET /audio/reportDevInfo?mac=&model=&ver= API->>Handler : 调用 ReportDevInfo() @@ -159,11 +206,18 @@ else Redis操作成功 Handler->>Client : 返回成功响应 end end +Note over Task,DB : 每5分钟定时执行 +Task->>Redis : HGetAll devices +Task->>Task : 解析JSON数据 +Task->>DB : 插入/更新 user_device +Task->>DB : 插入/更新 user_active +Task->>Redis : HDel 成功记录 +Task->>Logger : 记录同步结果 ``` **图表来源** -- [internal/handler/device.go:26-84](file://internal/handler/device.go#L26-L84) -- [internal/router/router.go:32-38](file://internal/router/router.go#L32-L38) +- [internal/handler/device.go:27-83](file://internal/handler/device.go#L27-L83) +- [internal/task/device_persist.go:37-91](file://internal/task/device_persist.go#L37-L91) ## 详细组件分析 @@ -177,8 +231,20 @@ class DeviceHandler { +NewDeviceHandler(redis, log) DeviceHandler +ReportDevInfo(c) void } +class DevicePersistTask { +-rdb : redis.Client +-repo : DeviceRepository +-log : zap.Logger ++NewDevicePersistTask(rdb, repo, log) DevicePersistTask ++Start(interval) void ++Persist() void ++persistDevice(ctx, info) bool ++persistActive(ctx, info) bool +} class RedisClient { +HSet(ctx, key, field, value) error ++HGetAll(ctx, key) map[string]string ++HDel(ctx, key, fields) error +Close() error } class Logger { @@ -187,11 +253,13 @@ class Logger { } DeviceHandler --> RedisClient : 使用 DeviceHandler --> Logger : 记录日志 +DevicePersistTask --> RedisClient : 读取数据 +DevicePersistTask --> Logger : 记录日志 ``` **图表来源** -- [internal/handler/device.go:14-24](file://internal/handler/device.go#L14-L24) -- [internal/handler/device.go:70-78](file://internal/handler/device.go#L70-L78) +- [internal/handler/device.go:15-25](file://internal/handler/device.go#L15-L25) +- [internal/task/device_persist.go:14-22](file://internal/task/device_persist.go#L14-L22) ### 参数验证流程 @@ -224,7 +292,7 @@ ReturnSuccess --> End ``` **图表来源** -- [internal/handler/device.go:26-84](file://internal/handler/device.go#L26-L84) +- [internal/handler/device.go:27-83](file://internal/handler/device.go#L27-L83) ### Redis 缓存交互 @@ -246,7 +314,7 @@ ReturnSuccess --> End ``` **章节来源** -- [internal/handler/device.go:52-78](file://internal/handler/device.go#L52-L78) +- [internal/handler/device.go:50-77](file://internal/handler/device.go#L50-L77) ### 中间件集成 @@ -266,6 +334,118 @@ ReturnSuccess --> End - [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45) - [internal/middleware/cors.go:7-20](file://internal/middleware/cors.go#L7-L20) +## 数据库持久化系统 + +### 设备持久化任务架构 + +新增的设备持久化任务系统实现了Redis到数据库的定时同步,确保设备信息的长期持久化存储。 + +```mermaid +flowchart TD +Start([启动持久化任务]) --> Timer["5分钟定时器"] +Timer --> GetData["从Redis读取所有设备数据"] +GetData --> ParseData["解析JSON数据"] +ParseData --> FixDate["修复日期格式"] +FixDate --> ProcessDevice["处理设备信息"] +ProcessDevice --> ProcessActive["处理活跃信息"] +ProcessActive --> Success{"处理成功?"} +Success --> |是| BatchDelete["批量删除已处理记录"] +Success --> |否| LogError["记录错误日志"] +BatchDelete --> Complete["完成同步"] +LogError --> Complete +Complete --> Timer +``` + +**图表来源** +- [internal/task/device_persist.go:24-35](file://internal/task/device_persist.go#L24-L35) +- [internal/task/device_persist.go:37-91](file://internal/task/device_persist.go#L37-L91) + +### 数据库表结构 + +#### 用户设备表 (user_device) + +| 字段名 | 类型 | 约束 | 描述 | +|--------|------|------|------| +| id | int | PRIMARY KEY, AUTO_INCREMENT | 主键ID | +| mac_addr | varchar(255) | UNIQUE, NOT NULL | 设备MAC地址 | +| model | varchar(255) | NOT NULL | 设备型号 | +| add_time | datetime | DEFAULT CURRENT_TIMESTAMP | 添加时间 | +| ver | varchar(10) | NULL | 设备版本号 | + +#### 用户活跃表 (user_active) + +| 字段名 | 类型 | 约束 | 描述 | +|--------|------|------|------| +| id | int | PRIMARY KEY, AUTO_INCREMENT | 主键ID | +| mac_addr | varchar(100) | NOT NULL | 设备MAC地址 | +| model | varchar(50) | NOT NULL | 设备型号 | +| active_date | date | NOT NULL | 活跃日期 | +| ip_addr | varchar(100) | NOT NULL | IP地址 | +| create_at | datetime | DEFAULT CURRENT_TIMESTAMP | 创建时间 | + +**章节来源** +- [sql/user_device.sql:24-32](file://sql/user_device.sql#L24-L32) +- [sql/user_active.sql:24-33](file://sql/user_active.sql#L24-L33) + +### 数据同步流程 + +设备持久化任务的数据同步流程如下: + +```mermaid +sequenceDiagram +participant Redis as Redis缓存 +participant Task as 持久化任务 +participant Repo as 数据访问层 +participant DB as MySQL数据库 +Task->>Redis : HGetAll devices +Redis->>Task : 返回设备数据 +Task->>Task : 解析JSON数据 +Task->>Task : 修复日期格式 +Task->>Repo : 查找设备信息 +Repo->>DB : 查询user_device +DB->>Repo : 返回查询结果 +alt 设备不存在 +Task->>Repo : 插入新设备 +Repo->>DB : INSERT user_device +DB->>Repo : 返回插入结果 +else 设备存在 +Task->>Repo : 更新设备版本 +Repo->>DB : UPDATE user_device +DB->>Repo : 返回更新结果 +end +Task->>Repo : 查找活跃信息 +Repo->>DB : 查询user_active +DB->>Repo : 返回查询结果 +alt 活跃信息不存在 +Task->>Repo : 插入新活跃记录 +Repo->>DB : INSERT user_active +DB->>Repo : 返回插入结果 +else 活跃信息存在 +Task->>Repo : 更新IP地址 +Repo->>DB : UPDATE user_active +DB->>Repo : 返回更新结果 +end +Task->>Redis : HDel 成功记录 +``` + +**图表来源** +- [internal/task/device_persist.go:93-131](file://internal/task/device_persist.go#L93-L131) +- [internal/task/device_persist.go:133-166](file://internal/task/device_persist.go#L133-L166) + +### 数据一致性保证 + +系统通过以下机制确保数据一致性: + +1. **原子性**: 使用数据库事务确保设备和活跃信息的更新原子性 +2. **幂等性**: 支持重复上报的处理,避免数据重复 +3. **回滚机制**: 当部分操作失败时,系统会记录错误并继续处理其他记录 +4. **数据修复**: 自动修复历史数据中的无效日期格式 + +**章节来源** +- [internal/task/device_persist.go:70-73](file://internal/task/device_persist.go#L70-L73) +- [internal/task/device_persist.go:101-128](file://internal/task/device_persist.go#L101-L128) +- [internal/task/device_persist.go:141-163](file://internal/task/device_persist.go#L141-L163) + ## 依赖关系分析 ### 外部依赖 @@ -280,28 +460,40 @@ end subgraph "第三方库" Gin[Gin Web框架] Redis[Redis客户端] +MySQL[MySQL驱动] Zap[Zap日志库] -end +Time[时间处理] +Context[上下文] +End subgraph "内部模块" Handler[处理器层] -Router[路由层] +Task[任务层] Cache[缓存层] +Database[数据库层] +Model[模型层] +Repository[仓库层] Response[响应层] Middleware[中间件层] end Handler --> Gin Handler --> Redis -Handler --> Zap -Router --> Gin +Handler --> Context +Task --> Redis +Task --> MySQL +Task --> Time +Task --> Model +Task --> Repository Cache --> Redis +Database --> MySQL +Repository --> Database Response --> Gin Middleware --> Gin Middleware --> Zap ``` **图表来源** -- [internal/handler/device.go:3-12](file://internal/handler/device.go#L3-L12) -- [internal/router/router.go:3-12](file://internal/router/router.go#L3-L12) +- [internal/handler/device.go:3-13](file://internal/handler/device.go#L3-L13) +- [internal/task/device_persist.go:3-12](file://internal/task/device_persist.go#L3-L12) ### 内部模块依赖 @@ -313,11 +505,21 @@ end subgraph "配置模块" Config[internal/config/config.go] RedisConfig[internal/config/redis.go] +DBConfig[internal/config/database.go] end subgraph "服务模块" Router[internal/router/router.go] Handler[internal/handler/device.go] +Task[internal/task/device_persist.go] Cache[internal/cache/redis.go] +Database[internal/database/mysql.go] +end +subgraph "数据模块" +Model[internal/model/user_device.go] +Model2[internal/model/user_active.go] +Repository[internal/repository/device.go] +SQL[sql/user_device.sql] +SQL2[sql/user_active.sql] end subgraph "工具模块" Response[internal/response/response.go] @@ -327,19 +529,29 @@ end Main --> Config Main --> Router Main --> Cache +Main --> Database Router --> Handler +Router --> Task Handler --> Response +Handler --> Cache +Task --> Repository +Task --> Model +Task --> Model2 +Repository --> Database +Repository --> Model +Repository --> Model2 Router --> Logger Router --> CORS Cache --> RedisConfig +Database --> DBConfig ``` **图表来源** -- [cmd/server/main.go:13-18](file://cmd/server/main.go#L13-L18) +- [cmd/server/main.go:27-76](file://cmd/server/main.go#L27-L76) - [internal/router/router.go:6-12](file://internal/router/router.go#L6-L12) **章节来源** -- [cmd/server/main.go:1-96](file://cmd/server/main.go#L1-L96) +- [cmd/server/main.go:1-156](file://cmd/server/main.go#L1-L156) - [internal/config/config.go:1-64](file://internal/config/config.go#L1-L64) ## 性能考虑 @@ -349,18 +561,28 @@ Cache --> RedisConfig 1. **连接池管理**: 使用单个 Redis 客户端实例,避免频繁创建连接 2. **内存使用**: 设备信息以 JSON 字符串形式存储,占用内存较小 3. **键设计**: 使用简单的哈希结构,查询效率高 +4. **批量操作**: 持久化任务使用批量删除操作,提高Redis清理效率 + +### 数据库性能优化 + +1. **连接池配置**: MySQL连接池最大25个连接,空闲5个连接,连接生命周期5分钟 +2. **分区策略**: user_active表按日期分区,提高查询性能 +3. **索引优化**: 设备表使用唯一索引,活跃表使用复合索引 +4. **批量写入**: 持久化任务支持批量数据写入 ### 请求处理优化 1. **参数预处理**: 使用 `strings.TrimSpace()` 去除多余空白字符 2. **早期返回**: 在参数验证失败时立即返回错误 3. **上下文传递**: 使用请求上下文进行异步操作 +4. **定时任务**: 使用ticker实现精确的5分钟定时执行 ### 监控建议 1. **Redis 监控**: 监控键数量、内存使用率、命令执行时间 -2. **应用监控**: 监控请求延迟、错误率、并发请求数 -3. **日志监控**: 设置适当的日志级别,避免过多的日志输出影响性能 +2. **数据库监控**: 监控连接数、查询性能、分区使用情况 +3. **应用监控**: 监控请求延迟、错误率、并发请求数 +4. **持久化监控**: 监控数据同步成功率、处理速度 ## 故障排除指南 @@ -381,34 +603,49 @@ Cache --> RedisConfig **原因**: 设备信息格式化过程中出现异常 **解决方法**: 检查设备信息的数据类型和格式 +#### 数据库连接错误 +**症状**: 持久化任务日志显示数据库连接失败 +**原因**: 数据库服务器不可达或配置错误 +**解决方法**: 检查数据库配置和网络连接 + +#### 数据同步失败 +**症状**: 持久化任务日志显示某些设备同步失败 +**原因**: 数据库约束冲突或数据格式问题 +**解决方法**: 检查设备数据的完整性和格式 + ### 调试步骤 1. **启用详细日志**: 检查日志中间件输出的请求信息 2. **验证参数**: 确认请求参数的完整性和正确性 3. **测试 Redis**: 验证 Redis 服务的可用性和权限设置 4. **查看响应**: 分析接口返回的具体错误信息 +5. **检查数据库**: 验证数据库连接和表结构 +6. **监控持久化**: 查看持久化任务的执行状态和日志 **章节来源** -- [internal/handler/device.go:32-38](file://internal/handler/device.go#L32-L38) -- [internal/handler/device.go:60-68](file://internal/handler/device.go#L60-L68) -- [internal/handler/device.go:70-78](file://internal/handler/device.go#L70-L78) +- [internal/handler/device.go:33-39](file://internal/handler/device.go#L33-L39) +- [internal/handler/device.go:69-76](file://internal/handler/device.go#L69-L76) +- [internal/task/device_persist.go:43-46](file://internal/task/device_persist.go#L43-L46) ## 结论 -设备管理接口提供了简单而高效的设备信息上报功能。通过合理的参数验证、统一的响应格式和可靠的 Redis 存储机制,该接口能够满足大多数设备管理场景的需求。 +设备管理接口提供了简单而高效的设备信息上报功能,并通过新增的设备持久化系统实现了数据的长期可靠存储。该系统结合了Redis的高性能缓存和MySQL的持久化存储,形成了完整的设备管理解决方案。 ### 主要优势 1. **简洁明了**: 接口设计简单,易于理解和使用 2. **可靠性强**: 完善的错误处理和日志记录机制 -3. **性能优秀**: 使用 Redis 缓存,响应速度快 +3. **性能优秀**: 使用 Redis 缓存,响应速度快;支持定时批量同步 4. **扩展性强**: 基于 Gin 框架,便于功能扩展 +5. **数据持久化**: 通过定时任务确保数据的长期存储 +6. **数据一致性**: 通过事务和幂等性设计保证数据一致性 ### 改进建议 1. **数据验证增强**: 可以添加更严格的数据格式验证 2. **限流机制**: 可以添加请求频率限制,防止恶意刷取 -3. **数据持久化**: 可以考虑将重要数据同时存储到数据库中 -4. **API 版本控制**: 可以添加 API 版本号,便于后续升级 +3. **API 版本控制**: 可以添加 API 版本号,便于后续升级 +4. **监控告警**: 可以添加更完善的监控和告警机制 +5. **数据备份**: 可以添加数据库备份和恢复机制 -该接口为设备管理系统提供了坚实的基础,可以根据具体需求进一步扩展和完善。 \ No newline at end of file +该接口为设备管理系统提供了坚实的基础,新增的持久化系统进一步增强了系统的可靠性和数据安全性,可以根据具体需求进一步扩展和完善。 \ No newline at end of file diff --git a/.qoder/repowiki/zh/content/基础设施/缓存系统.md b/.qoder/repowiki/zh/content/基础设施/缓存系统.md index 06d1ac0..a873999 100644 --- a/.qoder/repowiki/zh/content/基础设施/缓存系统.md +++ b/.qoder/repowiki/zh/content/基础设施/缓存系统.md @@ -25,6 +25,7 @@ - 添加缓存穿透防护和数据库降级机制 - 优化缓存键命名规范和数据序列化策略 - 增强缓存失效策略和数据一致性保证 +- 实现智能缓存回写和错误处理机制 ## 目录 1. [简介](#简介) @@ -245,6 +246,18 @@ Empty --> End - [internal/repository/brand.go:34-52](file://internal/repository/brand.go#L34-L52) - [internal/repository/model.go:27-79](file://internal/repository/model.go#L27-L79) +### 缓存回写机制 +系统实现了智能的缓存回写机制,确保数据的一致性和新鲜度: + +- **回写时机**:在数据库查询成功后,将数据写回到相应的缓存位置 +- **回写策略**:根据查询类型选择合适的缓存回写策略 +- **错误处理**:缓存回写失败时记录日志但不影响主流程 +- **性能优化**:避免重复查询相同数据,提升整体查询性能 + +**章节来源** +- [internal/repository/brand.go:44-51](file://internal/repository/brand.go#L44-L51) +- [internal/repository/model.go:44-74](file://internal/repository/model.go#L44-L74) + ## 缓存策略设计 ### TTL过期管理 @@ -264,6 +277,12 @@ Empty --> End - **二进制存储**:Redis存储二进制数据,提高传输效率 - **错误处理**:序列化和反序列化失败时返回明确的错误信息 +### 缓存查询策略 +- **品牌查询**:优先从缓存获取全量品牌列表,支持应用层模糊过滤 +- **型号查询**:根据查询条件选择合适的缓存策略 +- **缓存优先**:尽可能从缓存获取数据,减少数据库压力 +- **降级保护**:缓存失败时自动降级到数据库查询 + **章节来源** - [internal/cache/brand_cache.go:13-16](file://internal/cache/brand_cache.go#L13-L16) - [internal/cache/model_cache.go:13-17](file://internal/cache/model_cache.go#L13-L17) @@ -347,6 +366,17 @@ REPO --> REDIS - 验证TTL设置是否合理 - 分析数据更新频率 +### 缓存回写问题 +- **缓存未更新** + - 检查缓存回写逻辑是否正确执行 + - 验证缓存键是否正确生成 + - 查看回写错误日志 + +- **数据不一致** + - 检查缓存过期时间设置 + - 验证数据库更新后是否及时回写 + - 分析并发访问时的数据一致性 + **章节来源** - [cmd/server/main.go:103-131](file://cmd/server/main.go#L103-L131) - [internal/repository/brand.go:34-52](file://internal/repository/brand.go#L34-L52) @@ -358,6 +388,7 @@ Luxsin应用API的缓存系统实现了完整的Redis缓存解决方案,包含 - **完整的组件体系**:BrandCache和ModelCache提供了专业的缓存功能 - **智能的缓存策略**:支持TTL管理、自动预热和多级缓存 - **可靠的降级机制**:缓存失败时自动降级到数据库,确保服务可用性 +- **完善的回写机制**:智能缓存回写确保数据一致性 - **良好的扩展性**:清晰的架构设计便于添加新的缓存组件 建议在后续版本中进一步完善监控指标、缓存统计和动态配置功能,以提升系统的可观测性和运维效率。 @@ -382,6 +413,7 @@ Luxsin应用API的缓存系统实现了完整的Redis缓存解决方案,包含 - 缓存写入成功率 - 数据库查询次数 - Redis连接池使用情况 +- 缓存回写成功率 **章节来源** - [internal/cache/brand_cache.go:13-16](file://internal/cache/brand_cache.go#L13-L16) diff --git a/.qoder/repowiki/zh/content/数据库设计.md b/.qoder/repowiki/zh/content/数据库设计.md index fa0b7cd..fe0b8ef 100644 --- a/.qoder/repowiki/zh/content/数据库设计.md +++ b/.qoder/repowiki/zh/content/数据库设计.md @@ -17,8 +17,30 @@ - [internal/cache/redis.go](file://internal/cache/redis.go) - [internal/search/meilisearch.go](file://internal/search/meilisearch.go) - [cmd/server/main.go](file://cmd/server/main.go) +- [sql/user_device.sql](file://sql/user_device.sql) +- [sql/user_active.sql](file://sql/user_active.sql) +- [sql/ota.sql](file://sql/ota.sql) +- [sql/black_list.sql](file://sql/black_list.sql) +- [sql/ota_target_device.sql](file://sql/ota_target_device.sql) +- [internal/model/user_device.go](file://internal/model/user_device.go) +- [internal/model/user_active.go](file://internal/model/user_active.go) +- [internal/model/ota.go](file://internal/model/ota.go) +- [internal/repository/device.go](file://internal/repository/device.go) +- [internal/repository/ota.go](file://internal/repository/ota.go) +- [internal/handler/device.go](file://internal/handler/device.go) +- [internal/handler/ota.go](file://internal/handler/ota.go) +- [internal/task/device_persist.go](file://internal/task/device_persist.go) +## 更新摘要 +**所做更改** +- 新增设备持久化子系统:user_device、user_active 表及配套处理器和任务 +- 新增 OTA 固件升级子系统:ota、black_list、ota_target_device 表及配套仓库层 +- 更新架构图以反映新的数据流和处理流程 +- 新增设备上报接口和定时持久化任务 +- 新增 OTA 升级查询接口和复杂业务逻辑处理 +- 更新数据访问模式以支持新的业务场景 + ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) @@ -34,6 +56,8 @@ ## 简介 本文件面向 Luxsin 应用 API 的数据库与数据模型,系统化梳理实体关系、字段定义、索引与约束、数据访问模式、缓存与搜索集成、性能优化、数据生命周期与迁移路径,并给出品牌(Brand)与型号(Model)实体的设计理念与业务逻辑说明。文档同时覆盖数据库连接配置、查询优化建议、数据安全与隐私要求以及访问控制要点。 +**更新** 本次更新反映了数据库架构的重大扩展,新增了设备持久化和 OTA 固件升级两大核心功能模块,包括 user_device、user_active、ota、black_list、ota_target_device 五个新表及其配套的处理逻辑。 + ## 项目结构 本项目采用分层架构:入口程序负责初始化配置、数据库、搜索引擎与缓存;路由层组织 HTTP 接口;处理器层封装业务接口;仓库层实现数据访问;模型层承载数据结构;搜索与缓存模块作为外部依赖集成。 @@ -57,10 +81,18 @@ subgraph "业务层" ROUTER["路由(未在本文展开)"] HANDLER_B["internal/handler/brand.go"] HANDLER_M["internal/handler/model.go"] +HANDLER_D["internal/handler/device.go"] +HANDLER_O["internal/handler/ota.go"] REPO_B["internal/repository/brand.go"] REPO_M["internal/repository/model.go"] +REPO_D["internal/repository/device.go"] +REPO_O["internal/repository/ota.go"] MODEL_B["internal/model/brand.go"] MODEL_M["internal/model/model.go"] +MODEL_UD["internal/model/user_device.go"] +MODEL_UA["internal/model/user_active.go"] +MODEL_OTA["internal/model/ota.go"] +TASK_DP["internal/task/device_persist.go"] end MAIN --> CFG CFG --> DB_CFG @@ -71,13 +103,21 @@ MAIN --> REDIS MAIN --> MEILI ROUTER --> HANDLER_B ROUTER --> HANDLER_M +ROUTER --> HANDLER_D +ROUTER --> HANDLER_O HANDLER_B --> REPO_B HANDLER_M --> REPO_M +HANDLER_D --> REPO_D +HANDLER_O --> REPO_O REPO_B --> MODEL_B REPO_M --> MODEL_M +REPO_D --> MODEL_UD +REPO_D --> MODEL_UA +REPO_O --> MODEL_OTA +TASK_DP --> REPO_D ``` -图表来源 +**图表来源** - [cmd/server/main.go:1-96](file://cmd/server/main.go#L1-L96) - [internal/config/config.go:1-64](file://internal/config/config.go#L1-L64) - [internal/config/database.go:1-72](file://internal/config/database.go#L1-L72) @@ -88,31 +128,55 @@ REPO_M --> MODEL_M - [internal/search/meilisearch.go:1-46](file://internal/search/meilisearch.go#L1-L46) - [internal/handler/brand.go:1-50](file://internal/handler/brand.go#L1-L50) - [internal/handler/model.go:1-51](file://internal/handler/model.go#L1-L51) +- [internal/handler/device.go:1-83](file://internal/handler/device.go#L1-L83) +- [internal/handler/ota.go:1-133](file://internal/handler/ota.go#L1-L133) - [internal/repository/brand.go:1-51](file://internal/repository/brand.go#L1-L51) - [internal/repository/model.go:1-95](file://internal/repository/model.go#L1-L95) +- [internal/repository/device.go:1-88](file://internal/repository/device.go#L1-L88) +- [internal/repository/ota.go:1-159](file://internal/repository/ota.go#L1-L159) - [internal/model/brand.go:1-7](file://internal/model/brand.go#L1-L7) - [internal/model/model.go:1-15](file://internal/model/model.go#L1-L15) +- [internal/model/user_device.go:1-12](file://internal/model/user_device.go#L1-L12) +- [internal/model/user_active.go:1-13](file://internal/model/user_active.go#L1-L13) +- [internal/model/ota.go:1-43](file://internal/model/ota.go#L1-L43) +- [internal/task/device_persist.go:1-167](file://internal/task/device_persist.go#L1-L167) -章节来源 +**章节来源** - [cmd/server/main.go:1-96](file://cmd/server/main.go#L1-L96) - [internal/config/config.go:1-64](file://internal/config/config.go#L1-L64) ## 核心组件 - 数据库表 model:存储耳机型号信息,包含唯一组合索引以保证品牌+型号的唯一性。 +- 设备持久化表:user_device(设备信息持久化)、user_active(设备活跃度统计) +- OTA 升级表:ota(固件升级信息)、black_list(黑名单)、ota_target_device(定向设备) - 模型对象 Brand 与 Model:分别映射品牌与型号的 JSON 字段与数据库列。 - 仓库层:提供按品牌名或型号名检索的查询方法,支持模糊匹配与精确匹配。 - 处理器层:暴露 HTTP 接口,支持返回 JSON 或 Base64 编码响应。 - 配置层:集中加载数据库、搜索引擎与缓存的连接参数,并进行基本校验。 - 基础设施:MySQL 连接池配置、Redis 客户端、Meilisearch 搜索客户端。 -章节来源 +**更新** 新增设备持久化和 OTA 升级两大功能模块,包含完整的数据模型、业务逻辑和处理流程。 + +**章节来源** - [sql/model.sql:20-38](file://sql/model.sql#L20-L38) +- [sql/user_device.sql:20-35](file://sql/user_device.sql#L20-L35) +- [sql/user_active.sql:20-208](file://sql/user_active.sql#L20-L208) +- [sql/ota.sql:20-47](file://sql/ota.sql#L20-L47) +- [sql/black_list.sql:20-33](file://sql/black_list.sql#L20-L33) +- [sql/ota_target_device.sql:20-34](file://sql/ota_target_device.sql#L20-L34) - [internal/model/brand.go:1-7](file://internal/model/brand.go#L1-L7) - [internal/model/model.go:1-15](file://internal/model/model.go#L1-L15) +- [internal/model/user_device.go:1-12](file://internal/model/user_device.go#L1-L12) +- [internal/model/user_active.go:1-13](file://internal/model/user_active.go#L1-L13) +- [internal/model/ota.go:1-43](file://internal/model/ota.go#L1-L43) - [internal/repository/brand.go:1-51](file://internal/repository/brand.go#L1-L51) - [internal/repository/model.go:1-95](file://internal/repository/model.go#L1-L95) +- [internal/repository/device.go:1-88](file://internal/repository/device.go#L1-L88) +- [internal/repository/ota.go:1-159](file://internal/repository/ota.go#L1-L159) - [internal/handler/brand.go:1-50](file://internal/handler/brand.go#L1-L50) - [internal/handler/model.go:1-51](file://internal/handler/model.go#L1-L51) +- [internal/handler/device.go:1-83](file://internal/handler/device.go#L1-L83) +- [internal/handler/ota.go:1-133](file://internal/handler/ota.go#L1-L133) - [internal/config/database.go:1-72](file://internal/config/database.go#L1-L72) - [internal/config/meilisearch.go:1-51](file://internal/config/meilisearch.go#L1-L51) - [internal/config/redis.go:1-57](file://internal/config/redis.go#L1-L57) @@ -121,17 +185,17 @@ REPO_M --> MODEL_M - [internal/search/meilisearch.go:1-46](file://internal/search/meilisearch.go#L1-L46) ## 架构总览 -下图展示从 HTTP 请求到数据库与搜索引擎的调用链路,以及缓存的使用位置。 +下图展示从 HTTP 请求到数据库与搜索引擎的调用链路,以及缓存的使用位置。新增了设备上报和 OTA 升级的完整处理流程。 ```mermaid sequenceDiagram participant C as "客户端" -participant H as "处理器(品牌/型号)" -participant R as "仓库(品牌/型号)" +participant H as "处理器(品牌/型号/设备/OTA)" +participant R as "仓库(品牌/型号/设备/OTA)" participant DB as "MySQL 数据库" participant S as "Meilisearch" participant RC as "Redis" -C->>H : "HTTP GET /brands 或 /models" +C->>H : "HTTP GET /brands,/models,/device/report,/audio/ota" H->>R : "List(过滤条件)" alt "数据库查询" R->>DB : "执行 SQL 查询" @@ -141,25 +205,38 @@ H->>S : "SearchWithContext(key, attributes)" S-->>H : "命中结果" end H-->>C : "JSON 或 Base64 响应" -note over H,RC : "可选:对热点数据进行缓存读写" +note over H,RC : "可选:对热点数据进行缓存读写
设备上报:Redis 缓存 + 定时持久化" ``` -图表来源 +**图表来源** - [internal/handler/brand.go:26-49](file://internal/handler/brand.go#L26-L49) - [internal/handler/model.go:26-50](file://internal/handler/model.go#L26-L50) +- [internal/handler/device.go:27-82](file://internal/handler/device.go#L27-L82) +- [internal/handler/ota.go:23-132](file://internal/handler/ota.go#L23-L132) - [internal/repository/brand.go:20-50](file://internal/repository/brand.go#L20-L50) - [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61) +- [internal/repository/device.go:19-87](file://internal/repository/device.go#L19-L87) +- [internal/repository/ota.go:19-158](file://internal/repository/ota.go#L19-L158) - [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45) - [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16) ## 详细组件分析 ### 数据模型与实体关系 -- 实体:Brand(品牌)、Model(型号) -- 关系:Model 通过字段 brand_name 引导与品牌的关系;当前仓库未显式声明外键约束,但数据库层通过唯一索引确保品牌+型号组合唯一。 +- 实体:Brand(品牌)、Model(型号)、UserDevice(设备)、UserActive(活跃度)、OTA(固件升级)、BlackList(黑名单)、OTATargetDevice(定向设备) +- 关系: + - Model 通过字段 brand_name 引导与品牌的关系 + - UserDevice 与 UserActive 通过 mac_addr 关联 + - OTA 与 BlackList 通过 ota_id 关联 + - OTA 与 OTATargetDevice 通过 ota_id 关联 - 字段与类型: - Brand:id(整数,主键)、name(字符串) - Model:id(整数,主键)、brand_name(字符串,非空)、name(字符串,非空)、form(字符串,可空)、rig(字符串,可空)、source(字符串,可空)、eq_key(字符串,可空)、create_at(时间戳,默认当前时间) + - UserDevice:id(整数,主键)、mac_addr(字符串,唯一)、model(字符串)、add_time(时间戳,默认当前时间)、ver(字符串,可空) + - UserActive:id(整数,主键)、mac_addr(字符串)、model(字符串)、active_date(日期,主键部分)、ip_addr(字符串)、create_at(时间戳,默认当前时间) + - OTA:id(整数,主键)、verCode(整数)、verName(字符串)、url(字符串)、md5(字符串)、force(整数,默认0)、desc(字符串,可空)、model(字符串,可空)、hw(整数,默认0)、target(整数,默认0)、beta(整数,默认0)、pawVerCode(整数,默认0)、pawVerName(字符串)、pawUrl(字符串)、pawMd5(字符串)、startTime(时间戳,可空)、endTime(时间戳,可空)、status(整数,默认1) + - BlackList:id(整数,主键)、ota_id(整数)、mac(字符串,默认空)、create_at(时间戳,默认当前时间) + - OTATargetDevice:id(整数,主键)、ota_id(整数)、mac_addr(字符串)、type(整数,默认1,1-白名单;2-黑名单)、create_at(时间戳,默认当前时间) ```mermaid erDiagram @@ -177,29 +254,107 @@ string source string eq_key datetime create_at } +USER_DEVICE { +int id PK +string mac_addr UK +string model +datetime add_time +string ver +} +USER_ACTIVE { +int id PK +string mac_addr +string model +date active_date PK +string ip_addr +datetime create_at +} +OTA { +int id PK +int verCode +string verName +string url +string md5 +int force +string desc +string model +int hw +int target +int beta +int pawVerCode +string pawVerName +string pawUrl +string pawMd5 +datetime startTime +datetime endTime +int status +} +BLACK_LIST { +int id PK +int ota_id +string mac +datetime create_at +} +OTA_TARGET_DEVICE { +int id PK +int ota_id +string mac_addr +int type +datetime create_at +} BRAND ||--o{ MODEL : "拥有多个型号" +USER_DEVICE ||--o{ USER_ACTIVE : "每日活跃记录" +OTA ||--o{ BLACK_LIST : "黑名单关联" +OTA ||--o{ OTA_TARGET_DEVICE : "定向设备关联" ``` -图表来源 +**图表来源** - [internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6) - [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14) +- [internal/model/user_device.go:5-11](file://internal/model/user_device.go#L5-L11) +- [internal/model/user_active.go:5-12](file://internal/model/user_active.go#L5-L12) +- [internal/model/ota.go:6-25](file://internal/model/ota.go#L6-L25) +- [internal/model/ota.go:28-42](file://internal/model/ota.go#L28-L42) - [sql/model.sql:24-35](file://sql/model.sql#L24-L35) +- [sql/user_device.sql:24-32](file://sql/user_device.sql#L24-L32) +- [sql/user_active.sql:24-32](file://sql/user_active.sql#L24-L32) +- [sql/ota.sql:24-44](file://sql/ota.sql#L24-L44) +- [sql/black_list.sql:24-30](file://sql/black_list.sql#L24-L30) +- [sql/ota_target_device.sql:24-31](file://sql/ota_target_device.sql#L24-L31) -章节来源 +**章节来源** - [internal/model/brand.go:1-7](file://internal/model/brand.go#L1-L7) - [internal/model/model.go:1-15](file://internal/model/model.go#L1-L15) +- [internal/model/user_device.go:1-12](file://internal/model/user_device.go#L1-L12) +- [internal/model/user_active.go:1-13](file://internal/model/user_active.go#L1-L13) +- [internal/model/ota.go:1-43](file://internal/model/ota.go#L1-L43) - [sql/model.sql:20-38](file://sql/model.sql#L20-L38) +- [sql/user_device.sql:20-35](file://sql/user_device.sql#L20-L35) +- [sql/user_active.sql:20-208](file://sql/user_active.sql#L20-L208) +- [sql/ota.sql:20-47](file://sql/ota.sql#L20-L47) +- [sql/black_list.sql:20-33](file://sql/black_list.sql#L20-L33) +- [sql/ota_target_device.sql:20-34](file://sql/ota_target_device.sql#L20-L34) ### 数据库表结构与约束 -- 表名:model -- 主键:id(自增整数) -- 唯一索引:(brand_name, name),用于保证同一品牌下的型号名称唯一 -- 默认值:create_at 默认当前时间 -- 注释:耳机型号 +- 表名:model、user_device、user_active、ota、black_list、ota_target_device +- 主键:各表的 id 字段(自增整数) +- 唯一索引: + - model:(brand_name, name) + - user_device:(mac_addr) + - user_active:(mac_addr, active_date) +- 默认值:各表的 create_at 字段默认当前时间 +- 分区表:user_active 表按 active_date 进行范围分区,包含 170 个分区 - 存储引擎与字符集:InnoDB、utf8mb4、排序规则 0900_ai_ci -章节来源 +**更新** 新增了三个分区表和多个唯一索引约束,增强了数据完整性和查询性能。 + +**章节来源** - [sql/model.sql:20-38](file://sql/model.sql#L20-L38) +- [sql/user_device.sql:20-35](file://sql/user_device.sql#L20-L35) +- [sql/user_active.sql:20-208](file://sql/user_active.sql#L20-L208) +- [sql/ota.sql:20-47](file://sql/ota.sql#L20-L47) +- [sql/black_list.sql:20-33](file://sql/black_list.sql#L20-L33) +- [sql/ota_target_device.sql:20-34](file://sql/ota_target_device.sql#L20-L34) ### 数据访问模式 - 品牌列表: @@ -209,6 +364,14 @@ BRAND ||--o{ MODEL : "拥有多个型号" - 支持按品牌名精确匹配或按型号名模糊匹配,二者二选一 - 无匹配条件时返回空数组 - 结果按名称升序排列 +- 设备持久化: + - 设备上报:通过 Redis Hash 缓存设备信息 + - 定时持久化:每间隔时间从 Redis 读取并批量写入数据库 + - 支持设备首次注册和版本更新 +- OTA 升级: + - 支持按型号、硬件版本、灰度标识查询最新 OTA 版本 + - 支持黑名单检查和定向设备检查 + - 自动处理灰度发布和强制升级逻辑 ```mermaid flowchart TD @@ -221,33 +384,56 @@ Branch --> |均为空| Empty["返回空数组"] Q1 --> Exec["执行查询并扫描结果"] Q2 --> Exec Empty --> End(["结束"]) -Exec --> End +subgraph "设备持久化流程" +Report["设备上报"] --> Cache["Redis 缓存"] +Cache --> Persist["定时持久化"] +Persist --> DBWrite["写入 user_device"] +DBWrite --> Active["写入 user_active"] +end ``` -图表来源 +**图表来源** - [internal/repository/brand.go:20-50](file://internal/repository/brand.go#L20-L50) - [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61) +- [internal/handler/device.go:27-82](file://internal/handler/device.go#L27-L82) +- [internal/task/device_persist.go:37-91](file://internal/task/device_persist.go#L37-L91) +- [internal/repository/device.go:19-87](file://internal/repository/device.go#L19-L87) -章节来源 +**章节来源** - [internal/repository/brand.go:1-51](file://internal/repository/brand.go#L1-L51) - [internal/repository/model.go:1-95](file://internal/repository/model.go#L1-L95) +- [internal/handler/device.go:1-83](file://internal/handler/device.go#L1-L83) +- [internal/task/device_persist.go:1-167](file://internal/task/device_persist.go#L1-L167) +- [internal/repository/device.go:1-88](file://internal/repository/device.go#L1-L88) ### 处理器与接口行为 - 品牌接口:接收 query 参数 brandName,支持返回 JSON 或 Base64 编码响应 - 型号接口:接收 query 参数 brandName 与 modelName,支持返回 JSON 或 Base64 编码响应 +- 设备上报接口:接收 mac、model、ver 参数,将设备信息缓存到 Redis +- OTA 升级接口:接收 model、hw、mac、beta 参数,返回合适的 OTA 升级信息 - 错误处理:内部错误统一返回 500 并记录日志 -章节来源 +**更新** 新增设备上报和 OTA 升级两个核心接口,支持完整的设备管理和固件升级业务流程。 + +**章节来源** - [internal/handler/brand.go:1-50](file://internal/handler/brand.go#L1-L50) - [internal/handler/model.go:1-51](file://internal/handler/model.go#L1-L51) +- [internal/handler/device.go:1-83](file://internal/handler/device.go#L1-L83) +- [internal/handler/ota.go:1-133](file://internal/handler/ota.go#L1-L133) ### 搜索与缓存集成 - 搜索:Meilisearch 客户端按给定关键字检索,限定返回属性,支持空命中返回空数组 -- 缓存:Redis 客户端初始化,可用于热点数据缓存(当前仓库未直接使用) +- 缓存:Redis 客户端初始化,用于设备信息缓存和定时持久化 +- 设备缓存:使用 Redis Hash 存储设备上报信息,键为设备 MAC 地址 +- 持久化策略:定时任务批量处理 Redis 缓存数据,避免频繁数据库写入 -章节来源 +**更新** 新增了设备信息的 Redis 缓存机制,通过定时任务实现高效的数据持久化。 + +**章节来源** - [internal/search/meilisearch.go:1-46](file://internal/search/meilisearch.go#L1-L46) - [internal/cache/redis.go:1-17](file://internal/cache/redis.go#L1-L17) +- [internal/handler/device.go:27-82](file://internal/handler/device.go#L27-L82) +- [internal/task/device_persist.go:37-91](file://internal/task/device_persist.go#L37-L91) ### 数据库连接配置 - 加载顺序:环境变量优先于默认值;生产环境需提供密码 @@ -255,7 +441,7 @@ Exec --> End - 连接池:最大打开连接数、最大空闲连接数、连接最大生命周期 - Ping 校验:启动时进行可达性检测 -章节来源 +**章节来源** - [internal/config/database.go:17-72](file://internal/config/database.go#L17-L72) - [internal/database/mysql.go:14-47](file://internal/database/mysql.go#L14-L47) @@ -265,15 +451,44 @@ Exec --> End - 搜索引擎:MEILISEARCH_HOST、MEILISEARCH_API_KEY、MEILISEARCH_INDEX - 缓存:REDIS_HOST、REDIS_PORT、REDIS_DATABASE、REDIS_PASSWORD -章节来源 +**章节来源** - [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52) - [internal/config/database.go:42-55](file://internal/config/database.go#L42-L55) - [internal/config/meilisearch.go:14-37](file://internal/config/meilisearch.go#L14-L37) - [internal/config/redis.go:39-49](file://internal/config/redis.go#L39-L49) +### 设备持久化子系统 +- 设备上报:客户端通过 /device/report 接口上报设备信息,包含 MAC 地址、设备型号、软件版本 +- Redis 缓存:设备信息以 JSON 格式存储在 Redis Hash 中,键为设备 MAC 地址 +- 定时持久化:后台任务每间隔时间从 Redis 读取设备数据,批量写入数据库 +- 数据一致性:支持设备首次注册和版本更新,自动处理 IP 地址更新 + +**新增** 设备持久化子系统提供了完整的设备生命周期管理能力。 + +**章节来源** +- [internal/handler/device.go:27-82](file://internal/handler/device.go#L27-L82) +- [internal/task/device_persist.go:24-167](file://internal/task/device_persist.go#L24-L167) +- [internal/repository/device.go:19-87](file://internal/repository/device.go#L19-L87) + +### OTA 固件升级子系统 +- 版本查询:支持按型号、硬件版本、灰度标识查询最新可用 OTA 版本 +- 黑名单机制:支持将特定设备加入 OTA 升级黑名单 +- 定向升级:支持针对特定设备集合的定向升级策略 +- 灰度发布:通过 beta 标识实现渐进式升级发布 +- 强制升级:支持强制升级策略,阻止设备继续使用旧版本 + +**新增** OTA 固件升级子系统提供了完整的固件管理能力。 + +**章节来源** +- [internal/handler/ota.go:23-132](file://internal/handler/ota.go#L23-L132) +- [internal/repository/ota.go:19-158](file://internal/repository/ota.go#L19-L158) +- [internal/model/ota.go:6-42](file://internal/model/ota.go#L6-L42) + ## 依赖分析 - 处理器依赖仓库;仓库依赖数据库;应用入口依赖配置与基础设施。 - 搜索与缓存作为独立模块被配置层加载并在处理器中可选使用。 +- 设备持久化依赖 Redis 缓存和定时任务。 +- OTA 升级依赖复杂的业务逻辑和多表关联查询。 - 代码内未发现循环依赖。 ```mermaid @@ -284,11 +499,19 @@ MAIN --> REDIS["internal/cache/redis.go"] MAIN --> MEILI["internal/search/meilisearch.go"] HANDLER_B["internal/handler/brand.go"] --> REPO_B["internal/repository/brand.go"] HANDLER_M["internal/handler/model.go"] --> REPO_M["internal/repository/model.go"] +HANDLER_D["internal/handler/device.go"] --> REPO_D["internal/repository/device.go"] +HANDLER_O["internal/handler/ota.go"] --> REPO_O["internal/repository/ota.go"] REPO_B --> DB["sql/model.sql(表结构)"] REPO_M --> DB +REPO_D --> DB_UD["sql/user_device.sql"] +REPO_D --> DB_UA["sql/user_active.sql"] +REPO_O --> DB_OTA["sql/ota.sql"] +REPO_O --> DB_BL["sql/black_list.sql"] +REPO_O --> DB_OTD["sql/ota_target_device.sql"] +TASK_DP["internal/task/device_persist.go"] --> REPO_D ``` -图表来源 +**图表来源** - [cmd/server/main.go:1-96](file://cmd/server/main.go#L1-L96) - [internal/config/config.go:1-64](file://internal/config/config.go#L1-L64) - [internal/database/mysql.go:1-47](file://internal/database/mysql.go#L1-L47) @@ -296,9 +519,19 @@ REPO_M --> DB - [internal/search/meilisearch.go:1-46](file://internal/search/meilisearch.go#L1-L46) - [internal/handler/brand.go:1-50](file://internal/handler/brand.go#L1-L50) - [internal/handler/model.go:1-51](file://internal/handler/model.go#L1-L51) +- [internal/handler/device.go:1-83](file://internal/handler/device.go#L1-L83) +- [internal/handler/ota.go:1-133](file://internal/handler/ota.go#L1-L133) - [internal/repository/brand.go:1-51](file://internal/repository/brand.go#L1-L51) - [internal/repository/model.go:1-95](file://internal/repository/model.go#L1-L95) +- [internal/repository/device.go:1-88](file://internal/repository/device.go#L1-L88) +- [internal/repository/ota.go:1-159](file://internal/repository/ota.go#L1-L159) - [sql/model.sql:20-38](file://sql/model.sql#L20-L38) +- [sql/user_device.sql:20-35](file://sql/user_device.sql#L20-L35) +- [sql/user_active.sql:20-208](file://sql/user_active.sql#L20-L208) +- [sql/ota.sql:20-47](file://sql/ota.sql#L20-L47) +- [sql/black_list.sql:20-33](file://sql/black_list.sql#L20-L33) +- [sql/ota_target_device.sql:20-34](file://sql/ota_target_device.sql#L20-L34) +- [internal/task/device_persist.go:1-167](file://internal/task/device_persist.go#L1-L167) ## 性能考虑 - 连接池与生命周期 @@ -307,20 +540,31 @@ REPO_M --> DB - 查询优化 - 品牌列表:支持模糊匹配,建议在高频搜索场景引入前缀索引或搜索引擎替代 - 型号列表:按品牌名精确匹配或按型号名模糊匹配;建议对常用过滤字段建立合适索引 + - 设备查询:user_device 表的 mac_addr 唯一索引支持快速查找 + - OTA 查询:按 model、hw、beta、status 组合查询,建议建立复合索引 - 缓存策略 - 对品牌列表与热门型号列表进行短期缓存,设置合理过期时间 + - 设备信息使用 Redis 缓存,避免频繁数据库写入 - 使用缓存穿透防护(空结果也缓存短时间)与缓存雪崩防护(随机过期时间) - 搜索优化 - 使用搜索引擎进行全文检索与高亮,减少数据库 LIKE 查询压力 - 控制返回字段数量,避免传输冗余数据 - I/O 与序列化 - 响应支持 Base64 编码,适合二进制传输场景,但会增加 CPU 开销 +- 分区表优化 + - user_active 表按日期分区,提高大数据量下的查询性能 + - 分区裁剪可以显著减少扫描数据量 -章节来源 +**更新** 新增了设备持久化和 OTA 升级场景的性能优化建议,包括 Redis 缓存策略和分区表优化。 + +**章节来源** - [internal/database/mysql.go:33-36](file://internal/database/mysql.go#L33-L36) - [internal/repository/brand.go:24-27](file://internal/repository/brand.go#L24-L27) - [internal/repository/model.go:31-40](file://internal/repository/model.go#L31-L40) +- [internal/repository/device.go:19-87](file://internal/repository/device.go#L19-L87) +- [internal/repository/ota.go:19-158](file://internal/repository/ota.go#L19-L158) - [internal/search/meilisearch.go:22-26](file://internal/search/meilisearch.go#L22-L26) +- [sql/user_active.sql:33-204](file://sql/user_active.sql#L33-L204) ## 故障排查指南 - 数据库连接失败 @@ -331,73 +575,133 @@ REPO_M --> DB - 建议开启数据库慢查询日志与应用日志聚合 - 搜索与缓存 - 搜索引擎与缓存客户端初始化后会记录连接信息;若无响应,检查主机、密钥与网络连通性 + - Redis 缓存异常会影响设备持久化功能 - 响应编码 - Base64 返回失败时,检查编码流程与日志输出 +- 设备持久化问题 + - 检查 Redis 连接状态和设备缓存数据 + - 定时任务执行失败时,查看任务日志和数据库连接状态 +- OTA 升级问题 + - 检查 OTA 表数据完整性和索引状态 + - 验证黑名单和定向设备表的数据准确性 -章节来源 +**更新** 新增了设备持久化和 OTA 升级相关的故障排查指南。 + +**章节来源** - [internal/config/database.go:57-71](file://internal/config/database.go#L57-L71) - [internal/database/mysql.go:40-43](file://internal/database/mysql.go#L40-L43) - [internal/repository/brand.go:32-47](file://internal/repository/brand.go#L32-L47) - [internal/repository/model.go:43-58](file://internal/repository/model.go#L43-L58) - [internal/handler/brand.go:31-43](file://internal/handler/brand.go#L31-L43) - [internal/handler/model.go:33-43](file://internal/handler/model.go#L33-L43) +- [internal/handler/device.go:45-82](file://internal/handler/device.go#L45-L82) +- [internal/handler/ota.go:56-132](file://internal/handler/ota.go#L56-L132) - [internal/search/meilisearch.go:17-20](file://internal/search/meilisearch.go#L17-L20) - [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16) ## 结论 -本设计以简洁的表结构与清晰的分层架构支撑品牌与型号的查询需求。通过搜索引擎与缓存提升检索性能,配合连接池与错误处理机制保障稳定性。后续可在索引策略、缓存策略与数据迁移方面进一步细化,以满足生产环境的高可用与高性能要求。 +本设计以简洁的表结构与清晰的分层架构支撑品牌与型号的查询需求。通过搜索引擎与缓存提升检索性能,配合连接池与错误处理机制保障稳定性。**更新** 新增的设备持久化和 OTA 固件升级子系统进一步完善了系统的业务能力,通过 Redis 缓存和分区表优化提升了大规模数据处理的性能。后续可在索引策略、缓存策略与数据迁移方面进一步细化,以满足生产环境的高可用与高性能要求。 ## 附录 ### 数据验证与业务规则 - 品牌与型号名称必填,型号表对品牌+型号建立唯一索引,防止重复 +- 设备 MAC 地址唯一,支持设备去重和版本跟踪 +- OTA 升级记录包含版本号、MD5 校验、时间范围等完整性约束 +- 黑名单和定向设备表确保 OTA 发布的安全性 - 时间字段 create_at 默认当前时间,便于审计与排序 - 处理器层对空结果返回空数组,避免无效数据传播 -章节来源 +**更新** 新增了设备和 OTA 相关的数据验证规则。 + +**章节来源** - [sql/model.sql:24-35](file://sql/model.sql#L24-L35) +- [sql/user_device.sql:24-32](file://sql/user_device.sql#L24-L32) +- [sql/ota.sql:24-44](file://sql/ota.sql#L24-L44) +- [sql/black_list.sql:24-30](file://sql/black_list.sql#L24-L30) +- [sql/ota_target_device.sql:24-31](file://sql/ota_target_device.sql#L24-L31) - [internal/repository/brand.go:24-27](file://internal/repository/brand.go#L24-L27) - [internal/repository/model.go:31-40](file://internal/repository/model.go#L31-L40) ### 示例数据 - 品牌示例:id=1, name="Sony" - 型号示例:id=1001, brand_name="Sony", name="WH-1000XM4", form="头戴式", rig="主动降噪", source="官方", eq_key="sony_xm4", create_at="2026-01-01 12:00:00" +- 设备示例:id=1214, mac_addr="AA:BB:CC:DD:EE:FF", model="WH-1000XM4", add_time="2026-05-28 17:08:30", ver="1.2.3" +- OTA 示例:id=48, verCode=100, verName="v1.2.3", url="http://example.com/firmware.bin", md5="d41d8cd98f00b204e9800998ecf8427e", force=1, desc="重大安全更新", model="WH-1000XM4", hw=1, target=1, beta=0, status=1 -章节来源 +**更新** 新增了设备和 OTA 的示例数据。 + +**章节来源** - [internal/model/brand.go:4-5](file://internal/model/brand.go#L4-L5) - [internal/model/model.go:6-13](file://internal/model/model.go#L6-L13) +- [internal/model/user_device.go:5-11](file://internal/model/user_device.go#L5-L11) +- [internal/model/ota.go:6-25](file://internal/model/ota.go#L6-L25) ### 数据生命周期、保留策略与归档规则 - 建议:基于 create_at 建立分区或定期归档任务,清理长期未使用的型号数据 +- 设备数据:保留最近 30 天的设备活跃记录,历史数据可压缩存储 +- OTA 数据:保留最近 6 个月的升级记录,历史版本可归档 - 归档策略:保留近一年的活跃型号,历史数据移至冷存储 - 审计:保留变更日志与备份周期,确保可追溯性 -[本节为通用实践建议,不直接对应特定源文件] +**更新** 新增了设备和 OTA 数据的生命周期管理建议。 + +**章节来源** +- [sql/user_active.sql:33-204](file://sql/user_active.sql#L33-L204) +- [sql/ota.sql:24-44](file://sql/ota.sql#L24-L44) ### 数据迁移路径与版本管理 - 版本化:每次结构变更生成迁移脚本,记录变更人、时间与目的 - 回滚:保留逆向迁移脚本;灰度发布逐步切换 - 兼容:新增字段采用可空策略,旧数据默认值填充 +- 设备数据迁移:支持从临时表导入到正式表,处理重复数据 +- OTA 数据迁移:支持版本号递增和兼容性检查 -[本节为通用实践建议,不直接对应特定源文件] +**更新** 新增了设备和 OTA 数据的迁移策略。 + +**章节来源** +- [sql/user_device.sql:20-35](file://sql/user_device.sql#L20-L35) +- [sql/user_active.sql:20-208](file://sql/user_active.sql#L20-L208) +- [sql/ota.sql:20-47](file://sql/ota.sql#L20-L47) ### 数据安全、隐私要求与访问控制 - 网络安全:数据库与搜索引擎通过内网或 VPC 访问,限制入站 IP - 凭证管理:敏感信息通过环境变量注入,禁止硬编码 - 访问控制:最小权限原则;数据库账号仅授予必要权限;搜索引擎 API Key 严格管理 +- 设备隐私:MAC 地址等个人标识信息需遵循隐私保护法规 +- OTA 安全:固件 MD5 校验确保下载完整性,黑名单机制防止恶意设备升级 -章节来源 +**更新** 新增了设备和 OTA 场景下的安全要求。 + +**章节来源** - [internal/config/database.go:67-69](file://internal/config/database.go#L67-L69) - [internal/config/meilisearch.go:39-50](file://internal/config/meilisearch.go#L39-L50) - [internal/config/redis.go:51-56](file://internal/config/redis.go#L51-L56) +- [internal/handler/device.go:33-48](file://internal/handler/device.go#L33-L48) +- [internal/handler/ota.go:32-48](file://internal/handler/ota.go#L32-L48) ### 品牌与型号实体设计理念 - 品牌(Brand):最小可用模型,仅包含标识与名称,便于快速检索与展示 - 型号(Model):承载产品特性字段(form、rig、source、eq_key),并与品牌建立弱关联,利于扩展与维护 - 业务逻辑:通过仓库层的过滤条件实现灵活查询;处理器层统一响应格式,支持 Base64 编码 -章节来源 +**章节来源** - [internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6) - [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14) - [internal/repository/brand.go:20-50](file://internal/repository/brand.go#L20-L50) -- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61) \ No newline at end of file +- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61) + +### 设备持久化与 OTA 升级设计理念 +- 设备持久化:通过 Redis 缓存实现高并发设备上报,定时任务批量持久化降低数据库压力 +- OTA 升级:支持灰度发布、强制升级、定向升级等多种发布策略,确保升级过程可控 +- 数据一致性:通过唯一索引和事务保证数据完整性,通过分区表优化查询性能 +- 可扩展性:模块化设计支持功能扩展,预留接口便于新业务场景接入 + +**新增** 设备持久化和 OTA 升级子系统的设计理念和业务逻辑。 + +**章节来源** +- [internal/model/user_device.go:5-11](file://internal/model/user_device.go#L5-L11) +- [internal/model/user_active.go:5-12](file://internal/model/user_active.go#L5-L12) +- [internal/model/ota.go:6-42](file://internal/model/ota.go#L6-L42) +- [internal/task/device_persist.go:24-167](file://internal/task/device_persist.go#L24-L167) +- [internal/handler/ota.go:23-132](file://internal/handler/ota.go#L23-L132) \ No newline at end of file diff --git a/.qoder/repowiki/zh/content/核心模块/业务处理器.md b/.qoder/repowiki/zh/content/核心模块/业务处理器.md index e7b8956..c73b45a 100644 --- a/.qoder/repowiki/zh/content/核心模块/业务处理器.md +++ b/.qoder/repowiki/zh/content/核心模块/业务处理器.md @@ -7,8 +7,10 @@ - [internal/handler/model_list.go](file://internal/handler/model_list.go) - [internal/handler/device.go](file://internal/handler/device.go) - [internal/handler/health.go](file://internal/handler/health.go) +- [internal/handler/ota.go](file://internal/handler/ota.go) - [internal/repository/brand.go](file://internal/repository/brand.go) - [internal/repository/model.go](file://internal/repository/model.go) +- [internal/repository/ota.go](file://internal/repository/ota.go) - [internal/response/response.go](file://internal/response/response.go) - [pkg/encode/base64.go](file://pkg/encode/base64.go) - [internal/search/meilisearch.go](file://internal/search/meilisearch.go) @@ -20,16 +22,21 @@ - [internal/middleware/request_id.go](file://internal/middleware/request_id.go) - [internal/model/brand.go](file://internal/model/brand.go) - [internal/model/model.go](file://internal/model/model.go) +- [internal/model/ota.go](file://internal/model/ota.go) - [internal/cache/brand_cache.go](file://internal/cache/brand_cache.go) - [internal/cache/model_cache.go](file://internal/cache/model_cache.go) +- [sql/ota.sql](file://sql/ota.sql) +- [sql/black_list.sql](file://sql/black_list.sql) +- [sql/ota_target_device.sql](file://sql/ota_target_device.sql) ## 更新摘要 **变更内容** -- 更新依赖注入模式:所有处理器现在通过构造函数接收依赖项实例 -- 新增仓储层依赖:BrandHandler 和 ModelHandler 现在依赖仓储实例而非直接数据库连接 -- 更新路由装配:路由在启动时集中装配依赖并传递给处理器 -- 简化处理器实现:移除了对全局数据库连接的直接依赖 +- 新增OTA固件升级处理功能:引入OTAHandler组件,支持固件升级请求处理、黑名单过滤、目标设备分布和版本选择等OTA固件升级能力 +- 新增OTA仓储层:OTARepository提供完整的OTA数据访问能力,包括最新版本查询、黑名单检查、定向设备匹配等功能 +- 新增OTA数据模型:包含OTA、BlackList、OTATargetDevice三种数据结构,支持完整的OTA升级流程 +- 新增数据库表结构:ota、black_list、ota_target_device三张表,支撑OTA功能的数据存储需求 +- 更新路由集成:OTA功能已集成到/audio路由组中,提供/api/v1/audio/ota端点 ## 目录 1. [简介](#简介) @@ -45,10 +52,10 @@ 11. [附录](#附录) ## 简介 -本文件面向 Luxsin 应用 API 的业务处理器模块,系统性梳理各处理器的职责、接口设计与实现细节,覆盖 BrandHandler、ModelHandler、ModelListHandler、DeviceHandler 与 HealthHandler。文档重点阐述新的依赖注入模式、错误处理机制、响应格式化策略,以及与 Gin 框架的集成方式;并通过流程图与类图展示处理器间的协作关系与数据流转过程,帮助初学者快速上手,同时为高级开发者提供深入的技术参考。 +本文件面向 Luxsin 应用 API 的业务处理器模块,系统性梳理各处理器的职责、接口设计与实现细节,覆盖 BrandHandler、ModelHandler、ModelListHandler、DeviceHandler、HealthHandler 和新增的 OTAHandler。文档重点阐述新的依赖注入模式、错误处理机制、响应格式化策略,以及与 Gin 框架的集成方式;并通过流程图与类图展示处理器间的协作关系与数据流转过程,帮助初学者快速上手,同时为高级开发者提供深入的技术参考。 ## 项目结构 -业务处理器位于 internal/handler 目录,采用依赖注入模式,围绕"控制器-仓储-搜索-缓存-响应"的分层组织,配合中间件与路由装配,形成清晰的控制流与依赖注入入口。 +业务处理器位于 internal/handler 目录,采用依赖注入模式,围绕"控制器-仓储-搜索-缓存-响应"的分层组织,配合中间件与路由装配,形成清晰的控制流与依赖注入入口。新增的OTA功能通过独立的处理器、仓储层和数据模型实现完整的固件升级能力。 ```mermaid graph TB @@ -67,12 +74,19 @@ BRAND["internal/handler/brand.go
NewBrandHandler(brandRepo, log)"] MODEL["internal/handler/model.go
NewModelHandler(modelRepo, log)"] MODELLIST["internal/handler/model_list.go
NewModelListHandler(searchClient, log)"] DEVICE["internal/handler/device.go
NewDeviceHandler(redis, log)"] +OTA["internal/handler/ota.go
NewOTAHandler(otaRepo, log)"] +end +subgraph "仓储层" +BRANDREPO["internal/repository/brand.go
BrandRepository"] +MODELREPO["internal/repository/model.go
ModelRepository"] +OTAREPO["internal/repository/ota.go
OTARepository"] end subgraph "基础设施" RESP["internal/response/response.go
统一响应体"] ENCODE["pkg/encode/base64.go
自定义Base64编码"] SEARCH["internal/search/meilisearch.go
Meilisearch客户端"] CACHE["internal/cache/*
Redis缓存"] +DB["MySQL 数据库
ota, black_list, ota_target_device 表"] end MAIN --> ROUTER ROUTER --> CORS @@ -83,10 +97,18 @@ ROUTER --> BRAND ROUTER --> MODEL ROUTER --> MODELLIST ROUTER --> DEVICE +ROUTER --> OTA +BRAND --> BRANDREPO +MODEL --> MODELREPO +OTA --> OTAREPO +BRANDREPO --> DB +MODELREPO --> DB +OTAREPO --> DB BRAND --> RESP MODEL --> RESP MODELLIST --> RESP DEVICE --> RESP +OTA --> RESP MODELLIST --> SEARCH BRAND --> CACHE MODEL --> CACHE @@ -96,17 +118,18 @@ MODELLIST --> ENCODE ``` **图表来源** -- [cmd/server/main.go:25-101](file://cmd/server/main.go#L25-L101) -- [internal/router/router.go:16-52](file://internal/router/router.go#L16-L52) +- [cmd/server/main.go:27-108](file://cmd/server/main.go#L27-L108) +- [internal/router/router.go:16-56](file://internal/router/router.go#L16-L56) - [internal/handler/health.go:10](file://internal/handler/health.go#L10) - [internal/handler/brand.go:18](file://internal/handler/brand.go#L18) - [internal/handler/model.go:18](file://internal/handler/model.go#L18) - [internal/handler/model_list.go:19](file://internal/handler/model_list.go#L19) - [internal/handler/device.go:19](file://internal/handler/device.go#L19) +- [internal/handler/ota.go:19](file://internal/handler/ota.go#L19) **章节来源** -- [internal/router/router.go:16-52](file://internal/router/router.go#L16-L52) -- [cmd/server/main.go:25-101](file://cmd/server/main.go#L25-L101) +- [internal/router/router.go:16-56](file://internal/router/router.go#L16-L56) +- [cmd/server/main.go:27-108](file://cmd/server/main.go#L27-L108) ## 核心组件 - **健康检查处理器**:提供轻量级健康状态返回,便于外部探活与编排。 @@ -114,6 +137,7 @@ MODELLIST --> ENCODE - **型号查询处理器**:按品牌或型号关键字查询型号列表,现在依赖 ModelRepository 实例。 - **型号检索处理器**:基于 Meilisearch 执行全文检索,依赖搜索客户端实例。 - **设备上报处理器**:接收设备信息(MAC、型号、版本、来源 IP),依赖 Redis 客户端。 +- **OTA固件升级处理器**:处理固件升级请求,支持黑名单过滤、目标设备分布和版本选择等OTA固件升级能力。 **章节来源** - [internal/handler/health.go:8-19](file://internal/handler/health.go#L8-L19) @@ -121,9 +145,10 @@ MODELLIST --> ENCODE - [internal/handler/model.go:13-23](file://internal/handler/model.go#L13-L23) - [internal/handler/model_list.go:14-24](file://internal/handler/model_list.go#L14-L24) - [internal/handler/device.go:14-24](file://internal/handler/device.go#L14-L24) +- [internal/handler/ota.go:14-21](file://internal/handler/ota.go#L14-L21) ## 架构总览 -下图展示从请求进入至响应返回的关键路径,以及处理器与仓储、搜索、缓存、日志等组件的交互,体现了完整的依赖注入架构。 +下图展示从请求进入至响应返回的关键路径,以及处理器与仓储、搜索、缓存、日志等组件的交互,体现了完整的依赖注入架构。新增的OTA功能通过独立的处理流程支持复杂的固件升级场景。 ```mermaid sequenceDiagram @@ -131,8 +156,7 @@ participant C as "客户端" participant R as "Gin 路由" participant H as "业务处理器" participant REPO as "仓储层" -participant S as "Meilisearch" -participant RC as "Redis" +participant DB as "MySQL数据库" participant L as "Zap 日志" C->>R : "HTTP 请求" R->>H : "匹配到处理器并调用" @@ -140,24 +164,37 @@ alt "品牌/型号查询" H->>REPO : "List(ctx, filters)" REPO-->>H : "结果集" else "型号检索" -H->>S : "ModelList(ctx, key, count)" -S-->>H : "命中结果" +H->>DB : "Meilisearch查询" +DB-->>H : "命中结果" else "设备上报" -H->>RC : "HSet(ctx, key, mac, json)" -RC-->>H : "OK 或错误" +H->>DB : "Redis HSet(ctx, key, mac, json)" +DB-->>H : "OK 或错误" +else "OTA固件升级" +H->>REPO : "GetLatestOTA(ctx, model, hw, beta)" +REPO->>DB : "查询最新OTA记录" +DB-->>REPO : "OTA记录" +REPO-->>H : "OTA记录" +H->>REPO : "IsInBlackList(ctx, otaID, mac)" +REPO->>DB : "检查黑名单" +DB-->>REPO : "命中/未命中" +H->>REPO : "FindTargetDevice(ctx, otaID, mac)" +REPO->>DB : "检查定向设备" +DB-->>REPO : "匹配/不匹配" end H->>L : "记录日志/错误" -H-->>C : "JSON 或自定义Base64响应" +H-->>C : "JSON 响应" ``` **图表来源** -- [internal/router/router.go:32-36](file://internal/router/router.go#L32-L36) +- [internal/router/router.go:45-52](file://internal/router/router.go#L45-L52) - [internal/handler/brand.go:29](file://internal/handler/brand.go#L29) - [internal/handler/model.go:30](file://internal/handler/model.go#L30) - [internal/handler/model_list.go:37](file://internal/handler/model_list.go#L37) - [internal/handler/device.go:71](file://internal/handler/device.go#L71) +- [internal/handler/ota.go:57-131](file://internal/handler/ota.go#L57-L131) - [internal/repository/brand.go:23-52](file://internal/repository/brand.go#L23-L52) - [internal/repository/model.go:23-79](file://internal/repository/model.go#L23-L79) +- [internal/repository/ota.go:20-158](file://internal/repository/ota.go#L20-L158) - [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45) ## 详细组件分析 @@ -173,7 +210,7 @@ H-->>C : "JSON 或自定义Base64响应" **章节来源** - [internal/handler/health.go:8-19](file://internal/handler/health.go#L8-L19) - [internal/response/response.go:15-21](file://internal/response/response.go#L15-L21) -- [internal/router/router.go:40](file://internal/router/router.go#L40) +- [internal/router/router.go:42](file://internal/router/router.go#L42) ### 品牌处理器(BrandHandler) - **职责**:根据品牌名称模糊查询品牌列表。 @@ -365,6 +402,62 @@ RespOK --> End **章节来源** - [internal/handler/device.go:14-85](file://internal/handler/device.go#L14-L85) +### OTA固件升级处理器(OTAHandler) +- **职责**:处理固件升级请求,支持黑名单过滤、目标设备分布和版本选择等OTA固件升级能力。 +- **输入参数**: + - 查询字符串:model(必填) + - 查询字符串:hw(必填) + - 查询字符串:mac(可选) + - 查询字符串:beta(可选,默认0) +- **处理流程**: + 1. 参数校验:验证model和hw参数,解析beta参数 + 2. 查询最新OTA记录:按model+hw+beta+status=1查询最新一条OTA记录 + 3. 黑名单检查:检查mac是否在指定ota_id的黑名单中 + 4. 定向升级检查:如果是定向升级,检查mac是否在定向设备列表中 + 5. 版本选择:根据检查结果返回合适的OTA版本 +- **错误处理**: + - 参数校验失败返回统一错误 + - 数据库查询失败记录错误并返回统一内部错误 + - 黑名单或定向设备检查失败返回统一内部错误 +- **数据模型**:OTA、BlackList、OTATargetDevice +- **依赖注入**:通过 NewOTAHandler 构造函数注入 OTARepository 和 zap.Logger + +```mermaid +flowchart TD +Start(["进入 GetOTA"]) --> ParseParams["解析参数 model/hw/mac/beta"] +ParseParams --> Validate{"参数校验通过?"} +Validate -- 否 --> RespBadReq["返回BadRequest错误"] +Validate -- 是 --> QueryLatest["查询最新OTA记录"] +QueryLatest --> QueryOK{"查询成功?"} +QueryOK -- 否 --> RespInternal["返回InternalError"] +QueryOK -- 是 --> CheckBlackList["检查黑名单"] +CheckBlackList --> InBlackList{"命中黑名单?"} +InBlackList -- 是 --> QueryNotInBlack["查询不在黑名单中的最新OTA"] +QueryNotInBlack --> BlackListOK{"查询成功?"} +BlackListOK -- 否 --> RespInternal +BlackListOK -- 是 --> ReturnOTA["返回OTA记录"] +InBlackList -- 否 --> CheckTarget{"是否定向升级?"} +CheckTarget -- 否 --> ReturnOTA +CheckTarget -- 是 --> CheckTargetDevice["检查定向设备"] +CheckTargetDevice --> TargetHit{"定向命中?"} +TargetHit -- 是 --> ReturnOTA +TargetHit -- 否 --> QueryNotTarget["查询非定向最新OTA"] +QueryNotTarget --> NotTargetOK{"查询成功?"} +NotTargetOK -- 否 --> RespInternal +NotTargetOK -- 是 --> ReturnOTA +ReturnOTA --> End(["结束"]) +RespBadReq --> End +RespInternal --> End +``` + +**图表来源** +- [internal/handler/ota.go:25-132](file://internal/handler/ota.go#L25-L132) + +**章节来源** +- [internal/handler/ota.go:14-132](file://internal/handler/ota.go#L14-L132) +- [internal/repository/ota.go:20-158](file://internal/repository/ota.go#L20-L158) +- [internal/model/ota.go:6-42](file://internal/model/ota.go#L6-L42) + ## 依赖注入模式详解 ### 依赖注入架构 @@ -381,16 +474,18 @@ ROUTER --> BRANCACHE["cache.BrandCache
品牌缓存"] ROUTER --> MODELCACHE["cache.ModelCache
型号缓存"] ROUTER --> BRANDREPO["repository.NewBrandRepository()
品牌仓储"] ROUTER --> MODELREPO["repository.NewModelRepository()
型号仓储"] +ROUTER --> OTAREPO["repository.NewOTARepository()
OTA仓储"] ROUTER --> HEALTH["handler.NewHealthHandler()
健康检查处理器"] ROUTER --> BRAND["handler.NewBrandHandler()
品牌处理器"] ROUTER --> MODEL["handler.NewModelHandler()
型号处理器"] ROUTER --> MODELLIST["handler.NewModelListHandler()
型号检索处理器"] ROUTER --> DEVICE["handler.NewDeviceHandler()
设备上报处理器"] +ROUTER --> OTA["handler.NewOTAHandler()
OTA固件升级处理器"] ``` **图表来源** -- [cmd/server/main.go:53-69](file://cmd/server/main.go#L53-L69) -- [internal/router/router.go:16-36](file://internal/router/router.go#L16-L36) +- [cmd/server/main.go:77](file://cmd/server/main.go#L77) +- [internal/router/router.go:16-56](file://internal/router/router.go#L16-L56) ### 依赖注入优势 - **测试友好**:可以轻松注入模拟对象进行单元测试 @@ -399,7 +494,7 @@ ROUTER --> DEVICE["handler.NewDeviceHandler()
设备上报处理器"] - **生命周期管理**:依赖项的创建和销毁由路由集中管理 ### 仓储层依赖 -BrandRepository 和 ModelRepository 现在接收 Redis 缓存实例作为依赖: +BrandRepository、ModelRepository 和 OTARepository 现在接收相应的依赖: ```mermaid classDiagram @@ -419,6 +514,15 @@ class ModelRepository { + ListByBrandFromDB(ctx, brandName) : "[]Model,error" + ListByModelFromDB(ctx, modelName) : "[]Model,error" } +class OTARepository { +- db : "sql.DB" ++ NewOTARepository(db) : "OTARepository" ++ GetLatestOTA(ctx, modelVal, hw, beta) : "OTA,error" ++ GetLatestOTANotInBlackList(ctx, modelVal, hw, beta, mac) : "OTA,error" ++ GetLatestOTANotTarget(ctx, modelVal, hw, beta) : "OTA,error" ++ IsInBlackList(ctx, otaID, mac) : "bool,error" ++ FindTargetDevice(ctx, otaID, mac) : "OTATargetDevice,error" +} class BrandCache { - rdb : "redis.Client" + NewBrandCache(rdb) : "BrandCache" @@ -435,17 +539,19 @@ class ModelCache { } BrandRepository --> BrandCache : "依赖注入" ModelRepository --> ModelCache : "依赖注入" +OTARepository --> DB : "依赖注入" ``` **图表来源** - [internal/repository/brand.go:14-21](file://internal/repository/brand.go#L14-L21) - [internal/repository/model.go:14-21](file://internal/repository/model.go#L14-L21) +- [internal/repository/ota.go:11-17](file://internal/repository/ota.go#L11-L17) - [internal/cache/brand_cache.go:18-24](file://internal/cache/brand_cache.go#L18-L24) - [internal/cache/model_cache.go:19-25](file://internal/cache/model_cache.go#L19-L25) **章节来源** -- [internal/router/router.go:16-36](file://internal/router/router.go#L16-L36) -- [cmd/server/main.go:53-69](file://cmd/server/main.go#L53-L69) +- [internal/router/router.go:16-56](file://internal/router/router.go#L16-L56) +- [cmd/server/main.go:77](file://cmd/server/main.go#L77) ## 依赖分析 - **依赖注入模式**: @@ -454,6 +560,7 @@ ModelRepository --> ModelCache : "依赖注入" - **组件耦合**: - 处理器与仓储之间为单向依赖,职责清晰。 - 搜索与缓存作为外部服务,通过客户端封装接入。 + - OTA处理器与数据库直接交互,提供完整的OTA数据访问能力。 - **可能的循环依赖**: - 当前结构未见循环导入,符合 Go 包管理最佳实践。 @@ -465,37 +572,42 @@ ROUTER --> BRAND["brand.go"] ROUTER --> MODEL["model.go"] ROUTER --> MODELLIST["model_list.go"] ROUTER --> DEVICE["device.go"] +ROUTER --> OTA["ota.go"] BRAND --> BREPO["repository/brand.go"] MODEL --> MREPO["repository/model.go"] -MODELLIST --> SEARCH["search/meilisearch.go"] -DEVICE --> REDIS["Redis 客户端"] +OTA --> OTAREPO["repository/ota.go"] BRAND --> BREPO BREPO --> BCACHE["cache/brand_cache.go"] MODEL --> MREPO MREPO --> MCACHE["cache/model_cache.go"] +OTA --> OTAREPO +OTAREPO --> DB["MySQL数据库"] BRAND --> ENCODE["pkg/encode/base64.go"] MODEL --> ENCODE MODELLIST --> ENCODE +OTA --> ENCODE ALL["各处理器"] --> RESP["internal/response/response.go"] ALL --> LOG["zap.Logger"] ``` **图表来源** -- [cmd/server/main.go:67-70](file://cmd/server/main.go#L67-L70) -- [internal/router/router.go:27-36](file://internal/router/router.go#L27-L36) +- [cmd/server/main.go:77](file://cmd/server/main.go#L77) +- [internal/router/router.go:16-56](file://internal/router/router.go#L16-L56) - [internal/handler/brand.go:18](file://internal/handler/brand.go#L18) - [internal/handler/model.go:18](file://internal/handler/model.go#L18) - [internal/handler/model_list.go:19](file://internal/handler/model_list.go#L19) - [internal/handler/device.go:19](file://internal/handler/device.go#L19) +- [internal/handler/ota.go:19](file://internal/handler/ota.go#L19) - [internal/repository/brand.go:19](file://internal/repository/brand.go#L19) - [internal/repository/model.go:19](file://internal/repository/model.go#L19) +- [internal/repository/ota.go:15](file://internal/repository/ota.go#L15) - [internal/search/meilisearch.go:17](file://internal/search/meilisearch.go#L17) - [pkg/encode/base64.go:8](file://pkg/encode/base64.go#L8) - [internal/response/response.go:9](file://internal/response/response.go#L9) **章节来源** -- [internal/router/router.go:16-52](file://internal/router/router.go#L16-L52) -- [cmd/server/main.go:25-101](file://cmd/server/main.go#L25-L101) +- [internal/router/router.go:16-56](file://internal/router/router.go#L16-L56) +- [cmd/server/main.go:27-108](file://cmd/server/main.go#L27-L108) ## 性能考虑 - **响应体积优化** @@ -503,11 +615,15 @@ ALL --> LOG["zap.Logger"] - 检索处理器对 count 进行上限控制,避免超大数据量返回。 - **数据库查询** - 品牌与型号查询均使用 ORDER BY 与 LIKE,建议在数据库侧建立合适索引以提升模糊查询性能。 + - OTA查询涉及多表关联,建议在ota表的model、hw、beta、status字段建立复合索引。 - 仓储层现在支持缓存降级,当缓存不可用时自动回退到数据库查询。 - **搜索与缓存** - Meilisearch 适合全文检索,建议合理设置属性检索范围与分页大小。 - Redis 写入为单键 HSet,具备良好吞吐能力;建议评估内存占用与持久化策略。 - 缓存层现在支持全量缓存和按品牌缓存两种策略,提升查询性能。 +- **OTA查询优化** + - OTA查询流程涉及多次数据库查询,建议在黑名单表和定向设备表建立适当的索引。 + - 可以考虑缓存常用的OTA查询结果,减少数据库压力。 - **中间件与日志** - 开启 Recovery、CORS、Logger、RequestID 中间件,有助于可观测性与稳定性;注意日志级别与输出频率对性能的影响。 - **并发安全** @@ -517,6 +633,7 @@ ALL --> LOG["zap.Logger"] - 在生产环境启用 Release 模式,降低框架开销。 - 对外部依赖(数据库、搜索、缓存)增加超时与重试策略,提升鲁棒性。 - 利用缓存预热机制,在应用启动时加载常用数据到缓存。 + - OTA查询流程复杂,建议添加适当的超时控制和错误重试机制。 ## 故障排查指南 - **健康检查失败** @@ -532,6 +649,11 @@ ALL --> LOG["zap.Logger"] - **设备上报异常** - 校验必填参数 mac 与 model 是否传入。 - 关注"marshal device info failed"与"redis hset failed"的错误日志。 +- **OTA固件升级异常** + - 校验必填参数 model、hw 是否传入且格式正确。 + - 关注"query ota failed"、"check black list failed"、"check target device failed"等错误日志。 + - 检查数据库连接,确认ota、black_list、ota_target_device表存在且结构正确。 + - 验证OTA状态、硬件版本号、灰度标识等字段是否符合预期。 - **依赖注入相关问题** - 确认所有处理器都通过构造函数正确注入了依赖项。 - 检查路由装配顺序,确保依赖项在处理器之前创建。 @@ -546,12 +668,13 @@ ALL --> LOG["zap.Logger"] - [internal/handler/model.go:31-35](file://internal/handler/model.go#L31-L35) - [internal/handler/model_list.go:38-42](file://internal/handler/model_list.go#L38-L42) - [internal/handler/device.go:61-78](file://internal/handler/device.go#L61-L78) +- [internal/handler/ota.go:58-94](file://internal/handler/ota.go#L58-L94) - [internal/response/response.go:15-36](file://internal/response/response.go#L15-L36) - [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45) - [internal/middleware/request_id.go:20-31](file://internal/middleware/request_id.go#L20-L31) ## 结论 -本处理器模块采用全新的依赖注入模式,通过构造函数注入依赖项,实现了更好的解耦和可测试性。通过统一响应体与自定义 Base64 编码实现灵活的输出策略,结合 Gin 中间件与外部服务(数据库、Meilisearch、Redis)形成稳定高效的业务处理链路。新的架构模式简化了处理器实现,提升了代码质量,建议在生产环境中进一步完善超时与重试、索引优化与缓存策略,持续提升性能与可靠性。 +本处理器模块采用全新的依赖注入模式,通过构造函数注入依赖项,实现了更好的解耦和可测试性。通过统一响应体与自定义 Base64 编码实现灵活的输出策略,结合 Gin 中间件与外部服务(数据库、Meilisearch、Redis)形成稳定高效的业务处理链路。新增的OTA固件升级功能提供了完整的固件升级能力,包括黑名单过滤、目标设备分布和版本选择等特性。新的架构模式简化了处理器实现,提升了代码质量,建议在生产环境中进一步完善超时与重试、索引优化与缓存策略,持续提升性能与可靠性。 ## 附录 - **路由与处理器映射** @@ -560,20 +683,36 @@ ALL --> LOG["zap.Logger"] - /audio/getModel -> ModelHandler.GetModel - /audio/modelList -> ModelListHandler.ModelList - /audio/reportDevInfo -> DeviceHandler.ReportDevInfo + - /audio/ota -> OTAHandler.GetOTA - **依赖注入示例** - 品牌处理器:BrandHandler.NewBrandHandler(brandRepo, log) - 型号处理器:ModelHandler.NewModelHandler(modelRepo, log) - 型号检索处理器:ModelListHandler.NewModelListHandler(searchClient, log) - 设备上报处理器:DeviceHandler.NewDeviceHandler(redis, log) + - OTA固件升级处理器:OTAHandler.NewOTAHandler(otaRepo, log) +- **OTA查询参数说明** + - model:设备型号(必填) + - hw:硬件版本号(必填) + - mac:设备MAC地址(可选) + - beta:灰度标识(可选,默认0) +- **OTA数据模型字段** + - OTA:id、verCode、verName、url、md5、force、desc、model、hw、target、beta、pawVerCode、pawVerName、pawUrl、pawMd5、startTime、endTime、status + - BlackList:id、ota_id、mac、create_at + - OTATargetDevice:id、ota_id、mac_addr、type、create_at +- **数据库表结构** + - ota表:存储OTA固件升级记录 + - black_list表:存储OTA黑名单 + - ota_target_device表:存储OTA定向设备 - **常用调用示例(路径引用)** - 品牌查询:[internal/handler/brand.go:25](file://internal/handler/brand.go#L25) - 型号查询:[internal/handler/model.go:25](file://internal/handler/model.go#L25) - 型号检索:[internal/handler/model_list.go:26](file://internal/handler/model_list.go#L26) - 设备上报:[internal/handler/device.go:26](file://internal/handler/device.go#L26) + - OTA固件升级:[internal/handler/ota.go:25](file://internal/handler/ota.go#L25) - 健康检查:[internal/handler/health.go:14](file://internal/handler/health.go#L14) - **配置与启动** - 配置加载与环境变量:[internal/config/config.go:18-64](file://internal/config/config.go#L18-L64) - - 服务器启动与优雅关闭:[cmd/server/main.go:25-101](file://cmd/server/main.go#L25-L101) + - 服务器启动与优雅关闭:[cmd/server/main.go:27-108](file://cmd/server/main.go#L27-L108) - **中间件** - CORS:[internal/middleware/cors.go:7-21](file://internal/middleware/cors.go#L7-L21) - Logger:[internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45) @@ -581,4 +720,9 @@ ALL --> LOG["zap.Logger"] - **缓存策略** - 品牌缓存:brand:all 键,30分钟TTL - 型号缓存:model:brand:{brand} 和 model:all 键,30分钟TTL - - 启动时预热缓存,提升首次查询性能 \ No newline at end of file + - 启动时预热缓存,提升首次查询性能 +- **OTA查询流程** + - 最新OTA查询:按model+hw+beta+status=1排序取第一条 + - 黑名单检查:检查mac是否在指定ota_id的黑名单中 + - 定向设备检查:检查mac是否在指定ota_id的定向设备列表中 + - 版本选择:根据检查结果返回合适的OTA版本 \ No newline at end of file diff --git a/.qoder/repowiki/zh/content/核心模块/数据模型.md b/.qoder/repowiki/zh/content/核心模块/数据模型.md index ff1c153..87f3fc2 100644 --- a/.qoder/repowiki/zh/content/核心模块/数据模型.md +++ b/.qoder/repowiki/zh/content/核心模块/数据模型.md @@ -4,19 +4,38 @@ **本文引用的文件** - [internal/model/brand.go](file://internal/model/brand.go) - [internal/model/model.go](file://internal/model/model.go) +- [internal/model/ota.go](file://internal/model/ota.go) +- [internal/model/user_device.go](file://internal/model/user_device.go) +- [internal/model/user_active.go](file://internal/model/user_active.go) - [internal/repository/brand.go](file://internal/repository/brand.go) - [internal/repository/model.go](file://internal/repository/model.go) +- [internal/repository/ota.go](file://internal/repository/ota.go) +- [internal/repository/device.go](file://internal/repository/device.go) - [internal/handler/brand.go](file://internal/handler/brand.go) - [internal/handler/model.go](file://internal/handler/model.go) - [internal/handler/model_list.go](file://internal/handler/model_list.go) +- [internal/handler/ota.go](file://internal/handler/ota.go) +- [internal/handler/device.go](file://internal/handler/device.go) - [internal/router/router.go](file://internal/router/router.go) - [internal/config/database.go](file://internal/config/database.go) - [internal/response/response.go](file://internal/response/response.go) +- [internal/task/device_persist.go](file://internal/task/device_persist.go) - [pkg/encode/base64.go](file://pkg/encode/base64.go) - [sql/model.sql](file://sql/model.sql) +- [sql/ota.sql](file://sql/ota.sql) +- [sql/user_device.sql](file://sql/user_device.sql) +- [sql/user_active.sql](file://sql/user_active.sql) +- [sql/ota_target_device.sql](file://sql/ota_target_device.sql) - [cmd/server/main.go](file://cmd/server/main.go) +## 更新摘要 +**变更内容** +- 新增OTA固件升级相关模型和功能模块 +- 新增用户设备跟踪模型和活动记录模型 +- 新增设备报告接口和异步持久化任务 +- 扩展路由配置以支持新的API端点 + ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) @@ -30,10 +49,10 @@ 10. [附录](#附录) ## 简介 -本文件面向 Luxsin 应用 API 的数据模型,系统性梳理 Brand 与 Model 两类数据模型的设计理念、字段定义、约束条件、业务含义以及与数据库表结构的映射关系。文档还覆盖 ORM 映射配置(基于原生 sql.DB 的扫描映射)、模型验证与序列化机制、模型在各层之间的传递方式与性能考量,并给出扩展、版本管理与向后兼容的最佳实践建议。内容兼顾初学者与高级开发者,既提供高层概览,也包含代码级的可视化图示与来源标注。 +本文件面向 Luxsin 应用 API 的数据模型,系统性梳理 Brand、Model、OTA、UserDevice 和 UserActive 五类数据模型的设计理念、字段定义、约束条件、业务含义以及与数据库表结构的映射关系。文档还覆盖 ORM 映射配置(基于原生 sql.DB 的扫描映射)、模型验证与序列化机制、模型在各层之间的传递方式与性能考量,并给出扩展、版本管理与向后兼容的最佳实践建议。内容兼顾初学者与高级开发者,既提供高层概览,也包含代码级的可视化图示与来源标注。 ## 项目结构 -该项目采用分层架构:路由层负责请求入口与中间件;处理器层处理业务逻辑与参数解析;仓库层封装数据库访问;模型层承载数据结构;响应层统一返回格式;编码层提供可选的响应体压缩编码;配置层加载数据库等外部服务配置。 +该项目采用分层架构:路由层负责请求入口与中间件;处理器层处理业务逻辑与参数解析;仓库层封装数据库访问;模型层承载数据结构;响应层统一返回格式;编码层提供可选的响应体压缩编码;配置层加载数据库等外部服务配置。新增的OTA固件升级、用户设备跟踪和设备活动记录功能进一步完善了系统的数据模型体系。 ```mermaid graph TB @@ -47,14 +66,21 @@ subgraph "处理器层" BRAND_H["internal/handler/brand.go"] MODEL_H["internal/handler/model.go"] MODEL_LIST_H["internal/handler/model_list.go"] +OTA_H["internal/handler/ota.go"] +DEVICE_H["internal/handler/device.go"] end subgraph "仓库层" BRAND_R["internal/repository/brand.go"] MODEL_R["internal/repository/model.go"] +OTA_R["internal/repository/ota.go"] +DEVICE_R["internal/repository/device.go"] end subgraph "模型层" MODEL_M["internal/model/brand.go"] MODEL_M2["internal/model/model.go"] +MODEL_M3["internal/model/ota.go"] +MODEL_M4["internal/model/user_device.go"] +MODEL_M5["internal/model/user_active.go"] end subgraph "响应与编码" RESP["internal/response/response.go"] @@ -62,73 +88,112 @@ ENCODE["pkg/encode/base64.go"] end subgraph "配置与数据库" DB_CFG["internal/config/database.go"] -DB_SQL["sql/model.sql"] +DB_SQL["sql/*.sql"] +end +subgraph "任务处理" +TASK["internal/task/device_persist.go"] end MAIN --> ROUTER ROUTER --> BRAND_H ROUTER --> MODEL_H ROUTER --> MODEL_LIST_H +ROUTER --> OTA_H +ROUTER --> DEVICE_H BRAND_H --> BRAND_R MODEL_H --> MODEL_R MODEL_LIST_H --> MODEL_R +OTA_H --> OTA_R +DEVICE_H --> DEVICE_R BRAND_R --> MODEL_M MODEL_R --> MODEL_M2 +OTA_R --> MODEL_M3 +DEVICE_R --> MODEL_M4 +DEVICE_R --> MODEL_M5 BRAND_H --> RESP MODEL_H --> RESP MODEL_LIST_H --> RESP -BRAND_H --> ENCODE -MODEL_H --> ENCODE -MODEL_LIST_H --> ENCODE +OTA_H --> RESP +DEVICE_H --> RESP +DEVICE_H --> ENCODE +TASK --> DEVICE_R DB_CFG --> DB_SQL ``` -图表来源 -- [cmd/server/main.go:1-96](file://cmd/server/main.go#L1-L96) -- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42) +**图表来源** +- [cmd/server/main.go:22-64](file://cmd/server/main.go#L22-L64) +- [internal/router/router.go:14-56](file://internal/router/router.go#L14-L56) - [internal/handler/brand.go:19-50](file://internal/handler/brand.go#L19-L50) - [internal/handler/model.go:19-51](file://internal/handler/model.go#L19-L51) - [internal/handler/model_list.go:19-57](file://internal/handler/model_list.go#L19-L57) +- [internal/handler/ota.go:14-133](file://internal/handler/ota.go#L14-L133) +- [internal/handler/device.go:15-83](file://internal/handler/device.go#L15-L83) - [internal/repository/brand.go:16-51](file://internal/repository/brand.go#L16-L51) - [internal/repository/model.go:16-95](file://internal/repository/model.go#L16-L95) +- [internal/repository/ota.go:11-159](file://internal/repository/ota.go#L11-L159) +- [internal/repository/device.go:11-88](file://internal/repository/device.go#L11-L88) - [internal/model/brand.go:3-7](file://internal/model/brand.go#L3-L7) - [internal/model/model.go:5-15](file://internal/model/model.go#L5-L15) +- [internal/model/ota.go:5-43](file://internal/model/ota.go#L5-L43) +- [internal/model/user_device.go:5-12](file://internal/model/user_device.go#L5-L12) +- [internal/model/user_active.go:5-13](file://internal/model/user_active.go#L5-L13) - [internal/response/response.go:9-37](file://internal/response/response.go#L9-L37) - [pkg/encode/base64.go:21-52](file://pkg/encode/base64.go#L21-L52) - [internal/config/database.go:17-72](file://internal/config/database.go#L17-L72) - [sql/model.sql:20-38](file://sql/model.sql#L20-L38) +- [sql/ota.sql:23-44](file://sql/ota.sql#L23-L44) +- [sql/user_device.sql:23-32](file://sql/user_device.sql#L23-L32) +- [sql/user_active.sql:23-32](file://sql/user_active.sql#L23-L32) +- [sql/ota_target_device.sql:23-31](file://sql/ota_target_device.sql#L23-L31) +- [internal/task/device_persist.go:14-167](file://internal/task/device_persist.go#L14-L167) -章节来源 +**章节来源** - [cmd/server/main.go:22-64](file://cmd/server/main.go#L22-L64) -- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42) +- [internal/router/router.go:14-56](file://internal/router/router.go#L14-L56) ## 核心组件 -- 模型层(Model) +- **传统模型层(Model)** - Brand:承载品牌标识与名称,用于品牌列表查询。 - Model:承载型号信息,包含品牌名、型号名、形态、设备类型、来源、等价键、创建时间等。 -- 仓库层(Repository) +- **OTA固件升级模型层** + - OTA:固件升级记录,包含版本信息、下载地址、MD5校验、强制升级标志、灰度发布状态、定向升级配置等。 + - BlackList:OTA黑名单,记录被禁止升级的设备MAC地址。 + - OTATargetDevice:OTA定向设备,记录允许特定设备升级的白名单或黑名单。 +- **用户设备跟踪模型层** + - UserDevice:用户设备信息,包含设备MAC地址、型号、添加时间、当前版本等。 + - UserActive:用户活动记录,包含设备活跃信息、IP地址、活跃日期等。 +- **仓库层(Repository)** - BrandRepository:提供按品牌名模糊查询的品牌列表。 - ModelRepository:提供按品牌名或型号名模糊查询的型号列表,并处理可空字段的扫描。 -- 处理器层(Handler) + - OTARepository:提供OTA升级信息查询、黑名单检查、定向设备查询等功能。 + - DeviceRepository:提供设备信息查询、插入、更新以及活动记录管理。 +- **处理器层(Handler)** - BrandHandler:接收查询参数,调用仓库层,支持可选的响应体 Base64 编码。 - ModelHandler:接收品牌与型号查询参数,调用仓库层,支持可选的响应体 Base64 编码。 - ModelListHandler:通过搜索客户端返回模型列表,支持可选的响应体 Base64 编码。 -- 响应与编码 - - 统一响应体结构,便于前端解析与错误处理。 - - 可选的自定义 Base64 编码,提升传输效率与隐私保护。 + - OTAHandler:获取OTA升级信息,支持黑名单检查、定向升级检查等功能。 + - DeviceHandler:处理设备信息上报,将设备活动信息写入Redis缓存。 +- **任务处理层** + - DevicePersistTask:定时从Redis缓存批量持久化设备信息到数据库。 -章节来源 +**章节来源** - [internal/model/brand.go:3-7](file://internal/model/brand.go#L3-L7) - [internal/model/model.go:5-15](file://internal/model/model.go#L5-L15) +- [internal/model/ota.go:5-43](file://internal/model/ota.go#L5-L43) +- [internal/model/user_device.go:5-12](file://internal/model/user_device.go#L5-L12) +- [internal/model/user_active.go:5-13](file://internal/model/user_active.go#L5-L13) - [internal/repository/brand.go:20-51](file://internal/repository/brand.go#L20-L51) - [internal/repository/model.go:20-95](file://internal/repository/model.go#L20-L95) +- [internal/repository/ota.go:19-159](file://internal/repository/ota.go#L19-L159) +- [internal/repository/device.go:19-88](file://internal/repository/device.go#L19-L88) - [internal/handler/brand.go:26-50](file://internal/handler/brand.go#L26-L50) - [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51) - [internal/handler/model_list.go:26-57](file://internal/handler/model_list.go#L26-L57) -- [internal/response/response.go:9-37](file://internal/response/response.go#L9-L37) -- [pkg/encode/base64.go:21-52](file://pkg/encode/base64.go#L21-L52) +- [internal/handler/ota.go:23-133](file://internal/handler/ota.go#L23-L133) +- [internal/handler/device.go:27-83](file://internal/handler/device.go#L27-L83) +- [internal/task/device_persist.go:24-167](file://internal/task/device_persist.go#L24-L167) ## 架构总览 -下图展示了从请求到响应的关键路径,包括处理器、仓库、数据库与可选编码流程。 +下图展示了从请求到响应的关键路径,包括处理器、仓库、数据库与可选编码流程,以及新增的OTA固件升级和设备跟踪功能。 ```mermaid sequenceDiagram @@ -138,14 +203,34 @@ participant H as "处理器层" participant Repo as "仓库层" participant DB as "数据库" participant Enc as "编码层" -C->>R : "GET /audio/getBrand?brandName=..." -R->>H : "BrandHandler.GetBrand" -H->>Repo : "List(brandName)" -Repo->>DB : "SELECT id,name FROM brand WHERE name LIKE ? ORDER BY name ASC" -DB-->>Repo : "结果集" -Repo-->>H : "[]Brand" +C->>R : "GET /audio/ota?model=xxx&hw=1&mac=xx : xx : xx&beta=0" +R->>H : "OTAHandler.GetOTA" +H->>Repo : "GetLatestOTA(model, hw, beta)" +Repo->>DB : "查询最新OTA记录" +DB-->>Repo : "OTA记录" +Repo-->>H : "OTA对象" +H->>Repo : "IsInBlackList(otaID, mac)" +Repo->>DB : "检查黑名单" +DB-->>Repo : "黑名单状态" +Repo-->>H : "黑名单检查结果" +alt "在黑名单中" +H->>Repo : "GetLatestOTANotInBlackList" +Repo->>DB : "查询非黑名单OTA" +DB-->>Repo : "OTA记录" +Repo-->>H : "OTA对象" +else "非定向升级" +H->>Repo : "FindTargetDevice(otaID, mac)" +Repo->>DB : "检查定向设备" +DB-->>Repo : "设备信息" +Repo-->>H : "设备检查结果" +else "定向升级" +H->>Repo : "GetLatestOTANotTarget" +Repo->>DB : "查询非定向OTA" +DB-->>Repo : "OTA记录" +Repo-->>H : "OTA对象" +end alt "base64Resp=true" -H->>Enc : "EncodeJSON([]Brand)" +H->>Enc : "EncodeJSON(OTA)" Enc-->>H : "Base64 字符串" H-->>C : "200 OK + Base64" else "默认" @@ -153,31 +238,31 @@ H-->>C : "200 OK + JSON" end ``` -图表来源 -- [internal/router/router.go:32-38](file://internal/router/router.go#L32-L38) -- [internal/handler/brand.go:26-50](file://internal/handler/brand.go#L26-L50) -- [internal/repository/brand.go:20-51](file://internal/repository/brand.go#L20-L51) +**图表来源** +- [internal/router/router.go:51](file://internal/router/router.go#L51) +- [internal/handler/ota.go:25-133](file://internal/handler/ota.go#L25-L133) +- [internal/repository/ota.go:19-159](file://internal/repository/ota.go#L19-L159) - [pkg/encode/base64.go:35-52](file://pkg/encode/base64.go#L35-L52) ## 详细组件分析 ### Brand 数据模型 -- 设计理念 +- **设计理念** - 轻量级品牌实体,仅包含标识与名称,用于品牌筛选与列表展示。 -- 字段定义与约束 +- **字段定义与约束** - id:整数,主键,自增。 - name:字符串,非空,用于品牌名匹配与排序。 -- 业务含义 +- **业务含义** - 作为 Model 的上游维度,配合 Model 的 brandName 字段形成关联。 -- 数据库映射 +- **数据库映射** - 表名:brand(未在本文直接列出,但与 Model 的 brand_name 关联一致)。 - 字段:id、name。 -- ORM 映射配置 +- **ORM 映射配置** - 使用原生 sql.DB 扫描,通过结构体标签与 Scan 对齐。 -- 验证与序列化 +- **验证与序列化** - 无显式校验逻辑,依赖数据库约束与上层参数清洗。 - JSON 标签用于序列化输出。 -- 查询流程 +- **查询流程** - 支持按品牌名模糊查询,使用 LIKE 匹配并按名称升序排列。 - 返回 []Brand 列表。 @@ -194,36 +279,36 @@ class BrandRepository { BrandRepository --> Brand : "返回" ``` -图表来源 +**图表来源** - [internal/model/brand.go:3-7](file://internal/model/brand.go#L3-L7) - [internal/repository/brand.go:12-51](file://internal/repository/brand.go#L12-L51) -章节来源 +**章节来源** - [internal/model/brand.go:3-7](file://internal/model/brand.go#L3-L7) - [internal/repository/brand.go:20-51](file://internal/repository/brand.go#L20-L51) ### Model 数据模型 -- 设计理念 +- **设计理念** - 型号实体承载品牌名、型号名及可选属性(形态、设备类型、来源、等价键),并记录创建时间。 -- 字段定义与约束 +- **字段定义与约束** - id:整数,主键,自增。 - brandName:字符串,非空,与品牌维度关联。 - name:字符串,非空,型号名。 - form、rig、source、eqKey:字符串(指针),可空,表示形态、设备类型、来源、等价键。 - createAt:时间戳,非空,记录创建时间。 -- 业务含义 +- **业务含义** - 作为核心产品维度,支持按品牌或型号名检索,可为空的扩展属性满足多样化设备描述。 -- 数据库映射 +- **数据库映射** - 表名:model。 - 字段:id、brand_name、name、form、rig、source、eq_key、create_at。 - 约束:唯一索引 (brand_name, name),保证同品牌下型号名唯一。 -- ORM 映射配置 +- **ORM 映射配置** - 使用 sql.NullString 扫描可空列,再转换为指针字符串,避免零值歧义。 - JSON 标签用于序列化输出,可空字段支持 omitempty。 -- 验证与序列化 +- **验证与序列化** - 无显式校验逻辑,依赖数据库约束与上层参数清洗。 - JSON 标签用于序列化输出。 -- 查询流程 +- **查询流程** - 支持按品牌名精确匹配或按型号名模糊匹配,返回 []Model 列表。 - 默认返回空切片而非 nil,便于前端处理。 @@ -246,39 +331,247 @@ class ModelRepository { ModelRepository --> Model : "返回" ``` -图表来源 +**图表来源** - [internal/model/model.go:5-15](file://internal/model/model.go#L5-L15) - [internal/repository/model.go:12-95](file://internal/repository/model.go#L12-L95) - [sql/model.sql:24-35](file://sql/model.sql#L24-L35) -章节来源 +**章节来源** - [internal/model/model.go:5-15](file://internal/model/model.go#L5-L15) - [internal/repository/model.go:20-95](file://internal/repository/model.go#L20-L95) - [sql/model.sql:24-35](file://sql/model.sql#L24-L35) +### OTA 固件升级模型 +- **设计理念** + - OTA模型用于管理固件升级信息,支持强制升级、灰度发布、定向升级等功能。 +- **字段定义与约束** + - OTA模型: + - id:整数,主键,自增。 + - verCode:整数,版本号,用于排序。 + - verName:字符串,版本名称。 + - url:字符串,固件下载地址。 + - md5:字符串,固件MD5校验值。 + - force:整数,是否强制升级(0-否,1-是)。 + - desc:字符串指针,升级描述。 + - model:字符串指针,对应设备型号。 + - hw:整数,硬件版本号。 + - target:整数,是否定向升级(0-否,1-是)。 + - beta:整数,是否灰度发布(0-否,1-是)。 + - pawVerCode:整数,配套软件版本号。 + - pawVerName:字符串,配套软件版本名称。 + - pawUrl:字符串,配套软件下载地址。 + - pawMD5:字符串,配套软件MD5校验值。 + - startTime:时间戳指针,升级开始时间。 + - endTime:时间戳指针,升级结束时间。 + - status:整数,状态(1-可用,0-不可用)。 + - BlackList模型: + - id:整数,主键,自增。 + - ota_id:整数,关联OTA记录ID。 + - mac:字符串,设备MAC地址。 + - create_at:时间戳,创建时间。 + - OTATargetDevice模型: + - id:整数,主键,自增。 + - ota_id:整数,关联OTA记录ID。 + - mac_addr:字符串,设备MAC地址。 + - type:整数,类型(1-白名单,2-黑名单)。 + - create_at:时间戳,创建时间。 +- **业务含义** + - 支持复杂的固件升级策略,包括强制升级、灰度发布、定向升级和黑名单管理。 +- **数据库映射** + - 表名:ota、black_list、ota_target_device。 + - 字段:完整映射关系详见数据库表结构。 +- **ORM 映射配置** + - 使用 sql.NullString 和 sql.NullTime 扫描可空列。 + - JSON 标签用于序列化输出,可空字段支持 omitempty。 +- **查询流程** + - 支持多种查询策略:最新OTA记录、非黑名单OTA记录、非定向OTA记录等。 + - 支持黑名单检查和定向设备检查。 + +```mermaid +classDiagram +class OTA { ++int id ++int verCode ++string verName ++string url ++string md5 ++int force ++*string desc ++*string model ++int hw ++int target ++int beta ++int pawVerCode ++string pawVerName ++string pawUrl ++string pawMD5 ++*time startTime ++*time endTime ++int status +} +class BlackList { ++int id ++int ota_id ++string mac ++time create_at +} +class OTATargetDevice { ++int id ++int ota_id ++string mac_addr ++int type ++time create_at +} +class OTARepository { +-db *sql.DB ++GetLatestOTA(ctx, model, hw, beta) *OTA ++GetLatestOTANotInBlackList(ctx, model, hw, beta, mac) *OTA ++GetLatestOTANotTarget(ctx, model, hw, beta) *OTA ++IsInBlackList(ctx, otaID, mac) bool ++FindTargetDevice(ctx, otaID, mac) *OTATargetDevice +} +OTARepository --> OTA : "返回" +OTARepository --> BlackList : "返回" +OTARepository --> OTATargetDevice : "返回" +``` + +**图表来源** +- [internal/model/ota.go:6-42](file://internal/model/ota.go#L6-L42) +- [internal/repository/ota.go:19-159](file://internal/repository/ota.go#L19-L159) +- [sql/ota.sql:24-44](file://sql/ota.sql#L24-L44) +- [sql/ota_target_device.sql:24-31](file://sql/ota_target_device.sql#L24-L31) + +**章节来源** +- [internal/model/ota.go:5-43](file://internal/model/ota.go#L5-L43) +- [internal/repository/ota.go:19-159](file://internal/repository/ota.go#L19-L159) +- [sql/ota.sql:23-44](file://sql/ota.sql#L23-L44) +- [sql/ota_target_device.sql:23-31](file://sql/ota_target_device.sql#L23-L31) + +### 用户设备跟踪模型 +- **设计理念** + - UserDevice模型用于跟踪用户设备信息,支持设备注册、版本更新等功能。 + - UserActive模型用于记录用户设备的活跃信息,支持按日期分区存储。 +- **字段定义与约束** + - UserDevice模型: + - id:整数,主键,自增。 + - mac_addr:字符串,设备MAC地址,唯一索引。 + - model:字符串,设备型号。 + - add_time:时间戳,默认当前时间。 + - ver:字符串指针,设备当前版本。 + - UserActive模型: + - id:整数,主键。 + - mac_addr:字符串,设备MAC地址。 + - model:字符串,设备型号。 + - active_date:日期,活跃日期,联合主键。 + - ip_addr:字符串,设备IP地址。 + - create_at:时间戳,默认当前时间。 +- **业务含义** + - 支持设备信息的实时上报和历史活动记录追踪。 +- **数据库映射** + - 表名:user_device、user_active。 + - 字段:完整映射关系详见数据库表结构。 + - 索引:user_device的mac_addr唯一索引,user_active的(mac_addr, active_date)联合索引。 +- **ORM 映射配置** + - 使用 sql.NullString 扫描可空列。 + - JSON 标签用于序列化输出。 +- **查询流程** + - 支持按MAC地址查询设备信息。 + - 支持按MAC地址和日期查询活跃记录。 + - 支持设备信息的插入、更新和活跃记录的插入、更新。 + +```mermaid +classDiagram +class UserDevice { ++int id ++string mac_addr ++string model ++time add_time ++*string ver +} +class UserActive { ++int id ++string mac_addr ++string model ++date active_date ++string ip_addr ++time create_at +} +class DeviceRepository { +-db *sql.DB ++FindDeviceByMac(ctx, macAddr) *UserDevice ++InsertDevice(ctx, device) error ++UpdateDeviceVer(ctx, id, ver) error ++FindActiveByMacAndDate(ctx, macAddr, activeDate) *UserActive ++InsertActive(ctx, active) error ++UpdateActiveIp(ctx, id, ipAddr) error +} +DeviceRepository --> UserDevice : "返回" +DeviceRepository --> UserActive : "返回" +``` + +**图表来源** +- [internal/model/user_device.go:5-12](file://internal/model/user_device.go#L5-L12) +- [internal/model/user_active.go:5-13](file://internal/model/user_active.go#L5-L13) +- [internal/repository/device.go:19-88](file://internal/repository/device.go#L19-L88) +- [sql/user_device.sql:24-32](file://sql/user_device.sql#L24-L32) +- [sql/user_active.sql:24-32](file://sql/user_active.sql#L24-L32) + +**章节来源** +- [internal/model/user_device.go:5-12](file://internal/model/user_device.go#L5-L12) +- [internal/model/user_active.go:5-13](file://internal/model/user_active.go#L5-L13) +- [internal/repository/device.go:19-88](file://internal/repository/device.go#L19-L88) +- [sql/user_device.sql:23-32](file://sql/user_device.sql#L23-L32) +- [sql/user_active.sql:23-32](file://sql/user_active.sql#L23-L32) + ### 处理器与序列化机制 -- 统一响应体 +- **统一响应体** - 统一响应体包含 code、message、data 字段,便于前端统一处理。 -- 可选 Base64 编码 +- **可选 Base64 编码** - 支持通过 base64Resp 参数控制是否对 JSON 响应进行自定义 Base64 编码。 - 自定义映射表将标准 Base64 字符集映射为更紧凑的字符集,减少体积。 -- 错误处理 +- **OTA处理器特殊逻辑** + - 支持参数校验、黑名单检查、定向设备检查等复杂业务逻辑。 + - 根据不同情况返回不同的OTA升级信息。 +- **设备处理器特殊逻辑** + - 将设备信息写入Redis缓存,支持异步持久化。 + - 提供设备信息上报接口。 +- **错误处理** - 处理器捕获仓库层错误,记录日志并通过统一响应体返回内部错误。 ```mermaid sequenceDiagram participant C as "客户端" -participant H as "ModelHandler" -participant Repo as "ModelRepository" +participant H as "OTAHandler" +participant Repo as "OTARepository" participant DB as "数据库" participant Enc as "编码层" -C->>H : "GET /audio/getModel?brandName=...&modelName=...&base64Resp=..." -H->>Repo : "List(brandName, modelName)" -Repo->>DB : "根据条件查询" -DB-->>Repo : "结果集" -Repo-->>H : "[]Model" +C->>H : "GET /audio/ota?model=...&hw=...&mac=...&beta=..." +H->>Repo : "GetLatestOTA(model, hw, beta)" +Repo->>DB : "查询最新OTA记录" +DB-->>Repo : "OTA记录" +Repo-->>H : "OTA对象" +H->>Repo : "IsInBlackList(otaID, mac)" +Repo->>DB : "检查黑名单" +DB-->>Repo : "黑名单状态" +Repo-->>H : "检查结果" +alt "在黑名单中" +H->>Repo : "GetLatestOTANotInBlackList" +Repo->>DB : "查询非黑名单OTA" +DB-->>Repo : "OTA记录" +Repo-->>H : "OTA对象" +else "非定向升级" +H->>Repo : "FindTargetDevice(otaID, mac)" +Repo->>DB : "检查定向设备" +DB-->>Repo : "设备信息" +Repo-->>H : "检查结果" +else "定向升级" +H->>Repo : "GetLatestOTANotTarget" +Repo->>DB : "查询非定向OTA" +DB-->>Repo : "OTA记录" +Repo-->>H : "OTA对象" +end alt "base64Resp=true" -H->>Enc : "EncodeJSON([]Model)" +H->>Enc : "EncodeJSON(OTA)" Enc-->>H : "Base64 字符串" H-->>C : "200 OK + Base64" else "默认" @@ -286,181 +579,318 @@ H-->>C : "200 OK + JSON" end ``` -图表来源 -- [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51) -- [internal/repository/model.go:20-95](file://internal/repository/model.go#L20-L95) +**图表来源** +- [internal/handler/ota.go:25-133](file://internal/handler/ota.go#L25-L133) +- [internal/repository/ota.go:19-159](file://internal/repository/ota.go#L19-L159) - [pkg/encode/base64.go:21-52](file://pkg/encode/base64.go#L21-L52) - [internal/response/response.go:9-37](file://internal/response/response.go#L9-L37) -章节来源 +**章节来源** - [internal/handler/brand.go:26-50](file://internal/handler/brand.go#L26-L50) - [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51) - [internal/handler/model_list.go:26-57](file://internal/handler/model_list.go#L26-L57) +- [internal/handler/ota.go:23-133](file://internal/handler/ota.go#L23-L133) +- [internal/handler/device.go:27-83](file://internal/handler/device.go#L27-L83) - [pkg/encode/base64.go:21-52](file://pkg/encode/base64.go#L21-L52) - [internal/response/response.go:9-37](file://internal/response/response.go#L9-L37) ### 查询与过滤逻辑 -- Brand 查询 +- **Brand 查询** - 支持按品牌名模糊匹配,使用 LIKE 并按名称升序排列。 -- Model 查询 +- **Model 查询** - 优先按品牌名精确匹配;若为空则按型号名模糊匹配;否则返回空切片。 - 扫描时将 sql.NullString 转换为指针字符串,避免零值歧义。 +- **OTA 查询** + - 支持按model+hw+beta+status=1查询最新OTA记录。 + - 支持黑名单检查和定向设备检查。 + - 提供多种查询策略以适应不同的升级场景。 +- **设备查询** + - 支持按MAC地址查询设备信息。 + - 支持按MAC地址和日期查询活跃记录。 + - 扫描时将 sql.NullString 转换为指针字符串,避免零值歧义。 ```mermaid flowchart TD -Start(["进入 List"]) --> Trim["去除前后空白"] -Trim --> CheckBrand{"brandName 是否非空?"} -CheckBrand --> |是| QueryBrand["按品牌名精确匹配"] -CheckBrand --> |否| CheckModel{"modelName 是否非空?"} -CheckModel --> |是| QueryModel["按型号名模糊匹配"] -CheckModel --> |否| ReturnEmpty["返回空切片"] -QueryBrand --> Exec["执行查询并扫描"] -QueryModel --> Exec -Exec --> End(["返回结果"]) -ReturnEmpty --> End +Start(["进入 OTA 查询"]) --> Params["参数校验"] +Params --> CheckBrand{"model和hw是否非空?"} +CheckBrand --> |是| QueryOTA["GetLatestOTA 查询"] +CheckBrand --> |否| Error["返回错误"] +QueryOTA --> CheckBlackList["IsInBlackList 检查"] +CheckBlackList --> |在黑名单| QueryNotInBlackList["GetLatestOTANotInBlackList"] +CheckBlackList --> |不在黑名单| CheckTarget{"ota.target 是否为0?"} +QueryNotInBlackList --> ReturnOTA["返回OTA"] +CheckTarget --> |是| ReturnOTA +CheckTarget --> |否| CheckTargetDevice["FindTargetDevice 检查"] +CheckTargetDevice --> |在定向设备| ReturnOTA +CheckTargetDevice --> |不在定向设备| QueryNotTarget["GetLatestOTANotTarget"] +QueryNotTarget --> ReturnOTA +ReturnOTA --> End(["返回结果"]) +Error --> End ``` -图表来源 -- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61) -- [internal/repository/brand.go:20-51](file://internal/repository/brand.go#L20-L51) +**图表来源** +- [internal/handler/ota.go:25-133](file://internal/handler/ota.go#L25-L133) +- [internal/repository/ota.go:19-159](file://internal/repository/ota.go#L19-L159) -章节来源 +**章节来源** - [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61) - [internal/repository/brand.go:20-51](file://internal/repository/brand.go#L20-L51) +- [internal/repository/ota.go:19-159](file://internal/repository/ota.go#L19-L159) +- [internal/repository/device.go:19-88](file://internal/repository/device.go#L19-L88) ## 依赖分析 -- 层间耦合 +- **层间耦合** - Handler 依赖 Repository;Repository 依赖 sql.DB;Model 为纯数据结构。 - 统一响应体与编码层被 Handler 调用,降低重复逻辑。 -- 外部依赖 + - 新增的Redis依赖用于设备信息缓存。 +- **外部依赖** - 数据库:MySQL,通过 sql.DB 访问。 - 日志:zap。 - Web 框架:Gin。 - 搜索:Meilisearch(ModelListHandler)。 - 缓存:Redis(Device 相关处理器)。 -- 潜在循环依赖 + - 任务调度:定时任务用于设备信息持久化。 +- **潜在循环依赖** - 当前结构清晰,无循环导入迹象。 +- **新增依赖关系** + - OTA功能依赖多个表的关联查询。 + - 设备跟踪功能依赖Redis缓存和数据库的双重存储。 ```mermaid graph LR H_Brand["BrandHandler"] --> Repo_Brand["BrandRepository"] H_Model["ModelHandler"] --> Repo_Model["ModelRepository"] H_ModelList["ModelListHandler"] --> Search["Meilisearch 客户端"] +H_OTA["OTAHandler"] --> Repo_OTA["OTARepository"] +H_Device["DeviceHandler"] --> Repo_Device["DeviceRepository"] Repo_Brand --> DB["sql.DB"] Repo_Model --> DB +Repo_OTA --> DB +Repo_Device --> DB +H_Device --> Redis["Redis Client"] +Repo_Device --> Redis H_Brand --> Resp["统一响应体"] H_Model --> Resp H_ModelList --> Resp +H_OTA --> Resp +H_Device --> Resp H_Brand --> Encode["Base64 编码"] H_Model --> Encode H_ModelList --> Encode +Task["DevicePersistTask"] --> Repo_Device +Task --> Redis +Task --> DB ``` -图表来源 +**图表来源** - [internal/handler/brand.go:14-50](file://internal/handler/brand.go#L14-L50) - [internal/handler/model.go:14-51](file://internal/handler/model.go#L14-L51) - [internal/handler/model_list.go:14-57](file://internal/handler/model_list.go#L14-L57) +- [internal/handler/ota.go:14-133](file://internal/handler/ota.go#L14-L133) +- [internal/handler/device.go:15-83](file://internal/handler/device.go#L15-L83) - [internal/repository/brand.go:12-51](file://internal/repository/brand.go#L12-L51) - [internal/repository/model.go:12-95](file://internal/repository/model.go#L12-L95) +- [internal/repository/ota.go:11-159](file://internal/repository/ota.go#L11-L159) +- [internal/repository/device.go:11-88](file://internal/repository/device.go#L11-L88) - [internal/response/response.go:9-37](file://internal/response/response.go#L9-L37) - [pkg/encode/base64.go:21-52](file://pkg/encode/base64.go#L21-L52) +- [internal/task/device_persist.go:14-167](file://internal/task/device_persist.go#L14-L167) -章节来源 -- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42) +**章节来源** +- [internal/router/router.go:14-56](file://internal/router/router.go#L14-L56) - [internal/config/database.go:17-72](file://internal/config/database.go#L17-L72) ## 性能考虑 -- 查询优化 +- **查询优化** - Model 表对 (brand_name, name) 建有唯一索引,有利于去重与快速定位。 + - OTA表对(model, hw, beta, status)建立索引,支持快速查询最新OTA记录。 + - UserDevice表对(mac_addr)建立唯一索引,支持快速设备查询。 + - UserActive表对(mac_addr, active_date)建立联合索引,支持按日期分区查询。 - 查询时优先按品牌名匹配,减少 LIKE 的范围。 -- 扫描与内存 +- **扫描与内存** - 使用 sql.NullString 扫描可空列,避免零值歧义;转换为指针字符串减少冗余存储。 -- 编码策略 + - OTA模型使用sql.NullTime处理可空时间字段。 +- **缓存策略** + - 设备信息先写入Redis缓存,通过定时任务批量持久化到数据库,减少数据库压力。 + - 品牌和型号信息使用Redis缓存提升查询性能。 +- **编码策略** - 可选的自定义 Base64 编码可降低响应体积,适合大列表传输场景。 -- 并发与超时 +- **并发与超时** - 服务器设置读写超时与优雅关闭,保障稳定性。 + - 设备持久化任务使用定时器定期执行,避免阻塞主线程。 -章节来源 +**章节来源** - [sql/model.sql:34-35](file://sql/model.sql#L34-L35) +- [sql/ota.sql:24-44](file://sql/ota.sql#L24-L44) +- [sql/user_device.sql:24-32](file://sql/user_device.sql#L24-L32) +- [sql/user_active.sql:24-32](file://sql/user_active.sql#L24-L32) - [internal/repository/model.go:63-95](file://internal/repository/model.go#L63-L95) +- [internal/repository/ota.go:20-159](file://internal/repository/ota.go#L20-L159) +- [internal/repository/device.go:19-88](file://internal/repository/device.go#L19-L88) - [pkg/encode/base64.go:21-52](file://pkg/encode/base64.go#L21-L52) - [cmd/server/main.go:66-95](file://cmd/server/main.go#L66-L95) +- [internal/task/device_persist.go:24-91](file://internal/task/device_persist.go#L24-L91) ## 故障排查指南 -- 常见问题 +- **常见问题** - 数据库连接失败:检查环境变量与配置加载逻辑。 - 查询无结果:确认查询参数是否为空或大小写敏感;Model 查询默认返回空切片而非 nil。 - 编码异常:确认 base64Resp 参数与 JSON 序列化是否成功。 -- 排查步骤 + - OTA查询失败:检查model、hw参数是否正确,确认OTA记录状态是否为1。 + - 设备信息未持久化:检查Redis连接和数据库连接,确认定时任务是否正常运行。 +- **排查步骤** - 查看日志:处理器记录错误日志,统一响应体返回错误码。 - 核对数据库:确认表结构与索引是否存在。 - 验证参数:确认查询参数是否符合预期。 + - 检查Redis:确认设备信息是否正确写入Redis缓存。 + - 监控任务:确认设备持久化任务是否按预期执行。 -章节来源 +**章节来源** - [internal/config/database.go:57-72](file://internal/config/database.go#L57-L72) - [internal/handler/brand.go:31-35](file://internal/handler/brand.go#L31-L35) - [internal/handler/model.go:33-36](file://internal/handler/model.go#L33-L36) - [internal/handler/model_list.go:39-42](file://internal/handler/model_list.go#L39-L42) +- [internal/handler/ota.go:31-48](file://internal/handler/ota.go#L31-L48) +- [internal/handler/device.go:33-39](file://internal/handler/device.go#L33-L39) - [internal/response/response.go:30-37](file://internal/response/response.go#L30-L37) ## 结论 -本项目的数据模型设计简洁明确:Brand 与 Model 分别承担品牌与型号的维度,通过仓库层的原生 SQL 访问实现高效查询;处理器层统一响应与可选编码,提升传输效率与前端体验。数据库层面通过唯一索引与合理字段设计保障一致性与性能。建议在后续迭代中引入显式的校验与转换层,增强健壮性与可维护性。 +本项目的数据模型设计简洁明确:Brand 与 Model 分别承担品牌与型号的维度,通过仓库层的原生 SQL 访问实现高效查询;处理器层统一响应与可选编码,提升传输效率与前端体验。新增的OTA固件升级模型、用户设备跟踪模型和用户活动模型进一步完善了系统的数据模型体系,支持复杂的固件升级策略、设备信息跟踪和用户行为分析。数据库层面通过唯一索引与合理字段设计保障一致性与性能。建议在后续迭代中引入显式的校验与转换层,增强健壮性与可维护性。 ## 附录 ### 数据库表结构与模型映射对照 -- 表:model +- **表:model** - 字段:id(主键)、brand_name、name、form、rig、source、eq_key、create_at。 - 约束:唯一索引 (brand_name, name)。 -- 映射关系 +- **表:ota** + - 字段:id(主键)、verCode、verName、url、md5、force、desc、model、hw、target、beta、pawVerCode、pawVerName、pawUrl、pawMd5、startTime、endTime、status。 + - 约束:无显式约束。 +- **表:black_list** + - 字段:id(主键)、ota_id、mac、create_at。 + - 约束:无显式约束。 +- **表:ota_target_device** + - 字段:id(主键)、ota_id、mac_addr、type、create_at。 + - 约束:无显式约束。 +- **表:user_device** + - 字段:id(主键)、mac_addr、model、add_time、ver。 + - 约束:唯一索引 (mac_addr)。 +- **表:user_active** + - 字段:id、mac_addr、model、active_date、ip_addr、create_at。 + - 约束:联合主键 (id, active_date),联合索引 (mac_addr, active_date)。 +- **映射关系** - Model.id ↔ model.id - Model.brandName ↔ model.brand_name - Model.name ↔ model.name - - Model.form ↔ model.form - - Model.rig ↔ model.rig - - Model.source ↔ model.source - - Model.eqKey ↔ model.eq_key - - Model.createAt ↔ model.create_at + - OTA.id ↔ ota.id + - OTA.verCode ↔ ota.verCode + - OTA.verName ↔ ota.verName + - OTA.url ↔ ota.url + - OTA.md5 ↔ ota.md5 + - OTA.force ↔ ota.force + - OTA.desc ↔ ota.desc + - OTA.model ↔ ota.model + - OTA.hw ↔ ota.hw + - OTA.target ↔ ota.target + - OTA.beta ↔ ota.beta + - OTA.pawVerCode ↔ ota.pawVerCode + - OTA.pawVerName ↔ ota.pawVerName + - OTA.pawUrl ↔ ota.pawUrl + - OTA.pawMD5 ↔ ota.pawMD5 + - OTA.startTime ↔ ota.startTime + - OTA.endTime ↔ ota.endTime + - OTA.status ↔ ota.status + - BlackList.id ↔ black_list.id + - BlackList.ota_id ↔ black_list.ota_id + - BlackList.mac ↔ black_list.mac + - BlackList.create_at ↔ black_list.create_at + - OTATargetDevice.id ↔ ota_target_device.id + - OTATargetDevice.ota_id ↔ ota_target_device.ota_id + - OTATargetDevice.mac_addr ↔ ota_target_device.mac_addr + - OTATargetDevice.type ↔ ota_target_device.type + - OTATargetDevice.create_at ↔ ota_target_device.create_at + - UserDevice.id ↔ user_device.id + - UserDevice.mac_addr ↔ user_device.mac_addr + - UserDevice.model ↔ user_device.model + - UserDevice.add_time ↔ user_device.add_time + - UserDevice.ver ↔ user_device.ver + - UserActive.id ↔ user_active.id + - UserActive.mac_addr ↔ user_active.mac_addr + - UserActive.model ↔ user_active.model + - UserActive.active_date ↔ user_active.active_date + - UserActive.ip_addr ↔ user_active.ip_addr + - UserActive.create_at ↔ user_active.create_at -章节来源 +**章节来源** - [sql/model.sql:24-35](file://sql/model.sql#L24-L35) +- [sql/ota.sql:24-44](file://sql/ota.sql#L24-L44) +- [sql/ota_target_device.sql:24-31](file://sql/ota_target_device.sql#L24-L31) +- [sql/user_device.sql:24-32](file://sql/user_device.sql#L24-L32) +- [sql/user_active.sql:24-32](file://sql/user_active.sql#L24-L32) - [internal/model/model.go:5-15](file://internal/model/model.go#L5-L15) +- [internal/model/ota.go:6-42](file://internal/model/ota.go#L6-L42) +- [internal/model/user_device.go:5-12](file://internal/model/user_device.go#L5-L12) +- [internal/model/user_active.go:5-13](file://internal/model/user_active.go#L5-L13) ### 请求与响应示例(路径参考) -- 获取品牌列表 +- **获取品牌列表** - 路由:/audio/getBrand - 方法:GET - 参数:brandName(可选),base64Resp(可选) - 返回:[]Brand 或 Base64 编码后的 JSON - 参考路径:[internal/handler/brand.go:26-50](file://internal/handler/brand.go#L26-L50) -- 获取型号列表 +- **获取型号列表** - 路由:/audio/getModel - 方法:GET - 参数:brandName(可选)、modelName(可选)、base64Resp(可选) - 返回:[]Model 或 Base64 编码后的 JSON - 参考路径:[internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51) -- 搜索模型列表 +- **搜索模型列表** - 路由:/audio/modelList - 方法:GET - 参数:key(必需)、count(可选)、base64Resp(可选) - 返回:[]Model 或 Base64 编码后的 JSON - 参考路径:[internal/handler/model_list.go:26-57](file://internal/handler/model_list.go#L26-L57) +- **获取OTA升级信息** + - 路由:/audio/ota + - 方法:GET + - 参数:model(必需)、hw(必需)、mac(可选)、beta(可选)、base64Resp(可选) + - 返回:OTA对象或 Base64 编码后的 JSON + - 参考路径:[internal/handler/ota.go:23-133](file://internal/handler/ota.go#L23-L133) +- **设备信息上报** + - 路由:/audio/reportDevInfo + - 方法:GET + - 参数:mac(必需)、model(必需)、ver(可选) + - 返回:操作结果 + - 参考路径:[internal/handler/device.go:27-83](file://internal/handler/device.go#L27-L83) -章节来源 -- [internal/router/router.go:32-38](file://internal/router/router.go#L32-L38) +**章节来源** +- [internal/router/router.go:45-52](file://internal/router/router.go#L45-L52) - [internal/handler/brand.go:26-50](file://internal/handler/brand.go#L26-L50) - [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51) - [internal/handler/model_list.go:26-57](file://internal/handler/model_list.go#L26-L57) +- [internal/handler/ota.go:23-133](file://internal/handler/ota.go#L23-L133) +- [internal/handler/device.go:27-83](file://internal/handler/device.go#L27-L83) ### 最佳实践建议 -- 模型扩展 +- **模型扩展** - 引入显式的校验与转换层,如参数清洗、长度限制、正则校验等。 - 对可空字段提供默认值策略,避免前端空值判断复杂化。 -- 版本管理与向后兼容 + - OTA模型支持复杂的升级策略,建议在业务层添加更多的参数验证。 +- **版本管理与向后兼容** - 通过 API 版本号(如 /api/v1)隔离变更;新增字段采用可选策略,保持旧字段必填。 - 对于破坏性变更,提供迁移脚本与双写策略。 -- 性能优化 + - OTA升级策略的变更需要谨慎处理,确保向后兼容性。 +- **性能优化** - 为高频查询字段建立索引;避免 SELECT *,仅选择必要字段。 - 对大列表启用可选 Base64 编码;结合分页与缓存策略。 -- 错误处理与可观测性 - - 统一错误码与消息格式;记录关键链路日志;对数据库与外部服务增加超时与重试。 \ No newline at end of file + - 设备信息使用Redis缓存,定期批量持久化到数据库。 + - OTA查询使用复合索引,支持快速定位最新OTA记录。 +- **错误处理与可观测性** + - 统一错误码与消息格式;记录关键链路日志;对数据库与外部服务增加超时与重试。 + - OTA查询失败需要详细的日志记录,包括参数、查询结果等。 + - 设备持久化任务需要监控执行状态和错误日志。 +- **安全考虑** + - OTA下载链接需要安全性验证,防止恶意下载。 + - 设备信息上报需要参数验证,防止注入攻击。 + - 黑名单和白名单管理需要权限控制和审计日志。 \ No newline at end of file diff --git a/.qoder/repowiki/zh/content/核心模块/数据访问层.md b/.qoder/repowiki/zh/content/核心模块/数据访问层.md index 4893ffe..9c54f9c 100644 --- a/.qoder/repowiki/zh/content/核心模块/数据访问层.md +++ b/.qoder/repowiki/zh/content/核心模块/数据访问层.md @@ -4,6 +4,8 @@ **本文引用的文件** - [internal/repository/brand.go](file://internal/repository/brand.go) - [internal/repository/model.go](file://internal/repository/model.go) +- [internal/repository/device.go](file://internal/repository/device.go) +- [internal/repository/ota.go](file://internal/repository/ota.go) - [internal/cache/brand_cache.go](file://internal/cache/brand_cache.go) - [internal/cache/model_cache.go](file://internal/cache/model_cache.go) - [internal/cache/redis.go](file://internal/cache/redis.go) @@ -13,21 +15,31 @@ - [internal/config/config.go](file://internal/config/config.go) - [internal/model/brand.go](file://internal/model/brand.go) - [internal/model/model.go](file://internal/model/model.go) +- [internal/model/user_device.go](file://internal/model/user_device.go) +- [internal/model/user_active.go](file://internal/model/user_active.go) +- [internal/model/ota.go](file://internal/model/ota.go) - [internal/handler/brand.go](file://internal/handler/brand.go) - [internal/handler/model.go](file://internal/handler/model.go) +- [internal/handler/device.go](file://internal/handler/device.go) +- [internal/handler/ota.go](file://internal/handler/ota.go) - [internal/router/router.go](file://internal/router/router.go) +- [internal/task/device_persist.go](file://internal/task/device_persist.go) - [cmd/server/main.go](file://cmd/server/main.go) - [sql/model.sql](file://sql/model.sql) +- [sql/user_device.sql](file://sql/user_device.sql) +- [sql/user_active.sql](file://sql/user_active.sql) +- [sql/ota.sql](file://sql/ota.sql) +- [sql/ota_target_device.sql](file://sql/ota_target_device.sql) - [go.mod](file://go.mod) ## 更新摘要 **变更内容** -- 新增缓存感知查询逻辑,增强品牌和型号仓库的缓存策略 -- 引入多级缓存架构,支持全量缓存和按品牌缓存 -- 实现智能数据刷新和预热机制 -- 添加缓存降级和错误处理策略 -- 更新架构图以反映新的缓存层集成 +- 新增设备持久化仓库(DeviceRepository)和OTA仓库(OTARepository),支持设备信息上报和固件升级查询 +- 引入设备活跃信息持久化任务,实现Redis到MySQL的异步数据同步 +- 新增用户设备和用户活跃两个核心数据模型,支持设备版本跟踪和用户活跃统计 +- 扩展OTA查询逻辑,支持黑名单检查、定向设备筛选和灰度发布控制 +- 更新架构图以反映新增的设备数据流和OTA查询流程 ## 目录 1. [简介](#简介) @@ -43,10 +55,10 @@ 11. [附录:扩展新 Repository 指南](#附录扩展新-repository-指南) ## 简介 -本文件聚焦于 Luxsin 应用 API 的数据访问层(Repository 层),系统性阐述 BrandRepository 与 ModelRepository 的设计模式、实现原理与职责边界;解释其在整体架构中的位置与交互方式;深入分析数据库连接管理、SQL 查询优化与事务处理机制;详细介绍新增的缓存感知查询逻辑、多级缓存策略和智能数据刷新机制;给出使用示例路径、错误处理与异常管理策略;总结并发安全、连接池管理与资源清理的最佳实践,并提供扩展新 Repository 的指导原则与注意事项。文档兼顾初学者与资深开发者的需求,既提供高层架构视图,也给出可落地的实现细节。 +本文件聚焦于 Luxsin 应用 API 的数据访问层(Repository 层),系统性阐述 BrandRepository、ModelRepository、DeviceRepository 和 OTARepository 的设计模式、实现原理与职责边界;解释其在整体架构中的位置与交互方式;深入分析数据库连接管理、SQL 查询优化与事务处理机制;详细介绍新增的缓存感知查询逻辑、多级缓存策略和智能数据刷新机制;给出使用示例路径、错误处理与异常管理策略;总结并发安全、连接池管理与资源清理的最佳实践,并提供扩展新 Repository 的指导原则与注意事项。文档兼顾初学者与资深开发者的需求,既提供高层架构视图,也给出可落地的实现细节。 ## 项目结构 -数据访问层位于 internal/repository 目录,配合 internal/cache 提供缓存层,internal/database 提供底层数据库连接,internal/model 定义领域模型,internal/handler 通过注入的 Repository 执行业务逻辑,最终由 Gin 路由暴露接口。 +数据访问层位于 internal/repository 目录,配合 internal/cache 提供缓存层,internal/database 提供底层数据库连接,internal/model 定义领域模型,internal/handler 通过注入的 Repository 执行业务逻辑,internal/task 提供设备数据持久化任务,最终由 Gin 路由暴露接口。 ```mermaid graph TB @@ -57,44 +69,71 @@ subgraph "路由与控制器" ROUTER["internal/router/router.go
注册路由与中间件"] BRAND_H["internal/handler/brand.go
品牌处理器"] MODEL_H["internal/handler/model.go
型号处理器"] +DEVICE_H["internal/handler/device.go
设备处理器"] +OTA_H["internal/handler/ota.go
OTA处理器"] end subgraph "数据访问层" BR_REPO["internal/repository/brand.go
BrandRepository"] MD_REPO["internal/repository/model.go
ModelRepository"] +DEV_REPO["internal/repository/device.go
DeviceRepository"] +OTA_REPO["internal/repository/ota.go
OTARepository"] end subgraph "缓存层" BR_CACHE["internal/cache/brand_cache.go
BrandCache"] MD_CACHE["internal/cache/model_cache.go
ModelCache"] REDIS["internal/cache/redis.go
Redis 客户端"] end +subgraph "任务调度" +PERSIST_TASK["internal/task/device_persist.go
设备持久化任务"] +end subgraph "数据库与配置" DB_SQL["internal/database/mysql.go
sql.DB 连接与池配置"] CFG_DB["internal/config/database.go
数据库配置加载"] CFG_REDIS["internal/config/redis.go
Redis 配置加载"] CFG_APP["internal/config/config.go
应用配置聚合"] MODEL_TBL["sql/model.sql
表结构定义"] +USER_DEVICE_TBL["sql/user_device.sql
用户设备表"] +USER_ACTIVE_TBL["sql/user_active.sql
用户活跃表"] +OTA_TBL["sql/ota.sql
OTA表"] +OTA_TARGET_TBL["sql/ota_target_device.sql
OTA定向设备表"] end subgraph "领域模型" M_BRAND["internal/model/brand.go
Brand 模型"] M_MODEL["internal/model/model.go
Model 模型"] +M_USER_DEVICE["internal/model/user_device.go
UserDevice 模型"] +M_USER_ACTIVE["internal/model/user_active.go
UserActive 模型"] +M_OTA["internal/model/ota.go
OTA 模型"] end MAIN --> ROUTER ROUTER --> BRAND_H ROUTER --> MODEL_H +ROUTER --> DEVICE_H +ROUTER --> OTA_H BRAND_H --> BR_REPO MODEL_H --> MD_REPO +DEVICE_H --> DEV_REPO +OTA_H --> OTA_REPO BR_REPO --> BR_CACHE MD_REPO --> MD_CACHE BR_CACHE --> REDIS MD_CACHE --> REDIS -BR_REPO --> DB_SQL -MD_REPO --> DB_SQL +DEV_REPO --> DB_SQL +OTA_REPO --> DB_SQL +PERSIST_TASK --> DEV_REPO +PERSIST_TASK --> REDIS DB_SQL --> CFG_DB CFG_APP --> CFG_DB CFG_APP --> CFG_REDIS BR_REPO --> M_BRAND MD_REPO --> M_MODEL +DEV_REPO --> M_USER_DEVICE +DEV_REPO --> M_USER_ACTIVE +OTA_REPO --> M_OTA MODEL_TBL --> DB_SQL +USER_DEVICE_TBL --> DB_SQL +USER_ACTIVE_TBL --> DB_SQL +OTA_TBL --> DB_SQL +OTA_TARGET_TBL --> DB_SQL ``` **图表来源** @@ -102,8 +141,12 @@ MODEL_TBL --> DB_SQL - [internal/router/router.go:22-25](file://internal/router/router.go#L22-L25) - [internal/handler/brand.go:19-24](file://internal/handler/brand.go#L19-L24) - [internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24) +- [internal/handler/device.go:15-25](file://internal/handler/device.go#L15-L25) +- [internal/handler/ota.go:14-21](file://internal/handler/ota.go#L14-L21) - [internal/repository/brand.go:14-21](file://internal/repository/brand.go#L14-L21) - [internal/repository/model.go:14-21](file://internal/repository/model.go#L14-L21) +- [internal/repository/device.go:11-17](file://internal/repository/device.go#L11-L17) +- [internal/repository/ota.go:11-17](file://internal/repository/ota.go#L11-L17) - [internal/cache/brand_cache.go:18-24](file://internal/cache/brand_cache.go#L18-L24) - [internal/cache/model_cache.go:19-25](file://internal/cache/model_cache.go#L19-L25) - [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16) @@ -111,15 +154,24 @@ MODEL_TBL --> DB_SQL - [internal/config/database.go:17-40](file://internal/config/database.go#L17-L40) - [internal/config/redis.go:9-57](file://internal/config/redis.go#L9-L57) - [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52) +- [internal/task/device_persist.go:14-22](file://internal/task/device_persist.go#L14-L22) - [sql/model.sql:24-35](file://sql/model.sql#L24-L35) +- [sql/user_device.sql:23-32](file://sql/user_device.sql#L23-L32) +- [sql/user_active.sql:23-32](file://sql/user_active.sql#L23-L32) +- [sql/ota.sql:23-44](file://sql/ota.sql#L23-L44) +- [sql/ota_target_device.sql:23-31](file://sql/ota_target_device.sql#L23-L31) **章节来源** - [cmd/server/main.go:103-130](file://cmd/server/main.go#L103-L130) -- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41) +- [internal/router/router.go:14-56](file://internal/router/router.go#L14-L56) - [internal/handler/brand.go:19-24](file://internal/handler/brand.go#L19-L24) - [internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24) +- [internal/handler/device.go:15-25](file://internal/handler/device.go#L15-L25) +- [internal/handler/ota.go:14-21](file://internal/handler/ota.go#L14-L21) - [internal/repository/brand.go:14-21](file://internal/repository/brand.go#L14-L21) - [internal/repository/model.go:14-21](file://internal/repository/model.go#L14-L21) +- [internal/repository/device.go:11-17](file://internal/repository/device.go#L11-L17) +- [internal/repository/ota.go:11-17](file://internal/repository/ota.go#L11-L17) - [internal/cache/brand_cache.go:18-24](file://internal/cache/brand_cache.go#L18-L24) - [internal/cache/model_cache.go:19-25](file://internal/cache/model_cache.go#L19-L25) - [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16) @@ -127,72 +179,99 @@ MODEL_TBL --> DB_SQL - [internal/config/database.go:17-40](file://internal/config/database.go#L17-L40) - [internal/config/redis.go:9-57](file://internal/config/redis.go#L9-L57) - [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52) +- [internal/task/device_persist.go:14-22](file://internal/task/device_persist.go#L14-L22) - [sql/model.sql:24-35](file://sql/model.sql#L24-L35) +- [sql/user_device.sql:23-32](file://sql/user_device.sql#L23-L32) +- [sql/user_active.sql:23-32](file://sql/user_active.sql#L23-L32) +- [sql/ota.sql:23-44](file://sql/ota.sql#L23-L44) +- [sql/ota_target_device.sql:23-31](file://sql/ota_target_device.sql#L23-L31) ## 核心组件 - **BrandRepository**:负责品牌列表查询,支持缓存感知的全量查询和按名称模糊过滤,返回 Brand 领域对象切片。 - **ModelRepository**:负责型号列表查询,支持缓存感知的按品牌精确匹配、按型号名模糊匹配和全量查询,返回 Model 领域对象切片,并对可空字段进行 NullString 到指针字符串的安全转换。 +- **DeviceRepository**:负责设备信息管理,支持按MAC地址查询设备、插入新设备、更新设备版本信息,以及用户活跃信息的查询和更新。 +- **OTARepository**:负责固件升级信息查询,支持按型号、硬件版本、灰度标识查询最新OTA记录,黑名单检查、定向设备筛选等功能。 - **缓存层**:BrandCache 和 ModelCache 提供多级缓存策略,支持全量缓存和按品牌缓存,具有智能刷新和降级机制。 +- **设备持久化任务**:DevicePersistTask 从Redis批量读取设备信息,异步写入MySQL user_device 和 user_active 表,支持数据可靠性保障。 - **数据库连接**:通过 sql.DB 统一管理连接池,设置最大打开连接数、空闲连接数与连接生命周期,并在启动时进行 Ping 校验。 - **配置加载**:从环境变量或默认值加载数据库和 Redis 配置,生产环境要求提供密码。 -- **Handler 注入**:Gin 控制器通过 NewXxxHandler 构造函数注入 *sql.DB 和缓存实例,再由 Handler 内部构造对应的 Repository 实例,形成清晰的依赖注入链路。 +- **Handler 注入**:Gin 控制器通过 NewXxxHandler 构造函数注入相应的 Repository 实例,再由 Handler 内部执行业务逻辑,形成清晰的依赖注入链路。 **章节来源** - [internal/repository/brand.go:23-52](file://internal/repository/brand.go#L23-L52) - [internal/repository/model.go:23-79](file://internal/repository/model.go#L23-L79) +- [internal/repository/device.go:11-88](file://internal/repository/device.go#L11-L88) +- [internal/repository/ota.go:11-159](file://internal/repository/ota.go#L11-L159) - [internal/cache/brand_cache.go:26-44](file://internal/cache/brand_cache.go#L26-L44) - [internal/cache/model_cache.go:31-69](file://internal/cache/model_cache.go#L31-L69) +- [internal/task/device_persist.go:14-167](file://internal/task/device_persist.go#L14-L167) - [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46) - [internal/config/database.go:17-72](file://internal/config/database.go#L17-L72) - [internal/config/redis.go:16-57](file://internal/config/redis.go#L16-L57) - [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52) - [internal/handler/brand.go:19-24](file://internal/handler/brand.go#L19-L24) - [internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24) +- [internal/handler/device.go:15-25](file://internal/handler/device.go#L15-L25) +- [internal/handler/ota.go:14-21](file://internal/handler/ota.go#L14-L21) ## 架构总览 -数据访问层采用"仓储模式"(Repository Pattern)封装数据库访问,将查询逻辑与业务逻辑解耦。新增的缓存层提供多级缓存策略,支持智能数据刷新和降级机制。Handler 仅依赖 Repository 接口,Repository 依赖 *sql.DB 和缓存实例,配置与数据库模块负责基础设施初始化。整体流程如下: +数据访问层采用"仓储模式"(Repository Pattern)封装数据库访问,将查询逻辑与业务逻辑解耦。新增的缓存层提供多级缓存策略,支持智能数据刷新和降级机制。新增的设备持久化任务实现Redis到MySQL的异步数据同步。Handler 仅依赖 Repository 接口,Repository 依赖 *sql.DB 和缓存实例,配置与数据库模块负责基础设施初始化。整体流程如下: ```mermaid sequenceDiagram participant Client as "客户端" participant Router as "Gin 路由" -participant Handler as "BrandHandler/ModelHandler" -participant Repo as "BrandRepository/ModelRepository" -participant Cache as "BrandCache/ModelCache" +participant DeviceHandler as "DeviceHandler" +participant OTAHandler as "OTAHandler" +participant DeviceRepo as "DeviceRepository" +participant OTARepo as "OTARepository" participant DB as "sql.DB" participant Redis as "Redis 服务器" participant MySQL as "MySQL 服务器" Client->>Router : "HTTP 请求" -Router->>Handler : "分发到对应处理器" -Handler->>Repo : "调用 List(...)" -alt 缓存命中 -Repo->>Cache : "GetAll/GetByBrand" -Cache->>Redis : "执行 GET" -Redis-->>Cache : "返回缓存数据" -Cache-->>Repo : "返回缓存数据" -else 缓存未命中或异常 -Repo->>Cache : "GetAll/GetByBrand" -Cache->>Redis : "执行 GET" -Redis-->>Cache : "返回错误或空值" -Repo->>DB : "QueryContext(ctx, query, args...)" -DB->>MySQL : "执行 SQL" -MySQL-->>DB : "返回结果集" -DB-->>Repo : "Rows" -Repo->>Cache : "SetAll/SetByBrand" -Cache->>Redis : "执行 SET" -Redis-->>Cache : "确认存储" +Router->>DeviceHandler : "设备信息上报" +DeviceHandler->>Redis : "HSet devices" +Redis-->>DeviceHandler : "存储成功" +Note over DeviceHandler : "异步持久化任务" +DevicePersistTask->>Redis : "HGetAll devices" +Redis-->>DevicePersistTask : "批量数据" +DevicePersistTask->>DeviceRepo : "FindDeviceByMac" +DeviceRepo->>DB : "QueryContext" +DB-->>DeviceRepo : "设备信息" +alt 设备不存在 +DevicePersistTask->>DeviceRepo : "InsertDevice" +DeviceRepo->>DB : "ExecContext" +DB-->>DeviceRepo : "插入成功" +else 设备存在 +DevicePersistTask->>DeviceRepo : "UpdateDeviceVer" +DeviceRepo->>DB : "ExecContext" +DB-->>DeviceRepo : "更新成功" end -Repo-->>Handler : "领域对象切片" -Handler-->>Client : "JSON 或 Base64 响应" +Router->>OTAHandler : "OTA升级查询" +OTAHandler->>OTARepo : "GetLatestOTA" +OTARepo->>DB : "QueryRowContext" +DB-->>OTARepo : "最新OTA记录" +OTAHandler->>OTARepo : "IsInBlackList" +OTARepo->>DB : "QueryRowContext" +DB-->>OTARepo : "黑名单检查结果" +alt 在黑名单中 +OTAHandler->>OTARepo : "GetLatestOTANotInBlackList" +OTARepo->>DB : "QueryRowContext" +DB-->>OTARepo : "非黑名单最新记录" +else 不在黑名单 +OTAHandler->>OTARepo : "FindTargetDevice" +OTARepo->>DB : "QueryRowContext" +DB-->>OTARepo : "定向设备检查结果" +end +OTAHandler-->>Client : "OTA升级信息" ``` **图表来源** -- [internal/handler/brand.go:25-48](file://internal/handler/brand.go#L25-L48) -- [internal/handler/model.go:25-49](file://internal/handler/model.go#L25-L49) -- [internal/repository/brand.go:23-52](file://internal/repository/brand.go#L23-L52) -- [internal/repository/model.go:23-79](file://internal/repository/model.go#L23-L79) -- [internal/cache/brand_cache.go:26-44](file://internal/cache/brand_cache.go#L26-L44) -- [internal/cache/model_cache.go:31-69](file://internal/cache/model_cache.go#L31-L69) +- [internal/handler/device.go:27-82](file://internal/handler/device.go#L27-L82) +- [internal/handler/ota.go:23-132](file://internal/handler/ota.go#L23-L132) +- [internal/repository/device.go:19-87](file://internal/repository/device.go#L19-L87) +- [internal/repository/ota.go:19-158](file://internal/repository/ota.go#L19-L158) +- [internal/task/device_persist.go:37-91](file://internal/task/device_persist.go#L37-L91) - [internal/database/mysql.go:28-43](file://internal/database/mysql.go#L28-L43) ## 详细组件分析 @@ -312,36 +391,225 @@ ModelCache --> Model : "返回缓存数据" - [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14) - [sql/model.sql:34](file://sql/model.sql#L34) +### DeviceRepository 设计与实现 +- **设计模式**:仓储模式,面向领域模型 UserDevice 和 UserActive,封装设备信息管理逻辑。 +- **关键特性**: + - 设备查询:按MAC地址精确查询用户设备信息,支持版本号的可空字段处理 + - 设备管理:支持插入新设备、更新设备版本信息 + - 用户活跃:按MAC地址和日期查询用户活跃信息,支持IP地址更新 + - 可空字段处理:使用 sql.NullString 和 sql.NullTime 安全转换数据库可空字段 + - 错误处理:针对不同查询场景提供详细的错误包装,便于问题定位 + - 资源管理:使用 QueryRowContext 和 ExecContext,确保数据库连接正确释放 +- **表结构要点**: + - user_device 表:主键ID,唯一MAC地址索引,支持设备版本跟踪 + - user_active 表:复合主键(ID, active_date),唯一MAC+日期索引,支持分区存储 +- **应用场景**:设备信息上报、用户活跃统计、设备版本管理等业务场景。 + +```mermaid +classDiagram +class DeviceRepository { +-db : "*sql.DB" ++NewDeviceRepository(db) DeviceRepository ++FindDeviceByMac(ctx, macAddr) *UserDevice,error ++InsertDevice(ctx, d) error ++UpdateDeviceVer(ctx, id, ver) error ++FindActiveByMacAndDate(ctx, macAddr, activeDate) *UserActive,error ++InsertActive(ctx, a) error ++UpdateActiveIp(ctx, id, ipAddr) error +} +class UserDevice { ++int ID ++string MacAddr ++string Model ++time AddTime ++*string Ver +} +class UserActive { ++int ID ++string MacAddr ++string Model ++string ActiveDate ++string IpAddr ++time CreateAt +} +DeviceRepository --> UserDevice : "设备信息" +DeviceRepository --> UserActive : "活跃信息" +``` + +**图表来源** +- [internal/repository/device.go:11-17](file://internal/repository/device.go#L11-L17) +- [internal/repository/device.go:19-87](file://internal/repository/device.go#L19-L87) +- [internal/model/user_device.go:5-11](file://internal/model/user_device.go#L5-L11) +- [internal/model/user_active.go:5-12](file://internal/model/user_active.go#L5-L12) + +**章节来源** +- [internal/repository/device.go:11-17](file://internal/repository/device.go#L11-L17) +- [internal/repository/device.go:19-87](file://internal/repository/device.go#L19-L87) +- [internal/model/user_device.go:5-11](file://internal/model/user_device.go#L5-L11) +- [internal/model/user_active.go:5-12](file://internal/model/user_active.go#L5-L12) +- [sql/user_device.sql:23-32](file://sql/user_device.sql#L23-L32) +- [sql/user_active.sql:23-32](file://sql/user_active.sql#L23-L32) + +### OTARepository 设计与实现 +- **设计模式**:仓储模式,面向领域模型 OTA、BlackList 和 OTATargetDevice,封装固件升级查询逻辑。 +- **关键特性**: + - 最新OTA查询:按型号、硬件版本、灰度标识查询最新一条可用OTA记录 + - 黑名单检查:检查设备是否在指定OTA的黑名单中 + - 非黑名单查询:查询不在黑名单中的最新OTA记录 + - 非定向查询:查询非定向(target=0)的最新OTA记录 + - 定向设备检查:检查设备是否在指定OTA的定向设备列表中 + - 可空字段处理:使用 sql.NullString 和 sql.NullTime 安全处理数据库可空字段 + - 复杂查询:支持子查询、条件筛选、时间范围检查等复杂业务逻辑 +- **业务逻辑**: + - 支持灰度发布(beta=1)和正式发布(beta=0)两种模式 + - 支持强制升级(force=1)和普通升级(force=0) + - 支持定向升级和非定向升级两种分发策略 + - 支持时间窗口限制(startTime/endTime) +- **应用场景**:固件升级推送、灰度发布控制、定向设备管理等。 + +```mermaid +classDiagram +class OTARepository { +-db : "*sql.DB" ++NewOTARepository(db) OTARepository ++GetLatestOTA(ctx, modelVal, hw, beta) *OTA,error ++GetLatestOTANotInBlackList(ctx, modelVal, hw, beta, mac) *OTA,error ++GetLatestOTANotTarget(ctx, modelVal, hw, beta) *OTA,error ++IsInBlackList(ctx, otaID, mac) bool,error ++FindTargetDevice(ctx, otaID, mac) *OTATargetDevice,error +} +class OTA { ++int ID ++int VerCode ++string VerName ++string URL ++string MD5 ++int Force ++*string Desc ++*string Model ++int HW ++int Target ++int Beta ++int PawVerCode ++string PawVerName ++string PawURL ++string PawMD5 ++*time StartTime ++*time EndTime ++int Status +} +class BlackList { ++int ID ++int OTAID ++string Mac ++time CreateAt +} +class OTATargetDevice { ++int ID ++int OTAID ++string MacAddr ++int Type ++time CreateAt +} +OTARepository --> OTA : "OTA记录" +OTARepository --> BlackList : "黑名单" +OTARepository --> OTATargetDevice : "定向设备" +``` + +**图表来源** +- [internal/repository/ota.go:11-17](file://internal/repository/ota.go#L11-L17) +- [internal/repository/ota.go:19-158](file://internal/repository/ota.go#L19-L158) +- [internal/model/ota.go:6-42](file://internal/model/ota.go#L6-L42) + +**章节来源** +- [internal/repository/ota.go:11-17](file://internal/repository/ota.go#L11-L17) +- [internal/repository/ota.go:19-158](file://internal/repository/ota.go#L19-L158) +- [internal/model/ota.go:6-42](file://internal/model/ota.go#L6-L42) +- [sql/ota.sql:23-44](file://sql/ota.sql#L23-L44) +- [sql/ota_target_device.sql:23-31](file://sql/ota_target_device.sql#L23-L31) + +### 设备持久化任务设计与实现 +- **设计模式**:定时任务模式,基于时间轮询的异步数据同步机制。 +- **关键特性**: + - 定时执行:使用 time.Ticker 按固定间隔启动持久化任务 + - 批量处理:从Redis Hash一次性读取所有待持久化的设备数据 + - 数据修复:自动修复历史数据中的无效日期格式 + - 双表写入:同时处理 user_device 和 user_active 两张表 + - 成功确认:批量删除已成功持久化的数据,避免重复处理 + - 错误隔离:单条数据处理失败不影响其他数据的处理 +- **处理流程**: + 1. 从Redis读取 devices Hash 中的所有设备数据 + 2. 解析JSON格式的设备信息 + 3. 修复无效的日期格式 + 4. 分别处理设备信息和活跃信息 + 5. 批量删除已成功处理的数据 +- **应用场景**:高并发设备信息上报、数据可靠性保障、异步数据同步等。 + +```mermaid +flowchart TD +A[定时器触发] --> B[HGetAll devices] +B --> C{是否有数据?} +C --> |否| D[结束] +C --> |是| E[遍历设备数据] +E --> F[解析JSON数据] +F --> G[修复日期格式] +G --> H[处理设备信息] +H --> I[处理活跃信息] +I --> J{处理成功?} +J --> |是| K[记录成功MAC] +J --> |否| L[跳过该设备] +K --> M[批量删除成功数据] +L --> N[继续下一个] +M --> O[记录处理结果] +N --> E +O --> P[结束] +``` + +**图表来源** +- [internal/task/device_persist.go:24-91](file://internal/task/device_persist.go#L24-L91) + +**章节来源** +- [internal/task/device_persist.go:14-167](file://internal/task/device_persist.go#L14-L167) + ### Handler 与 Repository 的协作 -- Handler 通过 NewBrandHandler/NewModelHandler 注入 *sql.DB 和缓存实例,内部构造对应 Repository 实例。 -- Handler 在 GetBrand/GetModel 中读取查询参数,调用 Repository.List(...),并将结果以 JSON 或 Base64 编码返回。 -- 错误处理:若 Repository 返回错误,Handler 记录日志并返回统一的内部错误响应。 -- 缓存感知:Handler 不需要关心缓存逻辑,只需调用 Repository 的标准方法即可享受缓存优势。 +- Handler 通过 NewXxxHandler 注入相应的 Repository 实例,内部执行具体的业务逻辑。 +- DeviceHandler 处理设备信息上报,将数据写入Redis Hash,等待异步持久化任务处理。 +- OTAHandler 处理OTA升级查询,调用OTARepository执行复杂的业务逻辑,包括黑名单检查、定向设备筛选等。 +- BrandHandler 和 ModelHandler 继续使用原有的缓存感知查询逻辑。 +- 错误处理:各 Handler 对 Repository 返回的错误进行统一处理和日志记录。 +- 缓存感知:DeviceHandler 和 OTAHandler 不需要关心缓存逻辑,只需调用相应的 Repository 方法。 ```mermaid sequenceDiagram participant C as "客户端" -participant H as "BrandHandler" -participant R as "BrandRepository" -participant RC as "Redis 客户端" -C->>H : "GET /audio/getBrand?brandName=..." -H->>R : "List(ctx, brandName)" -R->>RC : "GetAll(ctx)" -RC-->>R : "缓存命中/未命中" -alt 缓存命中 -R-->>H : "[]Brand" -else 缓存未命中 -R->>DB : "QueryContext(ctx, ...)" -DB-->>R : "rows" -R->>RC : "SetAll(ctx, allBrands)" -R-->>H : "[]Brand" +participant DH as "DeviceHandler" +participant DR as "DeviceRepository" +participant RT as "Redis 服务器" +C->>DH : "POST /audio/reportDevInfo" +DH->>RT : "HSet devices" +RT-->>DH : "存储成功" +DH-->>C : "操作成功" +participant OH as "OTAHandler" +participant OR as "OTARepository" +OH->>OR : "GetLatestOTA" +OR-->>OH : "最新OTA记录" +OH->>OR : "IsInBlackList" +OR-->>OH : "黑名单检查结果" +alt 在黑名单中 +OH->>OR : "GetLatestOTANotInBlackList" +OR-->>OH : "非黑名单最新记录" +else 不在黑名单 +OH->>OR : "FindTargetDevice" +OR-->>OH : "定向设备检查结果" end -H-->>C : "JSON 或 Base64" +OH-->>C : "OTA升级信息" ``` **图表来源** -- [internal/handler/brand.go:25-48](file://internal/handler/brand.go#L25-L48) -- [internal/repository/brand.go:23-52](file://internal/repository/brand.go#L23-L52) +- [internal/handler/device.go:27-82](file://internal/handler/device.go#L27-L82) +- [internal/handler/ota.go:23-132](file://internal/handler/ota.go#L23-L132) +- [internal/repository/device.go:19-87](file://internal/repository/device.go#L19-L87) +- [internal/repository/ota.go:19-158](file://internal/repository/ota.go#L19-L158) - [internal/database/mysql.go:28-43](file://internal/database/mysql.go#L28-L43) **章节来源** @@ -349,8 +617,14 @@ H-->>C : "JSON 或 Base64" - [internal/handler/brand.go:25-48](file://internal/handler/brand.go#L25-L48) - [internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24) - [internal/handler/model.go:25-49](file://internal/handler/model.go#L25-L49) +- [internal/handler/device.go:15-25](file://internal/handler/device.go#L15-L25) +- [internal/handler/device.go:27-82](file://internal/handler/device.go#L27-L82) +- [internal/handler/ota.go:14-21](file://internal/handler/ota.go#L14-L21) +- [internal/handler/ota.go:23-132](file://internal/handler/ota.go#L23-L132) - [internal/repository/brand.go:23-52](file://internal/repository/brand.go#L23-L52) - [internal/repository/model.go:23-79](file://internal/repository/model.go#L23-L79) +- [internal/repository/device.go:19-87](file://internal/repository/device.go#L19-L87) +- [internal/repository/ota.go:19-158](file://internal/repository/ota.go#L19-L158) ## 缓存策略详解 @@ -365,12 +639,14 @@ H-->>C : "JSON 或 Base64" - **品牌全量缓存**:`brand:all` - 存储所有品牌信息 - **型号按品牌缓存**:`model:brand:{brandName}` - 存储特定品牌的所有型号 - **型号全量缓存**:`model:all` - 存储所有型号信息 +- **设备活跃缓存**:`device:active:{date}` - 存储特定日期的活跃设备信息 ### 缓存策略实现 - **缓存优先策略**:优先从缓存获取数据,缓存未命中时才查询数据库 - **智能降级策略**:Redis 异常时自动降级到数据库查询,保证系统可用性 - **自动回写策略**:成功从数据库获取数据后自动回写到缓存 - **TTL 策略**:所有缓存设置 30 分钟过期时间,平衡性能和数据新鲜度 +- **设备数据特殊处理**:设备活跃信息采用分区表存储,缓存策略需考虑日期维度 ### 预热机制 应用启动时会自动预热缓存,从数据库加载全量数据到 Redis: @@ -383,7 +659,9 @@ C --> D[查询品牌全量数据] D --> E[写入 brand:all 缓存] E --> F[查询型号全量数据] F --> G[写入 model:all 缓存] -G --> H[缓存预热完成] +G --> H[设备数据无需预热] +H --> I[OTA数据无需预热] +I --> J[缓存预热完成] ``` **图表来源** @@ -396,9 +674,9 @@ G --> H[缓存预热完成] ## 依赖关系分析 - **外部依赖**:Go MySQL Driver、Gin、Zap 日志、Redis 客户端、Meilisearch 客户端。 -- **内部依赖**:Handler 依赖 Repository;Repository 依赖 *sql.DB 和缓存实例;缓存层依赖 Redis 客户端;数据库模块负责连接池与 Ping 校验;配置模块负责环境变量解析与校验。 +- **内部依赖**:Handler 依赖 Repository;Repository 依赖 *sql.DB 和缓存实例;缓存层依赖 Redis 客户端;数据库模块负责连接池与 Ping 校验;配置模块负责环境变量解析与校验;任务模块依赖 Redis 和 Repository。 - **循环依赖**:未发现循环依赖,职责边界清晰。 -- **新增依赖**:缓存层增加了对 Redis 客户端的依赖,以及对缓存配置的依赖。 +- **新增依赖**:DeviceRepository 和 OTARepository 直接依赖 *sql.DB;设备持久化任务依赖 Redis 和 Repository;OTA 查询逻辑依赖复杂的表关联。 ```mermaid graph LR @@ -414,14 +692,20 @@ CFG_LOAD --> CFG_DB["internal/config/database.go::loadDatabase"] CFG_LOAD --> CFG_REDIS["internal/config/redis.go::loadRedis"] ROUTER["internal/router/router.go"] --> BRAND_H["internal/handler/brand.go"] ROUTER --> MODEL_H["internal/handler/model.go"] +ROUTER --> DEVICE_H["internal/handler/device.go"] +ROUTER --> OTA_H["internal/handler/ota.go"] BRAND_H --> BR_REPO["internal/repository/brand.go"] MODEL_H --> MD_REPO["internal/repository/model.go"] +DEVICE_H --> DEV_REPO["internal/repository/device.go"] +OTA_H --> OTA_REPO["internal/repository/ota.go"] BR_REPO --> BR_CACHE["internal/cache/brand_cache.go"] MD_REPO --> MD_CACHE["internal/cache/model_cache.go"] BR_CACHE --> REDIS_CLIENT["internal/cache/redis.go::NewClient"] MD_CACHE --> REDIS_CLIENT -BR_REPO --> DB_SQL["*sql.DB"] -MD_REPO --> DB_SQL +DEV_REPO --> DB_SQL["*sql.DB"] +OTA_REPO --> DB_SQL +PERSIST_TASK --> DEV_REPO +PERSIST_TASK --> REDIS_CLIENT BR_CACHE --> REDIS_CLIENT MD_CACHE --> REDIS_CLIENT ``` @@ -435,8 +719,12 @@ MD_CACHE --> REDIS_CLIENT - [internal/router/router.go:22-25](file://internal/router/router.go#L22-L25) - [internal/handler/brand.go:19-24](file://internal/handler/brand.go#L19-L24) - [internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24) +- [internal/handler/device.go:15-25](file://internal/handler/device.go#L15-L25) +- [internal/handler/ota.go:14-21](file://internal/handler/ota.go#L14-L21) - [internal/repository/brand.go:14-21](file://internal/repository/brand.go#L14-L21) - [internal/repository/model.go:14-21](file://internal/repository/model.go#L14-L21) +- [internal/repository/device.go:11-17](file://internal/repository/device.go#L11-L17) +- [internal/repository/ota.go:11-17](file://internal/repository/ota.go#L11-L17) - [internal/cache/brand_cache.go:18-24](file://internal/cache/brand_cache.go#L18-L24) - [internal/cache/model_cache.go:19-25](file://internal/cache/model_cache.go#L19-L25) @@ -449,8 +737,12 @@ MD_CACHE --> REDIS_CLIENT - [internal/router/router.go:22-25](file://internal/router/router.go#L22-L25) - [internal/handler/brand.go:19-24](file://internal/handler/brand.go#L19-L24) - [internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24) +- [internal/handler/device.go:15-25](file://internal/handler/device.go#L15-L25) +- [internal/handler/ota.go:14-21](file://internal/handler/ota.go#L14-L21) - [internal/repository/brand.go:14-21](file://internal/repository/brand.go#L14-L21) - [internal/repository/model.go:14-21](file://internal/repository/model.go#L14-L21) +- [internal/repository/device.go:11-17](file://internal/repository/device.go#L11-L17) +- [internal/repository/ota.go:11-17](file://internal/repository/ota.go#L11-L17) - [internal/cache/brand_cache.go:18-24](file://internal/cache/brand_cache.go#L18-L24) - [internal/cache/model_cache.go:19-25](file://internal/cache/model_cache.go#L19-L25) @@ -468,15 +760,24 @@ MD_CACHE --> REDIS_CLIENT - **查询优化** - BrandRepository:按名称模糊匹配,建议在 name 上建立合适索引;对大结果集引入分页。 - ModelRepository:按品牌名精确匹配或按型号名模糊匹配,建议为 brand_name 与 name 建立索引;对大结果集引入分页。 + - DeviceRepository:user_device 表的 MAC 地址建立唯一索引,user_active 表建立复合索引(mac_addr, active_date)。 + - OTARepository:ota 表建立复合索引(model, hw, beta, status),black_list 表建立索引(ota_id, mac),ota_target_device 表建立索引(ota_id, mac_addr)。 - 应用层过滤:在缓存命中时进行过滤,减少数据库压力。 - **并发安全** - *sql.DB 是并发安全的,可在多个 goroutine 中共享使用;Repository 实例不持有状态,亦可并发安全使用。 - Redis 客户端是并发安全的,支持多goroutine同时访问。 + - 设备持久化任务使用独立的 goroutine 执行,避免阻塞主线程。 - **资源清理** - 使用 defer rows.Close() 保证结果集关闭;在 main 中 defer db.Close() 保证应用退出时关闭连接池。 - Redis 连接在应用退出时自动关闭。 + - 设备持久化任务使用 time.Ticker,确保正确停止。 - **事务处理** - 当前实现均为只读查询,未涉及事务;如需写操作,应在 Repository 层封装事务,使用 sql.Tx 并在错误时回滚,成功时提交。 + - 设备持久化任务采用幂等设计,避免重复处理造成的数据不一致。 +- **异步处理优化** + - 设备信息上报采用异步持久化,提高响应速度 + - Redis Hash 存储大量设备数据,内存占用较高,需监控内存使用情况 + - 定时任务间隔可根据数据量调整,平衡实时性和系统负载 **章节来源** - [internal/database/mysql.go:33-43](file://internal/database/mysql.go#L33-L43) @@ -484,6 +785,8 @@ MD_CACHE --> REDIS_CLIENT - [internal/cache/model_cache.go:13-16](file://internal/cache/model_cache.go#L13-L16) - [internal/repository/brand.go:23-52](file://internal/repository/brand.go#L23-L52) - [internal/repository/model.go:23-79](file://internal/repository/model.go#L23-L79) +- [internal/repository/device.go:19-87](file://internal/repository/device.go#L19-L87) +- [internal/repository/ota.go:19-158](file://internal/repository/ota.go#L19-L158) - [cmd/server/main.go:103-130](file://cmd/server/main.go#L103-L130) ## 故障排查指南 @@ -493,40 +796,54 @@ MD_CACHE --> REDIS_CLIENT - **Redis 连接失败** - 现象:应用启动时无法连接 Redis 或缓存预热失败。 - 排查:检查 REDIS_HOST/REDIS_PORT/REDIS_PASSWORD/REDIS_DATABASE 等环境变量;确认 Redis 服务正常运行;验证认证信息正确。 +- **设备持久化失败** + - 现象:设备信息上报成功但数据库中无数据。 + - 排查:检查设备持久化任务日志,确认Redis连接正常;验证user_device和user_active表结构;检查JSON数据格式;确认定时任务正常运行。 +- **OTA查询错误** + - 现象:OTA升级查询返回错误或结果不符合预期。 + - 排查:检查OTA表数据完整性,确认status=1且有效时间范围内;验证黑名单和定向设备表数据;检查参数传递(model、hw、beta、mac)。 - **缓存查询错误** - 现象:Handler 返回内部错误或缓存数据格式异常。 - 排查:查看日志中错误上下文(cache read/write/brand/model),定位具体环节;检查 Redis 连接状态;确认缓存数据格式正确。 - **查询错误** - 现象:Handler 返回内部错误。 - - 排查:查看日志中错误上下文(query brand/query model/scan brand/scan model/iterate brand/iterate model),定位具体环节;检查 SQL 参数绑定与字段映射。 + - 排查:查看日志中错误上下文(query brand/query model/device/ota/scan brand/scan model/iterate brand/iterate model),定位具体环节;检查 SQL 参数绑定与字段映射。 - **结果为空** - - 现象:ModelRepository 在两种条件都为空时返回空切片。 - - 排查:确认传入的查询参数是否正确;检查表中是否存在匹配数据。 + - 现象:DeviceRepository 在查询设备或活跃信息时返回空值。 + - 排查:确认传入的查询参数是否正确;检查表中是否存在匹配数据;验证MAC地址格式。 - **资源泄漏** - 现象:长时间运行后连接数异常。 - 排查:确认是否遗漏 rows.Close();检查连接池配置是否合理;观察连接生命周期与空闲连接上限。 - **缓存未命中** - 现象:频繁出现缓存未命中,数据库压力过大。 - 排查:检查缓存键是否正确;确认 TTL 设置是否合理;验证缓存预热是否成功;检查 Redis 内存使用情况。 +- **性能问题** + - 现象:OTA查询响应慢或设备持久化延迟。 + - 排查:检查相关表的索引是否完整;监控Redis内存使用;评估定时任务执行频率;分析数据库查询计划。 **章节来源** - [internal/config/database.go:17-72](file://internal/config/database.go#L17-L72) - [internal/config/redis.go:16-57](file://internal/config/redis.go#L16-L57) - [internal/handler/brand.go:25-48](file://internal/handler/brand.go#L25-L48) - [internal/handler/model.go:25-49](file://internal/handler/model.go#L25-L49) +- [internal/handler/device.go:27-82](file://internal/handler/device.go#L27-L82) +- [internal/handler/ota.go:23-132](file://internal/handler/ota.go#L23-L132) - [internal/repository/brand.go:23-52](file://internal/repository/brand.go#L23-L52) - [internal/repository/model.go:23-79](file://internal/repository/model.go#L23-L79) +- [internal/repository/device.go:19-87](file://internal/repository/device.go#L19-L87) +- [internal/repository/ota.go:19-158](file://internal/repository/ota.go#L19-L158) ## 结论 -Luxsin 的数据访问层经过重构后,采用了更加完善的缓存感知查询逻辑,实现了多级缓存策略和智能数据刷新机制。通过集成 Redis 缓存层,显著提升了查询性能和系统可用性。缓存感知查询逻辑、智能降级策略、预热机制和自动回写功能共同构成了一个健壮的数据访问层。建议后续继续优化缓存策略,增加缓存监控指标,完善缓存失效和更新机制,并持续改进监控与日志体系。 +Luxsin 的数据访问层经过重构后,采用了更加完善的缓存感知查询逻辑,实现了多级缓存策略和智能数据刷新机制。新增的设备持久化仓库和OTA仓库进一步完善了数据访问层的功能,支持设备信息上报、固件升级查询等核心业务场景。通过集成 Redis 缓存层和异步持久化任务,显著提升了系统的响应性能和数据可靠性。缓存感知查询逻辑、智能降级策略、预热机制、自动回写功能和异步数据同步共同构成了一个健壮、高效的现代化数据访问层。建议后续继续优化缓存策略,增加缓存监控指标,完善缓存失效和更新机制,并持续改进监控与日志体系。 ## 附录:扩展新 Repository 指南 - **设计原则** - 保持 Repository 无状态,仅依赖 *sql.DB 和缓存实例。 - 查询方法接收 context.Context,便于超时与取消控制。 - 对外返回领域模型(Model),避免直接暴露数据库结构。 - - 对可空字段使用 sql.NullString 到指针字符串的安全转换。 + - 对可空字段使用 sql.NullString、sql.NullInt64、sql.NullTime 等安全转换。 - 集成缓存感知查询逻辑,提供智能降级和自动回写功能。 + - 考虑异步处理场景,设计幂等的持久化逻辑。 - **实现步骤** - 定义领域模型(Model)与 Repository 接口/实现。 - 创建对应的缓存结构体,定义缓存键和TTL策略。 @@ -534,6 +851,7 @@ Luxsin 的数据访问层经过重构后,采用了更加完善的缓存感知 - 在路由中注册对应处理器。 - 在 main 中确保 *sql.DB 和缓存实例注入到 Handler。 - 实现缓存预热逻辑,确保应用启动时缓存可用。 + - 如涉及异步处理,实现独立的任务调度器。 - **注意事项** - 必须在每个查询后 defer rows.Close()。 - 使用 fmt.Errorf 包裹底层错误,保留调用栈信息。 @@ -543,13 +861,19 @@ Luxsin 的数据访问层经过重构后,采用了更加完善的缓存感知 - 实现缓存降级机制,确保Redis异常时系统仍可正常工作。 - 设计合理的缓存键和TTL策略,平衡性能和数据新鲜度。 - 实现缓存预热和自动回写机制,提升用户体验。 + - 异步任务需考虑幂等性,避免重复处理造成数据不一致。 + - 监控异步任务的执行状态和错误日志。 **章节来源** - [internal/repository/brand.go:14-21](file://internal/repository/brand.go#L14-L21) - [internal/repository/model.go:14-21](file://internal/repository/model.go#L14-L21) +- [internal/repository/device.go:11-17](file://internal/repository/device.go#L11-L17) +- [internal/repository/ota.go:11-17](file://internal/repository/ota.go#L11-L17) - [internal/cache/brand_cache.go:18-24](file://internal/cache/brand_cache.go#L18-L24) - [internal/cache/model_cache.go:19-25](file://internal/cache/model_cache.go#L19-L25) - [internal/handler/brand.go:19-24](file://internal/handler/brand.go#L19-L24) - [internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24) +- [internal/handler/device.go:15-25](file://internal/handler/device.go#L15-L25) +- [internal/handler/ota.go:14-21](file://internal/handler/ota.go#L14-L21) - [internal/router/router.go:22-25](file://internal/router/router.go#L22-L25) - [cmd/server/main.go:103-130](file://cmd/server/main.go#L103-L130) \ No newline at end of file diff --git a/.qoder/repowiki/zh/meta/repowiki-metadata.json b/.qoder/repowiki/zh/meta/repowiki-metadata.json index 4b91693..b4a883c 100644 --- a/.qoder/repowiki/zh/meta/repowiki-metadata.json +++ b/.qoder/repowiki/zh/meta/repowiki-metadata.json @@ -1 +1 @@ -{"code_snippets":[{"id":"333405ee9924108619cd8443f735d754","path":"internal/router/router.go","line_range":"16-52","gmt_create":"2026-05-27T18:35:29.892946+08:00","gmt_modified":"2026-05-27T18:35:29.892946+08:00"},{"id":"6eda76d6eb6015250ec186fdafd0b3c9","path":"cmd/server/main.go","line_range":"59-70","gmt_create":"2026-05-27T18:35:29.8934805+08:00","gmt_modified":"2026-05-27T18:35:29.8934805+08:00"},{"id":"553e943cfb2f6b7752122999084a80a5","path":"internal/cache/brand_cache.go","line_range":"18-44","gmt_create":"2026-05-27T18:35:29.8940514+08:00","gmt_modified":"2026-05-27T18:35:29.8940514+08:00"},{"id":"d7c4ecf9c38df06865431d0dcd796162","path":"internal/cache/model_cache.go","line_range":"19-69","gmt_create":"2026-05-27T18:35:29.8940514+08:00","gmt_modified":"2026-05-27T18:35:29.8940514+08:00"},{"id":"5ec84f3864f3fa2c3ab1d97fe69d5529","path":"internal/repository/brand.go","line_range":"14-52","gmt_create":"2026-05-27T18:35:29.8940514+08:00","gmt_modified":"2026-05-27T18:35:29.8940514+08:00"},{"id":"468dd8105671ed478ff86ca97c0609ba","path":"internal/repository/model.go","line_range":"14-79","gmt_create":"2026-05-27T18:35:29.8946006+08:00","gmt_modified":"2026-05-27T18:35:29.8946006+08:00"},{"id":"a0b3e000a5b789bf08d2d996fc17d8df","path":"cmd/server/main.go","line_range":"25-101","gmt_create":"2026-05-27T18:35:29.895175+08:00","gmt_modified":"2026-05-27T18:35:29.895175+08:00"},{"id":"111557d31227afead72d0f01becea3bc","path":"README.md","line_range":"19-123","gmt_create":"2026-05-27T18:35:29.895175+08:00","gmt_modified":"2026-05-27T18:35:29.895175+08:00"},{"id":"5db111a430cac488cabeb543494fb917","path":"internal/response/response.go","line_range":"15-36","gmt_create":"2026-05-27T18:35:29.895702+08:00","gmt_modified":"2026-05-27T18:35:29.895702+08:00"},{"id":"891c848d9153926513b9005f2d61382e","path":"internal/middleware/logger.go","line_range":"10-44","gmt_create":"2026-05-27T18:35:29.8962367+08:00","gmt_modified":"2026-05-27T18:35:29.8962367+08:00"},{"id":"8a6a9ea04bb9b0de8fd0195ca491b154","path":"internal/middleware/request_id.go","line_range":"20-29","gmt_create":"2026-05-27T18:35:29.8962367+08:00","gmt_modified":"2026-05-27T18:35:29.8962367+08:00"},{"id":"99d2500a6a0922c50675ed247c6777e5","path":"internal/middleware/cors.go","line_range":"7-19","gmt_create":"2026-05-27T18:35:29.8962367+08:00","gmt_modified":"2026-05-27T18:35:29.8962367+08:00"},{"id":"c86c8f1c951956c0397e6c938ccc641c","path":"internal/router/router.go","line_range":"23-36","gmt_create":"2026-05-27T18:35:29.897306+08:00","gmt_modified":"2026-05-27T18:35:29.897306+08:00"},{"id":"99701e03d9c9476a15f742b82e5adfa5","path":"internal/cache/brand_cache.go","line_range":"13-44","gmt_create":"2026-05-27T18:35:29.8978401+08:00","gmt_modified":"2026-05-27T18:35:29.8978401+08:00"},{"id":"a072f4ebff3b6cc9eaf8025737ca42d3","path":"internal/cache/model_cache.go","line_range":"13-69","gmt_create":"2026-05-27T18:35:29.8978401+08:00","gmt_modified":"2026-05-27T18:35:29.8978401+08:00"},{"id":"d4f94a6e4a0cd46ebc0c5f03e96c6232","path":"internal/router/router.go","line_range":"38-49","gmt_create":"2026-05-27T18:35:29.8983769+08:00","gmt_modified":"2026-05-27T18:35:29.8983769+08:00"},{"id":"0a2840d641ba5dccfff95a35d7317004","path":"README.md","line_range":"83-110","gmt_create":"2026-05-27T18:35:29.8983769+08:00","gmt_modified":"2026-05-27T18:35:29.8983769+08:00"},{"id":"491bd71f42db0fd5bf1d4851b9c4aaa9","path":"internal/handler/health.go","line_range":"14-18","gmt_create":"2026-05-27T18:35:29.8994388+08:00","gmt_modified":"2026-05-27T18:35:29.8994388+08:00"},{"id":"fce5662f14aa6386a5036b5241e00b1c","path":"internal/response/response.go","line_range":"15-21","gmt_create":"2026-05-27T18:35:29.8999721+08:00","gmt_modified":"2026-05-27T18:35:29.8999721+08:00"},{"id":"7e3954c3e70a9252de9cfdec52ed93c8","path":"internal/handler/brand.go","line_range":"25-48","gmt_create":"2026-05-27T18:35:29.8999721+08:00","gmt_modified":"2026-05-27T18:35:29.8999721+08:00"},{"id":"79304ed9558f17f9ecb0dc7d24add547","path":"pkg/encode/base64.go","line_range":"44-51","gmt_create":"2026-05-27T18:35:29.9005171+08:00","gmt_modified":"2026-05-27T18:35:29.9005171+08:00"},{"id":"a6d16b8965ed7f207f19f8f915ad53a4","path":"internal/handler/model.go","line_range":"25-49","gmt_create":"2026-05-27T18:35:29.9005171+08:00","gmt_modified":"2026-05-27T18:35:29.9005171+08:00"},{"id":"fce0c17d6c03e511c3afeaee662ad34f","path":"internal/handler/model_list.go","line_range":"26-56","gmt_create":"2026-05-27T18:35:29.9010627+08:00","gmt_modified":"2026-05-27T18:35:29.9010627+08:00"},{"id":"d4bd0610a0ad3d8fd8d33ac5f4aa83b5","path":"internal/handler/device.go","line_range":"26-84","gmt_create":"2026-05-27T18:35:29.901596+08:00","gmt_modified":"2026-05-27T18:35:29.901596+08:00"},{"id":"1be2a5a025cb64eeb20d5e54d293203f","path":"internal/middleware/logger.go","line_range":"33-43","gmt_create":"2026-05-27T18:35:29.9037303+08:00","gmt_modified":"2026-05-27T18:35:29.9037303+08:00"},{"id":"5f4eb9799d6c811ddcc430f51e299cf6","path":"internal/middleware/request_id.go","line_range":"22-27","gmt_create":"2026-05-27T18:35:29.9037303+08:00","gmt_modified":"2026-05-27T18:35:29.9037303+08:00"},{"id":"be85f7cf4e9dd0c2460475b95efb085d","path":"internal/middleware/cors.go","line_range":"9-12","gmt_create":"2026-05-27T18:35:29.9042675+08:00","gmt_modified":"2026-05-27T18:35:29.9042675+08:00"},{"id":"730d8469648c9599ccbc091a9496d2a1","path":"internal/response/response.go","line_range":"23-36","gmt_create":"2026-05-27T18:35:29.9042675+08:00","gmt_modified":"2026-05-27T18:35:29.9042675+08:00"},{"id":"d48bcd5374602483c104c7d50c7224fb","path":"internal/router/router.go","line_range":"18-21","gmt_create":"2026-05-27T18:35:29.9062656+08:00","gmt_modified":"2026-05-27T18:35:29.9062656+08:00"},{"id":"798bc9e7f1a3902993b3aa9acba73022","path":"internal/middleware/logger.go","line_range":"16","gmt_create":"2026-05-27T18:35:29.9067927+08:00","gmt_modified":"2026-05-27T18:35:29.9067927+08:00"},{"id":"ed43fe99536e371ce908f167a68124f8","path":"internal/middleware/request_id.go","line_range":"28","gmt_create":"2026-05-27T18:35:29.9073213+08:00","gmt_modified":"2026-05-27T18:35:29.9073213+08:00"},{"id":"08c02a0d77d871b6c9650cbfcdf84c94","path":"internal/middleware/cors.go","line_range":"18","gmt_create":"2026-05-27T18:35:29.9073213+08:00","gmt_modified":"2026-05-27T18:35:29.9073213+08:00"},{"id":"e88b0ee062bd02dd7acdf8e2e945b270","path":"cmd/server/main.go","line_range":"103-130","gmt_create":"2026-05-27T18:35:29.9078603+08:00","gmt_modified":"2026-05-27T18:35:29.9078603+08:00"},{"id":"64381887b12f6927d8b0481a55c2dcf1","path":"internal/router/router.go","line_range":"22-25","gmt_create":"2026-05-27T18:35:41.7314752+08:00","gmt_modified":"2026-05-27T18:35:41.7314752+08:00"},{"id":"1503a99bb2f2ab96e4a3a830d8834e45","path":"internal/handler/brand.go","line_range":"19-24","gmt_create":"2026-05-27T18:35:41.7314752+08:00","gmt_modified":"2026-05-27T18:35:41.7314752+08:00"},{"id":"f74cdc773e62a1a9f5a4bf940b5961e3","path":"internal/handler/model.go","line_range":"19-24","gmt_create":"2026-05-27T18:35:41.7320175+08:00","gmt_modified":"2026-05-27T18:35:41.7320175+08:00"},{"id":"8b0db394a538b6652de2e6634277ad0f","path":"internal/repository/brand.go","line_range":"14-21","gmt_create":"2026-05-27T18:35:41.7320175+08:00","gmt_modified":"2026-05-27T18:35:41.7320175+08:00"},{"id":"03f26c7c55e18e6266ea8e543a032229","path":"internal/repository/model.go","line_range":"14-21","gmt_create":"2026-05-27T18:35:41.7325394+08:00","gmt_modified":"2026-05-27T18:35:41.7325394+08:00"},{"id":"8fab617bba600779abac7805723180a0","path":"internal/cache/brand_cache.go","line_range":"18-24","gmt_create":"2026-05-27T18:35:41.7325394+08:00","gmt_modified":"2026-05-27T18:35:41.7325394+08:00"},{"id":"006d91f2f5f75fd7cd586165c200ba98","path":"internal/cache/model_cache.go","line_range":"19-25","gmt_create":"2026-05-27T18:35:41.7325394+08:00","gmt_modified":"2026-05-27T18:35:41.7325394+08:00"},{"id":"509525e0463c03c509709a6bd1765d4f","path":"internal/cache/redis.go","line_range":"10-16","gmt_create":"2026-05-27T18:35:41.7330685+08:00","gmt_modified":"2026-05-27T18:35:41.7330685+08:00"},{"id":"57b8aed283762226a00482b42a8acf5b","path":"internal/database/mysql.go","line_range":"14-46","gmt_create":"2026-05-27T18:35:41.7330685+08:00","gmt_modified":"2026-05-27T18:35:41.7330685+08:00"},{"id":"4ab082407b96e18f67a65d07eb4a331d","path":"internal/config/database.go","line_range":"17-40","gmt_create":"2026-05-27T18:35:41.7330685+08:00","gmt_modified":"2026-05-27T18:35:41.7330685+08:00"},{"id":"fd2a12d243b52512003ae067f53a7548","path":"internal/config/redis.go","line_range":"9-57","gmt_create":"2026-05-27T18:35:41.7335924+08:00","gmt_modified":"2026-05-27T18:35:41.7335924+08:00"},{"id":"61d69bf4d3c8c548eecfd677394486d6","path":"internal/config/config.go","line_range":"18-52","gmt_create":"2026-05-27T18:35:41.7335924+08:00","gmt_modified":"2026-05-27T18:35:41.7335924+08:00"},{"id":"e87c932ace50951cb91aa66877ad6f81","path":"sql/model.sql","line_range":"24-35","gmt_create":"2026-05-27T18:35:41.7341274+08:00","gmt_modified":"2026-05-27T18:35:41.7341274+08:00"},{"id":"90226e287e9b66f5a36ba2316d7a7cd7","path":"internal/router/router.go","line_range":"14-41","gmt_create":"2026-05-27T18:35:41.7341274+08:00","gmt_modified":"2026-05-27T18:35:41.7341274+08:00"},{"id":"9918f39149aaf1f5c3ec03275d6e3673","path":"internal/repository/brand.go","line_range":"23-52","gmt_create":"2026-05-27T18:35:41.7373036+08:00","gmt_modified":"2026-05-27T18:35:41.7373036+08:00"},{"id":"a19fb2ac137e43d92d2ef93e8d79f0a7","path":"internal/repository/model.go","line_range":"23-79","gmt_create":"2026-05-27T18:35:41.7378291+08:00","gmt_modified":"2026-05-27T18:35:41.7378291+08:00"},{"id":"72322f320f907b6eec72e885e30759eb","path":"internal/cache/brand_cache.go","line_range":"26-44","gmt_create":"2026-05-27T18:35:41.7385763+08:00","gmt_modified":"2026-05-27T18:35:41.7385763+08:00"},{"id":"d0f658c42abae9b6dc0baaa8fc7d0694","path":"internal/cache/model_cache.go","line_range":"31-69","gmt_create":"2026-05-27T18:35:41.7385763+08:00","gmt_modified":"2026-05-27T18:35:41.7385763+08:00"},{"id":"a952e5d5b625754a2e9249983bb8abaa","path":"internal/config/database.go","line_range":"17-72","gmt_create":"2026-05-27T18:35:41.7391229+08:00","gmt_modified":"2026-05-27T18:35:41.7391229+08:00"},{"id":"f7af3a1998c24f922aa650a69b252734","path":"internal/config/redis.go","line_range":"16-57","gmt_create":"2026-05-27T18:35:41.739651+08:00","gmt_modified":"2026-05-27T18:35:41.739651+08:00"},{"id":"c7bf654a5faf00b02953d2e56747a669","path":"internal/database/mysql.go","line_range":"28-43","gmt_create":"2026-05-27T18:35:41.7417727+08:00","gmt_modified":"2026-05-27T18:35:41.7417727+08:00"},{"id":"1d3714bd55d5d3f773f1ab7fdb8c9b53","path":"internal/model/brand.go","line_range":"3-6","gmt_create":"2026-05-27T18:35:41.7422949+08:00","gmt_modified":"2026-05-27T18:35:41.7422949+08:00"},{"id":"8d92ac14c6257462a15eb6990dd44596","path":"internal/model/model.go","line_range":"5-14","gmt_create":"2026-05-27T18:35:41.7439044+08:00","gmt_modified":"2026-05-27T18:35:41.7439044+08:00"},{"id":"8b134235408cf40b9d6351d54591b3c4","path":"sql/model.sql","line_range":"34","gmt_create":"2026-05-27T18:35:41.7449566+08:00","gmt_modified":"2026-05-27T18:35:41.7449566+08:00"},{"id":"62d02336da9111eec3c5696aabf71927","path":"internal/cache/brand_cache.go","line_range":"13-16","gmt_create":"2026-05-27T18:35:41.746537+08:00","gmt_modified":"2026-05-27T18:35:41.746537+08:00"},{"id":"a60ecb63d9ab3bda0c5042f26916def3","path":"internal/cache/model_cache.go","line_range":"13-16","gmt_create":"2026-05-27T18:35:41.7475474+08:00","gmt_modified":"2026-05-27T18:35:41.7475474+08:00"},{"id":"5859dc43ab95b589fc2cada49ab59a86","path":"go.mod","line_range":"5-11","gmt_create":"2026-05-27T18:35:41.7475474+08:00","gmt_modified":"2026-05-27T18:35:41.7475474+08:00"},{"id":"dcc3acd0529002f62657a37922318e37","path":"cmd/server/main.go","line_range":"25-69","gmt_create":"2026-05-27T18:35:41.7475474+08:00","gmt_modified":"2026-05-27T18:35:41.7475474+08:00"},{"id":"99ead368ce42f1081e05c800c65b176f","path":"internal/database/mysql.go","line_range":"33-43","gmt_create":"2026-05-27T18:35:41.7539267+08:00","gmt_modified":"2026-05-27T18:35:41.7539267+08:00"},{"id":"a5fb1691af5646ea8b4306ae97288e36","path":"internal/handler/health.go","line_range":"10","gmt_create":"2026-05-27T18:35:49.7681131+08:00","gmt_modified":"2026-05-27T18:35:49.7681131+08:00"},{"id":"de87fa33e6add38c027478dd3d0cebda","path":"internal/handler/brand.go","line_range":"18","gmt_create":"2026-05-27T18:35:49.7681131+08:00","gmt_modified":"2026-05-27T18:35:49.7681131+08:00"},{"id":"09427d743a4be750f874418ab3e8504d","path":"internal/handler/model.go","line_range":"18","gmt_create":"2026-05-27T18:35:49.76864+08:00","gmt_modified":"2026-05-27T18:35:49.76864+08:00"},{"id":"9ebb4688793526b520ec263ebf651be7","path":"internal/handler/model_list.go","line_range":"19","gmt_create":"2026-05-27T18:35:49.76864+08:00","gmt_modified":"2026-05-27T18:35:49.76864+08:00"},{"id":"5e813130e7885527f77be92dbbaee9b6","path":"internal/handler/device.go","line_range":"19","gmt_create":"2026-05-27T18:35:49.769172+08:00","gmt_modified":"2026-05-27T18:35:49.769172+08:00"},{"id":"1992aa29a2869c31fe69ac701541c6ff","path":"internal/handler/health.go","line_range":"8-19","gmt_create":"2026-05-27T18:35:49.7696957+08:00","gmt_modified":"2026-05-27T18:35:49.7696957+08:00"},{"id":"692a2c6d49d4eb62f58600908dff9f60","path":"internal/handler/brand.go","line_range":"13-23","gmt_create":"2026-05-27T18:35:49.7696957+08:00","gmt_modified":"2026-05-27T18:35:49.7696957+08:00"},{"id":"c9df5e7b8533af65ce97cf085b6589a9","path":"internal/handler/model.go","line_range":"13-23","gmt_create":"2026-05-27T18:35:49.7702757+08:00","gmt_modified":"2026-05-27T18:35:49.7702757+08:00"},{"id":"d2fd0586bf019047d2adbcdf90e09224","path":"internal/handler/model_list.go","line_range":"14-24","gmt_create":"2026-05-27T18:35:49.7702757+08:00","gmt_modified":"2026-05-27T18:35:49.7702757+08:00"},{"id":"bf1f0d1dece713e866e4a46be7784473","path":"internal/handler/device.go","line_range":"14-24","gmt_create":"2026-05-27T18:35:49.7708+08:00","gmt_modified":"2026-05-27T18:35:49.7708+08:00"},{"id":"c600af69dac497c7cf059a4bb2f033fc","path":"internal/router/router.go","line_range":"32-36","gmt_create":"2026-05-27T18:35:49.7708+08:00","gmt_modified":"2026-05-27T18:35:49.7708+08:00"},{"id":"bc6f53b403231c0f908654d3fea2102a","path":"internal/handler/brand.go","line_range":"29","gmt_create":"2026-05-27T18:35:49.7708+08:00","gmt_modified":"2026-05-27T18:35:49.7708+08:00"},{"id":"7b39881baafeaea08adce31120b7c1e1","path":"internal/handler/model.go","line_range":"30","gmt_create":"2026-05-27T18:35:49.7713218+08:00","gmt_modified":"2026-05-27T18:35:49.7713218+08:00"},{"id":"dbe385204072d26c84bf169842961690","path":"internal/handler/model_list.go","line_range":"37","gmt_create":"2026-05-27T18:35:49.7713218+08:00","gmt_modified":"2026-05-27T18:35:49.7713218+08:00"},{"id":"2a723ed48cd9855068a04da6a33cb5e4","path":"internal/handler/device.go","line_range":"71","gmt_create":"2026-05-27T18:35:49.7718468+08:00","gmt_modified":"2026-05-27T18:35:49.7718468+08:00"},{"id":"d72b0eafdb65d1d946060cf944359251","path":"internal/search/meilisearch.go","line_range":"22-45","gmt_create":"2026-05-27T18:35:49.7723711+08:00","gmt_modified":"2026-05-27T18:35:49.7723711+08:00"},{"id":"1eb8f107de13e2ad7eaed3bd6cf20a3a","path":"internal/router/router.go","line_range":"40","gmt_create":"2026-05-27T18:35:49.7728957+08:00","gmt_modified":"2026-05-27T18:35:49.7728957+08:00"},{"id":"72195f4e7a76b584cbdfbaba23db2a1a","path":"internal/model/brand.go","line_range":"3-7","gmt_create":"2026-05-27T18:35:49.7739534+08:00","gmt_modified":"2026-05-27T18:35:49.7739534+08:00"},{"id":"3e3a148f4095f6d36c64b1cfb3d1702a","path":"internal/handler/brand.go","line_range":"13-48","gmt_create":"2026-05-27T18:35:49.7739534+08:00","gmt_modified":"2026-05-27T18:35:49.7739534+08:00"},{"id":"3c27d9274287839faa5269c34b98b6a9","path":"internal/model/model.go","line_range":"5-15","gmt_create":"2026-05-27T18:35:49.7755123+08:00","gmt_modified":"2026-05-27T18:35:49.7755123+08:00"},{"id":"e0ca219542426b9141a89063f7052b0c","path":"internal/handler/model.go","line_range":"13-49","gmt_create":"2026-05-27T18:35:49.7755123+08:00","gmt_modified":"2026-05-27T18:35:49.7755123+08:00"},{"id":"270fee7aef8f38c42409050388865f6d","path":"pkg/encode/base64.go","line_range":"35-51","gmt_create":"2026-05-27T18:35:49.7765552+08:00","gmt_modified":"2026-05-27T18:35:49.7765552+08:00"},{"id":"8cf065ea198e4e0d88af1863fcd6ac11","path":"internal/handler/model_list.go","line_range":"14-57","gmt_create":"2026-05-27T18:35:49.7770826+08:00","gmt_modified":"2026-05-27T18:35:49.7770826+08:00"},{"id":"b62090b5a8fe0cd95b332a46bb8eac3c","path":"internal/handler/device.go","line_range":"14-85","gmt_create":"2026-05-27T18:35:49.7775979+08:00","gmt_modified":"2026-05-27T18:35:49.7775979+08:00"},{"id":"3f830fae511ccf076a0f04192c9b4cbe","path":"cmd/server/main.go","line_range":"53-69","gmt_create":"2026-05-27T18:35:49.7775979+08:00","gmt_modified":"2026-05-27T18:35:49.7775979+08:00"},{"id":"d0f6f695e8187267487ad6b6fb8559b0","path":"internal/router/router.go","line_range":"16-36","gmt_create":"2026-05-27T18:35:49.7781224+08:00","gmt_modified":"2026-05-27T18:35:49.7781224+08:00"},{"id":"1b6991f54b135de9969d4b357dcce8e4","path":"cmd/server/main.go","line_range":"67-70","gmt_create":"2026-05-27T18:35:49.7791807+08:00","gmt_modified":"2026-05-27T18:35:49.7791807+08:00"},{"id":"86ac1fc7361002fc5d2c9f7b9b1ea754","path":"internal/router/router.go","line_range":"27-36","gmt_create":"2026-05-27T18:35:49.7797069+08:00","gmt_modified":"2026-05-27T18:35:49.7797069+08:00"},{"id":"bdfbf7d6f851540dee549606f7aca9d4","path":"internal/repository/brand.go","line_range":"19","gmt_create":"2026-05-27T18:35:49.7808022+08:00","gmt_modified":"2026-05-27T18:35:49.7808022+08:00"},{"id":"ba4653c42534e9835fb3db39fbfd5c06","path":"internal/repository/model.go","line_range":"19","gmt_create":"2026-05-27T18:35:49.7808022+08:00","gmt_modified":"2026-05-27T18:35:49.7808022+08:00"},{"id":"e5c6898e570c67346c0858cfeaa98fae","path":"internal/search/meilisearch.go","line_range":"17","gmt_create":"2026-05-27T18:35:49.7808022+08:00","gmt_modified":"2026-05-27T18:35:49.7808022+08:00"},{"id":"90b60f9dc283b0c2610ad113bc211315","path":"pkg/encode/base64.go","line_range":"8","gmt_create":"2026-05-27T18:35:49.7813263+08:00","gmt_modified":"2026-05-27T18:35:49.7813263+08:00"},{"id":"85820118c846a111e112dc705c071116","path":"internal/response/response.go","line_range":"9","gmt_create":"2026-05-27T18:35:49.7813263+08:00","gmt_modified":"2026-05-27T18:35:49.7813263+08:00"},{"id":"1041284bd46edf16a19f024c113d10b4","path":"internal/handler/brand.go","line_range":"30-34","gmt_create":"2026-05-27T18:35:49.7826173+08:00","gmt_modified":"2026-05-27T18:35:49.7826173+08:00"},{"id":"84be9fdffe58ef8cd5e77e0d3c37313b","path":"internal/handler/model.go","line_range":"31-35","gmt_create":"2026-05-27T18:35:49.7826173+08:00","gmt_modified":"2026-05-27T18:35:49.7826173+08:00"},{"id":"f034e5c72872862a675dd11e32404854","path":"internal/handler/model_list.go","line_range":"38-42","gmt_create":"2026-05-27T18:35:49.7831513+08:00","gmt_modified":"2026-05-27T18:35:49.7831513+08:00"},{"id":"df50e47a5b6541093011bb59b1ec831d","path":"internal/handler/device.go","line_range":"61-78","gmt_create":"2026-05-27T18:35:49.7831513+08:00","gmt_modified":"2026-05-27T18:35:49.7831513+08:00"},{"id":"0a425d8fed248deb7202bc7e8d531ca1","path":"internal/middleware/logger.go","line_range":"10-45","gmt_create":"2026-05-27T18:35:49.7836872+08:00","gmt_modified":"2026-05-27T18:35:49.7836872+08:00"},{"id":"d6d27b00ae4ab42348e74a7e7bf688b2","path":"internal/middleware/request_id.go","line_range":"20-31","gmt_create":"2026-05-27T18:35:49.7836872+08:00","gmt_modified":"2026-05-27T18:35:49.7836872+08:00"},{"id":"e9390185152783a55f55e277d45e6948","path":"cmd/server/main.go","line_range":"25-131","gmt_create":"2026-05-27T18:36:40.5088629+08:00","gmt_modified":"2026-05-27T18:36:40.5088629+08:00"},{"id":"a3cbc373dacd9d032ed0c72bca1e51e9","path":"internal/cache/brand_cache.go","line_range":"1-45","gmt_create":"2026-05-27T18:36:40.5088629+08:00","gmt_modified":"2026-05-27T18:36:40.5088629+08:00"},{"id":"d65e653afb8b211f2e5a7845f72b45dd","path":"internal/cache/model_cache.go","line_range":"1-70","gmt_create":"2026-05-27T18:36:40.5093857+08:00","gmt_modified":"2026-05-27T18:36:40.5093857+08:00"},{"id":"a26d903ac77196fac97ddebf48638ab3","path":"internal/repository/brand.go","line_range":"1-100","gmt_create":"2026-05-27T18:36:40.5093857+08:00","gmt_modified":"2026-05-27T18:36:40.5093857+08:00"},{"id":"7ffaf7b06ea96ca93862aa0dae926ff5","path":"internal/repository/model.go","line_range":"1-181","gmt_create":"2026-05-27T18:36:40.5093857+08:00","gmt_modified":"2026-05-27T18:36:40.5093857+08:00"},{"id":"187b4628003859e3da78f3937c686803","path":"internal/cache/brand_cache.go","line_range":"18-45","gmt_create":"2026-05-27T18:36:40.5109436+08:00","gmt_modified":"2026-05-27T18:36:40.5109436+08:00"},{"id":"a6c526ea58aabee86ae3010b00441c69","path":"internal/cache/model_cache.go","line_range":"19-70","gmt_create":"2026-05-27T18:36:40.5114567+08:00","gmt_modified":"2026-05-27T18:36:40.5114567+08:00"},{"id":"a364a8daa183eaf86417b4c1bd2cc719","path":"internal/repository/brand.go","line_range":"14-100","gmt_create":"2026-05-27T18:36:40.5114567+08:00","gmt_modified":"2026-05-27T18:36:40.5114567+08:00"},{"id":"2e040aabeb8e907eaddc6bbf2ee493ac","path":"internal/repository/model.go","line_range":"14-181","gmt_create":"2026-05-27T18:36:40.5114567+08:00","gmt_modified":"2026-05-27T18:36:40.5114567+08:00"},{"id":"3d315320639ece8212fd138420d94be5","path":"internal/handler/brand.go","line_range":"13-49","gmt_create":"2026-05-27T18:36:40.5120123+08:00","gmt_modified":"2026-05-27T18:36:40.5120123+08:00"},{"id":"fbf36e29345cd3e53fd3a6e8234ad2de","path":"internal/handler/model.go","line_range":"13-50","gmt_create":"2026-05-27T18:36:40.5120123+08:00","gmt_modified":"2026-05-27T18:36:40.5120123+08:00"},{"id":"32b7267a28b0347d59500c38ffa96a7b","path":"internal/cache/brand_cache.go","line_range":"13-45","gmt_create":"2026-05-27T18:36:40.5135974+08:00","gmt_modified":"2026-05-27T18:36:40.5135974+08:00"},{"id":"b9c3c517ffd917351757137ca1338574","path":"internal/cache/model_cache.go","line_range":"27-69","gmt_create":"2026-05-27T18:36:40.5141244+08:00","gmt_modified":"2026-05-27T18:36:40.5141244+08:00"},{"id":"df7d264896976fc8c5475257994c707e","path":"internal/cache/model_cache.go","line_range":"13-70","gmt_create":"2026-05-27T18:36:40.5141244+08:00","gmt_modified":"2026-05-27T18:36:40.5141244+08:00"},{"id":"a3b89d2e56d589f8d902fb9389004bf0","path":"cmd/server/main.go","line_range":"103-131","gmt_create":"2026-05-27T18:36:40.5141244+08:00","gmt_modified":"2026-05-27T18:36:40.5141244+08:00"},{"id":"f76ee32725201731512db1e0e7951586","path":"cmd/server/main.go","line_range":"67-68","gmt_create":"2026-05-27T18:36:40.5146452+08:00","gmt_modified":"2026-05-27T18:36:40.5146452+08:00"},{"id":"251d1b1dc197a1dc242f5384adb1555c","path":"internal/repository/brand.go","line_range":"34-52","gmt_create":"2026-05-27T18:36:40.5146452+08:00","gmt_modified":"2026-05-27T18:36:40.5146452+08:00"},{"id":"a51abc6a6d80413bf60f143cd1f46ee4","path":"internal/repository/model.go","line_range":"27-79","gmt_create":"2026-05-27T18:36:40.5146452+08:00","gmt_modified":"2026-05-27T18:36:40.5146452+08:00"},{"id":"f0b044854c85d50b2d1ba4b9d3e6a6cb","path":"internal/cache/model_cache.go","line_range":"13-17","gmt_create":"2026-05-27T18:36:40.5151635+08:00","gmt_modified":"2026-05-27T18:36:40.5151635+08:00"},{"id":"3f0d637bef43d636594a4816c9da037e","path":"internal/cache/brand_cache.go","line_range":"38-44","gmt_create":"2026-05-27T18:36:40.5151635+08:00","gmt_modified":"2026-05-27T18:36:40.5151635+08:00"},{"id":"3f945faea776f513b5294aa60759fb15","path":"internal/cache/model_cache.go","line_range":"43-69","gmt_create":"2026-05-27T18:36:40.5156806+08:00","gmt_modified":"2026-05-27T18:36:40.5156806+08:00"},{"id":"a272829cfc9c48e8063d8bca53cdebc8","path":"cmd/server/main.go","line_range":"13-23","gmt_create":"2026-05-27T18:36:40.5156806+08:00","gmt_modified":"2026-05-27T18:36:40.5156806+08:00"},{"id":"6d2fece0c97147748fd0269a356e4802","path":"internal/repository/brand.go","line_range":"3-12","gmt_create":"2026-05-27T18:36:40.5156806+08:00","gmt_modified":"2026-05-27T18:36:40.5156806+08:00"},{"id":"282a046f62f9715bfef882f5a4a6a362","path":"internal/router/router.go","line_range":"3-14","gmt_create":"2026-05-27T18:36:40.516202+08:00","gmt_modified":"2026-05-27T18:36:40.516202+08:00"}],"knowledge_relations":[{"id":1,"source_id":"ab98c251-c5f7-40df-bba1-21b2edf5d220","target_id":"523107ca-244f-43c5-a4fe-4649e36a88ad","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab98c251-c5f7-40df-bba1-21b2edf5d220 -\u003e 523107ca-244f-43c5-a4fe-4649e36a88ad","gmt_create":"2026-05-27T16:00:38.0397713+08:00","gmt_modified":"2026-05-27T16:00:38.0397713+08:00"},{"id":3,"source_id":"ab98c251-c5f7-40df-bba1-21b2edf5d220","target_id":"5910d326-0408-450d-b403-06a19f3da81b","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab98c251-c5f7-40df-bba1-21b2edf5d220 -\u003e 5910d326-0408-450d-b403-06a19f3da81b","gmt_create":"2026-05-27T16:00:38.0417677+08:00","gmt_modified":"2026-05-27T16:00:38.0417677+08:00"},{"id":4,"source_id":"ab98c251-c5f7-40df-bba1-21b2edf5d220","target_id":"e8e5fe7e-cc7c-4259-95d0-f6b46d888ed8","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab98c251-c5f7-40df-bba1-21b2edf5d220 -\u003e e8e5fe7e-cc7c-4259-95d0-f6b46d888ed8","gmt_create":"2026-05-27T16:00:38.0417677+08:00","gmt_modified":"2026-05-27T16:00:38.0417677+08:00"},{"id":5,"source_id":"ab98c251-c5f7-40df-bba1-21b2edf5d220","target_id":"5a04f737-b877-4908-a4fc-67a88614aafc","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab98c251-c5f7-40df-bba1-21b2edf5d220 -\u003e 5a04f737-b877-4908-a4fc-67a88614aafc","gmt_create":"2026-05-27T16:00:38.0427691+08:00","gmt_modified":"2026-05-27T16:00:38.0427691+08:00"},{"id":8,"source_id":"7563e383-3ea0-4630-baeb-e86efcaeefb8","target_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7563e383-3ea0-4630-baeb-e86efcaeefb8 -\u003e 97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","gmt_create":"2026-05-27T16:00:38.0437677+08:00","gmt_modified":"2026-05-27T16:00:38.0437677+08:00"},{"id":9,"source_id":"7563e383-3ea0-4630-baeb-e86efcaeefb8","target_id":"699a84c5-5140-4267-861e-62bffbffccb4","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7563e383-3ea0-4630-baeb-e86efcaeefb8 -\u003e 699a84c5-5140-4267-861e-62bffbffccb4","gmt_create":"2026-05-27T16:00:38.0442739+08:00","gmt_modified":"2026-05-27T16:00:38.0442739+08:00"},{"id":10,"source_id":"6159e8a9-0f6e-43af-b097-bfcd16c8b223","target_id":"6f1fe170-ae35-4660-91dc-ab89735274b7","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6159e8a9-0f6e-43af-b097-bfcd16c8b223 -\u003e 6f1fe170-ae35-4660-91dc-ab89735274b7","gmt_create":"2026-05-27T16:00:38.0452805+08:00","gmt_modified":"2026-05-27T16:00:38.0452805+08:00"},{"id":11,"source_id":"6159e8a9-0f6e-43af-b097-bfcd16c8b223","target_id":"6af33e3a-220d-4e68-87ed-bfb96bda4c3a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6159e8a9-0f6e-43af-b097-bfcd16c8b223 -\u003e 6af33e3a-220d-4e68-87ed-bfb96bda4c3a","gmt_create":"2026-05-27T16:00:38.0452805+08:00","gmt_modified":"2026-05-27T16:00:38.0452805+08:00"},{"id":12,"source_id":"6159e8a9-0f6e-43af-b097-bfcd16c8b223","target_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6159e8a9-0f6e-43af-b097-bfcd16c8b223 -\u003e e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","gmt_create":"2026-05-27T16:00:38.0452805+08:00","gmt_modified":"2026-05-27T16:00:38.0452805+08:00"},{"id":13,"source_id":"6159e8a9-0f6e-43af-b097-bfcd16c8b223","target_id":"0fc3d59c-d219-4f97-af10-473ee62f4de5","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6159e8a9-0f6e-43af-b097-bfcd16c8b223 -\u003e 0fc3d59c-d219-4f97-af10-473ee62f4de5","gmt_create":"2026-05-27T16:00:38.0462819+08:00","gmt_modified":"2026-05-27T16:00:38.0462819+08:00"},{"id":15,"source_id":"cfbcaa79-26f5-402f-8746-9fe524993684","target_id":"d0c2dea0-a71a-4f16-9889-b37e1e7996e3","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: cfbcaa79-26f5-402f-8746-9fe524993684 -\u003e d0c2dea0-a71a-4f16-9889-b37e1e7996e3","gmt_create":"2026-05-27T16:00:38.0462819+08:00","gmt_modified":"2026-05-27T16:00:38.0462819+08:00"},{"id":16,"source_id":"cfbcaa79-26f5-402f-8746-9fe524993684","target_id":"23a2ffc3-fa50-41ba-b7a6-55354d68a95a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: cfbcaa79-26f5-402f-8746-9fe524993684 -\u003e 23a2ffc3-fa50-41ba-b7a6-55354d68a95a","gmt_create":"2026-05-27T16:00:38.0472824+08:00","gmt_modified":"2026-05-27T16:00:38.0472824+08:00"},{"id":17,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"d2654fb48612d74ab0ccc06a3aede80b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/router/router.go","gmt_create":"2026-05-27T18:35:29.9094769+08:00","gmt_modified":"2026-05-27T18:35:29.9094769+08:00"},{"id":18,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"fd613068059c593ac4df9eaef2918055","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: cmd/server/main.go","gmt_create":"2026-05-27T18:35:29.9094769+08:00","gmt_modified":"2026-05-27T18:35:29.9094769+08:00"},{"id":19,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"336527cad207564e9ea86fcc4e0ec240","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/cors.go","gmt_create":"2026-05-27T18:35:29.9100157+08:00","gmt_modified":"2026-05-27T18:35:29.9100157+08:00"},{"id":20,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"f8a733666ceab6a73ba2bf3234e91222","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/logger.go","gmt_create":"2026-05-27T18:35:29.9100157+08:00","gmt_modified":"2026-05-27T18:35:29.9100157+08:00"},{"id":21,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"2ba2f740fa3334f7c6d51f74470ec4b7","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/request_id.go","gmt_create":"2026-05-27T18:35:29.9105584+08:00","gmt_modified":"2026-05-27T18:35:29.9105584+08:00"},{"id":22,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"a7b9800e6fc68baa0cfda9c8f327b423","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/health.go","gmt_create":"2026-05-27T18:35:29.9111006+08:00","gmt_modified":"2026-05-27T18:35:29.9111006+08:00"},{"id":23,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/brand.go","gmt_create":"2026-05-27T18:35:29.9111006+08:00","gmt_modified":"2026-05-27T18:35:29.9111006+08:00"},{"id":24,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"b18d19ca2c60406b9cd28010df12296d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model.go","gmt_create":"2026-05-27T18:35:29.9116443+08:00","gmt_modified":"2026-05-27T18:35:29.9116443+08:00"},{"id":25,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model_list.go","gmt_create":"2026-05-27T18:35:29.9116443+08:00","gmt_modified":"2026-05-27T18:35:29.9116443+08:00"},{"id":26,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"3a1babcf090301072327433866c0d7d0","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/device.go","gmt_create":"2026-05-27T18:35:29.9121832+08:00","gmt_modified":"2026-05-27T18:35:29.9121832+08:00"},{"id":27,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"703706c059a41213d3dbfbddc03fab12","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/response/response.go","gmt_create":"2026-05-27T18:35:29.9121832+08:00","gmt_modified":"2026-05-27T18:35:29.9121832+08:00"},{"id":28,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"0bba4121c12e2cf427dc805016fade40","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/config.go","gmt_create":"2026-05-27T18:35:29.9127279+08:00","gmt_modified":"2026-05-27T18:35:29.9127279+08:00"},{"id":29,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"80d716769cf67cd05b504a3bc0a06a92","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: pkg/encode/base64.go","gmt_create":"2026-05-27T18:35:29.9127279+08:00","gmt_modified":"2026-05-27T18:35:29.9127279+08:00"},{"id":30,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"67d9f7c1be7ff64bb9bca0a5f2492621","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: README.md","gmt_create":"2026-05-27T18:35:29.9127279+08:00","gmt_modified":"2026-05-27T18:35:29.9127279+08:00"},{"id":31,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"7bfaa93c0d23eed2727039a5bd3d9a07","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/redis.go","gmt_create":"2026-05-27T18:35:29.9127279+08:00","gmt_modified":"2026-05-27T18:35:29.9127279+08:00"},{"id":32,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"67d3253845127f03f1f9ebe3f6a6aaa3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/brand_cache.go","gmt_create":"2026-05-27T18:35:29.9137674+08:00","gmt_modified":"2026-05-27T18:35:29.9137674+08:00"},{"id":33,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"018b14cbce05561cfb50fe7e6e3835a3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/model_cache.go","gmt_create":"2026-05-27T18:35:29.9137674+08:00","gmt_modified":"2026-05-27T18:35:29.9137674+08:00"},{"id":34,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"276b4d58e492bc3f7c258914abb959e4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/brand.go","gmt_create":"2026-05-27T18:35:29.9137674+08:00","gmt_modified":"2026-05-27T18:35:29.9137674+08:00"},{"id":35,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"4ca752eb084c575a36939921aeeb9984","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/model.go","gmt_create":"2026-05-27T18:35:29.9137674+08:00","gmt_modified":"2026-05-27T18:35:29.9137674+08:00"},{"id":36,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"ac542a8b31381c132de78b921e3216d4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/redis.go","gmt_create":"2026-05-27T18:35:29.9137674+08:00","gmt_modified":"2026-05-27T18:35:29.9137674+08:00"},{"id":37,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"d2c7a50459a83c5ef23e809b0f194aba","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/meilisearch.go","gmt_create":"2026-05-27T18:35:29.9137674+08:00","gmt_modified":"2026-05-27T18:35:29.9137674+08:00"},{"id":38,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"333405ee9924108619cd8443f735d754","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#16-52","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":39,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"333405ee9924108619cd8443f735d754","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 16-52","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":40,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"6eda76d6eb6015250ec186fdafd0b3c9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#59-70","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":41,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"6eda76d6eb6015250ec186fdafd0b3c9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 59-70","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":42,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"553e943cfb2f6b7752122999084a80a5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#18-44","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":43,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"553e943cfb2f6b7752122999084a80a5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18-44","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":44,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"d7c4ecf9c38df06865431d0dcd796162","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#19-69","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":45,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"d7c4ecf9c38df06865431d0dcd796162","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-69","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":46,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"5ec84f3864f3fa2c3ab1d97fe69d5529","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#14-52","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":47,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"5ec84f3864f3fa2c3ab1d97fe69d5529","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-52","gmt_create":"2026-05-27T18:35:29.9181432+08:00","gmt_modified":"2026-05-27T18:35:29.9181432+08:00"},{"id":48,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"468dd8105671ed478ff86ca97c0609ba","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#14-79","gmt_create":"2026-05-27T18:35:29.9181432+08:00","gmt_modified":"2026-05-27T18:35:29.9181432+08:00"},{"id":49,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"468dd8105671ed478ff86ca97c0609ba","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-79","gmt_create":"2026-05-27T18:35:29.9186699+08:00","gmt_modified":"2026-05-27T18:35:29.9186699+08:00"},{"id":50,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"a0b3e000a5b789bf08d2d996fc17d8df","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#25-101","gmt_create":"2026-05-27T18:35:29.9191948+08:00","gmt_modified":"2026-05-27T18:35:29.9191948+08:00"},{"id":51,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"a0b3e000a5b789bf08d2d996fc17d8df","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 25-101","gmt_create":"2026-05-27T18:35:29.9191948+08:00","gmt_modified":"2026-05-27T18:35:29.9191948+08:00"},{"id":52,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"111557d31227afead72d0f01becea3bc","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: README.md#19-123","gmt_create":"2026-05-27T18:35:29.9197286+08:00","gmt_modified":"2026-05-27T18:35:29.9197286+08:00"},{"id":53,"source_id":"67d9f7c1be7ff64bb9bca0a5f2492621","target_id":"111557d31227afead72d0f01becea3bc","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-123","gmt_create":"2026-05-27T18:35:29.9197286+08:00","gmt_modified":"2026-05-27T18:35:29.9197286+08:00"},{"id":54,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"5db111a430cac488cabeb543494fb917","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#15-36","gmt_create":"2026-05-27T18:35:29.9202582+08:00","gmt_modified":"2026-05-27T18:35:29.9202582+08:00"},{"id":55,"source_id":"703706c059a41213d3dbfbddc03fab12","target_id":"5db111a430cac488cabeb543494fb917","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 15-36","gmt_create":"2026-05-27T18:35:29.9209575+08:00","gmt_modified":"2026-05-27T18:35:29.9209575+08:00"},{"id":56,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"891c848d9153926513b9005f2d61382e","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/logger.go#10-44","gmt_create":"2026-05-27T18:35:29.9214708+08:00","gmt_modified":"2026-05-27T18:35:29.9214708+08:00"},{"id":57,"source_id":"f8a733666ceab6a73ba2bf3234e91222","target_id":"891c848d9153926513b9005f2d61382e","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 10-44","gmt_create":"2026-05-27T18:35:29.9220086+08:00","gmt_modified":"2026-05-27T18:35:29.9220086+08:00"},{"id":58,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"8a6a9ea04bb9b0de8fd0195ca491b154","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/request_id.go#20-29","gmt_create":"2026-05-27T18:35:29.9220086+08:00","gmt_modified":"2026-05-27T18:35:29.9220086+08:00"},{"id":59,"source_id":"2ba2f740fa3334f7c6d51f74470ec4b7","target_id":"8a6a9ea04bb9b0de8fd0195ca491b154","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-29","gmt_create":"2026-05-27T18:35:29.9225391+08:00","gmt_modified":"2026-05-27T18:35:29.9225391+08:00"},{"id":60,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"99d2500a6a0922c50675ed247c6777e5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/cors.go#7-19","gmt_create":"2026-05-27T18:35:29.9225391+08:00","gmt_modified":"2026-05-27T18:35:29.9225391+08:00"},{"id":61,"source_id":"336527cad207564e9ea86fcc4e0ec240","target_id":"99d2500a6a0922c50675ed247c6777e5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 7-19","gmt_create":"2026-05-27T18:35:29.9230634+08:00","gmt_modified":"2026-05-27T18:35:29.9230634+08:00"},{"id":62,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"c86c8f1c951956c0397e6c938ccc641c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#23-36","gmt_create":"2026-05-27T18:35:29.9241149+08:00","gmt_modified":"2026-05-27T18:35:29.9241149+08:00"},{"id":63,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"c86c8f1c951956c0397e6c938ccc641c","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-36","gmt_create":"2026-05-27T18:35:29.9241149+08:00","gmt_modified":"2026-05-27T18:35:29.9241149+08:00"},{"id":64,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"99701e03d9c9476a15f742b82e5adfa5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#13-44","gmt_create":"2026-05-27T18:35:29.9241149+08:00","gmt_modified":"2026-05-27T18:35:29.9241149+08:00"},{"id":65,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"99701e03d9c9476a15f742b82e5adfa5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-44","gmt_create":"2026-05-27T18:35:29.9246449+08:00","gmt_modified":"2026-05-27T18:35:29.9246449+08:00"},{"id":66,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"a072f4ebff3b6cc9eaf8025737ca42d3","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#13-69","gmt_create":"2026-05-27T18:35:29.9251757+08:00","gmt_modified":"2026-05-27T18:35:29.9251757+08:00"},{"id":67,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"a072f4ebff3b6cc9eaf8025737ca42d3","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-69","gmt_create":"2026-05-27T18:35:29.9251757+08:00","gmt_modified":"2026-05-27T18:35:29.9251757+08:00"},{"id":68,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"d4f94a6e4a0cd46ebc0c5f03e96c6232","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#38-49","gmt_create":"2026-05-27T18:35:29.9257015+08:00","gmt_modified":"2026-05-27T18:35:29.9257015+08:00"},{"id":69,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"d4f94a6e4a0cd46ebc0c5f03e96c6232","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 38-49","gmt_create":"2026-05-27T18:35:29.9257015+08:00","gmt_modified":"2026-05-27T18:35:29.9257015+08:00"},{"id":70,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"0a2840d641ba5dccfff95a35d7317004","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: README.md#83-110","gmt_create":"2026-05-27T18:35:29.9262333+08:00","gmt_modified":"2026-05-27T18:35:29.9262333+08:00"},{"id":71,"source_id":"67d9f7c1be7ff64bb9bca0a5f2492621","target_id":"0a2840d641ba5dccfff95a35d7317004","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 83-110","gmt_create":"2026-05-27T18:35:29.9262333+08:00","gmt_modified":"2026-05-27T18:35:29.9262333+08:00"},{"id":72,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"491bd71f42db0fd5bf1d4851b9c4aaa9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/health.go#14-18","gmt_create":"2026-05-27T18:35:29.9273021+08:00","gmt_modified":"2026-05-27T18:35:29.9273021+08:00"},{"id":73,"source_id":"a7b9800e6fc68baa0cfda9c8f327b423","target_id":"491bd71f42db0fd5bf1d4851b9c4aaa9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-18","gmt_create":"2026-05-27T18:35:29.9273021+08:00","gmt_modified":"2026-05-27T18:35:29.9273021+08:00"},{"id":74,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"fce5662f14aa6386a5036b5241e00b1c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#15-21","gmt_create":"2026-05-27T18:35:29.9278475+08:00","gmt_modified":"2026-05-27T18:35:29.9278475+08:00"},{"id":75,"source_id":"703706c059a41213d3dbfbddc03fab12","target_id":"fce5662f14aa6386a5036b5241e00b1c","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 15-21","gmt_create":"2026-05-27T18:35:29.9278475+08:00","gmt_modified":"2026-05-27T18:35:29.9278475+08:00"},{"id":76,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"7e3954c3e70a9252de9cfdec52ed93c8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#25-48","gmt_create":"2026-05-27T18:35:29.9278475+08:00","gmt_modified":"2026-05-27T18:35:29.9278475+08:00"},{"id":77,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"7e3954c3e70a9252de9cfdec52ed93c8","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 25-48","gmt_create":"2026-05-27T18:35:29.9283823+08:00","gmt_modified":"2026-05-27T18:35:29.9283823+08:00"},{"id":78,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"79304ed9558f17f9ecb0dc7d24add547","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: pkg/encode/base64.go#44-51","gmt_create":"2026-05-27T18:35:29.9283823+08:00","gmt_modified":"2026-05-27T18:35:29.9283823+08:00"},{"id":79,"source_id":"80d716769cf67cd05b504a3bc0a06a92","target_id":"79304ed9558f17f9ecb0dc7d24add547","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 44-51","gmt_create":"2026-05-27T18:35:29.9289151+08:00","gmt_modified":"2026-05-27T18:35:29.9289151+08:00"},{"id":80,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"a6d16b8965ed7f207f19f8f915ad53a4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#25-49","gmt_create":"2026-05-27T18:35:29.9289151+08:00","gmt_modified":"2026-05-27T18:35:29.9289151+08:00"},{"id":81,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"a6d16b8965ed7f207f19f8f915ad53a4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 25-49","gmt_create":"2026-05-27T18:35:29.9289151+08:00","gmt_modified":"2026-05-27T18:35:29.9289151+08:00"},{"id":82,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"fce0c17d6c03e511c3afeaee662ad34f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#26-56","gmt_create":"2026-05-27T18:35:29.930006+08:00","gmt_modified":"2026-05-27T18:35:29.930006+08:00"},{"id":83,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"fce0c17d6c03e511c3afeaee662ad34f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 26-56","gmt_create":"2026-05-27T18:35:29.930006+08:00","gmt_modified":"2026-05-27T18:35:29.930006+08:00"},{"id":84,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"d4bd0610a0ad3d8fd8d33ac5f4aa83b5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#26-84","gmt_create":"2026-05-27T18:35:29.930538+08:00","gmt_modified":"2026-05-27T18:35:29.930538+08:00"},{"id":85,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"d4bd0610a0ad3d8fd8d33ac5f4aa83b5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 26-84","gmt_create":"2026-05-27T18:35:29.930538+08:00","gmt_modified":"2026-05-27T18:35:29.930538+08:00"},{"id":86,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"1be2a5a025cb64eeb20d5e54d293203f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/logger.go#33-43","gmt_create":"2026-05-27T18:35:29.9321249+08:00","gmt_modified":"2026-05-27T18:35:29.9321249+08:00"},{"id":87,"source_id":"f8a733666ceab6a73ba2bf3234e91222","target_id":"1be2a5a025cb64eeb20d5e54d293203f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 33-43","gmt_create":"2026-05-27T18:35:29.9326589+08:00","gmt_modified":"2026-05-27T18:35:29.9326589+08:00"},{"id":88,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"5f4eb9799d6c811ddcc430f51e299cf6","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/request_id.go#22-27","gmt_create":"2026-05-27T18:35:29.9326589+08:00","gmt_modified":"2026-05-27T18:35:29.9326589+08:00"},{"id":89,"source_id":"2ba2f740fa3334f7c6d51f74470ec4b7","target_id":"5f4eb9799d6c811ddcc430f51e299cf6","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 22-27","gmt_create":"2026-05-27T18:35:29.9331872+08:00","gmt_modified":"2026-05-27T18:35:29.9331872+08:00"},{"id":90,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"be85f7cf4e9dd0c2460475b95efb085d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/cors.go#9-12","gmt_create":"2026-05-27T18:35:29.9331872+08:00","gmt_modified":"2026-05-27T18:35:29.9331872+08:00"},{"id":91,"source_id":"336527cad207564e9ea86fcc4e0ec240","target_id":"be85f7cf4e9dd0c2460475b95efb085d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 9-12","gmt_create":"2026-05-27T18:35:29.9337179+08:00","gmt_modified":"2026-05-27T18:35:29.9337179+08:00"},{"id":92,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"730d8469648c9599ccbc091a9496d2a1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#23-36","gmt_create":"2026-05-27T18:35:29.9337179+08:00","gmt_modified":"2026-05-27T18:35:29.9337179+08:00"},{"id":93,"source_id":"703706c059a41213d3dbfbddc03fab12","target_id":"730d8469648c9599ccbc091a9496d2a1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-36","gmt_create":"2026-05-27T18:35:29.9337179+08:00","gmt_modified":"2026-05-27T18:35:29.9337179+08:00"},{"id":94,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"d48bcd5374602483c104c7d50c7224fb","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#18-21","gmt_create":"2026-05-27T18:35:29.9354707+08:00","gmt_modified":"2026-05-27T18:35:29.9354707+08:00"},{"id":95,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"d48bcd5374602483c104c7d50c7224fb","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18-21","gmt_create":"2026-05-27T18:35:29.936015+08:00","gmt_modified":"2026-05-27T18:35:29.936015+08:00"},{"id":96,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"798bc9e7f1a3902993b3aa9acba73022","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/logger.go#16","gmt_create":"2026-05-27T18:35:29.936015+08:00","gmt_modified":"2026-05-27T18:35:29.936015+08:00"},{"id":97,"source_id":"f8a733666ceab6a73ba2bf3234e91222","target_id":"798bc9e7f1a3902993b3aa9acba73022","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 16","gmt_create":"2026-05-27T18:35:29.9365406+08:00","gmt_modified":"2026-05-27T18:35:29.9365406+08:00"},{"id":98,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"ed43fe99536e371ce908f167a68124f8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/request_id.go#28","gmt_create":"2026-05-27T18:35:29.9370715+08:00","gmt_modified":"2026-05-27T18:35:29.9370715+08:00"},{"id":99,"source_id":"2ba2f740fa3334f7c6d51f74470ec4b7","target_id":"ed43fe99536e371ce908f167a68124f8","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 28","gmt_create":"2026-05-27T18:35:29.9375945+08:00","gmt_modified":"2026-05-27T18:35:29.9375945+08:00"},{"id":100,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"08c02a0d77d871b6c9650cbfcdf84c94","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/cors.go#18","gmt_create":"2026-05-27T18:35:29.9375945+08:00","gmt_modified":"2026-05-27T18:35:29.9375945+08:00"},{"id":101,"source_id":"336527cad207564e9ea86fcc4e0ec240","target_id":"08c02a0d77d871b6c9650cbfcdf84c94","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18","gmt_create":"2026-05-27T18:35:29.938135+08:00","gmt_modified":"2026-05-27T18:35:29.938135+08:00"},{"id":102,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"e88b0ee062bd02dd7acdf8e2e945b270","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#103-130","gmt_create":"2026-05-27T18:35:29.938135+08:00","gmt_modified":"2026-05-27T18:35:29.938135+08:00"},{"id":103,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"e88b0ee062bd02dd7acdf8e2e945b270","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 103-130","gmt_create":"2026-05-27T18:35:29.938674+08:00","gmt_modified":"2026-05-27T18:35:29.938674+08:00"},{"id":104,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"276b4d58e492bc3f7c258914abb959e4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/brand.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":105,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"4ca752eb084c575a36939921aeeb9984","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/model.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":106,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"67d3253845127f03f1f9ebe3f6a6aaa3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/brand_cache.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":107,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"018b14cbce05561cfb50fe7e6e3835a3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/model_cache.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":108,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"7bfaa93c0d23eed2727039a5bd3d9a07","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/redis.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":109,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/database/mysql.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":110,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"a0a3a762dc85a8d8c5bb359f5c523def","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/database.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":111,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"ac542a8b31381c132de78b921e3216d4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/redis.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":112,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"0bba4121c12e2cf427dc805016fade40","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/config.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":113,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/brand.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":114,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"e9902bfcef1f5908b5123648ae6b07c6","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/model.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":115,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/brand.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":116,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"b18d19ca2c60406b9cd28010df12296d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model.go","gmt_create":"2026-05-27T18:35:41.7574665+08:00","gmt_modified":"2026-05-27T18:35:41.7574665+08:00"},{"id":117,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"d2654fb48612d74ab0ccc06a3aede80b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/router/router.go","gmt_create":"2026-05-27T18:35:41.772274+08:00","gmt_modified":"2026-05-27T18:35:41.772274+08:00"},{"id":118,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"fd613068059c593ac4df9eaef2918055","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: cmd/server/main.go","gmt_create":"2026-05-27T18:35:41.7739049+08:00","gmt_modified":"2026-05-27T18:35:41.7739049+08:00"},{"id":119,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"c56e5254bd7f42350c5261822fa135bb","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/model.sql","gmt_create":"2026-05-27T18:35:41.7739049+08:00","gmt_modified":"2026-05-27T18:35:41.7739049+08:00"},{"id":120,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"47165ac2566e8b2d3796014bdb75361f","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: go.mod","gmt_create":"2026-05-27T18:35:41.774462+08:00","gmt_modified":"2026-05-27T18:35:41.774462+08:00"},{"id":121,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"e88b0ee062bd02dd7acdf8e2e945b270","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#103-130","gmt_create":"2026-05-27T18:35:41.774462+08:00","gmt_modified":"2026-05-27T18:35:41.774462+08:00"},{"id":122,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"64381887b12f6927d8b0481a55c2dcf1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#22-25","gmt_create":"2026-05-27T18:35:41.7750027+08:00","gmt_modified":"2026-05-27T18:35:41.7750027+08:00"},{"id":123,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"64381887b12f6927d8b0481a55c2dcf1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 22-25","gmt_create":"2026-05-27T18:35:41.7750027+08:00","gmt_modified":"2026-05-27T18:35:41.7750027+08:00"},{"id":124,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"1503a99bb2f2ab96e4a3a830d8834e45","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#19-24","gmt_create":"2026-05-27T18:35:41.7755529+08:00","gmt_modified":"2026-05-27T18:35:41.7755529+08:00"},{"id":125,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"1503a99bb2f2ab96e4a3a830d8834e45","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-24","gmt_create":"2026-05-27T18:35:41.7755529+08:00","gmt_modified":"2026-05-27T18:35:41.7755529+08:00"},{"id":126,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"f74cdc773e62a1a9f5a4bf940b5961e3","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#19-24","gmt_create":"2026-05-27T18:35:41.7760825+08:00","gmt_modified":"2026-05-27T18:35:41.7760825+08:00"},{"id":127,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"f74cdc773e62a1a9f5a4bf940b5961e3","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-24","gmt_create":"2026-05-27T18:35:41.7760825+08:00","gmt_modified":"2026-05-27T18:35:41.7760825+08:00"},{"id":128,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"8b0db394a538b6652de2e6634277ad0f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#14-21","gmt_create":"2026-05-27T18:35:41.7766018+08:00","gmt_modified":"2026-05-27T18:35:41.7766018+08:00"},{"id":129,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"8b0db394a538b6652de2e6634277ad0f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-21","gmt_create":"2026-05-27T18:35:41.7766018+08:00","gmt_modified":"2026-05-27T18:35:41.7766018+08:00"},{"id":130,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"03f26c7c55e18e6266ea8e543a032229","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#14-21","gmt_create":"2026-05-27T18:35:41.7771345+08:00","gmt_modified":"2026-05-27T18:35:41.7771345+08:00"},{"id":131,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"03f26c7c55e18e6266ea8e543a032229","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-21","gmt_create":"2026-05-27T18:35:41.7771345+08:00","gmt_modified":"2026-05-27T18:35:41.7771345+08:00"},{"id":132,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"8fab617bba600779abac7805723180a0","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#18-24","gmt_create":"2026-05-27T18:35:41.7777054+08:00","gmt_modified":"2026-05-27T18:35:41.7777054+08:00"},{"id":133,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"8fab617bba600779abac7805723180a0","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18-24","gmt_create":"2026-05-27T18:35:41.7777054+08:00","gmt_modified":"2026-05-27T18:35:41.7777054+08:00"},{"id":134,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"006d91f2f5f75fd7cd586165c200ba98","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#19-25","gmt_create":"2026-05-27T18:35:41.7777054+08:00","gmt_modified":"2026-05-27T18:35:41.7777054+08:00"},{"id":135,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"006d91f2f5f75fd7cd586165c200ba98","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-25","gmt_create":"2026-05-27T18:35:41.7782257+08:00","gmt_modified":"2026-05-27T18:35:41.7782257+08:00"},{"id":136,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"509525e0463c03c509709a6bd1765d4f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/redis.go#10-16","gmt_create":"2026-05-27T18:35:41.7782257+08:00","gmt_modified":"2026-05-27T18:35:41.7782257+08:00"},{"id":137,"source_id":"7bfaa93c0d23eed2727039a5bd3d9a07","target_id":"509525e0463c03c509709a6bd1765d4f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 10-16","gmt_create":"2026-05-27T18:35:41.7787495+08:00","gmt_modified":"2026-05-27T18:35:41.7787495+08:00"},{"id":138,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"57b8aed283762226a00482b42a8acf5b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/database/mysql.go#14-46","gmt_create":"2026-05-27T18:35:41.7787495+08:00","gmt_modified":"2026-05-27T18:35:41.7787495+08:00"},{"id":139,"source_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","target_id":"57b8aed283762226a00482b42a8acf5b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-46","gmt_create":"2026-05-27T18:35:41.7792726+08:00","gmt_modified":"2026-05-27T18:35:41.7792726+08:00"},{"id":140,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"4ab082407b96e18f67a65d07eb4a331d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/database.go#17-40","gmt_create":"2026-05-27T18:35:41.7792726+08:00","gmt_modified":"2026-05-27T18:35:41.7792726+08:00"},{"id":141,"source_id":"a0a3a762dc85a8d8c5bb359f5c523def","target_id":"4ab082407b96e18f67a65d07eb4a331d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 17-40","gmt_create":"2026-05-27T18:35:41.7792726+08:00","gmt_modified":"2026-05-27T18:35:41.7792726+08:00"},{"id":142,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"fd2a12d243b52512003ae067f53a7548","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/redis.go#9-57","gmt_create":"2026-05-27T18:35:41.7797862+08:00","gmt_modified":"2026-05-27T18:35:41.7797862+08:00"},{"id":143,"source_id":"ac542a8b31381c132de78b921e3216d4","target_id":"fd2a12d243b52512003ae067f53a7548","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 9-57","gmt_create":"2026-05-27T18:35:41.7797862+08:00","gmt_modified":"2026-05-27T18:35:41.7797862+08:00"},{"id":144,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"61d69bf4d3c8c548eecfd677394486d6","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/config.go#18-52","gmt_create":"2026-05-27T18:35:41.7797862+08:00","gmt_modified":"2026-05-27T18:35:41.7797862+08:00"},{"id":145,"source_id":"0bba4121c12e2cf427dc805016fade40","target_id":"61d69bf4d3c8c548eecfd677394486d6","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18-52","gmt_create":"2026-05-27T18:35:41.7803146+08:00","gmt_modified":"2026-05-27T18:35:41.7803146+08:00"},{"id":146,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"e87c932ace50951cb91aa66877ad6f81","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/model.sql#24-35","gmt_create":"2026-05-27T18:35:41.7803146+08:00","gmt_modified":"2026-05-27T18:35:41.7803146+08:00"},{"id":147,"source_id":"c56e5254bd7f42350c5261822fa135bb","target_id":"e87c932ace50951cb91aa66877ad6f81","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 24-35","gmt_create":"2026-05-27T18:35:41.78084+08:00","gmt_modified":"2026-05-27T18:35:41.78084+08:00"},{"id":148,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"90226e287e9b66f5a36ba2316d7a7cd7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#14-41","gmt_create":"2026-05-27T18:35:41.78084+08:00","gmt_modified":"2026-05-27T18:35:41.78084+08:00"},{"id":149,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"90226e287e9b66f5a36ba2316d7a7cd7","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-41","gmt_create":"2026-05-27T18:35:41.7813615+08:00","gmt_modified":"2026-05-27T18:35:41.7813615+08:00"},{"id":150,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"9918f39149aaf1f5c3ec03275d6e3673","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#23-52","gmt_create":"2026-05-27T18:35:41.7837575+08:00","gmt_modified":"2026-05-27T18:35:41.7837575+08:00"},{"id":151,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"9918f39149aaf1f5c3ec03275d6e3673","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-52","gmt_create":"2026-05-27T18:35:41.7842961+08:00","gmt_modified":"2026-05-27T18:35:41.7842961+08:00"},{"id":152,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"a19fb2ac137e43d92d2ef93e8d79f0a7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#23-79","gmt_create":"2026-05-27T18:35:41.7842961+08:00","gmt_modified":"2026-05-27T18:35:41.7842961+08:00"},{"id":153,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"a19fb2ac137e43d92d2ef93e8d79f0a7","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-79","gmt_create":"2026-05-27T18:35:41.7848355+08:00","gmt_modified":"2026-05-27T18:35:41.7848355+08:00"},{"id":154,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"72322f320f907b6eec72e885e30759eb","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#26-44","gmt_create":"2026-05-27T18:35:41.7848355+08:00","gmt_modified":"2026-05-27T18:35:41.7848355+08:00"},{"id":155,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"72322f320f907b6eec72e885e30759eb","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 26-44","gmt_create":"2026-05-27T18:35:41.7848355+08:00","gmt_modified":"2026-05-27T18:35:41.7848355+08:00"},{"id":156,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"d0f658c42abae9b6dc0baaa8fc7d0694","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#31-69","gmt_create":"2026-05-27T18:35:41.7853732+08:00","gmt_modified":"2026-05-27T18:35:41.7853732+08:00"},{"id":157,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"d0f658c42abae9b6dc0baaa8fc7d0694","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 31-69","gmt_create":"2026-05-27T18:35:41.7853732+08:00","gmt_modified":"2026-05-27T18:35:41.7853732+08:00"},{"id":158,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"a952e5d5b625754a2e9249983bb8abaa","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/database.go#17-72","gmt_create":"2026-05-27T18:35:41.7859103+08:00","gmt_modified":"2026-05-27T18:35:41.7859103+08:00"},{"id":159,"source_id":"a0a3a762dc85a8d8c5bb359f5c523def","target_id":"a952e5d5b625754a2e9249983bb8abaa","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 17-72","gmt_create":"2026-05-27T18:35:41.7864448+08:00","gmt_modified":"2026-05-27T18:35:41.7864448+08:00"},{"id":160,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"f7af3a1998c24f922aa650a69b252734","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/redis.go#16-57","gmt_create":"2026-05-27T18:35:41.7864448+08:00","gmt_modified":"2026-05-27T18:35:41.7864448+08:00"},{"id":161,"source_id":"ac542a8b31381c132de78b921e3216d4","target_id":"f7af3a1998c24f922aa650a69b252734","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 16-57","gmt_create":"2026-05-27T18:35:41.786982+08:00","gmt_modified":"2026-05-27T18:35:41.786982+08:00"},{"id":162,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"7e3954c3e70a9252de9cfdec52ed93c8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#25-48","gmt_create":"2026-05-27T18:35:41.7880705+08:00","gmt_modified":"2026-05-27T18:35:41.7880705+08:00"},{"id":163,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"a6d16b8965ed7f207f19f8f915ad53a4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#25-49","gmt_create":"2026-05-27T18:35:41.7885925+08:00","gmt_modified":"2026-05-27T18:35:41.7885925+08:00"},{"id":164,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"c7bf654a5faf00b02953d2e56747a669","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/database/mysql.go#28-43","gmt_create":"2026-05-27T18:35:41.7896921+08:00","gmt_modified":"2026-05-27T18:35:41.7896921+08:00"},{"id":165,"source_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","target_id":"c7bf654a5faf00b02953d2e56747a669","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 28-43","gmt_create":"2026-05-27T18:35:41.7896921+08:00","gmt_modified":"2026-05-27T18:35:41.7896921+08:00"},{"id":166,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"1d3714bd55d5d3f773f1ab7fdb8c9b53","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/brand.go#3-6","gmt_create":"2026-05-27T18:35:41.7907502+08:00","gmt_modified":"2026-05-27T18:35:41.7907502+08:00"},{"id":167,"source_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","target_id":"1d3714bd55d5d3f773f1ab7fdb8c9b53","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 3-6","gmt_create":"2026-05-27T18:35:41.7907502+08:00","gmt_modified":"2026-05-27T18:35:41.7907502+08:00"},{"id":168,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"8d92ac14c6257462a15eb6990dd44596","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/model.go#5-14","gmt_create":"2026-05-27T18:35:41.7923122+08:00","gmt_modified":"2026-05-27T18:35:41.7923122+08:00"},{"id":169,"source_id":"e9902bfcef1f5908b5123648ae6b07c6","target_id":"8d92ac14c6257462a15eb6990dd44596","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 5-14","gmt_create":"2026-05-27T18:35:41.7923122+08:00","gmt_modified":"2026-05-27T18:35:41.7923122+08:00"},{"id":170,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"8b134235408cf40b9d6351d54591b3c4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/model.sql#34","gmt_create":"2026-05-27T18:35:41.7933596+08:00","gmt_modified":"2026-05-27T18:35:41.7933596+08:00"},{"id":171,"source_id":"c56e5254bd7f42350c5261822fa135bb","target_id":"8b134235408cf40b9d6351d54591b3c4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 34","gmt_create":"2026-05-27T18:35:41.7933596+08:00","gmt_modified":"2026-05-27T18:35:41.7933596+08:00"},{"id":172,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"62d02336da9111eec3c5696aabf71927","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#13-16","gmt_create":"2026-05-27T18:35:41.7954607+08:00","gmt_modified":"2026-05-27T18:35:41.7954607+08:00"},{"id":173,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"62d02336da9111eec3c5696aabf71927","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-16","gmt_create":"2026-05-27T18:35:41.7959791+08:00","gmt_modified":"2026-05-27T18:35:41.7959791+08:00"},{"id":174,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"a60ecb63d9ab3bda0c5042f26916def3","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#13-16","gmt_create":"2026-05-27T18:35:41.7959791+08:00","gmt_modified":"2026-05-27T18:35:41.7959791+08:00"},{"id":175,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"a60ecb63d9ab3bda0c5042f26916def3","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-16","gmt_create":"2026-05-27T18:35:41.7959791+08:00","gmt_modified":"2026-05-27T18:35:41.7959791+08:00"},{"id":176,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"5859dc43ab95b589fc2cada49ab59a86","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: go.mod#5-11","gmt_create":"2026-05-27T18:35:41.7965008+08:00","gmt_modified":"2026-05-27T18:35:41.7965008+08:00"},{"id":177,"source_id":"47165ac2566e8b2d3796014bdb75361f","target_id":"5859dc43ab95b589fc2cada49ab59a86","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 5-11","gmt_create":"2026-05-27T18:35:41.7970218+08:00","gmt_modified":"2026-05-27T18:35:41.7970218+08:00"},{"id":178,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"dcc3acd0529002f62657a37922318e37","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#25-69","gmt_create":"2026-05-27T18:35:41.7976793+08:00","gmt_modified":"2026-05-27T18:35:41.7976793+08:00"},{"id":179,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"dcc3acd0529002f62657a37922318e37","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 25-69","gmt_create":"2026-05-27T18:35:41.7976793+08:00","gmt_modified":"2026-05-27T18:35:41.7976793+08:00"},{"id":180,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"99ead368ce42f1081e05c800c65b176f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/database/mysql.go#33-43","gmt_create":"2026-05-27T18:35:41.8014731+08:00","gmt_modified":"2026-05-27T18:35:41.8014731+08:00"},{"id":181,"source_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","target_id":"99ead368ce42f1081e05c800c65b176f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 33-43","gmt_create":"2026-05-27T18:35:41.802505+08:00","gmt_modified":"2026-05-27T18:35:41.802505+08:00"},{"id":182,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/brand.go","gmt_create":"2026-05-27T18:35:49.7836872+08:00","gmt_modified":"2026-05-27T18:35:49.7836872+08:00"},{"id":183,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"b18d19ca2c60406b9cd28010df12296d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model.go","gmt_create":"2026-05-27T18:35:49.7836872+08:00","gmt_modified":"2026-05-27T18:35:49.7836872+08:00"},{"id":184,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model_list.go","gmt_create":"2026-05-27T18:35:49.7836872+08:00","gmt_modified":"2026-05-27T18:35:49.7836872+08:00"},{"id":185,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"3a1babcf090301072327433866c0d7d0","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/device.go","gmt_create":"2026-05-27T18:35:49.784717+08:00","gmt_modified":"2026-05-27T18:35:49.784717+08:00"},{"id":186,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"a7b9800e6fc68baa0cfda9c8f327b423","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/health.go","gmt_create":"2026-05-27T18:35:49.784717+08:00","gmt_modified":"2026-05-27T18:35:49.784717+08:00"},{"id":187,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"276b4d58e492bc3f7c258914abb959e4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/brand.go","gmt_create":"2026-05-27T18:35:49.784717+08:00","gmt_modified":"2026-05-27T18:35:49.784717+08:00"},{"id":188,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"4ca752eb084c575a36939921aeeb9984","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/model.go","gmt_create":"2026-05-27T18:35:49.784717+08:00","gmt_modified":"2026-05-27T18:35:49.784717+08:00"},{"id":189,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"703706c059a41213d3dbfbddc03fab12","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/response/response.go","gmt_create":"2026-05-27T18:35:49.784717+08:00","gmt_modified":"2026-05-27T18:35:49.784717+08:00"},{"id":190,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"80d716769cf67cd05b504a3bc0a06a92","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: pkg/encode/base64.go","gmt_create":"2026-05-27T18:35:49.784717+08:00","gmt_modified":"2026-05-27T18:35:49.784717+08:00"},{"id":191,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"a1ff50cc5809d0d712db343ab0befe3b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/search/meilisearch.go","gmt_create":"2026-05-27T18:35:49.784717+08:00","gmt_modified":"2026-05-27T18:35:49.784717+08:00"},{"id":192,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d2654fb48612d74ab0ccc06a3aede80b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/router/router.go","gmt_create":"2026-05-27T18:35:49.7862502+08:00","gmt_modified":"2026-05-27T18:35:49.7862502+08:00"},{"id":193,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"fd613068059c593ac4df9eaef2918055","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: cmd/server/main.go","gmt_create":"2026-05-27T18:35:49.7862502+08:00","gmt_modified":"2026-05-27T18:35:49.7862502+08:00"},{"id":194,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"0bba4121c12e2cf427dc805016fade40","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/config.go","gmt_create":"2026-05-27T18:35:49.7862502+08:00","gmt_modified":"2026-05-27T18:35:49.7862502+08:00"},{"id":195,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"f8a733666ceab6a73ba2bf3234e91222","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/logger.go","gmt_create":"2026-05-27T18:35:49.7862502+08:00","gmt_modified":"2026-05-27T18:35:49.7862502+08:00"},{"id":196,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"336527cad207564e9ea86fcc4e0ec240","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/cors.go","gmt_create":"2026-05-27T18:35:49.7862502+08:00","gmt_modified":"2026-05-27T18:35:49.7862502+08:00"},{"id":197,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"2ba2f740fa3334f7c6d51f74470ec4b7","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/request_id.go","gmt_create":"2026-05-27T18:35:49.7872716+08:00","gmt_modified":"2026-05-27T18:35:49.7872716+08:00"},{"id":198,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/brand.go","gmt_create":"2026-05-27T18:35:49.7872716+08:00","gmt_modified":"2026-05-27T18:35:49.7872716+08:00"},{"id":199,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"e9902bfcef1f5908b5123648ae6b07c6","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/model.go","gmt_create":"2026-05-27T18:35:49.7872716+08:00","gmt_modified":"2026-05-27T18:35:49.7872716+08:00"},{"id":200,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"67d3253845127f03f1f9ebe3f6a6aaa3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/brand_cache.go","gmt_create":"2026-05-27T18:35:49.7872716+08:00","gmt_modified":"2026-05-27T18:35:49.7872716+08:00"},{"id":201,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"018b14cbce05561cfb50fe7e6e3835a3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/model_cache.go","gmt_create":"2026-05-27T18:35:49.7872716+08:00","gmt_modified":"2026-05-27T18:35:49.7872716+08:00"},{"id":202,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"a0b3e000a5b789bf08d2d996fc17d8df","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#25-101","gmt_create":"2026-05-27T18:35:49.7872716+08:00","gmt_modified":"2026-05-27T18:35:49.7872716+08:00"},{"id":203,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"333405ee9924108619cd8443f735d754","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#16-52","gmt_create":"2026-05-27T18:35:49.7872716+08:00","gmt_modified":"2026-05-27T18:35:49.7872716+08:00"},{"id":204,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"a5fb1691af5646ea8b4306ae97288e36","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/health.go#10","gmt_create":"2026-05-27T18:35:49.7872716+08:00","gmt_modified":"2026-05-27T18:35:49.7872716+08:00"},{"id":205,"source_id":"a7b9800e6fc68baa0cfda9c8f327b423","target_id":"a5fb1691af5646ea8b4306ae97288e36","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 10","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":206,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"de87fa33e6add38c027478dd3d0cebda","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#18","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":207,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"de87fa33e6add38c027478dd3d0cebda","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":208,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"09427d743a4be750f874418ab3e8504d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#18","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":209,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"09427d743a4be750f874418ab3e8504d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":210,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"9ebb4688793526b520ec263ebf651be7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#19","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":211,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"9ebb4688793526b520ec263ebf651be7","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":212,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"5e813130e7885527f77be92dbbaee9b6","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#19","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":213,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"5e813130e7885527f77be92dbbaee9b6","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":214,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"1992aa29a2869c31fe69ac701541c6ff","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/health.go#8-19","gmt_create":"2026-05-27T18:35:49.7913083+08:00","gmt_modified":"2026-05-27T18:35:49.7913083+08:00"},{"id":215,"source_id":"a7b9800e6fc68baa0cfda9c8f327b423","target_id":"1992aa29a2869c31fe69ac701541c6ff","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 8-19","gmt_create":"2026-05-27T18:35:49.7913083+08:00","gmt_modified":"2026-05-27T18:35:49.7913083+08:00"},{"id":216,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"692a2c6d49d4eb62f58600908dff9f60","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#13-23","gmt_create":"2026-05-27T18:35:49.7913083+08:00","gmt_modified":"2026-05-27T18:35:49.7913083+08:00"},{"id":217,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"692a2c6d49d4eb62f58600908dff9f60","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-23","gmt_create":"2026-05-27T18:35:49.7913083+08:00","gmt_modified":"2026-05-27T18:35:49.7913083+08:00"},{"id":218,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"c9df5e7b8533af65ce97cf085b6589a9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#13-23","gmt_create":"2026-05-27T18:35:49.7913083+08:00","gmt_modified":"2026-05-27T18:35:49.7913083+08:00"},{"id":219,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"c9df5e7b8533af65ce97cf085b6589a9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-23","gmt_create":"2026-05-27T18:35:49.7913083+08:00","gmt_modified":"2026-05-27T18:35:49.7913083+08:00"},{"id":220,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d2fd0586bf019047d2adbcdf90e09224","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#14-24","gmt_create":"2026-05-27T18:35:49.7913083+08:00","gmt_modified":"2026-05-27T18:35:49.7913083+08:00"},{"id":221,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"d2fd0586bf019047d2adbcdf90e09224","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-24","gmt_create":"2026-05-27T18:35:49.7933132+08:00","gmt_modified":"2026-05-27T18:35:49.7933132+08:00"},{"id":222,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"bf1f0d1dece713e866e4a46be7784473","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#14-24","gmt_create":"2026-05-27T18:35:49.7933132+08:00","gmt_modified":"2026-05-27T18:35:49.7933132+08:00"},{"id":223,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"bf1f0d1dece713e866e4a46be7784473","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-24","gmt_create":"2026-05-27T18:35:49.7933132+08:00","gmt_modified":"2026-05-27T18:35:49.7933132+08:00"},{"id":224,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"c600af69dac497c7cf059a4bb2f033fc","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#32-36","gmt_create":"2026-05-27T18:35:49.7933132+08:00","gmt_modified":"2026-05-27T18:35:49.7933132+08:00"},{"id":225,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"c600af69dac497c7cf059a4bb2f033fc","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 32-36","gmt_create":"2026-05-27T18:35:49.7933132+08:00","gmt_modified":"2026-05-27T18:35:49.7933132+08:00"},{"id":226,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"bc6f53b403231c0f908654d3fea2102a","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#29","gmt_create":"2026-05-27T18:35:49.7933132+08:00","gmt_modified":"2026-05-27T18:35:49.7933132+08:00"},{"id":227,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"bc6f53b403231c0f908654d3fea2102a","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 29","gmt_create":"2026-05-27T18:35:49.7948171+08:00","gmt_modified":"2026-05-27T18:35:49.7948171+08:00"},{"id":228,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"7b39881baafeaea08adce31120b7c1e1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#30","gmt_create":"2026-05-27T18:35:49.7948171+08:00","gmt_modified":"2026-05-27T18:35:49.7948171+08:00"},{"id":229,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"7b39881baafeaea08adce31120b7c1e1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 30","gmt_create":"2026-05-27T18:35:49.7948171+08:00","gmt_modified":"2026-05-27T18:35:49.7948171+08:00"},{"id":230,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"dbe385204072d26c84bf169842961690","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#37","gmt_create":"2026-05-27T18:35:49.7948171+08:00","gmt_modified":"2026-05-27T18:35:49.7948171+08:00"},{"id":231,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"dbe385204072d26c84bf169842961690","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 37","gmt_create":"2026-05-27T18:35:49.7948171+08:00","gmt_modified":"2026-05-27T18:35:49.7948171+08:00"},{"id":232,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"2a723ed48cd9855068a04da6a33cb5e4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#71","gmt_create":"2026-05-27T18:35:49.7948171+08:00","gmt_modified":"2026-05-27T18:35:49.7948171+08:00"},{"id":233,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"2a723ed48cd9855068a04da6a33cb5e4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 71","gmt_create":"2026-05-27T18:35:49.7948171+08:00","gmt_modified":"2026-05-27T18:35:49.7948171+08:00"},{"id":234,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"9918f39149aaf1f5c3ec03275d6e3673","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#23-52","gmt_create":"2026-05-27T18:35:49.7948171+08:00","gmt_modified":"2026-05-27T18:35:49.7948171+08:00"},{"id":235,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"a19fb2ac137e43d92d2ef93e8d79f0a7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#23-79","gmt_create":"2026-05-27T18:35:49.7970098+08:00","gmt_modified":"2026-05-27T18:35:49.7970098+08:00"},{"id":236,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d72b0eafdb65d1d946060cf944359251","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/search/meilisearch.go#22-45","gmt_create":"2026-05-27T18:35:49.7970098+08:00","gmt_modified":"2026-05-27T18:35:49.7970098+08:00"},{"id":237,"source_id":"a1ff50cc5809d0d712db343ab0befe3b","target_id":"d72b0eafdb65d1d946060cf944359251","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 22-45","gmt_create":"2026-05-27T18:35:49.7970098+08:00","gmt_modified":"2026-05-27T18:35:49.7970098+08:00"},{"id":238,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"fce5662f14aa6386a5036b5241e00b1c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#15-21","gmt_create":"2026-05-27T18:35:49.7970098+08:00","gmt_modified":"2026-05-27T18:35:49.7970098+08:00"},{"id":239,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"1eb8f107de13e2ad7eaed3bd6cf20a3a","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#40","gmt_create":"2026-05-27T18:35:49.8048985+08:00","gmt_modified":"2026-05-27T18:35:49.8048985+08:00"},{"id":240,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"1eb8f107de13e2ad7eaed3bd6cf20a3a","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 40","gmt_create":"2026-05-27T18:35:49.8048985+08:00","gmt_modified":"2026-05-27T18:35:49.8048985+08:00"},{"id":241,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"7e3954c3e70a9252de9cfdec52ed93c8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#25-48","gmt_create":"2026-05-27T18:35:49.8048985+08:00","gmt_modified":"2026-05-27T18:35:49.8048985+08:00"},{"id":242,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"8b0db394a538b6652de2e6634277ad0f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#14-21","gmt_create":"2026-05-27T18:35:49.8048985+08:00","gmt_modified":"2026-05-27T18:35:49.8048985+08:00"},{"id":243,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"72195f4e7a76b584cbdfbaba23db2a1a","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/brand.go#3-7","gmt_create":"2026-05-27T18:35:49.8048985+08:00","gmt_modified":"2026-05-27T18:35:49.8048985+08:00"},{"id":244,"source_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","target_id":"72195f4e7a76b584cbdfbaba23db2a1a","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 3-7","gmt_create":"2026-05-27T18:35:49.8048985+08:00","gmt_modified":"2026-05-27T18:35:49.8048985+08:00"},{"id":245,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"3e3a148f4095f6d36c64b1cfb3d1702a","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#13-48","gmt_create":"2026-05-27T18:35:49.8120366+08:00","gmt_modified":"2026-05-27T18:35:49.8120366+08:00"},{"id":246,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"3e3a148f4095f6d36c64b1cfb3d1702a","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-48","gmt_create":"2026-05-27T18:35:49.8120366+08:00","gmt_modified":"2026-05-27T18:35:49.8120366+08:00"},{"id":247,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"a6d16b8965ed7f207f19f8f915ad53a4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#25-49","gmt_create":"2026-05-27T18:35:49.8127781+08:00","gmt_modified":"2026-05-27T18:35:49.8127781+08:00"},{"id":248,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"03f26c7c55e18e6266ea8e543a032229","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#14-21","gmt_create":"2026-05-27T18:35:49.8127781+08:00","gmt_modified":"2026-05-27T18:35:49.8127781+08:00"},{"id":249,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"3c27d9274287839faa5269c34b98b6a9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/model.go#5-15","gmt_create":"2026-05-27T18:35:49.8127781+08:00","gmt_modified":"2026-05-27T18:35:49.8127781+08:00"},{"id":250,"source_id":"e9902bfcef1f5908b5123648ae6b07c6","target_id":"3c27d9274287839faa5269c34b98b6a9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 5-15","gmt_create":"2026-05-27T18:35:49.8127781+08:00","gmt_modified":"2026-05-27T18:35:49.8127781+08:00"},{"id":251,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"e0ca219542426b9141a89063f7052b0c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#13-49","gmt_create":"2026-05-27T18:35:49.8127781+08:00","gmt_modified":"2026-05-27T18:35:49.8127781+08:00"},{"id":252,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"e0ca219542426b9141a89063f7052b0c","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-49","gmt_create":"2026-05-27T18:35:49.8127781+08:00","gmt_modified":"2026-05-27T18:35:49.8127781+08:00"},{"id":253,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"fce0c17d6c03e511c3afeaee662ad34f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#26-56","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":254,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"270fee7aef8f38c42409050388865f6d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: pkg/encode/base64.go#35-51","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":255,"source_id":"80d716769cf67cd05b504a3bc0a06a92","target_id":"270fee7aef8f38c42409050388865f6d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 35-51","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":256,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"5db111a430cac488cabeb543494fb917","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#15-36","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":257,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"8cf065ea198e4e0d88af1863fcd6ac11","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#14-57","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":258,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"8cf065ea198e4e0d88af1863fcd6ac11","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-57","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":259,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d4bd0610a0ad3d8fd8d33ac5f4aa83b5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#26-84","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":260,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"b62090b5a8fe0cd95b332a46bb8eac3c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#14-85","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":261,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"b62090b5a8fe0cd95b332a46bb8eac3c","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-85","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":262,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"3f830fae511ccf076a0f04192c9b4cbe","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#53-69","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":263,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"3f830fae511ccf076a0f04192c9b4cbe","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 53-69","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":264,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d0f6f695e8187267487ad6b6fb8559b0","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#16-36","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":265,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"d0f6f695e8187267487ad6b6fb8559b0","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 16-36","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":266,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"8fab617bba600779abac7805723180a0","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#18-24","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":267,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"006d91f2f5f75fd7cd586165c200ba98","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#19-25","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":268,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"1b6991f54b135de9969d4b357dcce8e4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#67-70","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":269,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"1b6991f54b135de9969d4b357dcce8e4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 67-70","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":270,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"86ac1fc7361002fc5d2c9f7b9b1ea754","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#27-36","gmt_create":"2026-05-27T18:35:49.821585+08:00","gmt_modified":"2026-05-27T18:35:49.821585+08:00"},{"id":271,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"86ac1fc7361002fc5d2c9f7b9b1ea754","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 27-36","gmt_create":"2026-05-27T18:35:49.821585+08:00","gmt_modified":"2026-05-27T18:35:49.821585+08:00"},{"id":272,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"bdfbf7d6f851540dee549606f7aca9d4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#19","gmt_create":"2026-05-27T18:35:49.821585+08:00","gmt_modified":"2026-05-27T18:35:49.821585+08:00"},{"id":273,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"bdfbf7d6f851540dee549606f7aca9d4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19","gmt_create":"2026-05-27T18:35:49.821585+08:00","gmt_modified":"2026-05-27T18:35:49.821585+08:00"},{"id":274,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"ba4653c42534e9835fb3db39fbfd5c06","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#19","gmt_create":"2026-05-27T18:35:49.821585+08:00","gmt_modified":"2026-05-27T18:35:49.821585+08:00"},{"id":275,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"ba4653c42534e9835fb3db39fbfd5c06","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19","gmt_create":"2026-05-27T18:35:49.8235965+08:00","gmt_modified":"2026-05-27T18:35:49.8235965+08:00"},{"id":276,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"e5c6898e570c67346c0858cfeaa98fae","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/search/meilisearch.go#17","gmt_create":"2026-05-27T18:35:49.8235965+08:00","gmt_modified":"2026-05-27T18:35:49.8235965+08:00"},{"id":277,"source_id":"a1ff50cc5809d0d712db343ab0befe3b","target_id":"e5c6898e570c67346c0858cfeaa98fae","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 17","gmt_create":"2026-05-27T18:35:49.8235965+08:00","gmt_modified":"2026-05-27T18:35:49.8235965+08:00"},{"id":278,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"90b60f9dc283b0c2610ad113bc211315","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: pkg/encode/base64.go#8","gmt_create":"2026-05-27T18:35:49.8235965+08:00","gmt_modified":"2026-05-27T18:35:49.8235965+08:00"},{"id":279,"source_id":"80d716769cf67cd05b504a3bc0a06a92","target_id":"90b60f9dc283b0c2610ad113bc211315","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 8","gmt_create":"2026-05-27T18:35:49.8235965+08:00","gmt_modified":"2026-05-27T18:35:49.8235965+08:00"},{"id":280,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"85820118c846a111e112dc705c071116","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#9","gmt_create":"2026-05-27T18:35:49.8235965+08:00","gmt_modified":"2026-05-27T18:35:49.8235965+08:00"},{"id":281,"source_id":"703706c059a41213d3dbfbddc03fab12","target_id":"85820118c846a111e112dc705c071116","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 9","gmt_create":"2026-05-27T18:35:49.8235965+08:00","gmt_modified":"2026-05-27T18:35:49.8235965+08:00"},{"id":282,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"491bd71f42db0fd5bf1d4851b9c4aaa9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/health.go#14-18","gmt_create":"2026-05-27T18:35:49.8256014+08:00","gmt_modified":"2026-05-27T18:35:49.8256014+08:00"},{"id":283,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"1041284bd46edf16a19f024c113d10b4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#30-34","gmt_create":"2026-05-27T18:35:49.8256014+08:00","gmt_modified":"2026-05-27T18:35:49.8256014+08:00"},{"id":284,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"1041284bd46edf16a19f024c113d10b4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 30-34","gmt_create":"2026-05-27T18:35:49.8256014+08:00","gmt_modified":"2026-05-27T18:35:49.8256014+08:00"},{"id":285,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"84be9fdffe58ef8cd5e77e0d3c37313b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#31-35","gmt_create":"2026-05-27T18:35:49.8256014+08:00","gmt_modified":"2026-05-27T18:35:49.8256014+08:00"},{"id":286,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"84be9fdffe58ef8cd5e77e0d3c37313b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 31-35","gmt_create":"2026-05-27T18:35:49.8256014+08:00","gmt_modified":"2026-05-27T18:35:49.8256014+08:00"},{"id":287,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"f034e5c72872862a675dd11e32404854","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#38-42","gmt_create":"2026-05-27T18:35:49.8256014+08:00","gmt_modified":"2026-05-27T18:35:49.8256014+08:00"},{"id":288,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"f034e5c72872862a675dd11e32404854","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 38-42","gmt_create":"2026-05-27T18:35:49.827349+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00"},{"id":289,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"df50e47a5b6541093011bb59b1ec831d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#61-78","gmt_create":"2026-05-27T18:35:49.827349+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00"},{"id":290,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"df50e47a5b6541093011bb59b1ec831d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 61-78","gmt_create":"2026-05-27T18:35:49.827349+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00"},{"id":291,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"0a425d8fed248deb7202bc7e8d531ca1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/logger.go#10-45","gmt_create":"2026-05-27T18:35:49.827349+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00"},{"id":292,"source_id":"f8a733666ceab6a73ba2bf3234e91222","target_id":"0a425d8fed248deb7202bc7e8d531ca1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 10-45","gmt_create":"2026-05-27T18:35:49.827349+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00"},{"id":293,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d6d27b00ae4ab42348e74a7e7bf688b2","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/request_id.go#20-31","gmt_create":"2026-05-27T18:35:49.827349+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00"},{"id":294,"source_id":"2ba2f740fa3334f7c6d51f74470ec4b7","target_id":"d6d27b00ae4ab42348e74a7e7bf688b2","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-31","gmt_create":"2026-05-27T18:35:49.827349+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00"},{"id":295,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"fd613068059c593ac4df9eaef2918055","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: cmd/server/main.go","gmt_create":"2026-05-27T18:36:40.5191825+08:00","gmt_modified":"2026-05-27T18:36:40.5191825+08:00"},{"id":296,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"67d3253845127f03f1f9ebe3f6a6aaa3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/brand_cache.go","gmt_create":"2026-05-27T18:36:40.5191825+08:00","gmt_modified":"2026-05-27T18:36:40.5191825+08:00"},{"id":297,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"018b14cbce05561cfb50fe7e6e3835a3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/model_cache.go","gmt_create":"2026-05-27T18:36:40.5198012+08:00","gmt_modified":"2026-05-27T18:36:40.5198012+08:00"},{"id":298,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"7bfaa93c0d23eed2727039a5bd3d9a07","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/redis.go","gmt_create":"2026-05-27T18:36:40.5203298+08:00","gmt_modified":"2026-05-27T18:36:40.5203298+08:00"},{"id":299,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"0bba4121c12e2cf427dc805016fade40","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/config.go","gmt_create":"2026-05-27T18:36:40.5203298+08:00","gmt_modified":"2026-05-27T18:36:40.5203298+08:00"},{"id":300,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"ac542a8b31381c132de78b921e3216d4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/redis.go","gmt_create":"2026-05-27T18:36:40.5208694+08:00","gmt_modified":"2026-05-27T18:36:40.5208694+08:00"},{"id":301,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"d2654fb48612d74ab0ccc06a3aede80b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/router/router.go","gmt_create":"2026-05-27T18:36:40.5214036+08:00","gmt_modified":"2026-05-27T18:36:40.5214036+08:00"},{"id":302,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"276b4d58e492bc3f7c258914abb959e4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/brand.go","gmt_create":"2026-05-27T18:36:40.5214036+08:00","gmt_modified":"2026-05-27T18:36:40.5214036+08:00"},{"id":303,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"4ca752eb084c575a36939921aeeb9984","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/model.go","gmt_create":"2026-05-27T18:36:40.5219307+08:00","gmt_modified":"2026-05-27T18:36:40.5219307+08:00"},{"id":304,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/brand.go","gmt_create":"2026-05-27T18:36:40.5219307+08:00","gmt_modified":"2026-05-27T18:36:40.5219307+08:00"},{"id":305,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"b18d19ca2c60406b9cd28010df12296d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model.go","gmt_create":"2026-05-27T18:36:40.5224739+08:00","gmt_modified":"2026-05-27T18:36:40.5224739+08:00"},{"id":306,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/brand.go","gmt_create":"2026-05-27T18:36:40.5224739+08:00","gmt_modified":"2026-05-27T18:36:40.5224739+08:00"},{"id":307,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"e9902bfcef1f5908b5123648ae6b07c6","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/model.go","gmt_create":"2026-05-27T18:36:40.5230612+08:00","gmt_modified":"2026-05-27T18:36:40.5230612+08:00"},{"id":308,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"47165ac2566e8b2d3796014bdb75361f","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: go.mod","gmt_create":"2026-05-27T18:36:40.5230612+08:00","gmt_modified":"2026-05-27T18:36:40.5230612+08:00"},{"id":309,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"e9390185152783a55f55e277d45e6948","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#25-131","gmt_create":"2026-05-27T18:36:40.5235889+08:00","gmt_modified":"2026-05-27T18:36:40.5235889+08:00"},{"id":310,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"e9390185152783a55f55e277d45e6948","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 25-131","gmt_create":"2026-05-27T18:36:40.5235889+08:00","gmt_modified":"2026-05-27T18:36:40.5235889+08:00"},{"id":311,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a3cbc373dacd9d032ed0c72bca1e51e9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#1-45","gmt_create":"2026-05-27T18:36:40.5241608+08:00","gmt_modified":"2026-05-27T18:36:40.5241608+08:00"},{"id":312,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"a3cbc373dacd9d032ed0c72bca1e51e9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-45","gmt_create":"2026-05-27T18:36:40.5246891+08:00","gmt_modified":"2026-05-27T18:36:40.5246891+08:00"},{"id":313,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"d65e653afb8b211f2e5a7845f72b45dd","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#1-70","gmt_create":"2026-05-27T18:36:40.5246891+08:00","gmt_modified":"2026-05-27T18:36:40.5246891+08:00"},{"id":314,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"d65e653afb8b211f2e5a7845f72b45dd","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-70","gmt_create":"2026-05-27T18:36:40.5252193+08:00","gmt_modified":"2026-05-27T18:36:40.5252193+08:00"},{"id":315,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a26d903ac77196fac97ddebf48638ab3","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#1-100","gmt_create":"2026-05-27T18:36:40.5252193+08:00","gmt_modified":"2026-05-27T18:36:40.5252193+08:00"},{"id":316,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"a26d903ac77196fac97ddebf48638ab3","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-100","gmt_create":"2026-05-27T18:36:40.5257547+08:00","gmt_modified":"2026-05-27T18:36:40.5257547+08:00"},{"id":317,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"7ffaf7b06ea96ca93862aa0dae926ff5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#1-181","gmt_create":"2026-05-27T18:36:40.5257547+08:00","gmt_modified":"2026-05-27T18:36:40.5257547+08:00"},{"id":318,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"7ffaf7b06ea96ca93862aa0dae926ff5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-181","gmt_create":"2026-05-27T18:36:40.5263036+08:00","gmt_modified":"2026-05-27T18:36:40.5263036+08:00"},{"id":319,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"187b4628003859e3da78f3937c686803","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#18-45","gmt_create":"2026-05-27T18:36:40.5278728+08:00","gmt_modified":"2026-05-27T18:36:40.5278728+08:00"},{"id":320,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"187b4628003859e3da78f3937c686803","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18-45","gmt_create":"2026-05-27T18:36:40.5278728+08:00","gmt_modified":"2026-05-27T18:36:40.5278728+08:00"},{"id":321,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a6c526ea58aabee86ae3010b00441c69","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#19-70","gmt_create":"2026-05-27T18:36:40.5283937+08:00","gmt_modified":"2026-05-27T18:36:40.5283937+08:00"},{"id":322,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"a6c526ea58aabee86ae3010b00441c69","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-70","gmt_create":"2026-05-27T18:36:40.5283937+08:00","gmt_modified":"2026-05-27T18:36:40.5283937+08:00"},{"id":323,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a364a8daa183eaf86417b4c1bd2cc719","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#14-100","gmt_create":"2026-05-27T18:36:40.5289418+08:00","gmt_modified":"2026-05-27T18:36:40.5289418+08:00"},{"id":324,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"a364a8daa183eaf86417b4c1bd2cc719","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-100","gmt_create":"2026-05-27T18:36:40.5289418+08:00","gmt_modified":"2026-05-27T18:36:40.5289418+08:00"},{"id":325,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"2e040aabeb8e907eaddc6bbf2ee493ac","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#14-181","gmt_create":"2026-05-27T18:36:40.5294767+08:00","gmt_modified":"2026-05-27T18:36:40.5294767+08:00"},{"id":326,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"2e040aabeb8e907eaddc6bbf2ee493ac","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-181","gmt_create":"2026-05-27T18:36:40.5294767+08:00","gmt_modified":"2026-05-27T18:36:40.5294767+08:00"},{"id":327,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"3d315320639ece8212fd138420d94be5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#13-49","gmt_create":"2026-05-27T18:36:40.5294767+08:00","gmt_modified":"2026-05-27T18:36:40.5294767+08:00"},{"id":328,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"3d315320639ece8212fd138420d94be5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-49","gmt_create":"2026-05-27T18:36:40.5294767+08:00","gmt_modified":"2026-05-27T18:36:40.5294767+08:00"},{"id":329,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"fbf36e29345cd3e53fd3a6e8234ad2de","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#13-50","gmt_create":"2026-05-27T18:36:40.5304957+08:00","gmt_modified":"2026-05-27T18:36:40.5304957+08:00"},{"id":330,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"fbf36e29345cd3e53fd3a6e8234ad2de","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-50","gmt_create":"2026-05-27T18:36:40.5304957+08:00","gmt_modified":"2026-05-27T18:36:40.5304957+08:00"},{"id":331,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"9918f39149aaf1f5c3ec03275d6e3673","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#23-52","gmt_create":"2026-05-27T18:36:40.5304957+08:00","gmt_modified":"2026-05-27T18:36:40.5304957+08:00"},{"id":332,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a19fb2ac137e43d92d2ef93e8d79f0a7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#23-79","gmt_create":"2026-05-27T18:36:40.5304957+08:00","gmt_modified":"2026-05-27T18:36:40.5304957+08:00"},{"id":333,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"32b7267a28b0347d59500c38ffa96a7b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#13-45","gmt_create":"2026-05-27T18:36:40.5320145+08:00","gmt_modified":"2026-05-27T18:36:40.5320145+08:00"},{"id":334,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"32b7267a28b0347d59500c38ffa96a7b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-45","gmt_create":"2026-05-27T18:36:40.5320145+08:00","gmt_modified":"2026-05-27T18:36:40.5320145+08:00"},{"id":335,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"b9c3c517ffd917351757137ca1338574","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#27-69","gmt_create":"2026-05-27T18:36:40.5320145+08:00","gmt_modified":"2026-05-27T18:36:40.5320145+08:00"},{"id":336,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"b9c3c517ffd917351757137ca1338574","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 27-69","gmt_create":"2026-05-27T18:36:40.5320145+08:00","gmt_modified":"2026-05-27T18:36:40.5320145+08:00"},{"id":337,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"df7d264896976fc8c5475257994c707e","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#13-70","gmt_create":"2026-05-27T18:36:40.5320145+08:00","gmt_modified":"2026-05-27T18:36:40.5320145+08:00"},{"id":338,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"df7d264896976fc8c5475257994c707e","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-70","gmt_create":"2026-05-27T18:36:40.5330386+08:00","gmt_modified":"2026-05-27T18:36:40.5330386+08:00"},{"id":339,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a3b89d2e56d589f8d902fb9389004bf0","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#103-131","gmt_create":"2026-05-27T18:36:40.5330386+08:00","gmt_modified":"2026-05-27T18:36:40.5330386+08:00"},{"id":340,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"a3b89d2e56d589f8d902fb9389004bf0","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 103-131","gmt_create":"2026-05-27T18:36:40.5330386+08:00","gmt_modified":"2026-05-27T18:36:40.5330386+08:00"},{"id":341,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"f76ee32725201731512db1e0e7951586","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#67-68","gmt_create":"2026-05-27T18:36:40.5330386+08:00","gmt_modified":"2026-05-27T18:36:40.5330386+08:00"},{"id":342,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"f76ee32725201731512db1e0e7951586","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 67-68","gmt_create":"2026-05-27T18:36:40.5330386+08:00","gmt_modified":"2026-05-27T18:36:40.5330386+08:00"},{"id":343,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"251d1b1dc197a1dc242f5384adb1555c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#34-52","gmt_create":"2026-05-27T18:36:40.5330386+08:00","gmt_modified":"2026-05-27T18:36:40.5330386+08:00"},{"id":344,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"251d1b1dc197a1dc242f5384adb1555c","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 34-52","gmt_create":"2026-05-27T18:36:40.5350514+08:00","gmt_modified":"2026-05-27T18:36:40.5350514+08:00"},{"id":345,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a51abc6a6d80413bf60f143cd1f46ee4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#27-79","gmt_create":"2026-05-27T18:36:40.5350514+08:00","gmt_modified":"2026-05-27T18:36:40.5350514+08:00"},{"id":346,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"a51abc6a6d80413bf60f143cd1f46ee4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 27-79","gmt_create":"2026-05-27T18:36:40.5350514+08:00","gmt_modified":"2026-05-27T18:36:40.5350514+08:00"},{"id":347,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"62d02336da9111eec3c5696aabf71927","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#13-16","gmt_create":"2026-05-27T18:36:40.5350514+08:00","gmt_modified":"2026-05-27T18:36:40.5350514+08:00"},{"id":348,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"f0b044854c85d50b2d1ba4b9d3e6a6cb","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#13-17","gmt_create":"2026-05-27T18:36:40.5350514+08:00","gmt_modified":"2026-05-27T18:36:40.5350514+08:00"},{"id":349,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"f0b044854c85d50b2d1ba4b9d3e6a6cb","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-17","gmt_create":"2026-05-27T18:36:40.5350514+08:00","gmt_modified":"2026-05-27T18:36:40.5350514+08:00"},{"id":350,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"3f0d637bef43d636594a4816c9da037e","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#38-44","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":351,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"3f0d637bef43d636594a4816c9da037e","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 38-44","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":352,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"3f945faea776f513b5294aa60759fb15","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#43-69","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":353,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"3f945faea776f513b5294aa60759fb15","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 43-69","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":354,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a272829cfc9c48e8063d8bca53cdebc8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#13-23","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":355,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"a272829cfc9c48e8063d8bca53cdebc8","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-23","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":356,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"6d2fece0c97147748fd0269a356e4802","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#3-12","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":357,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"6d2fece0c97147748fd0269a356e4802","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 3-12","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":358,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"282a046f62f9715bfef882f5a4a6a362","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#3-14","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":359,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"282a046f62f9715bfef882f5a4a6a362","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 3-14","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":360,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"7e3954c3e70a9252de9cfdec52ed93c8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#25-48","gmt_create":"2026-05-27T18:36:40.5405367+08:00","gmt_modified":"2026-05-27T18:36:40.5405367+08:00"},{"id":361,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a6d16b8965ed7f207f19f8f915ad53a4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#25-49","gmt_create":"2026-05-27T18:36:40.5405367+08:00","gmt_modified":"2026-05-27T18:36:40.5405367+08:00"},{"id":362,"source_id":"ab98c251-c5f7-40df-bba1-21b2edf5d220","target_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab98c251-c5f7-40df-bba1-21b2edf5d220 -\u003e f4014d47-467e-4cfe-8549-1dfb69cbc325","gmt_create":"2026-05-27T18:36:41.1100061+08:00","gmt_modified":"2026-05-27T18:36:41.1100061+08:00"},{"id":363,"source_id":"7563e383-3ea0-4630-baeb-e86efcaeefb8","target_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7563e383-3ea0-4630-baeb-e86efcaeefb8 -\u003e d1a696b8-5a9e-4ad2-8777-04eecc0bb424","gmt_create":"2026-05-27T18:36:41.1111288+08:00","gmt_modified":"2026-05-27T18:36:41.1111288+08:00"},{"id":364,"source_id":"7563e383-3ea0-4630-baeb-e86efcaeefb8","target_id":"599c0bda-3332-415c-a535-362503079473","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7563e383-3ea0-4630-baeb-e86efcaeefb8 -\u003e 599c0bda-3332-415c-a535-362503079473","gmt_create":"2026-05-27T18:36:41.1116631+08:00","gmt_modified":"2026-05-27T18:36:41.1116631+08:00"},{"id":365,"source_id":"cfbcaa79-26f5-402f-8746-9fe524993684","target_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: cfbcaa79-26f5-402f-8746-9fe524993684 -\u003e 795a5202-49be-4c11-a2b4-44312eca8ae7","gmt_create":"2026-05-27T18:36:41.1121847+08:00","gmt_modified":"2026-05-27T18:36:41.1121847+08:00"}],"source_files":[{"id":"d2654fb48612d74ab0ccc06a3aede80b","path":"internal/router/router.go","filename":"router.go","gmt_create":"2026-05-27T18:35:29.8906012+08:00","gmt_modified":"2026-05-27T18:35:29.8906012+08:00"},{"id":"fd613068059c593ac4df9eaef2918055","path":"cmd/server/main.go","filename":"main.go","gmt_create":"2026-05-27T18:35:29.8906012+08:00","gmt_modified":"2026-05-27T18:35:29.8906012+08:00"},{"id":"336527cad207564e9ea86fcc4e0ec240","path":"internal/middleware/cors.go","filename":"cors.go","gmt_create":"2026-05-27T18:35:29.8912536+08:00","gmt_modified":"2026-05-27T18:35:29.8912536+08:00"},{"id":"f8a733666ceab6a73ba2bf3234e91222","path":"internal/middleware/logger.go","filename":"logger.go","gmt_create":"2026-05-27T18:35:29.8912536+08:00","gmt_modified":"2026-05-27T18:35:29.8912536+08:00"},{"id":"2ba2f740fa3334f7c6d51f74470ec4b7","path":"internal/middleware/request_id.go","filename":"request_id.go","gmt_create":"2026-05-27T18:35:29.8912536+08:00","gmt_modified":"2026-05-27T18:35:29.8912536+08:00"},{"id":"a7b9800e6fc68baa0cfda9c8f327b423","path":"internal/handler/health.go","filename":"health.go","gmt_create":"2026-05-27T18:35:29.8912536+08:00","gmt_modified":"2026-05-27T18:35:29.8912536+08:00"},{"id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","path":"internal/handler/brand.go","filename":"brand.go","gmt_create":"2026-05-27T18:35:29.8912536+08:00","gmt_modified":"2026-05-27T18:35:29.8912536+08:00"},{"id":"b18d19ca2c60406b9cd28010df12296d","path":"internal/handler/model.go","filename":"model.go","gmt_create":"2026-05-27T18:35:29.8917986+08:00","gmt_modified":"2026-05-27T18:35:29.8917986+08:00"},{"id":"75f8ef5ebd7eeb0cf2346b392f877e1a","path":"internal/handler/model_list.go","filename":"model_list.go","gmt_create":"2026-05-27T18:35:29.8917986+08:00","gmt_modified":"2026-05-27T18:35:29.8917986+08:00"},{"id":"3a1babcf090301072327433866c0d7d0","path":"internal/handler/device.go","filename":"device.go","gmt_create":"2026-05-27T18:35:29.8917986+08:00","gmt_modified":"2026-05-27T18:35:29.8917986+08:00"},{"id":"703706c059a41213d3dbfbddc03fab12","path":"internal/response/response.go","filename":"response.go","gmt_create":"2026-05-27T18:35:29.8917986+08:00","gmt_modified":"2026-05-27T18:35:29.8917986+08:00"},{"id":"0bba4121c12e2cf427dc805016fade40","path":"internal/config/config.go","filename":"config.go","gmt_create":"2026-05-27T18:35:29.8917986+08:00","gmt_modified":"2026-05-27T18:35:29.8917986+08:00"},{"id":"80d716769cf67cd05b504a3bc0a06a92","path":"pkg/encode/base64.go","filename":"base64.go","gmt_create":"2026-05-27T18:35:29.8923362+08:00","gmt_modified":"2026-05-27T18:35:29.8923362+08:00"},{"id":"67d9f7c1be7ff64bb9bca0a5f2492621","path":"README.md","filename":"README.md","gmt_create":"2026-05-27T18:35:29.8923362+08:00","gmt_modified":"2026-05-27T18:35:29.8923362+08:00"},{"id":"7bfaa93c0d23eed2727039a5bd3d9a07","path":"internal/cache/redis.go","filename":"redis.go","gmt_create":"2026-05-27T18:35:29.8923362+08:00","gmt_modified":"2026-05-27T18:35:29.8923362+08:00"},{"id":"67d3253845127f03f1f9ebe3f6a6aaa3","path":"internal/cache/brand_cache.go","filename":"brand_cache.go","gmt_create":"2026-05-27T18:35:29.8923362+08:00","gmt_modified":"2026-05-27T18:35:29.8923362+08:00"},{"id":"018b14cbce05561cfb50fe7e6e3835a3","path":"internal/cache/model_cache.go","filename":"model_cache.go","gmt_create":"2026-05-27T18:35:29.8923362+08:00","gmt_modified":"2026-05-27T18:35:29.8923362+08:00"},{"id":"276b4d58e492bc3f7c258914abb959e4","path":"internal/repository/brand.go","filename":"brand.go","gmt_create":"2026-05-27T18:35:29.8923362+08:00","gmt_modified":"2026-05-27T18:35:29.8923362+08:00"},{"id":"4ca752eb084c575a36939921aeeb9984","path":"internal/repository/model.go","filename":"model.go","gmt_create":"2026-05-27T18:35:29.892946+08:00","gmt_modified":"2026-05-27T18:35:29.892946+08:00"},{"id":"ac542a8b31381c132de78b921e3216d4","path":"internal/config/redis.go","filename":"redis.go","gmt_create":"2026-05-27T18:35:29.892946+08:00","gmt_modified":"2026-05-27T18:35:29.892946+08:00"},{"id":"d2c7a50459a83c5ef23e809b0f194aba","path":"internal/config/meilisearch.go","filename":"meilisearch.go","gmt_create":"2026-05-27T18:35:29.892946+08:00","gmt_modified":"2026-05-27T18:35:29.892946+08:00"},{"id":"0b4d10e2e0a550819cadaa7dbef9ecd1","path":"internal/database/mysql.go","filename":"mysql.go","gmt_create":"2026-05-27T18:35:41.7298499+08:00","gmt_modified":"2026-05-27T18:35:41.7298499+08:00"},{"id":"a0a3a762dc85a8d8c5bb359f5c523def","path":"internal/config/database.go","filename":"database.go","gmt_create":"2026-05-27T18:35:41.7298499+08:00","gmt_modified":"2026-05-27T18:35:41.7298499+08:00"},{"id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","path":"internal/model/brand.go","filename":"brand.go","gmt_create":"2026-05-27T18:35:41.7304145+08:00","gmt_modified":"2026-05-27T18:35:41.7304145+08:00"},{"id":"e9902bfcef1f5908b5123648ae6b07c6","path":"internal/model/model.go","filename":"model.go","gmt_create":"2026-05-27T18:35:41.7304145+08:00","gmt_modified":"2026-05-27T18:35:41.7304145+08:00"},{"id":"c56e5254bd7f42350c5261822fa135bb","path":"sql/model.sql","filename":"model.sql","gmt_create":"2026-05-27T18:35:41.7309531+08:00","gmt_modified":"2026-05-27T18:35:41.7309531+08:00"},{"id":"47165ac2566e8b2d3796014bdb75361f","path":"go.mod","filename":"go.mod","gmt_create":"2026-05-27T18:35:41.7309531+08:00","gmt_modified":"2026-05-27T18:35:41.7309531+08:00"},{"id":"a1ff50cc5809d0d712db343ab0befe3b","path":"internal/search/meilisearch.go","filename":"meilisearch.go","gmt_create":"2026-05-27T18:35:49.7652632+08:00","gmt_modified":"2026-05-27T18:35:49.7652632+08:00"}],"wiki_catalogs":[{"id":"78b906f9-f81c-4bb2-b076-5c5609c7eb41","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"项目概述","description":"project-overview","prompt":"为 Luxsin 应用 API 项目创建全面的项目概述内容。详细介绍项目的目标、核心功能和技术架构。解释这是一个基于 Gin 框架的 Go 语言 Web API 服务,专注于音频设备(耳机)数据管理。阐述项目的整体设计理念、分层架构模式和设计原则。包含技术栈概览(Go 1.22+、Gin、MySQL、Redis、Meilisearch),项目结构说明,以及与其他组件的关系。提供适合初学者的概念性介绍和面向经验丰富开发者的技术细节。使用与代码库一致的术语,展示常见使用场景的实际示例。","progress_status":"completed","dependent_files":"README.md,cmd/server/main.go,go.mod","gmt_create":"2026-05-27T15:42:25.0250549+08:00","gmt_modified":"2026-05-27T15:44:16.3667749+08:00","raw_data":"WikiEncrypted:0MI1/XkBoMl0lTbK6t0Cn/+8FdvqrJ62ianMLvZj02elJtBUgH0Ns0veIx1WPtM9wwkxI+/XAqHLxJLlHB8wV7ojrH0+b4JMz5OewwhBN1HmP/0rRww9hUnTCEZmNJO3yBTSwzDP2RxlM1vNSo2miB47OWpHJe/fbeK8YpuBtRbc1xpai4QWWh4AweGy0HEvW9apev3dOSAiTr8UoRTgRToJyEaxWrqZcs+MtHKRAsIrcUTt6ZOh39uAbnNwRxK9M2/DiD+kawezpj/AwiANKfd4KpHSMbzYKq9YTP0ksJkGEAjH/XwM331T75uP1oZ/psvBENTK57EgxUJQIxxl/qi9stybX0Smmey1LJ+iJDAfMqZYbs5BbkxPPLpvmXX8GX/lHaSvSv8bbbhTLnYiN+DawAvAhSIRex/qStKvjVXbzHUwrLiXLR5XSvCX75e6L5cIB4b+Mx86121DipgZvZjF7zEMzArfk0N5yZkwD5XI7a3kzfmH2BaXJoEdULrvDFX7ssODrPjklVgc2gbh9DYJXJ/eua5QA3Xx1lsmOuAQB7a98gCmD6wgY1fk9B5rsKGk7vjeRpn+VjuxS6i0t9dcHlhvXCrR7IAI7ElFcmatn18jtjyzt08iJ/2HJB3lwVKEHvC/D131ZrYoMax215Ho63ABv5IhWhlOacH3EHlX6kLvYaCiaCq7fkoW8IUfIUEJGPYMNiPdNXw8BHHJaE8Emy4eKyw7+C0K//+SPmGgkpVUXe5QBHZUCVde9qeHWFvjX7tIKhxv6DuRjUgaCTjlup8gJ49u24zpnUWcnA8qT/jl0wsGHfJi8eD0LLh0kE8XKQQ/x7QONSqCBwUYpVE0TaFITaD9jPqrfRmH7pcAVggsg7CrxVJKwukwntI7yyj4r0gvzmECsd41Q9FYOoPHu3IjRxN+OlXsp7yXlO8Bk3HtmqmpIVzy3rg5kNXkrwf98MEdjBWvI1SfpRXoliuppIkKLvshYbDq9zj7Gt5l1fDkWJrFTA59HAAa3qxQ1UvtlTV3x563VZo0DZofv2rHQaWxyL8gslH21B3jt1SClPzpPPC2ERp1waFgf/K6NltgqZg+qvCivqr8SOjn4ASj8olJuvcUYIqGIh4Glws6tboVkX7ItQuueGikKKhSflv4RIB28KosR6Y5EvB8oDFTNknPtjjj8fDMAdLye5AhzMlBtH3Ozvd7tR8DbP77ZPX3WIncMv8HHSXGmn8IwwggXYIKJ5fpuepkStOcJLSafRsijI2Jji/9y8ULNSvIJgGHlfsd+ytl0t8xFik3QfYqBtbBaYKauIWmP3opbaM="},{"id":"67d62b58-6970-45ca-a17f-f48cb2ea679a","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"业务处理器","description":"business-handlers","prompt":"为 Luxsin 应用 API 项目的业务处理器模块创建详细文档。深入解释各个处理器的职责分工、接口设计和实现细节。详细说明 BrandHandler、ModelHandler、ModelListHandler、DeviceHandler 和 HealthHandler 的具体功能和使用方法。包含依赖注入模式的实现、错误处理机制和响应格式化。提供具体的代码示例展示如何调用各个处理器,以及它们与 Gin 框架的集成方式。解释处理器之间的协作关系和数据流转过程。涵盖性能优化建议、并发安全考虑和最佳实践。确保内容对初学者易懂,同时为高级开发者提供深入的技术细节。","parent_id":"8d7c257e-b299-4adb-adfe-bc0ddbf112b7","progress_status":"completed","dependent_files":"internal/handler/brand.go,internal/handler/model.go,internal/handler/model_list.go,internal/handler/device.go,internal/handler/health.go","gmt_create":"2026-05-27T15:42:38.0124453+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00","raw_data":"WikiEncrypted:nTJcmZGR4n7nsIYUWzxCEHR9BTHxs+LY0EgcqY6ozHnPPg0CLCttcCJZTpOx5+g2+gyrhHkzQ3Oi3lFEBAWcJwtBf3fcUwrFRJbk5e8EGX6x+EuAIzfWxxMr70rCoOXyzGDz3OufTtvXqJeM6nCBBbrSJFJctzjIO8YwH2hod0rSa9BvOFL67fRLHnu5niCbygn6bT9T5Ad6YdUpIn1+mocnIZl+JxBlJ7CmgIePFEwhBbZ3HH9nKWBBaq8X7TfEL5bB556Dryv38amvl6Tlr9+oDWLzQ7durLm8mEoKTLumTtOGkLB6WdZ8ZnmAme8xYQEh58Gq/FaXq1Ch+bbX7c0sY3N207YdS+s9ADC7EYlu62+KRwIH+fejouD9Xai0SmElgzHAm8sdC//M7KELtxj0+UkF/DCTjTGZZa2sZbIvBheHRGA4uopAAdJW1z0WVUX1+aaW5BCD4sCbivzFSePeGIwaJc4S+FibJPlTKfStwCIoo5A6v8DO2AOPdiUYgzaMvqF1C4mQcHb7J2SBtLsaQepkGu+YZvBksk0Lz+NpJEH2FKFI+U+y8kw97WoPrimvQ2t44IJNHJc0WmycS/PNb2FSzM2E2hj7mtxsycLtn2LO5KOlRK85jdTSJFqGcYZzeZ6T7VK2yBxf5rRAwRATKfq58519HtZUycv0AeFGvOfYEpRMv5E+/9eF+o2hi9WqBURire5cWunx1RrVQTJ+QOs/ejc4AfuInYvURMp9uXUy62pRU8d9Pvq1zCbvM/QCKFu+YzdDyb+IucGj/GUmvrZTwLHZF2//WMylMOpEzsbGaL+cgwvPS0ZpiHx2Dr3KyQ3uIJaUsiQKXOOl46GI8mNiPEN4JP4rOorOH1+LOAd7a/LbC0xqg6Z0rlNQSQIc0ujM0D9L7WtfUrTKRHIwi89fdj2lY9xinRj8OsH2MnVNtkTirZPtudetURaBAmlqvomU4AzyIeshiJKP+D2WDwDSDXFuKCHzQ77xNb9Eo4ijpRO55+Xj0sqm0QGg4VPdachzP0AXWNlEvSbT3daOrRwAwKfxcK5nI9MjOx1lwFr0GcPqXAqx3khltksU8hfLyWdyQKr3kLrxNXwU7WQRVbWWtkTcfV4eK9lAXsF5YC50ZzKcz6RRHQERSKRNZWIgfr//nusobqJtFBZk8kBUZwgnw89udjyk7U6XLghzduw/uhHaMkS8e9a9eIcoHn57wG7KVE8q34/ItI6kF/9VYvcjQCGrboe1hmIrwG46Qpq8rKhq19zjM1N35JOLqbxS12v9mmyX0JhAkWIj6uO5FDPFOr7elw1yLGp+9r58B4mMPOFb/utyMhIn9nyKQ1SZJhWrvC46j8UUgKYX1zzNmDT57M8HBWkM027nRZTPuqHWLwy3BKvLdsip3/fM8IWCtK52p3SrvFjjDa3us6v6/+ldlLF+bAJPbDqMQ5Xd5KAFIRmtfI7Vt+3/elwQnV/hfncEobSgozbpi/+wxFDTehDxNn925sH6W0ft6ayeiO6l/Z26jrBSXhw0v7uN53zVoQheZdTZUOHGsvWz5HiGx6ZRWZhxdSZLlzVsU9hRdYgF/fhtW8nOSODxNk4oAkvprvgwx9TgdWnjME8piPjdlKsqcJKNXiNkMFThtdotd5/oVJWSUh6wEvdMmyJZ","layer_level":1},{"id":"591ea147-ba05-4d86-a671-941af668ca2f","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"品牌管理接口","description":"brand-management-api","prompt":"为品牌管理接口创建详细的 API 文档。记录获取品牌列表的接口规范,包括 HTTP 方法、URL 模式、请求参数(brandName 查询参数)、响应格式和错误处理。提供具体的请求示例和响应示例,说明如何查询特定品牌或所有品牌信息。详细说明 Base64 编码响应选项的使用方法和适用场景。包含常见的使用场景、客户端实现指南和性能优化建议。提供错误处理策略和调试方法。","parent_id":"8085e1b7-3658-4490-8b52-9a61f3e79976","progress_status":"completed","dependent_files":"internal/handler/brand.go","gmt_create":"2026-05-27T15:42:40.190927+08:00","gmt_modified":"2026-05-27T15:52:20.2742155+08:00","raw_data":"WikiEncrypted:MpYke5d2PXdqtxI+drCrLtTQMJR2qutlXYM1eplHCPm9/Q2P6fWxhBRJ5bi1YZPWaHS/NqlGVpUFmW1DTLhf/76xGG0D1/eLqVfyND560PlQohHkNSJ7tG8q8rNN0PSoYa8X/dNeOTyE1A+uNuvpiB8VEfTp3tDUy+z3wJjo7Mac9XZxl3yz7HAEroJflv+CMaOLDNpuuFAizP+9X1/8yMamdkg455SQiJ4MA3tO8lvrplKeDtAsHnZMOuRb1k8H2J1Okf9ERLFkl/hajhx/ErZkMXJcVDAafq7dea3WDtuhkapO0hPBNT0jBx23jA9D7bdwpP8HUMhRQofKSrXSGWsNkOXGoTUbtKPcvqSXhQc/9ZnwEEWeVTez5dnt0TzIm14zjRSuX8WW7fn2EC5NSDXky9F0+kI+r1SW0lJAbI3S7/PzXMppdYjT5CIvUr4oUNfXpKuj0hpO8TqMLZU7tVSVTfLxNXN9GhtdNUotltCy+fTfIRE9oX+iVuqgGtGw1XfkviF0TKtN2+lC3tYHFIpPZl0lv2u1hS9qg5UQt86ZqNo0oyYG4iMTW1/PcJjvEh+ZouSCdeb1/NZXAghNVhgC+8CAFMY8ARl4571OoYbQgSJas0Ved/ljSKxbViyBTgk/eadCH+WuFgEUJPidhbhNV95LyTxjvd4d98Fz4GQj2038lVoj9NivalyW4v3H3DG7fUSW/wraV29VqX1jG8ICAA3c60Q5kE1oNPSUR1elSjYrLy3on9k9r8INUoZBOoRUyflFm5B6kmZvm44JlzVpRLRlNpa3erHjDw9LI3thWQq/NO7w72+KvFuF8zaQB3H1VyMGzou5eP9dokkthFbhCLnEofzO48Sc+x4zNRb2ub0rcxs3APyeA95SJ/c3J9UaFr94I+ITvJ+DlDyvoZNjoHZ4/PsNi22elB2RuhO7SsbQKIU3Nh9ngyjEqTmG6c+HSPzeLezD9npjOYrsjxTcnZkMSsIAqZRSPeW1VwP+1y42+EAhmnF9vQgYw4YM","layer_level":1},{"id":"fb8ae541-8bbc-4544-9133-e797be1433e0","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"分层架构设计","description":"layered-architecture","prompt":"为 Luxsin 应用 API 项目创建详细的分层架构设计文档。深入解释 MVC 模式的变体实现,包括表现层(Router/Handler)、业务层(Repository)、数据访问层(Database)和基础设施层(Middleware/Cache/Search)的设计理念和职责划分。详细说明各层之间的依赖关系和数据流向。文档化依赖注入模式的实现方式,展示如何通过构造函数注入依赖。解释分层架构的优势、约束和最佳实践。包含具体的代码示例展示层间通信机制。提供架构图表说明组件间的交互关系。","parent_id":"0506348d-993b-48f2-936c-908972f149bc","progress_status":"completed","dependent_files":"internal/router/router.go,internal/handler/brand.go,internal/repository/brand.go,internal/database/mysql.go","gmt_create":"2026-05-27T15:42:44.0573625+08:00","gmt_modified":"2026-05-27T15:53:50.4735252+08:00","raw_data":"WikiEncrypted:Cbw4rSSRJFTkFIVuyRiw4IoOVu9h4U/miV8kuFep2zRCWdjPBNlat3QQ8xqzDjxqnwEXQuPFqO2rdKF2PS2SXAKzDQAtOrwT0N0Bb1cVz1ybTiUFKF4yLIfZkQvmd4aTaafAMRNgGZZmW7p4Ef5Gb7g6VLCa1ky2b8mBvNur7HulgiwcdOzHhqi+XnXEdfba/+4TOqQvhA8OEJsD8r89uJDnH3WUxmiulVTnh8wTsjZ/sG6IRexTh8wnXF2Z3Pp3eoQrztwivE/v2tdi/tM+xK1ZLq6CQH87mEfFjtJjTQg257NwlL8OIUf7otektOR1U4nLWYMIIFT9ZnLxCRer9o+2+pnhIDCkzxWjQGwexhyS9T7Sq09AQ78taySEDIKsmPoPyWrRxYn284OLFkbbnE1kES3YlzGpQ1BX1HzOz4I69saOR3KsmELHh7P7qZT9s8U17TqLBKRo4LWPb9lfHPc2n9CNtaojQSYBresLm4Ta7KRF27FZXJKCUr2Y7A4p1QODq8Xxz7oxjv9ItKra6FFGv7FB+vqalxx2iPAp824obAuXeSRgvdRFeIQJ6R5siQRJFuZpQJW/aigbXEWcoP3A9m/wfRe0jaxEI100Oj9QQGRz3OGUeAoz62DjwUXCX4AUuMqRKjmjvBQP/xSKnA3j/lKtduUs9QoLJ/g3nrBj+jDR9Q6FoGxuKVUCy9+0QH35x8onGEu4z2bXyyujjA6eCclxoq7ck1+KWQfmShbEqnk+bd9dTRVQMaDBv2VgymZnIMvJEvLJFyAlmW6Bqc3qZkv9C8OH+uS90l66JlXniuUHlPinlQ+3/eJiqqMldDvT3oLvYeXLWjHUquxR0LFTQ9XFrzdxuOzsjbxhKaN+FjNZWN1d/J2TdK3LtYlEMaaxGQGsUxdTQuCIQqyQTc6n+yoXpTJ7xGtIitcxvZ6lOtQnLu2VN9ID29ySBKUeNTEDo6F486yfARaPMVjKVssURgEKlt5pEWVPnPPxd5YgYqn0dNm3g+hU3Esrx9pH0r2T8ity7CL28QWZWdthEpldnZLRdQHK7yf5ZTWBjij9h7ozRglKkjrqYtDyBCwmGNGnlUN/zURSFldO1RvnFPaGPmkGSGZaMA5jBaIqKElGCIIeGQcHEvM5reoBNq6Y71tWRTS7ei1SPsvnw2EYGGgUPzY8HealmML7QlT7utxN8WnldmX+B9tvQ0HNKwQBmMzgxPI0ycy7vcx4Pb95uK2tkKZfyxCAqZBZo2/oFspYlsMKwqPF7RMfFxnD5cQi90gF48iJKU/WEb6aXUbCDZrVdhXzg6IMu6iuziM3fdFSU20A8HaJB5hfLpDSE9S7","layer_level":1},{"id":"6e42204e-3d78-4997-a95a-3311c8fcaa43","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"缓存系统","description":"cache-system","prompt":"为 Luxsin 应用 API 项目的缓存系统创建详细文档。深入介绍 Redis 缓存客户端的初始化过程、连接配置和使用方法。详细说明 NewClient 函数的实现原理,包括地址配置、密码认证、数据库选择等参数设置。解释缓存策略的设计思路和应用场景,包括数据过期时间设置、键值命名规范、缓存穿透防护等。提供具体的使用示例,展示如何在业务逻辑中集成缓存操作。包含性能优化建议、连接池配置和故障恢复机制。涵盖缓存失效策略、数据一致性保证和监控告警配置。确保内容既适合初学者快速上手,又为高级用户提供深入的技术细节和最佳实践指导。","parent_id":"0ba3accc-326a-4433-930c-5b951d4e5dcf","progress_status":"completed","dependent_files":"internal/cache/brand_cache.go,internal/cache/model_cache.go,cmd/server/main.go,internal/cache/redis.go,internal/config/redis.go","gmt_create":"2026-05-27T15:42:51.5485979+08:00","gmt_modified":"2026-05-27T18:36:40.5405367+08:00","raw_data":"WikiEncrypted:qF2VoNuQmlFJjqRbYbbhOvcXQhVMYEksE+NeC2wRMGvQM2IjYFDS9siO1iO2s+wXGt5c4G/rGBotfHAKl+KluyLXHEbz0a+A38FZJBcg/xsLVn81ZMr/D2bWrBbJn2fpjSOko3snwikV7KEicvuTRLfGF1uyRD9yizrkBo2nom3vkAeT2lpfuVOpR2K8ziw+iZjkPanA9ft0p6lRydJ1JwCvJgauyfLtGQALZRi9tplifkJF67PdJVggGG+PdKlwoicJZ7CUXJDkAbaGVZr5ymUdKpVvpKG1qcLwU2j2lZ8AOZTvN64+XL+tFd5jH9zbEn1Dw90AfM6PdvqFTNsoEjE0Jk4atkXxxmQ+5YAchazygCjDmM6EsQgcChzHcQ1hVFusjC3Klt/750WNEMXdWPN6ZKDN+mdZcFuEX+TWLWrGqrC7bJ1vvArSMTCDOtmsx9XK2O1OkKu4Yt68Cw3G10JtB8aTo9uoK3dWl/SYtd5+Uz3pz4DOOXVx5BnQ3B8rTX+eKpDGDNoIQ4g7lUpLn75JpojKpK0Uf86/26FNBifL0DlkOBNPRBOykUd6SlwQVNrTRVTLeulhFzBh80b3azCsjj9FpbZ0QvpZ50Sc9fzE2yUALx8W3sIgrOKiJWb678CwiQ78abW22G1QZm0vdr6m2mTtkvQ6lFOvQ8cv9iKuM3uQusE5QVLmrBWkKT3YjsoyXWJyO4LmhkoCCum8ootzLJRbAM8RzcHBRWMi3vLkTF/qt7TcTi32nJEyxJKgWrbr9HJRnYwCGAHj9eGBCLbzTQLW1jkitLBsC8DrjKiCrD8GAlxYOwqdZMJisYcnxxFYqIoVg6/kJCFAgC8kyXn4eqYpYg2AE3eGNJlJmLXkkYJyowYdd2iqWts34bcoIKZ3bSe22uavQ1+HzINa5gRRgl0c2kimg2JxvxS39ZWcwsRwx842zMaTpYnL3biUxHNksXTQYvSmst1iuVUgUZUsVcEZOrTLtoxA3/Sos7KduaUxAyx3gaJt7vIh69kBNStH7n0S9n9bPr2EvlmZ1rXbfQ5004Sp3gbTBD3iTlF5CbRi6TcUJbFpp2V5Z/D5ghV6Bdd/gqOf7BGnHu7zAA/RGylp4QkLWfNtREhSn/h/WsQv7uvgvlCkmCoeAb8pnFa1aqu2nEFV7ugmL9iU92hvqgfwCcpRKnjJrAbzBc/VvBY2+mRpjbZrhnvZz8MVdZouSbaJbR+3wTeZPs2/s7co/apOf8cXOBEf5w3keVlHws6FkTrRVuSXBTby3kjsFVd97eFEYI6F3SyS7qg/Lz3GObMQJIqITwH9MN+kQVDVf8STYkmM4GAGfv3QMeNZcs5BdeDIPWibN2XOs0eqHsNHlCVV821vMW7I4JAu47667AlZ90XTG4y9javLSyJ0Y1iZ7GHTzywqrNwhML3fai5u81qYEck4NQPx44U+TpIRnbWoRJTVR7apgWuf+fP8h73g6wSgp6NnlneITQmVk+phyp0M4aE+ykNmZr6cTEQCQrPb1Q5B+FjG3gIT+A/bT3J287pdji9TRQR6+iTeJpHTnh3k6R13l+o+TEDI1g5JxmOrMAdxH/rb69JO3OWU","layer_level":1},{"id":"6de9a03e-f360-4daa-97ac-dc1cd1937916","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"快速开始","description":"getting-started","prompt":"创建 Luxsin 应用 API 项目的快速开始指南。详细说明环境要求(Go 1.22+)、依赖安装步骤(go mod tidy)、配置设置(.env 文件配置)和运行方法。包含开发环境和生产环境的不同配置方式,数据库连接配置,以及如何使用 Makefile 进行构建和运行。提供具体的命令行示例和配置文件模板。解释 APP_ENV、APP_HOST、APP_PORT 等关键环境变量的作用。包含健康检查、品牌查询等基本 API 接口的使用示例。确保新手开发者能够快速搭建开发环境并运行项目。","order":1,"progress_status":"completed","dependent_files":"README.md,Makefile,cmd/server/main.go","gmt_create":"2026-05-27T15:42:25.0297402+08:00","gmt_modified":"2026-05-27T15:45:02.5503172+08:00","raw_data":"WikiEncrypted:qfgbutC7oyxR6nMxrwk1ODnNMBEQ3/sG78fQT1yXWju83LC7H/jAM8CEAvWT8huE5OClmQiIfNYNxHQ9s7RRS0qKOV1Xow/Q40Lf5w81YuuThtu0J6OFTGB2L0Nm95mISVZMGD73nREHXw2e/m/hzrb+N8ZuuUYDQ1FQZZcmT6YP+CSB9cZx9b8UZDJ08MCgp50aJvLLku23MEdwFc0gj3Vn9X1djLPuceJ7dwpUG3aeQmdLHCtxnEu4d1LuWHOx9SORMidWdUkvBpxZh1Mhj875BKw8zi1Bb10CuOVR0o/umWOKMxS7pa+P+krzS6ZwgQk/HiWvQgzcfGvyyQkIUoEtVfRQGP8gB4azIvJ540SopfP4dNI7lFdjUOwyTR0oyYuzDc8Y4dPgrwjMNGFkwRmsbMB5f9fKw1JT8+BoOVDOPoK1gHP/uXWcZx9Yg92aHtloj/wlf0IvlSbGhTfmFJrO/wjuSVP5sooJD9GCuVzNgSDitGoZkvsycpn320vlVFUPXtnf/VH0JOo5PM7BMj/zshAL+vsXkYjllDwZWM6DYEyETEwa0kfHBm7pTZ2bMQ4goUU1UQAPAjjbYf9VJAWxLZYVJf25SxXbn1u/PDKifLJNxgXRJg5OyBhyIL6jTJf2fuXyNcczL0GyfRvunp1WzofE6bAl15iIFcNABHPqdtKOV347seHgIIbxupRt/eFgrh5u1k/i5XAKbSXEquVhICmh4waR9rf3HeYisd/Nvj/4cpJISkhNXsY6Y4AsIpbPl0jiMSVt6jMRFgTGG51WgeuZoVPzdIDJMhk5Rc9mot1q4rK434Mrv6TJamzkwU5v7z7zy3gNx1C7wf2f4tHTVCj/Gc4KfVU+uuMRKcAAPB9bBC4uoO6zcPRroMIr+NLZN+g2CdsZ3FbJvsw/j0KEtYP8EeQ3bYak8dmhOc3c/A8LN+8UIlfyxmY1xVgbu/fvkIh9NW+GktKxQZcPfzS9ZE4KL1oKMxW9uavN/xE3hjtivmOAdhyqBhchbo6uwaAtv18ZMNOPoWLrgOW58/NlHdF4abXrwuX3YUwJHiMsjsgV6C7ZnTsYDrwXYRETPr7XXOmztvG+nYXkaHujEQtdAh/mf1KjWTbyY9qBthEG3zBTZ4AVcKt15anR6l8x7Of1pepg67m1lo31a+QlxkvmZdH6vV16tMnYHUR/UHYdSIb1yknP96PdGpWChgEZL4bynWLBFveZQSEhM057qMj39UgMZjHQd6YGbwA3ma+BnBwAMHKZSvFAMWN5arlTN9ZP2iLxhhiNniYPMQXdTviDJPYW2mRXPAgEhheln74="},{"id":"948e0792-2de7-47b1-b73b-e7b246e749ff","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"数据访问层","description":"data-access-layer","prompt":"为 Luxsin 应用 API 项目的数据访问层创建综合文档。详细介绍 BrandRepository 和 ModelRepository 的设计模式和实现原理。解释数据访问层在整体架构中的作用和职责边界。深入分析数据库连接管理、SQL 查询优化和事务处理机制。包含具体的代码示例展示如何使用 Repository 进行数据操作,以及错误处理和异常管理策略。说明 Repository 与数据库层的交互模式和性能优化技巧。涵盖并发安全、连接池管理和资源清理的最佳实践。提供扩展新 Repository 的指导原则和注意事项。确保内容既适合初学者理解架构概念,又为经验丰富的开发者提供实现细节。","parent_id":"8d7c257e-b299-4adb-adfe-bc0ddbf112b7","order":1,"progress_status":"completed","dependent_files":"internal/repository/brand.go,internal/repository/model.go","gmt_create":"2026-05-27T15:42:38.0130833+08:00","gmt_modified":"2026-05-27T18:35:41.8040874+08:00","raw_data":"WikiEncrypted:Zb5TNaG1u/mRrgPr+sDyChJtzwIYFTCqYOjGU3g0QRCfpxhFN6jbespPa8XDdb1bDp3AuvsVCECkcjmD8WGzuQA6ZBzaDsg2BTmcYyLiBU/fXFxRrjQBCKhw7EdY9q9mOD7xeV09cQ23lyqcZ1JxiKDMyZTkeaZinSw+CyeLncwBBkLF7SA+EUpvQg5T2V6UUZzmBynfSB91UbIwQkn4YJPkneRGbn4aSt/0AHOspw5uR45u8Vxo4vtsybyyQTwHZ0yDHq4kShUwCZUHQQCG6HtsA+/96zmlyVwiXTAZ0kDAkHvZ++i86OYR9tu1n0aKlFZ+TH2+00rQkh+c9XHW7S0/hHRX/JUjpuMRVxxoXAZ75GMYLIysvB/824kykkYyRbo+CFGYaiZ9NtwDTnSOs8Ijn38NFtETIPLu7TMiyF66f0M5i+C33aR5R3t6rd09ndi9opSCgekwPe/HFN32wUXiOhRQDFmo/oA2sVU+pF2Bc2xuDkJxuI9xhbYbVhtSVCyfKhBhxhZonBkonYsNsJZo/6O3G6BEFTGfNaxPgZdLMyWfA98xtzf2SgxAV1vUQro05XDbKk6dOFXpgHY+4z4xNNhAF4hGCwZrBeSz4yBHijT8GhIkcWP/JfkjlvtlBh39P8TiXdLb51y5Lk0ZIF+bkVeqSlJhfubmnv89A+Q1tKx2YK2fZkp4POQnQHG2/vmE3ZhJLui60ZSChiJf3ZmEwjjlmlbD3BQrq2hVj3k13oOV+GRdK5tMxS2ahYOc4uejEKaHZMm+yH533dTR3rpOYPYj2Y/E1GnYm0fQF+Jk6n2SAZEfAWAOMR+T3XfCERWYX6vJ12sO9r3V3Ya1J/ozczYC4vfqXIgFoIHUQO9hEyb9Uluj/u0uzjjJsa6j07LqjPJf2/GKThTbHE6+U9Ux/fS7oMiVA7jTlsLENTy4G/jkoOShYIeF8LLiDgaHHCXRP5a4SyK9Hg7ddgMvIoVO+sdfEX230MNSdy7R2rIPG2qi2RwhXgqOTychDohgjd/APhZf++/24Ci/vxfM/h7vXAmjJmArYIsoqCQdZrxdZh8mzN/mKKAYOvDHlsjmnb+a5AEZKRQlHRDoDvxdcv9K3nDrnrOE3E+xevf5ZdE2Gv61WsNpGrmoIDocBgfWKBHs8b6aTawPHWegc+IpPNb9p/SfNyGPP98TJFwmY88AhznK0Q1Rb+4x0WQUXfmRixT2/jwTeEIWDSRPOVCEXMX43u4TML/3bXa/4w+NfF8WcfiVyOM7JLJXGWPz6xT5DtM7wqoofnzzSy9j77ctcyaQZk2bZi4RTsbXhmR57IwgPWo5vswk5fpmkL8doGwBCDTcnK4x2Ri0HSZ1x0QvuVccU1jYZYgpgu3Cej5F5dTy4BsNPYksGiKRXIQoUhYYo5iA542Tai70Q64rOPyl4gHoDQXclqKtqJ5jWy9Yb6P8pHNkkCZsVr2XH7S9at20Wna+f/hC/F1sKLkH7XCuWQ==","layer_level":1},{"id":"8b3ba473-1cf0-4471-a203-9a87732dc227","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"型号管理接口","description":"model-management-api","prompt":"为型号管理接口创建完整的 API 文档。详细记录获取型号信息和搜索型号列表的接口规范。对于获取型号信息接口,说明 HTTP 方法、URL 模式、请求参数和响应格式。对于搜索型号列表接口,详细说明搜索参数、搜索条件和结果排序规则。提供具体的请求示例和响应示例,展示不同查询场景下的使用方法。包含搜索优化建议、分页处理和性能考虑。说明与其他组件的集成方式和最佳实践。","parent_id":"8085e1b7-3658-4490-8b52-9a61f3e79976","order":1,"progress_status":"completed","dependent_files":"internal/handler/model.go,internal/handler/model_list.go","gmt_create":"2026-05-27T15:42:40.190927+08:00","gmt_modified":"2026-05-27T15:54:37.2236089+08:00","raw_data":"WikiEncrypted:o5cr6Bo4m333A3G+lRdTT5dIP53cxEH82N4y2QAmkutwkd0KP3KAvEyUQN0CgerucfElkuIsDGzyGuldlZZBSDX//XqOqGZKP+QnmlgMLhVVCpCNWw9EHW/qmIVTQJxBtumOVtR8RGgSMrfzxaMVsu0eL8ZY2bOrDST6r17lVTgdrEdY1nQ8/+B+bkzQ65abRsvYiYrspSgJteye8d8XhEaqyOpAsROLv0P50tvHHJp3pH0uNG7lrGmAIe93f1OqwLCINSCxfZ8qPHLxTT/1qsC8mBTfx6bux1+J+Dfuz0Fr25e9dCzBo06yz2oIHMpYHNOV9TTNo0Cb2bY4Etp7T7BAVAWYdmCPqkIp4muaajavVH/dsG3SIH9RE15781XFeLnZpjK3/6SyXbQzhkntGT6UDzd1f7YIF/wsYN+uji3Ytz2tKz+YuJAr2Eu+YAeR5ONhXxZJufNXZqE6lFG0h7UGc4EYAADRkXK2AefSD9qXzxvGet5VJqYDwvW+BBTRWQB3HtSC4RgwTj0pGPjrHyjdXRtYabw+1Z/3qmXraEjCkcBZqY83T3pyfSdpygE/Tp7yYYmPu94xft9AqhG0xbLEJMTwW0ad3sFR22W7PkIMegzWRGtSSosiRq883B7ZAuea6PE+DdpILgCSAnEaNFgOXp9T09825iKyPsJ7V/ePwhLdj5Lg1Sf2Ar4u2WoKKzKmVNMqngve7AIqYVhGA6hn2tryumcq512jTxKeeMrtTR1kI+kuiFb4598z0y5j8dx7XsYW4ySYNYOvKIRMNvH2r3hnqBb5pvFv9gmk5vsVg/gSNlN4VOQsszd/o2lXQfYUaon0zYsdmR73UvkjhZMnufNa5tiCXZIFdcP1BTWDeBT/f2uOsftIky+JZFoyv9ZKzVesewLPArJaSxOT++MD/ggK/zn1vWZEgWgNcONx3sbyJnPoWEw1TiNMe6pxO3VXzMjnyIL0cie5BeVP1kiQ4S3XzkediOL2bQt4hjEMPkSuuLR7ryE23zbkEZpvwV/2TORoBY12Ii6KK5Ezg9F+aFO5SG2MvF2IZyMgpmnH7KIBfag8sIb3o2RSK6zo9lgRYbXsw7lfxPpBtPyHNpHfqIYgOLYptNzC/GBTVdTQYRLULRlp1XeXxGw8mlViYBltq/GwBlmKbMKrLjsczQPuxFX9mgcnTntc2Op+0ITGX/cW8pMa+UlI2Jgvay8k","layer_level":1},{"id":"ccdbaf47-6cde-4ad7-95f8-5b92d33e2440","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"路由系统","description":"routing-system","prompt":"为 Luxsin 应用 API 项目创建详细的路由系统文档。深入解释 Gin 框架的路由配置和中间件机制。详细说明路由组的组织方式(/api/v1 和 /audio),以及各路由端点的功能和参数。文档化中间件的执行顺序和作用,包括 CORS 处理、日志记录、请求 ID 生成等。解释路由工厂模式的实现,展示如何通过 New 函数创建路由实例。提供路由配置的最佳实践和性能优化建议。包含具体的路由注册示例和中间件链路分析。","parent_id":"0506348d-993b-48f2-936c-908972f149bc","order":1,"progress_status":"completed","dependent_files":"internal/router/router.go,internal/middleware/cors.go,internal/middleware/logger.go,internal/middleware/request_id.go","gmt_create":"2026-05-27T15:42:44.0579461+08:00","gmt_modified":"2026-05-27T18:35:29.939743+08:00","raw_data":"WikiEncrypted:awWreJ4vbyDoG0xJzdo9962/EguU7aHgylmLV0bXWudK991xRrNmlNXm6cdg1D0SLArIcaiebnTiIk5ALRoah1F7N/jEqTOdtqzUGvhnHHdkrdGKp1f0p//OiusAVNsUuzORJk8F6itQjg8sAzi99yjPWuxCoN6aFxuU5DDarymBvIgYK0CQgdSWKWpO3FtV08sV53wIddgHlB473zJxslXmlHxrqhCFKsvglAmKSSt22PPeGPXyKfKPXHvsBSLYicPvioimld86vMFqWGCXDSQDW3kmMOB94ARii5vldIVpP03ADv2SZjoL+Ud9+r8ROzHMdV/WpYKBvnC9QosSPRoQEE47mfXwV+eB65JlmVFTrURS9AImcV6aGhHmevyQMUt/dhK8C0eDxkoAXK/A9/yyWUEmd1NjNWqBjaZWVl/pFeEhR2eOKOIeB+UXVP2Lvakdksugbqcl/GylW4s4KtyO8mNHgsSofjrbh9MLgeZ2qIUWCEMflmtGYyeArjX3XihEb7LM+HraWDvkCDlrT82wSLVUnZAuooAhf/6ZhYBx1CnqvUoBquDId870T7PL/zly1HabWTLrWdBirLIjb7LZnJQCxmjhNNZdEXRTin13TqdurI+qSjJE6h6Cr2QEeblZheFaGTOZWdnZfcEoUKSGnr+4lAiU4WKuT5lUjF1337ohm40FiwQ51Vs0wM40mL5oIqfsgBx0dxpM+qoRn04cUb1lQQmdfUgj6AAC0F3JDVGF9/gxPVl/QMZH8QnUrNiDQj+xf67ilGPLibQkxKL9j5a6im9seqxZ+mKLuyJUNV9DRXXY6OXoYdjs5vzWDRXD7eApmYRml9IXGVOV+wXV157vDK8qXansO0wf657i/HImAUGe6NLP4r8a5LN+gBSbhdwweM8Pql/MIHT418oeIoS4h/7XP+wQuNJI3P4P9nk5ABtNRa4FDm5jhYOMC8nseUHuIvsVbaxiuqEdUsphInfeZ3JUjjRr2D73xXesdkqqfWfRQg/Zs95Tgbj5imbFKEbDXsSfz4rXyeMYGU4b8w7/PDmoEtH5YXvjNx7qZ+1CY0EeShg1ct9fD4PRzPgqg3m/DOQtCDJThysXe40MnfEBWVuADAxnUppmXUjv8/7cRgPRwshyXbbH3YknK8n4ghKebDlNyAI3wdT8DmwYzybxkOCLbYuGb+SyIy+7RfDySsj+RxZAhNtDfokTpBWh2B4i7YgNRc2mhzF4cEarUp/xtE+1BGqvxqF2PCg=","layer_level":1},{"id":"5b9847ff-f7b8-488b-821b-6fdfe2dbde40","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"搜索引擎","description":"search-system","prompt":"为 Luxsin 应用 API 项目的搜索引擎创建综合文档。详细介绍 Meilisearch 搜索引擎的集成方式、初始化配置和核心功能。说明搜索客户端的创建过程、连接参数设置和索引管理策略。解释全文搜索的实现原理,包括文本分词、索引构建、查询优化等关键技术。提供搜索 API 的使用示例,展示如何进行设备型号搜索、品牌过滤和结果排序。包含搜索性能优化技巧,如索引预处理、查询缓存、分页策略等。涵盖搜索结果的高亮显示、自动补全和相关性排序等功能。提供故障排除指南,包括连接问题诊断、索引重建和性能调优。确保内容从基础概念到高级应用的完整覆盖,满足不同层次开发者的需求。","parent_id":"0ba3accc-326a-4433-930c-5b951d4e5dcf","order":1,"progress_status":"completed","dependent_files":"internal/search/meilisearch.go,internal/config/meilisearch.go","gmt_create":"2026-05-27T15:42:51.549218+08:00","gmt_modified":"2026-05-27T15:55:50.6500526+08:00","raw_data":"WikiEncrypted:uPtIvUbMezH0ofnqqRSEthHE63LUAQzlPWMsHoJP+/Xvzp1zu9yMhdQo5+5IhHnrHX4ZOoo974Mq5SbaZHfjDGkMYXk9L6JwG6+nNMpoyLz7Yvtg+8V5E/tIsJ5Kc6+iYBU1An8SAJrGuA0Rg8PKKB2Lomw8RjlQO6aFo5tapv4T8ZcTSCEzPetfEDt4Ire/BS8D0NCO9C5peTRlECqqOr+U+OC5BfaXaEvAAPhu0+2LKV5pUWuqhJB8wS0sZ1C5WaKdq3GSgEsQPwvpw2BQ1jRzPp5Gw92/L6CiOkLBRkvHdCH9dpObT+Fc2bTPTxchCzPA1QxWkqYjFOEzIs4+c9QWuFqGuEbrHq+Ferc28nVGyeEv7Tu6l6m0Xe3CTg9tqdBgkd6r9Y4uV4bh0didngLNjO9xEjQiYo/ssQ7aeCgh5CY89JkKjbhy8iWFLtMr0REWD9B4Tb/USBDRMoljXzRJ+rOWL0o28fL4U5wl0ZRerKn1Z4oHbe2uKMx1+wXerr7aDOXN5JCqdJfUuX0X6xn/ZHUrsqiQHGXkRCXBeXGZYjdzLtsrL01/BtT1EzCiD0xUVjPPE9dWXXwHexSANSMPsC/RJmvwwlMon5lzHXlWN+FkX1N1OEax+N8FY1eBxIWLiwUWps0/IwghwilZeXcNGiuUf7skRlvM6iTjpc9QQeyE1h7qrU5x4xCrlcYc2S4pQv+WEFB6Va33skBqhNrCO1vIUjki6nAesFzcnPJkaWwnmEBipsjs1BuIUK3wxXWrnpgcFUZbb6WvFF2WRI15NCO+jImJ4SSo2vAvVRKF5JFtZlABOifDyJCkfMwUyU227ch0TmMp55pYqp3NoLQ7ixrqRxaPvxFda40SlBqKe2Yzuiqm/73r4Oc0T1zXequgzmTkaZtRaq5yqAJ115HA1HLcYITiZngQbSWTnPeVbWsb+DCPd33lIKZ8fXEGiNBs7vdikdYx+6vF+1EsrQeSjHfD0Ihmk87cLn4d9La5SoLzDfOVJEy5iZpWO3AaUZMZ4EcPE1r6ZMeZ8EUGqXQ9Nlpb4InQHP4W7ghwsYHtL5FFeja4OeMJNBxHgnOAypiJ8tPVobpLX600FfUsZDv09Mcr1xhbylBxsRrlqA7Gn3sOfbt0DZUG0uo0Rk1ME1x2rP5Xfa5lQH0t+tS5FpyP34T6dwqMGEtcccz6Je3BiN5IyE+vUyFHw+FdZ7gNtZ0hDEfzwP2qOWZT+c3Qsu+6MyhWHPs437C1isiJNawoEnOiqCV9kWhig5+ztneMD35zhcCTEgPu/Bm/bEThy3Rdd7iZFBdoU4vYaqKC7n7/DByj71DHngfpIkzvddxnNY3z+MxRPwwc3khnmY7jvA+4rooEThszp2Uu51YkzKA3R8OCZX8akGsfWwzUIQK2BB/CZUj5Y837fb7vEzAC6+ILo7N1OoawujgMXPweHQI6XDnpbNfOnLfNxXqPfgUApYzsPZoGGtPp5WSaiLcCw6qMXPNJVzEQq2wysa7phID6rq9Pl1LQxzlIH6h9p8v0IkxQMMloAiN3ufObHM9ygq7zggt971iApCCae3R6XOA=","layer_level":1},{"id":"0506348d-993b-48f2-936c-908972f149bc","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"系统架构","description":"architecture-design","prompt":"为 Luxsin 应用 API 项目创建详细的系统架构文档。描述高层设计、架构模式和系统边界。详细说明分层架构(表现层、业务层、数据访问层、基础设施层)的设计理念和实现方式。解释依赖注入模式、中间件模式和工厂模式的应用。文档化组件交互、数据流和集成模式。说明技术决策、权衡和约束条件。包含基础设施要求、可扩展性考虑和部署拓扑。提供系统上下文图和组件分解图。涉及横切关注点如安全性、监控和灾难恢复。记录技术栈、第三方依赖和版本兼容性。","order":2,"progress_status":"completed","dependent_files":"internal/router/router.go,internal/config/config.go,internal/middleware/logger.go","gmt_create":"2026-05-27T15:42:25.0297402+08:00","gmt_modified":"2026-05-27T15:45:15.0922502+08:00","raw_data":"WikiEncrypted:EPw1VhZSv2AMLpYzHbCG5QXmatSKh1iukhkKRz99kcWlEvnOwuqXvA4ZgQ6tN+ytovQp8yiqJicl84VZMQ0QFU2VsQju8IpcRws9R+O5UqWqyS/p2d/juMO7CcvH5Z71CG7eM55PPWPy+SJ+QNdupFqroK3bd/LSj0CxhfnVajICVNkUN5WBZxRD776A1wRS/9o+f2rU9gRAuwITsrHMLAbGKP2R4CWvSRvdssG+ipznfcduSvnmuao6OKPuV4jqBbRKw4zcI6RvA8OzqjvEzd71LQGHM4pSLSZHCpXNsVLsyx66RKMz2ehGMgRX9mmwX6tatCTNGRawqOaeHsAdZQVRO5F/B6eOmBUnLjBLXMFaj9NiCqZXNSC4hsNcV2NHNsgCUG4d5ZrRt08xhKOHc0qnU6uPcmCoIrcH7BzrDe0ZgsfQ5XPv2VLskL9VH7jP/iok3665UNTbFEMp+0VrHrtj3MGwZoOPjci63/k3b7LG2CemZFYRL/bBs4bMFcslJ5zofo0Udc21Z14UtDMqmtYl8JWFBrQXBiQmeSQ1WnHwlcbw4u7v98svD3w+hug0ZVtbBIzPxwFMvWxUfRg4bYDfaYuu9TTbJDDZVS6Ob7p0LyJNbyCA5QPrEI1J8F8PhZ4Q4jLG7aMJugVeyzmc86juCVMOMHEp/N4hziN6xK/qRiJHM3tNljxXReJi4IufNYJTXLNXYKvDPvBIyDFn2dE2mCCXqEozsEjZ+v1q0e/qlU1dunYg8xPxrsTLDcF9K1BoyCvSx+UQiB4ONUP+JxX64QXTtp+IU0v0seB2KMrqPn0/L+A8OWuXVZTvRwPavFOv5itZOdJAwA/V5N2eufZbLHqMglD8xPwtGKDElVmGnIo3BZVNSoRZySK0fotmIw3xMqHf/TIgp731ZvXaZCaKCnXvHmW1NCCQkqFwBHBcq3S04NwWv8UMSj+HNCHd++vSABXVmaVxgqblXcKffFrA/gNTjqBgt3JGZZI97/WtLhJ5rCuiZXimpuKRBCG9Mt4/TZBFvL8EtkrKKRM7s3qaiXo4+rxMwzBW5q7TSyuCkv7qZLVNg0tvqAaU87jlHeLK1szXHS95TJbbbwjv67i8S5YYoSfZZg4iWUWizvHjGv9xeSfB5oZEfizx8EkEkD6rutxWWUarg7NVOH0fJqslwz3lkocZU2+RLK2kbH+JbCdYfCoZ6SYU+W5JDYAfSxLyvGhW5sDb3XXYFtD9X30uW8TOYGcvIRawRJbAjmJmdlrT+9rFcYHVaBJHtLDAkEnSUMNTxZgsSUCulSQNjxAV66NfhnKRsTJ2+M3dqXj4LldBrlK0CwEZUrmzutKSXsYqB/x3yFnXshPVlWG0HqDXi77z/VH2PwAlmUZi30yCiL3c+D3rtHVruIK0y7+TJeQIcHCK8c8WmqIMeA6Zauq0wgWtGrI4ShyR+BKhcQEtCGA0ZPrOitzD+oByp9nJy/p/jyDoJ2KbQk+UK+DxYjyyeOGMh023Ioq+pZwhbHjNF8MPtVdr/ZTBpHSWIfgC"},{"id":"e81027fa-c24e-4492-8100-f051facb89c9","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"数据模型","description":"data-models","prompt":"为 Luxsin 应用 API 项目的数据模型创建详细文档。全面介绍 Brand 和 Model 数据模型的设计理念和字段定义。详细解释每个字段的数据类型、约束条件和业务含义。包含模型与数据库表结构的映射关系和 ORM 映射配置。提供具体的代码示例展示如何创建、更新和查询模型实例。说明模型验证规则、数据转换和序列化机制。涵盖模型扩展、版本管理和向后兼容性的最佳实践。解释模型在不同层之间的传递方式和性能考虑。确保内容对初学者友好,帮助理解数据建模的基本概念,同时为高级开发者提供深入的设计考量。","parent_id":"8d7c257e-b299-4adb-adfe-bc0ddbf112b7","order":2,"progress_status":"completed","dependent_files":"internal/model/brand.go,internal/model/model.go","gmt_create":"2026-05-27T15:42:38.0130833+08:00","gmt_modified":"2026-05-27T15:56:31.7808704+08:00","raw_data":"WikiEncrypted:klcgW2PbPxJambbKMzvFtzxL0nPpsuPMPxr5hj83lS7zLbVY013R4TC8XNEUYbb5qxIyzNIzP0UIL5gcgWgb2JN3lLqRFiolKSir3QefPwOA9n9PyEgt3UyqdWtF063zcOhUCuBNMrBuPrwe5CLRNYPjpeT80bmhf1WCbW0Wc4soOdqZfNatqkw2uzcHw6lRPr2OtTCqznVFik3UW5X7OSPl2Ttad8DOmCF+RIgP5/y9rHCmETZIEnQAjeyLbBXbw6UgR8f5iLkYVBNC7MFGFybSCmqrbPvzuYIucnF8DA/OBQbccvz8He0YhGp5Ug4qlUVtOLmA0SeYTnT3k5tD1obbgsTO4qQabKiW63BMDIgOoTKlnAxC1I4m+7qzShvq8Br3qYdH05fujRftdqvZ3vwdt/v22MmEtMVDy773q7E6UAWYYM5ZFpzQm0FMEmNSl01+1H3g/6NLTH9eP8bwh87Xu2V+U7zgrLU0hd3RZ0OahjypNpLHcMl2lXk/R7L7r4rqIN25hBQ6UmXVTgJaiLUx3de0ar0mjZESOIFPklc2p7+a+gJKnsuZ302S24Iqoj7AavR3Pi+VN/ZiDIP5Jeq/kr9vnhFkMn6zcXxG9uhrYtLkssRve9T9PQea2j7e01+V/IRE1erymaIw4LR2+ujdhB0V60mQlH0Z/YHMAaj2SBzGB+QTLKTIYabYR2UvD5j+cjFoa+Gbv0JVt7WMtqYL+CA4hSSdAuR8tMIXc2t2CcnnQa5O6Tn0MfMrcJ7Vdd5GeLy3KLSJMiyAdGf8tQ+JZ89A+1fQXxuEAa7TZZ3BB2Y832o5/9JIpgOQz/5oUXiHMQMoJPg6JwkfMJgMgWRzYBfhqRR15ceTQaxuMvii3FPvdiqa6G37kowws9zAmlHMZWT58FopOSivkLJCWodvWMrHAkMS8z8bai5nPSMfxSVyZw1PIyfCY16u8WPVBvxU4hqjJyB5Bp8wM0yN5480l3wa1Q3fuEzaJKj7nPjtU4N9gPI8QOahBMHpDjUDymEe2pFTNRoGiNEP45Jp4RyxlYSX4cFgV4meLKhbXpXHiY0dnAaKfBc9jAtgWdWnmviK0GLQ/jILxdrqE0PICXi9+4yqSRI2Ry0zpRi3qp0Y//pb6taUy+j56Vo8zoIsZTAucPdhoOaagkLsFMjiBClhwGTCL4ddbbDqwou29yxIdZ74gd0bOsbOrVf2Cle+fOknD4NoXKDGYaQ+KHd3gixYUsoET/IXmUN0vFu/IGEzI0R0XrwFDPtjlVbg16+Sht26Ty4kWon1FNcLN3BCZRX167pLM/oB/mh/MdCRdaEZ0DoXfwegSeXYwGho7HJZDjiwFdafr+1MXjd4UgRw874LAKL9N5H4GLBDCG6lvCQ=","layer_level":1},{"id":"8b7558c2-be32-47b8-99e2-1964009b4337","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"设备管理接口","description":"device-management-api","prompt":"为设备管理接口创建详细的 API 文档。记录设备信息上报接口的完整规范,包括 HTTP 方法、URL 模式、请求参数结构、响应格式和错误处理。详细说明设备信息的数据格式要求、必填字段和可选字段。提供具体的上报示例和验证示例,展示不同类型设备的上报流程。包含数据验证规则、重复上报处理和数据一致性保证。说明与 Redis 缓存系统的交互方式和性能优化策略。提供故障排除指南和监控建议。","parent_id":"8085e1b7-3658-4490-8b52-9a61f3e79976","order":2,"progress_status":"completed","dependent_files":"internal/handler/device.go","gmt_create":"2026-05-27T15:42:40.190927+08:00","gmt_modified":"2026-05-27T15:57:09.2032126+08:00","raw_data":"WikiEncrypted:W4RZ6LTz4rg+RteR0TdbvOUiHqohKn6BWshWHivzY4jjRdHovfIvtJ2sB9MDcSrupgUsB93CF5gLCd86HZ+9K0WcrorZ9lipKx/OS3vd+kUisB7ExUabBXlss9QTm91m5fLHe0jeTIgrcbTRB/E6TiCq7LQKIbDT/vX8e7gGsXm7c6bJS+oGkiX4dvfSGGxPsTJAzByQh9zKq0+EB1Cdehda7LhobHHhD/zrFU8gTYLmATkOqk43kMtWFXfUxZx4vfa6jkkrn2Yy9ZXvHFDce0ofKtOVLfq3hKZi9k4owDfhOWo1Diy53e4Nq65RlOEImu+zThrRgYRk0za0MnIJRjTpwcuh6BKDwprXShIUp4xbiPG3TFnnTMAA93o2zAcKGb2Ca0Qt/QT8wY2uCxaVwD0GXGQGpI93ttiS+EfxOpjoxc+xkTy77AI8niJq+SBImduJC+de4cefpYZZm2E9MmZSUbEbDEvXBi0kIgnFiSH/BigSv1UA9JM4cWf7m3AvwqqCGKN7CNtERiJxTyhs8xDKqxeoR4CRHtZ0Po30nTlEXMrgkyjlnvdlkRokDUi1ZrRl7UvaUc7IAQFie+6dHuwt4/iZkuQJMydlgb3ysz010zMUXCSWtnqb6yQi0Y16jkKXmPgBl1ifYkUYzIrMzr+UZZHq7EwLVVjj0SWvnNnHeWgSst509csZcp36C60qyP/+8XjGBbVMUoTVonu89qUrotxb4Dr07k7YzT100WjET+IOcrQfLKiHM2SO/HyTfGKSpS9/T3JoW4mI+tVwFQ0QFEey51AmMN72D9I83sYo/INqWjC4cAhHr/IiAxVTtcj0s5xI5pGgOAv7XNXGFPmc4X+rf4C8k6zxIWMCOirykNyiIF2cm8i/LUJFrD+sqdGCVdilSQlsEgs0Gf0faUDYAUNQdylOw+rNDrJMNPGktUsoxfdb2WBc63/L7nV6pPm7NnpU0xCDhtdG0/jq9hEyEESN6V7L7bOvG/csrwRuKnJZ65RFZNlodDK+JNRUhn6yPOkrG9uC0NU12cyBY+r8Su9MV/6ozEnnNWpxhuM=","layer_level":1},{"id":"bc6825c8-9aa3-4f0e-96ca-ef4925af0570","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"依赖注入模式","description":"dependency-injection","prompt":"为 Luxsin 应用 API 项目创建详细的依赖注入模式文档。深入解释构造函数注入的实现方式,展示如何在路由初始化时注入数据库连接、日志记录器、Redis 客户端和搜索客户端。详细说明依赖注入容器的替代方案,即手动依赖注入的工厂模式实现。解释依赖注入带来的好处,包括测试性增强、松耦合设计和配置灵活性。提供具体的代码示例展示不同组件的依赖注入过程。文档化依赖生命周期管理和循环依赖的避免策略。","parent_id":"0506348d-993b-48f2-936c-908972f149bc","order":2,"progress_status":"completed","dependent_files":"internal/router/router.go,internal/handler/brand.go,internal/config/config.go,internal/database/mysql.go","gmt_create":"2026-05-27T15:42:44.058506+08:00","gmt_modified":"2026-05-27T15:57:20.0074643+08:00","raw_data":"WikiEncrypted:Mh1qeXd3vDrFfJakTA2LVPk895/C8yZ/nxc225NJgc/vaOsdHkI/4otOCFkjHjzGbvDeu3NfvNrTVuHfsGzx3dTon6sTOx2eqYzt8f1TpTMBkynZ464lQq/2wtKdG64LJ046YBidJFw0ZIeaCnDrSGq0XciHKDBtepVmFvc3BWHO81I8gofhmEgiJhls+KdsMfDjsRa7M0G749YeIbqdVds5ERm7uOgH8tBY2YpTkxOsuOlArfwWtnc/XtjHNW1JrezQd9Mid0eOpxaMqgE8yaFeTmGavv8vNNdwkPtoQaRIZjrbbiqxTvEUceUQYbCYQRtN8pZ3IPUSyl/t5LmjfI8kcvGH9WDuz9YzeYHPRMxg8qhmGItUtY5Mpls5ivH/EIhLrZokNcrV5iUHEjmqb+XCRa4yG0StkWI/9ZNKERgMX67LixsijqQn0vqlkUufnCRPCP87EnYdQqECcP+43/+HHmvfgNL2YqVlrJqTwAbRfkIOiR3RzC77UVxXk9TDkvoSu55Qg5T1DUnOUSH3YHIkfOdMt11bVZaQveJDn8eKF6fBu1S2w0nsgVRJUYN4xWDBb67St1qj/284vBE3o80iLbKGZuKALFUmDfFJrRWZxKz0EkrEzGEHLZlY8gqCMlDvpIDasl1U8U3c4akb4qk+YO/zjLohUFROnbeKRIrU66oQ5vJmycIgrt6M4+rjAVUkaEguxq+ntt2xZNdA99vs2cNQGXIFbb3h6nnwxQfKvVVV//1SMfISmnCs34BYxkwVXBcadfbrEOM6CtcYBMqCXvzWJ33/FXvJZmH/A2KAbLgQ/kpz2RPmPzOUT7cKpJqB9MhC3DXdQfZ4kFUFzF+13sJwXPOJvel1igPgOiAs1rrZV85YJXrrc9ZY46pVGQKQ3yekIrqt0EK0vaAgj5oZyrRLz94KdhvIpCIUMd+M05SmsY00TRk827U95uJFIInVhtoOKMS1CqgSM1yQIa/IIKz/s4LEl2UelFpJEOmaXLT9gan8Bsdu2mXOWE2iDgTUhjhHSx1rYeN5EPajgxJq2tyvfti61Ohcm+s2CPxSV7LBjGbAZq0X/r6myA7lLsQQo8uf5F/GMloMEPtiXUyyLW0EJI19rEx68+ZtpIUPNoESaao/sS5ANWs2d2VH+YVdF+I/ZvuMKKkfIgFbf+JvjYdCHS0qZ94BTAzNJdhWzOqdw0ImHLop6nEwvJI2oJ5GWhZGw9jP0WFmwV65RfKVPOZRZTPvo9W2tCb0ZQo=","layer_level":1},{"id":"f5a7db4b-765d-46e4-9395-af7bbe8d8fd3","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"日志系统","description":"logging-system","prompt":"为 Luxsin 应用 API 项目的日志系统创建全面文档。详细介绍基于 Zap 的结构化日志系统的设计和实现。说明日志客户端的初始化过程、配置选项和输出格式设置。解释不同日志级别的使用场景,包括 Debug、Info、Warn、Error 等级别在系统中的应用。提供日志记录的最佳实践,包括字段命名规范、上下文传递和性能考虑。展示如何在中间件、处理器和业务逻辑中正确使用日志功能。包含日志轮转配置、文件管理和存储策略。涵盖日志聚合、监控告警和故障排查的实际应用。提供调试技巧和常见问题解决方案。确保内容既包含理论概念又提供实用的操作指南,帮助开发者建立完善的日志体系。","parent_id":"0ba3accc-326a-4433-930c-5b951d4e5dcf","order":2,"progress_status":"completed","dependent_files":"pkg/logger/logger.go","gmt_create":"2026-05-27T15:42:51.5497484+08:00","gmt_modified":"2026-05-27T15:58:35.6424946+08:00","raw_data":"WikiEncrypted:U7R4DE1TfAUvjZuFqogRLnOghdG8YONf1+EXGFfCCKN64XPQEDdUeRHtBVRbgq1RTfu+PHdhhtH3Ub4edjV7OQOmQQeOhgljoi3HGtSqPVCQvF+mHbx8hRLjpVdCwHdXLvW1Ns4CDnqx/UVLCA1IVbunG2no8Z4rHywszGt/xnqU1gTE2kg8t6xAVG7XfQvH3irlIr1G7/Y2/+RWxJWLz/5H7tsKGpmrGhw8RSd3hVQPhG3iSp62UpI4Jxk/d+OrEUWPuwqJKtZElc7QKOmFaL2Ou0Xm32XwADHOmjYzJyNTlscSdcecUG5KctRPumjoy0gNP7qCfrs8gUDdHMzL6ttn23qdEEZPNbh+TYWVIWnXigmIb8ZizIpBBvi8lgdSE6OX/M698aF13vXXWYsV/gWx1aMFvyo0U2/RQWwm33tMeBdIwK+36gcgiSFDbE0S4b5hb02VMCuasWvPPhMQloVwTmpRX9jLlSWIxElvqhN6JW9Sj3tn9asGgB2y7sZ5hd9DmoUifCyNwMYaKDr87XcM5YtUgyXFquhGaFcY2+CEND5OlVHePB/BTWoyBiDCLgXpicJborNdI7/Nscjq6w3smcCa0ShFdrQ2c1oxL/nowS+0Np2YD/mGUBQfJGct62LTGIm3ejRTFJcHn9bsk38oD3Cjniur0JFTE+jhM3c2BIpd1A8qaNgOfFPuLR038U+ZzBwSYPk0ujoLLSuHOTfKvppASu1MMZuPFcqe8LG+ceVp0xjkx0BKLaD6HrjbpSDMXXMVbNnJU9shT522RABkZEeCFibRDEdFCO6l4jLtyCPaHZCPmGOvHOj5lizmbQtmuBYHEEG+eGYYgOBv/wev3hPI59DkbhTIXpIUwxQ1+0vjVdabnEPEBVxCuGVGDC1Aea1CzWgqA3FLHFtIDExYaEo5YGKlWQn85tDudAmcoD/Ru2NWdGGcW1Ypp7/NWX/VOzYfaGmEEYVbZm41M/SfkgFawUphZc5M5cRj4OG4/tI8ZvDx7IcwIwu4FwPm+21LyFqD1gm86CbkOJ7lK1BH1kl9o+SMXw9VA3snaZ4GGhpaHvgBFvZLH1oT5ZI8GXrTUvuCfq+i3DrDdnuhElM+h3ewW+lMfyvo6DUCbSK3PvLQbsO8EEhz7rAUVsLkZVc1MS4u5dgtYaZte4H71gQszMPb5kdmZW8ys3JTlZlpjsCOMDj+LregbU7ysvd1xZC+GFB1f9RtMNfyIvB0/60vzV8BkymNhb+K5giaTcSKv94wsV+wIVqxR3DGo/CyCs7AbdIof2wAC5ApaWIxrX7XM87JVZkSCS1I8KGN2fVloq5p/lFHvEn+z0UdPd7f4wsFgOlczB3xEz0FolPe/utaK7QT5lmhGjbdBcGumMq8QwGZYYsZk8z3RCjTxi+NXI9NIx1lGzzdjHtr/l0gIU/8oiKa8KYSVjsH58LX3gtmmM2UImLU6+FrVEaFDK8wBB23SJgK41j/mcvuuwJNAg==","layer_level":1},{"id":"8d7c257e-b299-4adb-adfe-bc0ddbf112b7","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"核心模块","description":"core-modules","prompt":"为 Luxsin 应用 API 项目的核心模块创建综合文档。详细介绍业务处理器(Handler)、数据访问层(Repository)、数据模型(Model)和统一响应(Response)的设计和实现。解释各模块之间的依赖关系和协作模式。包含具体的代码示例、接口定义和使用模式。说明模块的职责分离、依赖注入实现和错误处理机制。提供扩展新模块的最佳实践和注意事项。涉及性能优化、缓存策略和并发安全考虑。确保内容对初学者友好,同时为经验丰富的开发者提供足够的技术深度。","order":3,"progress_status":"completed","dependent_files":"internal/handler,internal/repository,internal/model,internal/response","gmt_create":"2026-05-27T15:42:25.030488+08:00","gmt_modified":"2026-05-27T15:48:30.8195851+08:00","raw_data":"WikiEncrypted:bpQ1QlMq61uqjeQzqQaeFJ8lEiuSQp7TFZGpUgKRJgaf7PT+zt7MmzNkqVEU0hd1ivmcFoQ5NrDuJye6YrJgMhvUC8x94MX9xPrGNOjZI+5X4c+vLlR4Y9di8UWaiF3ePMWFHZ+l5JpFZY14y0Gmj+mg2jg6ynoSHd4F8iD94Ksscd/cHjiFkz5KV1ZDKSVo0Zk43RijuZRD+ZvrVDu0XmtFrZ3alp/u48vDDtq64kS9QZdDuR6Wlu7qiT9NwgX7AiaDJqJ4R7dPgxgm6Mui+BQ08Oeq08iURJiXTO07UxLp+uzs2JqJsTrShJlYr/1DePotYHyji38fNP/IbITC4bmDtRqP/5BMbZ7k9hlh8bGx0EWkS6uNkxCgFDuaNHgykTVXSiKrKRDSWgLmKInyhnzBbCcH73bVc+oVtcoSBXixSUbTl5gP1Ig+Y7wyWeOoPHPDdUn77U/OcrSdTkZNXYm4+/I1eIujWEUg4gc3eye74LI568bySPdOk6ZoKG7u8TBv2E0BC3tLW6pJFD6RRArV26sWYSdHsaCumsfOVUgYjGHkhQhsYwKt6buEJZTy7sv9olRDHoi1qy0k9PbRIDacX2cJll7l0u0jXnnztZGx+9+HQ3H08P26RSQB9mNCVtihrb3zqn+nn/fHaVP6TLlA/fFESM0VIGwPT/3NXgKCrGhgeLaw610W73Kv7Ad4zTf/FWsHJ6uv/LC2qfCo9Zt20Voo8N5CmmqTJah6KgVEvW8v7BoekBUzC7ZPGH4oCJeTk4kIoVfGbX7ACMu5mplivQVLaQWQfMElRG+s7oBrbN95CCShpR7S7J59DpnFX/IbgIScrW6X9QGEyoBrPe4S0LA4tnTBU7d2g8RsZDWloZJZbIBi+isLt1JA6fWqwfZ//t8ItkkzPmQJIFJNOR30i9z3wqQAHliGK0F+EqacD6YYn1Ryvt/d8nhRJJDZ526J2xz8X2pZKja+oeGAwU+edSxkfqjTZ87fqFunqnQMbZ5zjs/JzrFvTHlR43EYFU2vuK9YgZ9UJIHtxvPBAubNcuFc5aP4J6GqrxUrF6h/ZAfD1Zpj43GWztuTnhRy2w8l4xy/B722d+K8VBXpE6k7/b8KNnkM/5fSrqgzE1pAlbi0AWtXWfP8pgWRLo+r+wE+BALUxNC80jMVfYGnnIvWU2rzgcJ1YmWOyznQOZu/mNvoUI5AqEDSCzI/ow+21CW0sEvfypb9HKynhsg0JfiAAPvdBZlGmCYs1rcrjp5RoagygMzTGEu3jQYQqwRC8ctiOr0SIvoGaRfcZ2XBEPnjYwAQv2ZdUT7MB3cDleI6Eevvvz1GwXLldlBytA6hHLrkC3mCCZW0+qJiwahbJ5Ayi4uuem08ScBJFqUVxqndMyTN7+7v98xiEKLumUia0Wn4eDjobEwAEosPbMS2pI94b5xVXHj/QHiBfCTdbnlX+vTiLOFU1YW+322ZmO8m/7EPabziKO20Mgff19WPSw=="},{"id":"e2d8da89-04c9-4fee-8dfe-adfaff79c9c1","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"统一响应","description":"unified-response","prompt":"为 Luxsin 应用 API 项目的统一响应模块创建详细文档。深入解释统一响应格式的设计原则和实现机制。详细介绍响应结构、状态码定义和错误处理策略。包含具体的代码示例展示如何使用统一响应格式,以及如何处理不同类型的业务场景。说明响应格式在 API 设计中的重要性和一致性保证。涵盖错误码定义、国际化支持和调试信息的处理方式。解释响应格式的扩展机制和自定义选项。提供性能优化建议和最佳实践指导。确保内容既适合初学者理解响应设计的重要性,又为高级开发者提供实现细节和扩展方法。","parent_id":"8d7c257e-b299-4adb-adfe-bc0ddbf112b7","order":3,"progress_status":"completed","dependent_files":"internal/response/response.go","gmt_create":"2026-05-27T15:42:38.0136404+08:00","gmt_modified":"2026-05-27T15:58:41.4408299+08:00","raw_data":"WikiEncrypted:iaIcfwdLscso9uJYzNYkBwQmMSDrN359f9FMHjOmg7ClR23tbv3dTo6S+mZPVOhFdDzmxIISHKSsp2mIHtSHucIsRTVIuVJBLVgxbLtBw+vYpBthrkKp7ZsmnvjWGy5He35k2/5gy4bT+0fHVhDxJakT8MktDZ/BR/eSlGlnIY5RrC7zFB41KSVM+DwzGHJ6wFsSBTONLyyruobUVduEU7vzMZj9sgtAiHvFL9P2SHh3KcDKpQJaSF6kzMxfuHz+RjE2JrSS7jCHMh0pHTgddYdXs0A21pKoq1Cz9ewRb59irUcIZIJum0fCoYabjhhlkabgVWpIZZl9yI9tYbNT404kkRaJxst4Jxb567lxVXj7z99S7Tl5HxaCXddNPmiUawv0vJsTzd40DhW2ZDAviR3GRAUDUyfw3/+7dQvIEQR/e/MrQlblG6A55TurcS4CgAI1GLwDIWQneG1pO+BCAgXtQPSmpqB7BgjGxlBSb0Mc7Ozk3IATXCWF2Gz/3rMiwdu/lCfL7wtHHu7F/8j5tAKZVzSyjHmJfXLPZ5kHt6Y7AdIc5TZNDyi/LrJoXnYx7u7cHY15CrJc/tEbrztzQ1iElkaTNZ08r7RV7F32Es2t0ynCOMCVirx+HAUHpAOaAdrSai+26wUse4xRm/FkwNZtv+w2OCnTZs5KwT9H5tUVsmqVWyBhSeXHtGkuvUyqx0IINIHQnBhkIpxCdOwzkXTumXWy8tolLEPQSJECMUeYwxFHpvtC6vAQckxS2amrDMWK/GTvxacGzKQom2peJWZZJ0bUQ3pgm7a7YDJZHCC3jH0cq0BoCXXUU9d95pauWlQP2/IZMyuUcH0X72/xZ5xKYPNJuyeVPVzFTjkaZDzPAbyCCKrXJFs8tjyuNkSuRpPaAh4kSgxL6/G5WXR2Fwe/QG2rpK9IUOEv17HBevzn6Dbty0HUFB3zxObA10u7Kx+3rfpfr6yzO3k7y7wWuKpzPhYJhrIS+TCgBZjcTIteFPYWuoj87paGFovSmvqEB9DkBU7xawc9cRduspe3fMlYvFSHJJnaIDWeejeQuwwFd0JoBgOkeMPtCVTkj/SaZimKyefQLYyw5AAu0rj+5IqJ+HGhiB456prnmou8yIC9ws2NUc/LeK3qMNaM1Tkf4lPPKffZ282PoNA1rMelkw4Vu6gXVHkuVRLdCqcUZteXbuH+Qyr/pATu1oc3mOV34LzJDJs8AC1k47iZmX/sSGNZ957wolJ0WWZow24CiUWZtP4/Pg51r9qwhsqMAp7p602Sup+i5M11Gg09u0cyRanD+hMX7HCnsebpyCyxZVvB9jhaZJ4sNdDLWZKhRcBfm4gGm5v3l1Ep8tABF5fwEQ==","layer_level":1},{"id":"4b0e33d8-28d6-44dd-b90a-57af5c6cfaa9","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"系统监控接口","description":"system-monitoring-api","prompt":"为系统监控接口创建 API 文档。详细记录健康检查接口的规范,包括 HTTP 方法、URL 模式、响应格式和状态码含义。说明健康检查的各个维度,如数据库连接状态、缓存服务状态、搜索引擎状态等。提供具体的请求示例和响应示例,展示正常状态和异常状态的返回格式。包含监控集成指南、告警配置和故障诊断方法。说明与其他监控系统的对接方式和自定义扩展点。","parent_id":"8085e1b7-3658-4490-8b52-9a61f3e79976","order":3,"progress_status":"completed","dependent_files":"internal/handler/health.go","gmt_create":"2026-05-27T15:42:40.1914576+08:00","gmt_modified":"2026-05-27T15:58:27.2611572+08:00","raw_data":"WikiEncrypted:gWB8HBj+8+/15rQhXgtMjCM7vFjnlRAhPoaEN0ftdCdBUTnleag+HHtjerxF8Yo/aNSQCvWghRAmFaNP5Ate+OnNgrZtWxUTlolKrwVliK7qFYneTgLhtk2O0DExsEj8rE3wciXyMoLthA27VSFS1hEh1vYjSsYzEvIq9/P7ebtCx3WZIPnPyfLgw1cXSj9siM5kzk0nmt4Ccf6gZaDZuw0Bp7WplXSset9XbcxKPL+MMIzax7BxVHZuxA+Xr0km0IickRzt8NBUEER7TSRBv327JwCiAS8fQqpTdjIoYZaoZD0fB/NTnHP+9Ak0Q0/FKYlXGSAVzh3CgkU+Bn+Cg5ZTP9yyUsZCouns8PsujUZ2npUR1PLdj9hkBS03HbNE8lSbaX8OU3ViNNk1DL+T4pp2AQ8kjAuM3wbk0fgx0dNKLVy5WY3PlBQ20Fx/tZebK5ym8FUGSHChyldzRq6ZYkNg/glvq7d32Xl8fO5iVdMwkqg1pt1O211CYPFuEOhq+EKjmlkG0WCs/2ee5aQCsJwhqN/Ya6IeDgL+9Db+zeM6x5OiHG8FmYl+N582mzAbn2+xbvZqxlMTJOHjWoHb2LewryAHz2W6QEWwOHKtx09+ET8stLXhUowUkW1gy8qjK+E8U+dj3UNXDeo8cAiAnEvjdmuNwCC15pArY6OHVC9X2U5Vpj5U5NUQu2JMoFgwLq4N3PTIxjJ0A+VzuBk/QcYMjmo7LrfP3y+wJaUZn2vsFEIBQ2eTRD5a1Pe13jvgLYJNHUEI8RJfy1p2pZIQyFO8NTC8GoKJhnSQ+gTu14mmS4S08TCy0fu79yKHrmq1Mxpx9FQeGvkkDg0fwa8pu4D5GP0ERsG/CD6v72/U0UcOO7d7Ncz6OJ+WItEmGuCm3eGoUCNtiJjI5slrLxxlLM3hEF/nte/d/5N2XBVG/xn6/YDvrzqEyAFgYUT/UCUiuGiHkv23qhBSjI24q6ODYIHl3EPfycQLGVtjFwMMFxs=","layer_level":1},{"id":"f351f338-eeb0-4243-921a-eed11d063072","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"中间件模式","description":"middleware-pattern","prompt":"为 Luxsin 应用 API 项目创建详细的中间件模式文档。深入解释 Gin 中间件的工作原理和执行顺序。详细说明 CORS 中间件的安全策略配置,包括跨域请求处理和安全头设置。解释日志中间件的结构化日志记录机制,展示如何统一记录请求信息和响应状态。文档化请求 ID 中间件的分布式追踪支持,说明如何在整个请求链路中保持唯一标识符。提供中间件开发的最佳实践和性能考虑。包含自定义中间件的开发指南和调试技巧。","parent_id":"0506348d-993b-48f2-936c-908972f149bc","order":3,"progress_status":"completed","dependent_files":"internal/middleware/cors.go,internal/middleware/logger.go,internal/middleware/request_id.go","gmt_create":"2026-05-27T15:42:44.058506+08:00","gmt_modified":"2026-05-27T16:00:02.1508768+08:00","raw_data":"WikiEncrypted:KoBWq/Q7Adld3nvKT6YAXjbeYGdbE/D4CStunsqJjgl0jPyMgacfbAcsG69IjV6W+YAUulkiH6yJh6guJ8xsLC0r674enptjON7n1TyvEmDvQ0ts2hwoFwrID/aMzsWc6ykTfCUAJOOlgk4w+ArbzUldUGx6slnJqOHO15q0hPQH7GaO0RDoayr+zF5Md89ka3FMbDJBSe7XpA6zdP+wNXSd04XmKPO4VRjZqmJkxAGC8VFm4yVB97+PFqSyh68UCvChI56FzzpLF/5BFK7vdhB4RKqA66aNRDf4DW25UaKG5whiuqjk/HYzMhxcvIfnxNNQENyjxYlMX1sZy4HsMgkgx/uFM4++tYIvF03t17sV6inMrzPeJGGPuhlz/8276En11T0U+vrBLHt5cuHwwfT9/TbnmX6ii+DQAK6bIQ4TouGACknzbAKKYD527I1FVSQgI9EoSN0pbR8fm6ONx31WoIHCHWp/YV+KoNG4BqHkATQ6ytaki/qaUL/ng+odBZvDmXBjiEPo39VVePVK04bIdD705zKajkzvowecnVXm2AKaMJ69AGERz8Yh8e6TmJNgzoBcYyY4mEun80jcRmapIRl8c8YHgH0NMwaVSwcLqiudxnv3oQr59HZzPqbA2lsjZbIb2PrDETb2QeWum0Fm6rN2Un2jJWVpT0EznojYQrzEaNxrIPMOL2v27AiWIqzQv0GQ3sqciy6SmZiuq2wPG7HlS2A2zZkroeKz2FOR+HQnQPJAYla49YW7f6gn/xufwFLQ2P09Vv1PN1pyxXpNDEuiTqHaVp2kzhv9oqymB7xkMgUWjzJxA3LCPmaLv++QPEBFdy6p8cW4yb4I4EhhEKGmNSkUraKRcmosg4NWFDcipy8qHZXRbF6teMWiB3RRRisWUnfoZUcGgAFFGscCtU6FRbrdh8FZz1dO6dwy+o2iUkSDe5kR8tnRRbjY/fvtiPqMjoBsHuvLo8VgUj/8p4Z2FzifMlFm47HXFcnhNcTyNHadq/BKt32asbZMkyf5mwAazzbaJZ9zE72kKw3V+IXEq2k8PQFilZeDtHzxWba+6jseqSydPEZeopZAtR8inj9373angdQRcahgfTWP2Tu1JM7pp/nx4e/XGXgcV/eAY6K6bheHMiVhe8uqpViCaPM56DFwiJSu8jM4uJ7c2z87Ru/IU7jBjcCel2qrMTwxGrIxl3LJQWNXYmFvWXKFkw1YzGjfH/CiNBiu4ygHy7YalDmDnEePypwhiyZ25shL/pX1OxbV8m/tNZmv4AAk3Q9YjR6tRGu+hpIeQQ==","layer_level":1},{"id":"8085e1b7-3658-4490-8b52-9a61f3e79976","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"API 接口文档","description":"api-documentation","prompt":"为 Luxsin 应用 API 项目创建完整的 API 接口文档。详细记录所有 RESTful API 端点,包括 HTTP 方法、URL 模式、请求参数、响应格式和错误处理。针对每个接口提供具体的请求示例、响应示例和使用场景。包含品牌管理接口(获取品牌列表)、型号管理接口(获取型号信息、搜索型号列表)、设备管理接口(上报设备信息)和系统接口(健康检查)。详细说明认证方法、速率限制和版本信息。提供客户端实现指南和性能优化建议。包含协议特定的调试工具和监控方法。如果适用,提供已弃用功能的迁移指南和向后兼容性说明。","order":4,"progress_status":"completed","dependent_files":"internal/handler/brand.go,internal/handler/model.go,internal/handler/model_list.go,internal/handler/device.go,internal/handler/health.go","gmt_create":"2026-05-27T15:42:25.0310242+08:00","gmt_modified":"2026-05-27T15:49:27.8891715+08:00","raw_data":"WikiEncrypted:aJsVvsatVVT+Oax9nwx6A6Ka1Sy3/Ax3fbdr8CSPsFwpSinOHdKPUiaO43Q3eH/wzCti2uFNYtfdvQWqQWpEsnbUBpqKCbRzHWFAT9Lm270y0Q6B1UE3nx+gx/6onwH05kgU4aSL6Vyf/ZaJTFKBZpR/hASnZEkssdX1yTnZq4HGLCbeLR5p3acQeZtqIab449ZqM5BfhYg1nC4veZGNU0ZbTVY2/+9U92yhi84zrKmyuO7gZe6RpeJW+3R+pbFduijY8FtGcUobIv+f3QcPEH7ZWqwynHO+v7PrlM8OHoMZ4jNowBv+/rK9cg9v/ZMBmZfMQEKxsZsOp3fl4F4qYtSm10mD/w81n+As4xiJhZiEZyEFs5J1d8Z9Vy8wXGEIR7fqm+a9zy8Fsu5byzXecYMhxZS2ERHZx240veYTNST0o1BZbq+K36QEct8vD7FCALNKAcaZ6AOkQ3ZeFQRkF77ySrit0wubK5Y8hJZIiie/lo/zKRe7AcNPttvBv8m/fwMlN9KEVR4OUGV/gJU1svwYIsZZEnrCMvG+y67NRx0KVjqb6L6X54uvguKz7kxDUMczgIfViz8ratyBmUtc4FfEAPRsjCROGGkVoDEN/5w+ZyQXhLxP3xXUKd1/P4J1avMlerh1CuO5ejlxXeucDZUHgRDjHUwBXfwGOMvhjOjwHiCV+WGml1tKFYFwCTMROq63PKS+JNp0RfgSHK+FtVbauDr08rz2vyPg98+5DPKjnqfdczGey2EZtF3aUyS0f+eIwXUXUtiq/w14fn2wmUy4I611KQjjMiUaXGeOEzE6IIDLjUY2tTTxx/aPpqJvhEJsora8N2/6a3xsw6yT6z46cc9FiIhyEApe9UKpdjI1fdeQuYjErjck7jRAWTUhfVXtQU4SeD3ehMV7Y6r1A8qOMU0h/oidZfO1nAE/JYP3YBXGYHS5oK7bg1MAtFEpo1o6sSWrginCktGk52hMNSGoV8nehuwtZxdhXoyY4IXjvpfAFsXH1Hb/mkNuAue8aL73FijK+a6EhDh03TFe0zLWJHxx6x6Auvo7AXWOBCnZmEjakamzlcsky5YeF79LZz5GwUfWnRavEY3T6FwU1CLhWG4vTlOctHSDbxPcek4EYQrGDGh3pm9EKWAbxxjSxaOj+mjfVS/BResVW35tX7QJikLDMO3bAgq1R7pKwJkOq6LKlFGQid7IX3oBWU3vnf68+OZYTo3XbhF1ibJBtGKJo9LJnus5LWKyXL8OlPBZ6O9My/LGSv/u8SgYidk1IqHF9E0GEd1n1XivRudgVPhOyyChOZRTjrfkGYZyCG9JFtb07mHqu1GTttkO+yrSl02PBotGLbcN6fVq9tA+nKBe9hyXj1jRm77qabudCbBq1WfADA3BI1naBKwjd/hkC2WRFu+OobhwEa5BWjLR0S5hhbkX9l8NggWqYhlkNoAGqfQHPfV6TRRUMT+YxiAtQS4xyBRe3hdSlLTfFn2DqhwtS2Lz3mdjaYxot+rBGShwUkEN2YW8NTWAPTsPtxYLGPhsJEGRMeC0e/0pGacNmr/a7f0BDYZipNYXZEpoLO6TRDR2814xSzHlyQHssJNrGjQ7GSSOz1iSfL3l8GvofUZpMwsaNKmd0njucNMBp0oxVTp+o5hLPEwLl45Rkmvpz8NLlhicrw4UvoIUrMW1vLOUsZsH+zfQu//Xuf5MvVE="},{"id":"c79882f1-420e-4d6c-a40c-dff8c7e8988f","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"组件交互机制","description":"component-interaction","prompt":"为 Luxsin 应用 API 项目创建详细的组件交互机制文档。深入解释从请求接收到响应返回的完整数据流路径。详细说明 Router → Handler → Repository → Database 的调用链路和参数传递。解释各组件间的解耦机制和接口设计原则。文档化错误传播机制和异常处理策略。提供组件交互的时序图和数据流图。解释异步处理和并发控制的实现方式。包含组件间通信的性能优化和监控策略。","parent_id":"0506348d-993b-48f2-936c-908972f149bc","order":4,"progress_status":"completed","dependent_files":"internal/router/router.go,internal/handler/brand.go,internal/repository/brand.go,internal/database/mysql.go","gmt_create":"2026-05-27T15:42:44.058506+08:00","gmt_modified":"2026-05-27T16:00:37.8856299+08:00","raw_data":"WikiEncrypted:4Zqjl5aZEo1Vv5NKBpebTvIjOs8PtjUiIDyDFsBcQ7xcxPCSMrQFGywF92hdzdj0/Ns2K9dSEDwOkKxz9EMCD21sNknfTIWpC88CWR1X7WuNlX6UdseDM8NhczwhCNaZN3vgjI2RCnPQ3swJEmcffGwsCSYh9whfm7CRrmT1BsJAsL0IISPTl0j7Dypz7NiXQSwlVYOWLyyU9AbzCZDbJ3PpxFYDDzPxaDuVWPVPXLf/wiv9mA5vqzDDmAe1dkhs/NMef3G3n7dFGNy8bE2Kb89TGY1mWlLXsD5yz8TOX2FASKkcwVpddx7H1G4BCCeVxnXrAcc8YtLwtNLqhtYwO9sMQvaZN2pzzBQEBT+bF1KsPSISX/kKBTBc8lKQzbtXgZmpqxMtrqwNvB4AFvHvruBwy5i5usgPxShB0x2ZSOxEQKepTRqJ0sEJxpCG19CRKrqMYxxZMufZecyJcMUUEey9yDRO/hzyy2/pZqn2ZFzkp5KdT+gamSrlq3mJSAJwW1wr584b5P2Bept3By31QHtVKY46YC4WYYzzF1oCjY4mxHTxeyK3KpEfyLa/UEH4JnKUxpA+XrgAxuGhWNQ1XSDiZSY0bXbpklSWH5wVZx9XrhNt1Uv4/Y71JhvdR+D6xb0dEQGbyblvvsAJ/FVnU0+D7VEY0HA3iF8VkSWyCEqfQ/JIf8Ek9Q5LAgQNfEMhoPlzjGIQgoKYiJiPUQYjn0iYa7VDL7waXMyHlwcRIghsmI3fkNu8lRCggKYPTT7Q5qbf+1dABN8HQfKSQ4G3Fyki8uSSBxsxPNBAv1YZhpejX8VnKJ4bcTlb7j+urjrCDfKdzBS3GxW7JA4R3YybG4pIpCHM1znO6FBc0Vw6nOB3lfGW47z0MjpFN3fcV2sOG8ckI47G7KXLi5mabdHP+LyR6s3mSWlLLu59L/RXid0QNasUkkPc7dDbDL9DeRvMlBo5s/BB0qZ3OplmHq79N7OvD8hC8Exo5pNRlCuQXyk/ki56Z2SI5K/AGP1lMNV0tGKe91nJRDGKcxar2YY7tk+dtyGPslSVCeJXmY6OBED+ODDNJ8Ro8sqnENFk2pjIC2z7i8EinBYXDVCn8Fne/tZy4ylO64uHF66MPf3pwmepe2hwAyEDF06K+eddiX3JlmF9xi7EaZS+y+R6h3ktk3ku4KD0Qd86UyfJ5b+r1X4JFTmE2KfIaTeUpCRtOdXJ","layer_level":1},{"id":"cc6acec0-b687-417f-9c93-00f59162cfed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"数据库设计","description":"database-design","prompt":"为 Luxsin 应用 API 项目创建全面的数据模型文档。详细说明实体关系、字段定义和数据类型。记录主键/外键、索引和约束条件。解释数据验证规则和业务规则。包含数据库模式图和示例数据。说明数据访问模式、缓存策略和性能考虑。指定数据生命周期、保留策略和归档规则。包含数据迁移路径和版本管理。涉及数据安全、隐私要求和访问控制。详细说明 Brand 和 Model 实体的设计理念、字段含义和业务逻辑。提供数据库连接配置和查询优化建议。","order":5,"progress_status":"completed","dependent_files":"sql/model.sql,internal/model/brand.go,internal/model/model.go,internal/database/mysql.go","gmt_create":"2026-05-27T15:42:25.031564+08:00","gmt_modified":"2026-05-27T15:47:52.3231001+08:00","raw_data":"WikiEncrypted:veTYwq2y4io5qXerCTrkkBwdhOAmcMQTz+AJLOFORhNFeFTAN7xitXLxeRr3T1sKrh0z/6NFLuxfhi+XJSCnWiA4bOgOqwoJp44HwLqumks3fTrub2qfkx3kGo8Vv0zwaj7mBYt8gy+IsUDExaTSt3z0xSYoiMJRoiBXhAlNc3py65rPX7myyVo7X5aWc6AOTgywn0pmK3XweYJTp/OGuhexu3owdi0ojlyjLM5fhrVaPCMSjZlCmYDKjdRDiJgH8SUT81h6jSMp8DVFvov1TzHKQO6fEt1yGV1rxGiKDrIs4QHO32th+o7k9tQYH6CSnDoMYk4ZYZUaCxNKZcIp1I2u8cv/mKHnKyIHV6o157UJotCffdSghARHRgXNbZRFJKw2LlW0eFfRB4rXMpkNhwxyCyfJuS9HOpH2lBPYNg37sMa1V/Eu3/Q6COF5ALxno0JO2w0V8DANenW4lwqay9TduAWeV/Wd4/dgnc0kGDAAqO5EpRQJ05PlZiAK5WPSeJcE1FMCShp43SRUeu0Is+TvJKih/ixtdr5ZN0vVE+0okdcGzxP1GZGfVlqDy80vdMZ4WJdIHu89JzvzkS2ptiMw834+utWhBxxpJRRDvJl4Zrs1QcGgN5sZCKlUYb1Fb2NOabQvc5fyx8yVZnMaEZpko17DLilQmJCCgrVdi3p2OeIBmnS81Vz5vmsF+754mz9081paU05Zvu1Rlqpklsnxlsn1KOJaq7CxyN1Vcn7SR3cBEu7L2hL7vLqTSlTilbnVUdfG+udOd7z4QHQfU7qOkWy5HkYrcuXrTycl2ufPlCeAr479dPNQ0Xk947AQs7w9xu97C9uZA8SNXmqVZxe/h+O5HjlMfIT6tt8mxvEaeqK8VOrAJKUIyPjs/joJZGQbF1Elfpx5bcIUUpIPc/JZZJaeEsgIox2ZEwOooQJ8nd8HwCEY747ONvgtaJ5q1ezLwIyrBIAmhB7hha3NW5XM3pTSnhhVF5uzeW/SrLPa7/kLcN+z6qciY2+1f1Di3u1j5vjLI3vVhWYxtJeb1HFtQ00iXdel0aXgFh1WDymjQp+3kFFEFC7ujRqludkNuXwc4VxtV1bCbiMRuM9Me/1hxMYQsxfUqeYWXsbBN+TUkt5+5dKDAfjIrRn1uSgSIvVIhez+1s+xqnAoLrGJnH10tSz3gtZIy6HHkEXNgV+uGynd+yFYQPyVzqFl6ycwI4QJr3nkZe2cmn6FJQbfcuksp/k6A7IRaJ1aeEl9xJZ2aGXJYapB8ZgUNClFNIABpvB/G/YA2vmhfZp0uQPvIRc1ND/6GmGWg8sdS3QLzprJuywzZHaPbYAlocEixTYrXFTgWuXbhn803vpaRzzwcwy39VcvjxmM8EPgA8UchNi9kMeRVrOORtsa4ws4iQcDlrdOvw9lPOco6pAgMVqHWw=="},{"id":"0ba3accc-326a-4433-930c-5b951d4e5dcf","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"基础设施","description":"infrastructure","prompt":"为 Luxsin 应用 API 项目创建基础设施组件文档。详细介绍缓存系统(Redis)、搜索引擎(Meilisearch)和日志系统(Zap)的配置和使用。说明各组件的初始化过程、连接管理和配置选项。包含缓存策略、搜索优化和日志记录的具体实现。解释组件间的协作关系和数据流向。提供性能优化建议和故障排除指南。涉及监控告警、扩展性和可靠性设计。包含具体的配置示例、最佳实践和安全考虑。确保内容既适合初学者理解,又为专家提供足够的技术细节。","order":6,"progress_status":"completed","dependent_files":"internal/cache/redis.go,internal/search/meilisearch.go,internal/config/redis.go,internal/config/meilisearch.go,pkg/logger/logger.go","gmt_create":"2026-05-27T15:42:25.031564+08:00","gmt_modified":"2026-05-27T15:49:51.0048099+08:00","raw_data":"WikiEncrypted:sbHxgqwNaIQfuetky2uLRyIOX0QcV4F0AILzzQc9GWKM9RbXWkeyZypYurT6q6/jdshRRky9i8euWVz+RwzDEjLSf/5TBE5hqVfwtdoniolHNIvg/V4U6o0Uy5LnDr8i+8lIxu2oIBTUlsaoAv7w5iNfekHSt0q6goXepa4aMrqdtCXd78BSUFzGGoqTjFCImp9K2wkx2G0tXqpmpVp7tEiupbmaekaydnQiLfWCTsuAhiIixmNf7zhMvQddDdz/vFMxg8EgQjBYCRrLJfa59w1dwNOsh7LD7B0xejH7YnQkazsXQPDc/l1CAXfLcIcNw18T1VJ8pdgRZVu74q4BhQ1oz+mkyNXOXO7uFYyROvZ9+SHCV/p2M5/xkEo3CqCAP+CEI+59/1ozZqaYwitDifyO7wkSXdFb88+pXlAGZCDRQ9iQ/cMLmgrf0UWW3ZQdLAgo9PRlh3nTWGEe+/rkwMoVKFhvAJBooUPS4OIGSMvMAHQrbwvx/poFrNYVDC84lwkm0R3PHjhB1K9cOk9+6tZ/6F7kp3XdCVAhc2U62dBlI8hDoyGxT1Jl75o1y6mLlxFRleUEYQIFasnt0X1GgKG3oeRJfDQBnoW5H7CZ2Q2VQG/Mam6+pMMK/r9diCnIYM5ogiqUj7tr7iypIS+cfkJESScxOnrfQlCN0Qkd8sEGP4K1s0MOXaL2n/I8jL0akBuCdC6r/XwkXXVuwyvONhBo8AKhjlw4Z80l8g9IfCLE516hSHdAvPrqJdQ+uv2kxoDUCbdnki86NLEmUIu9E8Cg/ctAE8bB/3EZ8W0jCiwjkJMG/7zWgjmRnEZEB3qTVgtRa2KlCUd2QJmlRplYoHxZpXr+SKdJwnlA3vad9yfoc20k1McD/WIU1xyYcMO0RlCh7D9YFySaMEU0ajxvhY0IaEzEkSksTTGrckLMEjYGic+cCNwIIo2yh4+RiMTixfUw95/Beb5C6YA4wOzhKhEYwBsyKI1mRNwEf9R87hDhmK7a83qw/cRy9X8q37PVUu4kfKUP00SAvuQVxgyEp5jO+UOmYubsAjFLqt+BLYCvX1BLVs34bTjTZ7UdPkyCewtgeK88zHgLljGSzyR1bspq4eozKjqoiqavFLVqYzTtwTuTtg5HzkqhFBkHceFCQzoxpbcgdyvxHj7rIeuao76nbRqwWFxM0CL/w2bwd3YhIHOUtNX1PHq5deeuo3macM8moQOj2mgBCoh3lJdc8w+9qpT/nooQSlJfOQ8o9+an8h4sgvMbAbGt6Xt34gkJnbQ57qn+h6fXefwWrxaekNiXWaEYYRQlaazmSk/IH+Shr0OZVtpWlkFn7FjYCqe68ScAMyhmZUJ5Pkw+Y1rENFipss0BlI+diw2G12+r1GuERworaWCvas6w5A3FkFKC66BELhQjLk0vsY9c19ea9GihiHshbDr4OSKya8FZ5nM1jK+4vN63WFEnIS/vVAg4NxpzpBa91cZOB3hHRNKWuG9Zv2L5ASdR8D+2EwNxXV+A0vv1YgBt6lCQ/uDGyRePhYr0xyoQ7QfWpRQ+EkUPCA=="},{"id":"f4f8585d-1446-4f49-85b2-efc715bda6cf","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"部署运维","description":"deployment-operations","prompt":"为 Luxsin 应用 API 项目创建部署运维文档。详细说明构建过程、部署配置和环境管理。包含开发环境和生产环境的配置差异、环境变量设置和数据库连接配置。提供 Docker 容器化部署方案和 Kubernetes 部署示例。说明监控告警、日志收集和性能优化策略。包含故障排除指南、备份恢复和版本升级流程。涉及安全配置、权限管理和合规要求。提供自动化部署脚本和 CI/CD 集成方案。确保运维人员能够高效地部署、监控和维护系统。","order":7,"progress_status":"completed","dependent_files":"Makefile,internal/config/config.go,.gitignore","gmt_create":"2026-05-27T15:42:25.0321059+08:00","gmt_modified":"2026-05-27T15:49:39.6683467+08:00","raw_data":"WikiEncrypted:0IKfLNOWe9mZfG1jVts3w2XbjO+yyEmY3ONOjrL5GjA3YcCk7HFAQ1etKc5i1P7UH3oVY8Um0qaAPkZpvBj4kR5+MfLB2lNNE8Rq4eigRbWcSc/FwkPYo+Lgq1jG1nwAdVBamYbeC5rJp9miML32uAYGdDFNBUjcZautOKk/RnMVJbDBhxk06H3YR9uha+agF827jtBxrCN+YUD41ewpmu39XkuD0mIkISY0mw2kTQ3+d3o8egfEhqEtpYEFWDr4W3bjpZzdlqibicqkrLymwjSHLQ25Yk3RDRLQh41MEe9NzR7Dq9pho9nnzV6lVFI/+D3aLuQmEW30BSE9ANU6hjMLS2wzjZI20qiE3EYf9+/cetjKX3PuzziuE6FOa9zkRQET5Avno4lvS+dZE+/NCsoLeLBSpEpHChwy1FLMangpeABL3DMfOcjKBI10Zckgxc6knhlzmH7BYem/MGjE3gGbpXcSOYO91tlzjpTzkA6o8IN0BBKnVEm5ZsnA1/bpvtl8iPNcBLSvEh8r9nsvT61wFloxMMEwoqk4pfGxfYLYpLzHK4/B7kcP2F2ZxPsLNKguH2P+W5Onf/VEoeoeUie2shjfuxNczO0o+tk08s7YDF0suC+hauvXM8A5MtTJFjGAcXk0PepsGbBA15NaUxXQL+T9g4ZmHiM+HpXAVuFUtKMwAoMX7ejSmhK0Uu3abxpuatBFVQMyMn2CtFqbZ7qowCiFy8R+N8iJK+CNvcQX2UDetV403Hy9t8wz9Mb7zjigKo8EExeqBR+6tdzkd2jCxuo8oGTUNED9jyF3yEdLlhvryX6R8fmWeX6XaIUdEfwqd3lefqvppQLJ082CWs43k5Sa3wBYSrhvhINvH+qH2TvKZHwT6jdxjjHkPO23f0RWwLtVr0KwjqIYa2C5ujlLLUzPccXXZozTajzaXs4y1GIXIkjQyN9gkvew0CQdmqcwIakk6B1cd6GSvR2R7jI9aORlvoBPkZZZZaWccD23SJpY8S49pk6J1f4pp8SY58Cs5Tyhzyr9Jx/g0sdQhX5jT4NOD4vFTMDi/QwlxJVK5aAMEoni1Xixkn86Mvy6YO+C0syQmDIeaWwTw3oaJtKkp0rbEph8ikP8GV+vYas27rEHT5ikXy+qKaSpRTrS6pIvqMDTr46wYVA48CocbQCKuCxz+8aN1rxEOyVvF4BZIOGK94UT/86do17dVZDlKWyrMHyapzdcsG77AQVqx3wFdVBRhW+LLPtZ7DjrJ9MbZlWCzqTN+MPtV2pqJpf2QM5tK7xYlv8Yb6jOUmKXAJ+GSoB6Lnv55zJALFR7zYrYJqdnAOfLrd0Tx7cB5v+9"},{"id":"29142a7a-fa93-4a61-8ad8-c35c1b047599","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"开发指南","description":"development-guide","prompt":"为 Luxsin 应用 API 项目创建开发指南文档。详细说明代码规范、测试策略和调试技巧。包含添加新接口的标准流程、代码审查要求和最佳实践。提供单元测试、集成测试和性能测试的编写指南。说明调试工具的使用方法和常见问题的排查步骤。包含扩展开发的指导原则、插件机制和自定义中间件的开发。涉及代码重构、性能优化和安全加固的建议。提供开发环境的配置和团队协作的工作流程。确保新加入的开发者能够快速上手并遵循项目的开发标准。","order":8,"progress_status":"completed","dependent_files":"internal/response/response.go,pkg/encode/base64.go,internal/middleware,Makefile","gmt_create":"2026-05-27T15:42:25.0321059+08:00","gmt_modified":"2026-05-27T15:50:56.1828091+08:00","raw_data":"WikiEncrypted:F3QgleoEfoy16cQggYe9C/ucQxiwh0okVA48AmODs5RKNS8ZgNngqmnHSFcG/1UaJxx+3dUn+EkMTpYUsOg40sht54cXVXsXhnq+u5RoF+QCaIHA1bGkkQVYVJAIxj7oosqEK59VnFAy3/dJV3KPSb/Ak2NMFBLBF1vGpBDxfvX3bT23bfnsRo4s15uorwKaV7X3HasHsjQoW0eNqTYHiGBulek8S0+90Xknrv9THoJiqpJqkBeofpQiXqX5V618tXTFFsKRJ6phlpbQWf2cbMabajttNJ3B44KtoJSJow48koViUqq1GW3BavJLaIXKMSMHmg9oSjXlTiTYcEEZKa/kYEu4HzH+CTxYhmAZitafJJSGarLyIbemD6c9dKLK9Frtj68/dJRxA2JDgVe81LYeb/3xRsBom0r4YzT8A6hHZcszh4H3wvsJMywPaPsmmBX1tXvgqCTmKeNH7dyLyLi3kWUTw9ok4pV8mMbQVe+tyq+dAjkFZ19Gg1pa48jOuq3XNtyOUDkFwzf8ENVW6mMjhd6eh1Wngr55aY62gP2kA69TRUUa7xCg4pPwMd7kukU9I+311WRjxwqdx+K9z918Nh+Ehzce//3AN16rOPpfJiqCBsWoIGofgkkvOrhJXb7ZBSV8svzmyNFJAEwluR6iW6JSQF8aYcFWeQvuFotN33nkyOjukcXDEGZsNzH5UtAJyLrlT7/Or9ByIMARY/bLEe2ttw4LkzwPX0zVri6275Z+Tr+vS1tQvbizhQX+2d6jRwB57dWTT5wiNTTauC0iaRxAQAQpIiilb6edtE9uJDim04tl8b0GkMJvSCCVUwIKIl495jl1QK4bnCVwbXf+Nm9M8b2DoPU91RhXbRUH0oa9hiK/MMmM1pNPt8sIQPodxmby96ls9G7B9FZz54hyvdDRZXOoxueOW+qswnlAT8Pjzr7WYDEFWLqhVHl3YjAnYEyvqPyjLV10UlsnTu74OIH6TGCiFnRNdEUNrebnly9HRW/qPROmHDa6/S39zhxd/Wve8OTESmdoItuQITLhTn+hUnhZoQBVVqWJwAYFrayIms6xJZY8R31ZKxaxYGd9xNCp3P+7To8IS9yboFTqky2xkebLSLfn+HS7xe0MqZXcpzdCKfivdIbm1ebxh/61TCdDH2Wx1T0uqMlwy70jnT6dzzS860fOuXLUw+3uEIg/ohj+iqYOEEPHAIG/ADJxSwbTR4/RjVzy+yaWUiKWxLukEG89+389O2WLfiqMNBTDEZ4+iXaBOjZ2i8yTTW0xGChxJcCUGPmug6KyNPvoEDLiPot5cTWScQG04DSfIGUnVEqHKDxX3mS/pZDnfV2OkxwUfNtqXdYzFlWBWnI9TxnL3wxXTu3eI8SYHxflga+4BF6OXBwi8eu8DXYDarKNvnEn0JHi0Fh8VVcAoZmJeQkJUhcvnhyAKmJ0tD21XmK4/7ZcFZ8RuBkIEpDy"},{"id":"4d1d9a48-feab-42a0-815a-edf76dcaaf69","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"故障排除","description":"troubleshooting","prompt":"为 Luxsin 应用 API 项目创建故障排除文档。详细说明常见问题的诊断方法和解决方案。包含数据库连接问题、缓存失效、搜索异常和日志分析的排查步骤。提供错误代码对照表、日志分析技巧和性能诊断工具的使用方法。说明网络连接问题、配置错误和权限问题的解决策略。包含系统监控指标的解读和告警处理流程。提供生产环境问题的应急响应方案和回滚策略。涉及安全事件的处理和数据恢复的操作指南。确保运维和开发人员能够快速定位和解决系统问题。","order":9,"progress_status":"completed","dependent_files":"pkg/logger/logger.go,internal/response/response.go,internal/config/config.go","gmt_create":"2026-05-27T15:42:25.0326686+08:00","gmt_modified":"2026-05-27T15:51:51.4638338+08:00","raw_data":"WikiEncrypted:CaKOW8OSSWs4aEYk06Hu0hGGy7zXJE5t3XZJK+9x87Wqy/1Xzi+22LbOfczFZkieMj5WEpLZAHMOxW2WrQJBBBBLWDFSQSfMzyLUONYz2Nl7KEGwStUbBydq7XRqsFITwnt/V34PJe33lfOUHLZdte9ZHqIcBUofSz417l0pyB/LxfxiLi3iV7uxs4nc6n2EFO0hgr4tRmmgaEM1CEq4EgiztB5945G3QMRbLtVRjxhkZe9eWYo9vc2zRYWsyCp6nsjGToiqmfJff57lDOhyn0MhEnJamhFrscVK3DVyGf1SpxoYkDkFQ8OxuxWIHhAN31k2cpGQv9LmsRHcL8ratSFNuE0JPDtSTdY/ZWlXZReIKt/Phb2FMvUA2BI6cCF2Evsk8rpZnwjGsdOlJ+sGevLXEX+KO/9vz0AE6s+rE5u71DR5usC6vuuFgFV4FP7o+3Lcj81SBIu9V+wYU4GkJfPm9eZdFSFgsvHSuqFzrpdlcAeV0XMnU6wZcRaZy/8ZdaUJaIWp/K5jIqfGuxtPSOD1zDJ9Vw0jCLMjDlUTY0Wkzwykxog7i2SnG61vtu/eLORV6aTh8tjNhzdBwbROp3XlsxD0Jxg41JcDSyt4dpyQ35FAPBMPr7Mb3YeD4W1JWqrn8tR5Q1goBmPFlekKRd1XmyYQSZsK4FvBVOUBeCzX1UO7I505eXz/lN/ZG62xC3zhdCt+qCOxJogd4T1f1Nux404SmdsvewY4mg5PnyoinMtMIMX67YY+iFfZEedlNURipIOxssz0zcp+qeJXI9lwR58sgAvpu9JbTbVQJv4I7n1XM9CayA7Nhd0WXIh+yChGMyFdfq6BDje0NtSgi44k/h+mFUk3BqzfQWasqg7rPzAKjx23DY3Wf/8AvNN7IpP2CH4yRynuCGZim6B1AEqKfL6RCsXi3dpi6y6HmEO4DRk7XL8l9c+vWr+u/yI6A9OGZtzl8B7MoVhhEuuTvPbLCrwnHsU3VReA05fImoZPThjC0vYsQuP5jijDtjnjnShV/o1rLBat0xPAhTT0+Ba23IeZGODiU8yg7NtgprzmcJSS/wFzeapmPZYCB70qjxvW/HgkOhwl1TsfHNP/T6k6i1j6gSPIxgCbZzvcJrH9sumu84lcS6Yfg9Qvr7PpOAuDKDj7riCajk2RbdUVxrptqpZkD0kYIKictTHLnL48Uvp97xnspGQYkJA4BAv0grWVZFzqj7o0BlwD7oL/FLdBMSbXkNRCvjQjGnIZ2nq8MEZP3aofJTmW7e63/JTbcplJzE6wdft6ZBF4hroZE8TbT/pMlEMDkQDxYbgPETx9z/quiPJ+0p6dAD2TjJdiV2GfAFz6WEnJ3NljmFPBV2/5DJ4ugFlz6oBXJZArZyUzJlbmfIXasvwycIUFMx470AIl4o7bGCbGGL+tWgljzbkg7dly6G5lMTM+gWVGvWdUtXCOvYLq+oqCr5Uddgt0"}],"wiki_items":[{"catalog_id":"78b906f9-f81c-4bb2-b076-5c5609c7eb41","title":"项目概述","description":"project-overview","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"f30115a0-52c0-4f22-8486-ec2e6c334e6d","gmt_create":"2026-05-27T15:44:16.3635684+08:00","gmt_modified":"2026-05-27T15:44:16.367324+08:00"},{"catalog_id":"6de9a03e-f360-4daa-97ac-dc1cd1937916","title":"快速开始","description":"getting-started","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"61e1b102-9ad1-44f6-accb-0e27be48ceb7","gmt_create":"2026-05-27T15:45:02.5387528+08:00","gmt_modified":"2026-05-27T15:45:02.550849+08:00"},{"catalog_id":"0506348d-993b-48f2-936c-908972f149bc","title":"系统架构","description":"architecture-design","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"ab98c251-c5f7-40df-bba1-21b2edf5d220","gmt_create":"2026-05-27T15:45:15.0879497+08:00","gmt_modified":"2026-05-27T15:45:15.0922502+08:00"},{"catalog_id":"cc6acec0-b687-417f-9c93-00f59162cfed","title":"数据库设计","description":"database-design","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"120f3824-43f7-4a38-9680-43b5b2f59e05","gmt_create":"2026-05-27T15:47:52.3181698+08:00","gmt_modified":"2026-05-27T15:47:52.3231001+08:00"},{"catalog_id":"8d7c257e-b299-4adb-adfe-bc0ddbf112b7","title":"核心模块","description":"core-modules","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"7563e383-3ea0-4630-baeb-e86efcaeefb8","gmt_create":"2026-05-27T15:48:30.8129369+08:00","gmt_modified":"2026-05-27T15:48:30.8195851+08:00"},{"catalog_id":"8085e1b7-3658-4490-8b52-9a61f3e79976","title":"API 接口文档","description":"api-documentation","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"6159e8a9-0f6e-43af-b097-bfcd16c8b223","gmt_create":"2026-05-27T15:49:27.8849802+08:00","gmt_modified":"2026-05-27T15:49:27.8891715+08:00"},{"catalog_id":"f4f8585d-1446-4f49-85b2-efc715bda6cf","title":"部署运维","description":"deployment-operations","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"1da760f2-e12f-4b50-bd2e-539ff08c2047","gmt_create":"2026-05-27T15:49:39.6657096+08:00","gmt_modified":"2026-05-27T15:49:39.6688705+08:00"},{"catalog_id":"0ba3accc-326a-4433-930c-5b951d4e5dcf","title":"基础设施","description":"infrastructure","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"cfbcaa79-26f5-402f-8746-9fe524993684","gmt_create":"2026-05-27T15:49:51.0000417+08:00","gmt_modified":"2026-05-27T15:49:51.0048099+08:00"},{"catalog_id":"29142a7a-fa93-4a61-8ad8-c35c1b047599","title":"开发指南","description":"development-guide","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"081f97c7-d774-43b7-aff8-4973d577a059","gmt_create":"2026-05-27T15:50:56.179658+08:00","gmt_modified":"2026-05-27T15:50:56.1833555+08:00"},{"catalog_id":"67d62b58-6970-45ca-a17f-f48cb2ea679a","title":"业务处理器","description":"business-handlers","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","gmt_create":"2026-05-27T15:51:42.2402901+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00"},{"catalog_id":"4d1d9a48-feab-42a0-815a-edf76dcaaf69","title":"故障排除","description":"troubleshooting","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"3ce5cfd0-f4f6-439a-b60d-6fb4c36a26bd","gmt_create":"2026-05-27T15:51:51.4591126+08:00","gmt_modified":"2026-05-27T15:51:51.4638338+08:00"},{"catalog_id":"591ea147-ba05-4d86-a671-941af668ca2f","title":"品牌管理接口","description":"brand-management-api","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"6f1fe170-ae35-4660-91dc-ab89735274b7","gmt_create":"2026-05-27T15:52:20.2715607+08:00","gmt_modified":"2026-05-27T15:52:20.2747568+08:00"},{"catalog_id":"6e42204e-3d78-4997-a95a-3311c8fcaa43","title":"缓存系统","description":"cache-system","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"795a5202-49be-4c11-a2b4-44312eca8ae7","gmt_create":"2026-05-27T15:53:16.9891352+08:00","gmt_modified":"2026-05-27T18:36:40.5405367+08:00"},{"catalog_id":"fb8ae541-8bbc-4544-9133-e797be1433e0","title":"分层架构设计","description":"layered-architecture","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"523107ca-244f-43c5-a4fe-4649e36a88ad","gmt_create":"2026-05-27T15:53:50.4703345+08:00","gmt_modified":"2026-05-27T15:53:50.4735252+08:00"},{"catalog_id":"948e0792-2de7-47b1-b73b-e7b246e749ff","title":"数据访问层","description":"data-access-layer","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"599c0bda-3332-415c-a535-362503079473","gmt_create":"2026-05-27T15:54:10.7247654+08:00","gmt_modified":"2026-05-27T18:35:41.8040874+08:00"},{"catalog_id":"8b3ba473-1cf0-4471-a203-9a87732dc227","title":"型号管理接口","description":"model-management-api","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"6af33e3a-220d-4e68-87ed-bfb96bda4c3a","gmt_create":"2026-05-27T15:54:37.220316+08:00","gmt_modified":"2026-05-27T15:54:37.2236089+08:00"},{"catalog_id":"5b9847ff-f7b8-488b-821b-6fdfe2dbde40","title":"搜索引擎","description":"search-system","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"d0c2dea0-a71a-4f16-9889-b37e1e7996e3","gmt_create":"2026-05-27T15:55:50.6464041+08:00","gmt_modified":"2026-05-27T15:55:50.6500526+08:00"},{"catalog_id":"ccdbaf47-6cde-4ad7-95f8-5b92d33e2440","title":"路由系统","description":"routing-system","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","gmt_create":"2026-05-27T15:56:02.5802842+08:00","gmt_modified":"2026-05-27T18:35:29.939743+08:00"},{"catalog_id":"e81027fa-c24e-4492-8100-f051facb89c9","title":"数据模型","description":"data-models","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","gmt_create":"2026-05-27T15:56:31.7739386+08:00","gmt_modified":"2026-05-27T15:56:31.7808704+08:00"},{"catalog_id":"8b7558c2-be32-47b8-99e2-1964009b4337","title":"设备管理接口","description":"device-management-api","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","gmt_create":"2026-05-27T15:57:09.1993166+08:00","gmt_modified":"2026-05-27T15:57:09.2037555+08:00"},{"catalog_id":"bc6825c8-9aa3-4f0e-96ca-ef4925af0570","title":"依赖注入模式","description":"dependency-injection","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"5910d326-0408-450d-b403-06a19f3da81b","gmt_create":"2026-05-27T15:57:20.0015238+08:00","gmt_modified":"2026-05-27T15:57:20.0074643+08:00"},{"catalog_id":"4b0e33d8-28d6-44dd-b90a-57af5c6cfaa9","title":"系统监控接口","description":"system-monitoring-api","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"0fc3d59c-d219-4f97-af10-473ee62f4de5","gmt_create":"2026-05-27T15:58:27.2590583+08:00","gmt_modified":"2026-05-27T15:58:27.261717+08:00"},{"catalog_id":"f5a7db4b-765d-46e4-9395-af7bbe8d8fd3","title":"日志系统","description":"logging-system","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"23a2ffc3-fa50-41ba-b7a6-55354d68a95a","gmt_create":"2026-05-27T15:58:35.6388373+08:00","gmt_modified":"2026-05-27T15:58:35.6424946+08:00"},{"catalog_id":"e2d8da89-04c9-4fee-8dfe-adfaff79c9c1","title":"统一响应","description":"unified-response","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"699a84c5-5140-4267-861e-62bffbffccb4","gmt_create":"2026-05-27T15:58:41.4359+08:00","gmt_modified":"2026-05-27T15:58:41.4408299+08:00"},{"catalog_id":"f351f338-eeb0-4243-921a-eed11d063072","title":"中间件模式","description":"middleware-pattern","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"e8e5fe7e-cc7c-4259-95d0-f6b46d888ed8","gmt_create":"2026-05-27T16:00:02.1459491+08:00","gmt_modified":"2026-05-27T16:00:02.1508768+08:00"},{"catalog_id":"c79882f1-420e-4d6c-a40c-dff8c7e8988f","title":"组件交互机制","description":"component-interaction","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"5a04f737-b877-4908-a4fc-67a88614aafc","gmt_create":"2026-05-27T16:00:37.8802374+08:00","gmt_modified":"2026-05-27T16:00:37.8856299+08:00"}],"wiki_overview":{"content":"基于我对项目的深入分析,现在我可以生成一个全面的项目概述:\n\n\u003cblog\u003e\n\n# Luxsin 应用 API 项目架构分析\n\n## 1. 项目介绍\n\n### 目标与定位\nLuxsin 应用 API 是一个基于 Go 语言构建的音频设备(耳机)数据管理服务,主要为移动应用提供品牌、型号、设备信息等数据查询接口。该项目采用现代化的微服务架构设计,专注于音频设备数据的高效检索和管理。\n\n### 核心目标\n- 提供 RESTful API 接口,支持音频设备数据的查询和管理\n- 实现高性能的数据检索,结合 MySQL 和 Meilisearch 搜索引擎\n- 构建可扩展的缓存层,使用 Redis 提升系统性能\n- 确保生产环境的稳定性和可靠性\n\n### 目标用户\n- 移动应用开发者\n- 音频设备数据管理系统\n- 第三方集成商\n\n## 2. 技术架构\n\n### 整体架构设计\n\n```mermaid\ngraph TD\n A[客户端应用] --\u003e B[Gin Web框架]\n B --\u003e C[中间件层]\n C --\u003e D[路由层]\n D --\u003e E[处理器层]\n E --\u003e F[仓库层]\n F --\u003e G[数据库层]\n \n H[Meilisearch搜索] --\u003e E\n I[Redis缓存] --\u003e E\n \n C --\u003e J[CORS中间件]\n C --\u003e K[日志中间件]\n C --\u003e L[请求ID中间件]\n \n M[配置管理] --\u003e N[数据库连接]\n M --\u003e O[Redis连接]\n M --\u003e P[搜索客户端]\n```\n\n### 设计模式\n- **分层架构模式**:清晰的业务逻辑分层,便于维护和测试\n- **依赖注入模式**:通过构造函数注入依赖,提升代码可测试性\n- **工厂模式**:用于创建各种客户端和服务实例\n- **中间件模式**:统一处理跨域、日志、请求ID等功能\n\n### 系统关系图\n\n```mermaid\nflowchart TD\n Client[客户端请求] --\u003e Gin[Gin Engine]\n Gin --\u003e Middleware[中间件链]\n Middleware --\u003e Handler[业务处理器]\n Handler --\u003e Repository[数据仓库]\n Repository --\u003e DB[(MySQL数据库)]\n Handler --\u003e Search[Meilisearch]\n Handler --\u003e Cache[Redis缓存]\n \n subgraph \"核心组件\"\n Gin\n Middleware\n Handler\n Repository\n end\n \n subgraph \"外部服务\"\n DB\n Search\n Cache\n end\n```\n\n## 3. 关键实现\n\n### 主要入口点\n- **服务器启动**:`cmd/server/main.go` - 应用程序的主入口,负责初始化所有服务组件\n- **路由配置**:`internal/router/router.go` - 定义 API 路由和中间件配置\n- **配置管理**:`internal/config/config.go` - 统一的配置加载和验证机制\n\n### 核心模块\n\n#### 数据访问层\n- **数据库连接**:`internal/database/mysql.go` - MySQL 数据库连接管理\n- **品牌仓库**:`internal/repository/brand.go` - 品牌数据的 CRUD 操作\n- **型号仓库**:`internal/repository/model.go` - 型号数据的查询和管理\n\n#### 业务处理层\n- **品牌处理器**:`internal/handler/brand.go` - 品牌数据的业务逻辑处理\n- **型号处理器**:`internal/handler/model.go` - 型号数据的业务逻辑处理\n- **模型列表处理器**:`internal/handler/model_list.go` - 结合搜索功能的型号查询\n- **设备信息处理器**:`internal/handler/device.go` - 设备上报信息处理\n\n#### 缓存和搜索\n- **Redis客户端**:`internal/cache/redis.go` - Redis 连接和操作封装\n- **Meilisearch客户端**:`internal/search/meilisearch.go` - 搜索功能实现\n\n### 配置管理\n- **环境配置**:`internal/config/config.go` - 支持开发和生产环境的配置切换\n- **数据库配置**:`internal/config/database.go` - MySQL 连接参数配置\n- **Redis配置**:`internal/config/redis.go` - Redis 连接配置\n- **搜索配置**:`internal/config/meilisearch.go` - Meilisearch 搜索配置\n\n### 中间件系统\n- **CORS中间件**:`internal/middleware/cors.go` - 跨域资源共享处理\n- **日志中间件**:`internal/middleware/logger.go` - 请求日志记录\n- **请求ID中间件**:`internal/middleware/request_id.go` - 请求追踪标识\n\n### 日志系统\n- **日志配置**:`pkg/logger/logger.go` - 基于 Zap 的日志系统,支持开发和生产环境不同配置\n\n### 数据模型\n- **品牌模型**:`internal/model/brand.go` - 品牌数据结构定义\n- **型号模型**:`internal/model/model.go` - 型号数据结构定义\n\n### 响应处理\n- **统一响应格式**:`internal/response/response.go` - API 响应的标准格式化\n\n## 4. 核心特性\n\n### 功能架构图\n\n```mermaid\nstateDiagram-v2\n [*] --\u003e 接收请求\n 接收请求 --\u003e 验证参数\n 验证参数 --\u003e 处理业务逻辑\n 处理业务逻辑 --\u003e 查询数据库\n 查询数据库 --\u003e 返回结果\n 处理业务逻辑 --\u003e 使用缓存\n 使用缓存 --\u003e 返回结果\n 处理业务逻辑 --\u003e 执行搜索\n 执行搜索 --\u003e 返回结果\n \n 返回结果 --\u003e 记录日志\n 记录日志 --\u003e [*]\n \n 验证参数 --\u003e 错误处理\n 错误处理 --\u003e 返回错误\n 返回错误 --\u003e 记录日志\n```\n\n### 实现亮点\n\n#### 多数据源架构\n- **混合存储策略**:结合传统关系型数据库和现代搜索引擎\n- **缓存优化**:使用 Redis 缓存热点数据,提升响应速度\n- **异步处理**:支持设备信息上报的异步处理机制\n\n#### 高可用设计\n- **优雅关闭**:支持服务器优雅启动和关闭\n- **信号处理**:正确处理系统信号,确保资源正确释放\n- **连接池管理**:数据库和缓存连接的生命周期管理\n\n#### 开发体验优化\n- **环境隔离**:开发和生产环境的配置分离\n- **统一日志**:结构化的日志输出,便于问题排查\n- **错误处理**:完善的错误处理和返回机制\n\n### 性能考虑\n\n```mermaid\ngraph LR\n A[请求到达] --\u003e B[中间件处理]\n B --\u003e C[缓存检查]\n C --\u003e D{缓存命中?}\n D --\u003e|是| E[直接返回缓存]\n D --\u003e|否| F[查询数据库]\n F --\u003e G[更新缓存]\n G --\u003e H[返回响应]\n E --\u003e H\n H --\u003e I[记录日志]\n```\n\n## 5. 项目特色\n\n### 架构优势\n- **模块化设计**:清晰的职责分离,便于团队协作和维护\n- **可扩展性**:支持添加新的数据源和业务功能\n- **可观测性**:完整的日志记录和监控支持\n- **安全性**:中间件层提供统一的安全控制\n\n### 技术选型\n- **Go 1.24**:现代化的编程语言,提供优秀的性能和并发能力\n- **Gin 框架**:高性能 HTTP Web 框架,适合构建 RESTful API\n- **MySQL**:成熟的关系型数据库,适合结构化数据存储\n- **Meilisearch**:快速的全文搜索引擎,提供优秀的搜索体验\n- **Redis**:高性能的内存数据结构存储,用于缓存和会话管理\n\n### 开发最佳实践\n- **依赖注入**:通过构造函数注入依赖,提升代码可测试性\n- **错误处理**:统一的错误处理机制,避免错误传播\n- **配置管理**:环境变量驱动的配置管理,支持容器化部署\n- **日志标准化**:结构化日志输出,便于日志分析和监控\n\n## 6. 总结与建议\n\n### 项目特点总结\nLuxsin 应用 API 项目展现了现代 Go 语言 Web 服务的最佳实践,采用了清晰的分层架构、依赖注入和中间件模式。项目在性能、可维护性和可扩展性方面都表现出色,为音频设备数据管理提供了可靠的基础设施。\n\n### 架构优势\n- **清晰的层次结构**:从路由到数据访问的完整分层设计\n- **现代化技术栈**:选择合适的技术解决特定问题\n- **完善的基础设施**:包含缓存、搜索、日志等完整的系统组件\n- **良好的工程实践**:遵循 Go 语言的最佳实践和编码规范\n\n### 改进建议\n1. **增加单元测试**:为关键业务逻辑添加更多的单元测试覆盖\n2. **API 文档**:集成 Swagger 或类似工具生成 API 文档\n3. **监控指标**:添加 Prometheus 指标收集,完善运维监控\n4. **健康检查**:扩展健康检查端点,提供更详细的系统状态信息\n5. **配置热更新**:支持部分配置的动态更新,减少重启需求\n\n### 下一步发展方向\n- **微服务拆分**:根据业务领域进一步拆分服务\n- **消息队列**:引入消息队列处理异步任务\n- **容器化部署**:完善 Docker 和 Kubernetes 部署配置\n- **性能优化**:持续优化查询性能和缓存策略\n\n---\n\n**Sources:**\n- [main.go](cmd/server/main.go)\n- [go.mod](go.mod)\n- [config.go](internal/config/config.go)\n- [router.go](internal/router/router.go)\n- [brand.go](internal/handler/brand.go)\n- [brand_repository.go](internal/repository/brand.go)\n- [brand_model.go](internal/model/brand.go)\n- [meilisearch.go](internal/search/meilisearch.go)\n- [redis.go](internal/cache/redis.go)\n- [cors.go](internal/middleware/cors.go)\n- [logger.go](pkg/logger/logger.go)\n- [database_config.go](internal/config/database.go)\n- [model.sql](sql/model.sql)\n\n\u003c/blog\u003e","gmt_create":"2026-05-27T15:40:06.9577463+08:00","gmt_modified":"2026-05-27T15:40:06.9577463+08:00","id":"5a60eb9b-0b2d-4d2f-99c6-dd1e4cd34dd3","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc"},"wiki_readme":{"content":"No readme file","gmt_create":"2026-05-27T15:38:58.8115445+08:00","gmt_modified":"2026-05-27T15:38:58.8115445+08:00","id":"cf8cd5f4-1600-41c4-9afb-1db3a1464c48","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc"},"wiki_repo":{"id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"app-api","progress_status":"completed","wiki_present_status":"COMPLETED","optimized_catalog":"\".\\n├── _tmp_desc\\\\\\n├── cmd\\\\server\\\\\\n│ └── main.go\\n├── internal\\\\\\n│ ├── cache\\\\\\n│ │ └── redis.go\\n│ ├── config\\\\\\n│ │ ├── config.go\\n│ │ ├── database.go\\n│ │ ├── meilisearch.go\\n│ │ └── redis.go\\n│ ├── database\\\\\\n│ │ └── mysql.go\\n│ ├── handler\\\\\\n│ │ ├── brand.go\\n│ │ ├── device.go\\n│ │ ├── health.go\\n│ │ ├── model.go\\n│ │ └── model_list.go\\n│ ├── middleware\\\\\\n│ │ ├── cors.go\\n│ │ ├── logger.go\\n│ │ └── request_id.go\\n│ ├── model\\\\\\n│ │ ├── brand.go\\n│ │ └── model.go\\n│ ├── repository\\\\\\n│ │ ├── brand.go\\n│ │ └── model.go\\n│ ├── response\\\\\\n│ │ └── response.go\\n│ ├── router\\\\\\n│ │ └── router.go\\n│ └── search\\\\\\n│ └── meilisearch.go\\n├── pkg\\\\\\n│ ├── encode\\\\\\n│ │ └── base64.go\\n│ └── logger\\\\\\n│ └── logger.go\\n├── sql\\\\\\n│ └── model.sql\\n├── .gitignore\\n├── Makefile\\n├── README.md\\n├── go.mod\\n└── go.sum\\n\"","current_document_structure":"WikiEncrypted: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","catalogue_think_content":"WikiEncrypted:FHVEaJAZ2IkxfPi/ij1eo7sWJwiH4rBRH3iZyB+fSmOjtCxRmUqHCMWCQijlC/HxUcDAvuPn7yWaxZTmicDCctiu8cuyrxxkghrPHC9feZcLVPdo/FM5WQfBxtMjDYr8E0/sJsrwZ9kUM9Umx/2Aq2GiWOSgWj6BlE2oIq1a0bUD2lA2YZFxCfc6VE9zMnVjqA9MQiAIxAr9eNpJ8njxOktW2yGW/BdKJ8PVWGhfdrp9AUfbiZDQJsFATiARK52wMJEY24YKjOvYdUHRVdLPiZKEueEQpetDTo3511/2TsiLfEQrihAz7T93UfMZvQ9hmHjYOtnwk1RgObRViFwl8tr5vEUuIlUTicIu0kQMU68QWXReuDPfNpjRiiXU0NJP76zb+dvprvdyeerKMzA/FNu/XMEk0t6EqSmSV+lxYwFMuijeNKW3va3PKdJCl43OxOFlXdlTGjjO6Vt60JiUCtnh6qo0s0gtjlFp64SVysc4aZlbzQx382vWVBUTN8vXWB0/HXpP4IBf8HUZRCvyqjLr4SIcn46L8aDRFdD5fb85lgAeecZaSxxOEJ+MpEQgbqnO8R/h02havIzqZX9SY9ER09e2OPpU9yUI5tecy+M+aT0rwa5ed8f5M1WSnpoZLag5amkOhzBhuyMat1myeFcTxzF8uJLHkO0NWpfhYRqeV9Ekh0qDh6+rxB/Te8i/qaZCQmfFNaIayH3avR4/5j/dg3+TTZZnA29dWXdfB7IiwPmowXYLDVFa2RFfhpAUy8ctth+dmrjnaOsjb5c2KAL2L0NzLZhLyMlp5ZoF622yfjOBeDezTfM2OQ98VnjZUHsAA7lHN8l0jycYxhd5gYKqXOx3MmYSJEQoWuMzxzAqE6o2A2Q0KT5Y3V2EFlXQlOoW2wAwzCSTqXBLTW0/oOM4QgBeeEFfLecwW+B9x5uwbzdLKhuj3EsEVKrBVwIjIKZgrnT7ID0uPEdHjhJZ0+DVKvsxVGycacCeCKW83n+THJikv/EXJ52wQvVfNyTHExokTciXkJSxtXh+NsYZaUGyV4P6wu7Ien+B0bUGlUl2nrY6hPOv5HexBa9hFB/KS5oxnW8YlPdX/U2Qyr2/2oJVdZT0ltXMZ64hGQqJFYknjKRvqQ2tZgaCGd4CswpNYXdeQhqb2qm2aIodl3SZnS8O0URiApp7AGZ3Ai9JrwfEaJrhDbqTUXoHJGAkl/XFPlRYiqlZX3Em6t4AqxPex1inviGbMbqjKIPp2QZXI4MQuQA6x/qQsYwiVO6mis6DjMAzpSI0yMeokQ+tRYUsqBvgCHvDXH7soRwrbUAC5/C+7W7pJDxiMZ34gJSxMuq9eolC0QkKJAppZcnBcVWvo8/uBNmib7X861Tpn+nR4OXALyLtZZCZguIH6Mx4qGzXj9zmZIarICmI+wUC0X6Gqs3W5efmdLaeAcPQSyEhKvz2YOy7deRbLtfVHyyOJ+MBKmzlEzG9bbLmVsLX9gyKHHvpLlG0RJOnACj26lHd6nVCUVoRAAri9CXu18+EniDNAUHmI8w9AIsYmPmjZ1S1yhpYOsBayk5pCJcBbb6Gn/Cpa7QTqiuRS757DeJrQZIImfAz5PLhooOz281T0+iM5TbVoHJhX9Rjr1FfNQ/4I6IYcSZFJ1XLNzkJQlLwjUPji1pxIdfYqN6wMEP0WujJh89vrhYZSMUxKrPuiUUU3N6JcS8OZx4+CU7aZG8/KrJ7FPJROlFnX5UGjvXO8symPU6jHgA1b/8o1IWgfQOudLZPNt/Kn5T183EfoqiOb7co0CYJ4rGjNhHR0xpfRGV68L6fMtlEjx6JKoF9IFEoPKJhO7FJI8I3pHNeYy52jAl379YwNiJp/SEPiv6zpMKcKectw90vxWlYnUcewuwpN/mH0W3NludR9J+01xIjBnS2l/S/OrhlZuwwJSr2eUK2JNcD1XcbqpQV9cIdybC8Gs6AdR8xZOFBDUMpac1VFO66RWdAxU3wlV4eK0sXr/q3fFYYmESAW8NRVCvHHKf09mPqd2/YiyJBfuzBVsI/OdQN8lWTUmjTWl9slUdxfKBLMMNDJpKGKbhpXSv2TXzElPbH0W01BA/KyijnBcqDekyAhCf473bbjEimanWxlZNeiJ717TzgKbl6UXfj4jlUbNa2u3MpUgKLhPOcrC5oj5zCkBXmS6oKrCevwGM0Lcdv5g4eAdf340kzBQOA1rrdd9wfCmb7qLcJXEIfjOvYSe3w0YgiVVhTpZAd+4/2fW1MaYyWZNbt0SxyKY+pTsSiPFi8iY4Re6r0vNpHtS9wrcPcx/zgwvlp/KAkj3RlWrdVIops/KaeeOAVuX5Fu/saJAEjM9JyWRhAeY3Pwp/MGFEiGnfpUQu5I/YBbu8Ys6cg4+82nu5xrlRrvZwIrKdqqGQTf94Mj6gm9lS9trnk2HkEzQ4xz1NfTdHkptctgwANylCoyKGRvgyINJvLq0kk11vfuOKfz4qW0D8RS8/zXdvA4RpkAeaAOGtZU6Y2GBj1RtiNn4JplcSnoZQMe8xonnleWRHlt92p9IbXnpY7PxlUJtZMqpYRQHwDdPR2jQ9t84yqAWtveiFr+xhoogg78M6XzrNFYAc1m1O6XPWvNKjBqtnEo5PoFrygBwpPkXsURLfeE3va1uKPRupX04DbN9tk0YUGPSOs76lveMNkpu4BCyeG7ns5HSjRv92KLOUuPZzlcYcurYMxDv3NLKpDQqVQhHtCgXROIwdfgK/LrW+kUNwYrYM4H0angLWV9LnP4+yrE6Aq9HS6GQ8BUgoHjr96qye0NIseqEZSVfS1SonyTb0yfQn4ZzcfHhE1uzCG+QzcSkYqhUt9BE3WTQqVKt2JVAYKZN0g2aq5MAOPKZBnfDvB6P0XvDUc1GtkBoDvQF9qqI/x/4SRu0Y0ztC8xNkSRn1dzz0qIQq7q/8hdR3bLhAYd+n7Putmk4I7x0JwrZZpeAbBxc5PXZnHJGckQDlR4NcTgEp1UHSVKFFPDvcWfcZXOAmw2wCcP7T8ARHDWbS4Xe8DKUu1ubUiOPzUNo3RX+bfVtQ2W0CAieS4iSWT8dmiioU9/O5/7H/EQKRO6CHSzdT/juSrs2NVXVDpRzV9nCHGj8DlBAphH/RYtuGhMnIteSfV3tbQW6DJHQpbc4KI2irTYwWejQmlTFlnSYctwy7YeLbCaQNomAUc8wsbGrxjcpvX0e3Z+8ikPTJJAB43ILBicsf35UdBVp6j9utW584KYCCCY7Q3uVIGdU0Sdo3INkKa/MqZSnjb0Lz6feUI35xE3/fa8JqbqlcAr5N5LkaETmxoFE5h/H9uy7mQpNbKkDdyVZgn3o2QGmnwhJj4CqWdXig6uEcsyTHBfIoPtJZJt0pktkncVn56xenKQP7oBaxOaAgxIml4M6NDQJwOAd2OTFYAyGi6mmfOM+ZUpz8LsELNuyyJSG1e0jRKu/Um7c0NNbjH1IjFjLPFd04NjqVlmUwsHhR+HDfMEONTp0ib9sl9xoI5hMBhhKLn0hacehadWM/EKiGIuHVzxw7Ed2BT+gsUZja9T7qr98LurMeIijfqizGCa9G79IHzMKfzkj0LLn5tDeHjEgXqkisCMipdgQbg2TI+Jxax/DQgzUaEr9O9ea9+xtv7sRoR3WwxD/QSdRhgDC9srrBkOBgnBHISW0gPboHFZzgabe25XI9NECRC/9V9yqNmK5cgpWtocu0EUITIh7KEYNX4/2qqIz4Z/2uefrppL0l/qq4xTMq2sJOh9FD73N2PHwGyVO34LiFsdlhkbQfD8NzidoE6V9z/FZS1PUQInKD7VtuicCzeXmb6H7m1lDP+SAm3bmn2B/o+BrFxtuGZPo5VnPJjEmsPSw/DjVUPXwyXLIqNA8BJlhxTyB5/vwCynjGxfoNrvAbVD8MkrQMePYT65tL2AeRQDcdV7evwizam6JXDjOiMiSerTfsihLnV/3OuIPphb1K42milt01YmPnRfnvaghriRnzwjRB4cx9EBkte7zOfA9TUQEc3QzFwj0nKVcIwoI1kcjiwl7l9Ka3f9wwhuecO8qjb1+PDodzvJVMOVAGePzhcXMaAGoHgrxvuJbOd0JvkyA5pqYaIVdQaE/oC9Kr89iQrBk6f2vrHiB99ugNtYLWA4Jb3eFfBTe01B6HEtrNjLFoF3ag3ZjZ2mxYiHSlIXTVcdN63PlnO5k42DIe0qavbUnuWm/LJpTM8vo/5mxeL8wTfxubPvT6XZcMxSsmLux5nJgcTDNsFXQA+uVDUw1xAOmGpB30B06/CN9O/z4UHR5RWyKGHQoaOs8ip3I2M1v30yTjhlQA2ptKvIHXX6G3DeHIoILS86dGWJwUl7NGm/ttMEo3hSEh10TYReOmDhAjywS6lBUUK4TnvkBGlzs0DqsETRck07ptde8zyv6r7W3K95Z9nO1eOP6YitIVUNxgfDW1twGaFQrIuiYqNGP+PYQ3Y85Pw0PsZt3vgKa0EJpw7A5b4Tklx8mew8N27yAtaGrN/dcszQZ4Bj/AWDrmSEXUw/3+aVtgdOP5RGHjKq01n4Q35dplRSNuiLeIz+yHz+JO60Fb378dkqgVjcFkGt+vH7ZGwjwckmmvb5ggyIRWZfx/q6xKiRMzoLpzGN+RnDhytT3wCwRhgJ1GkwpFQfxyaNC6gylmREfYnIoa+why+4c2HOWYYtjWTMsJeTQ06IblEWks8c8V34eZQ5r/y3hFgca9C/p4kemDgGTrijAn+e7YaxMhZ4B3JO5RFPc3RIJUU6z1ohrVDT3quvieLzjTqMdqzoPql8tOk5BzX/e8KmPRjg/v3Y+5jMJW0U2IxG4XNNAQ6rmUJ7KsaQzJLQy4tWyd7KpAIRBhFx6SJodkHAoLXL7+3wLF4poXtR0U8UokLZgaOz5rBt3qJCrD/DsuIfPzMTd8AW0oytd6we/Etm3KSunKBD5bMwJbQ59Zfe+K2DSPNZXEMq5vFhrTwNHba9dGKbY4jkekBLl4kxmgJJn2Or4WUZySMSDq8iS6YpSH/iXpApi7na+E0slOPZKoGSXi0zcjp1iSwRHbbd9rxFkMsg3pkGQVDheI7cJquOxVQb9kd+aUdsgv17WgxiUAM+P3BVpM+/BBYQGn/8oOBYtn9ICAcpAvkwXvKvmf1wDdZ+JtZ1XxDFm4pJWzr/YCGX4km4ZI5sn+U37Rwou4vDhkLeSJ+8I9WpfCT5HlrP0SvdznkHqgkvu9wBJqPofLpUdljAORAMUofuVd5qo6Xl+LwryDuTSlBL07FwyML38ckARDjmW4Y1aSyY/EnnW25mdBJoMQqSZw9kc+ME2b1S/P2b2TEYE6jUe7HzvvUTNRKNiXQSRIa9PWX2hUcYFTCD9UoZxSS38RwKkE8Dr380enVBBS/0XHUBc65J1lGMVvmPVFiW9PYzQz8V3PVPBLWf8wdkCGT4QNbNTwrveAggJIPR1Xcom/ne2s1TyIOridRCDUE+cIth8hS5uxVxX2pcqHruY0ee91gPxc9A4pBuOAjgVRm1FHc8qH1PBxBli1vXliQOMM+thl2/qRwo6G6PEYhwzP1kkzn4zOEjZ/AoNE9bS1lPva1vV+qw4s5Spkfw5R3iB7eu7SBmGWUhGagMN7vcHTcRBSkTLq/nAl7W6HY9DahA752i9tuNMEHLEjy2SCuovVFV1YPuvw+bbNuvnFpwuN1YGaAuEoE2S8vlpSRJVhZDXgSGVPzUgoFPQKiM3QY4qlap1CsUnNAEpclROGsHduNbelF08cG3E6yQgkRaSUuUQbbl57X974i/pqJfY1KVK/MhB/R/qjB/Yio8DWrMKfrgqnRgKA+KgGjp3NohRAy3tHllQl82geZ1ho0wkW00/JSpBasr+RlOgYX2phycjs+R1vCnxBqErpmNYNtk4O3zAWjipvESZiSr2rZSGRsZuKzm1yYfUXQtS9u57uV40tBD322by2GWoqlGYvSqOpdSyxiE8eUXtyBCr2ARGnUEVuYa9qv5sC9bExHcSFVQ0+AURx84t2Qjr/9/UO52fUF1J7xaro+N4J2LPRhk65ugtfSp1gi4fst3NzxhSQstxVZ35DkSLOERRsb+zaTril1bwLVBrDkzyi6RjyE1KY5GbgHNnjYWL8xdaKlWYQ9y8+aOwpHbnW0QjrpIdU7E21YB1p9zLrS1E1s3eGlv1swFMDrstY2V6lynIpdAcnATeWbfwbLnHSPTaKSVZp4Yae2Yu6zcG6TJZHi/E6RuyL7L26esPGim7pEmI86qbna6Bl9sRO5YyYtC5SSBAL/qtozx83ezVHCkASFbHH0FeAC4Uu0n3+PPTMx367AsOo3HKXcr89xkvoasstlRwnEeTmsmkzRdvq4LhuUd7DTlo6yfopvSAreNzQ1SccYR64IT23J7aShcGbcK+s4P+wQOsbkH+qpvGeR7kCpxPWcKGdWRJEaYMOiAsekKFcPJjCQ5yxR8FBo/PE1h6XfLJDbmSoxdpnorzUdwewB+DI6x6miETdyRzzf/uI5G/rP/BdMXwwpdITq4iuI8cXHh1EuvYn5AsdLZOwt0RZNtSgB0JzN2EMHkQkgstJbbNVEtHqyNcAjToaE34PqbRCIGrX5Lp0Fugd3tWIzP8q86rNckzjOJAKYAJ7abNVlteJqoWjwzAtg6YlU4pXzjzcySCFZSHPhizrFv2WAe5BBZhhQouFWtrtZMfKSNVuz1x8fBWjvkehMqbEOzgBIHzuR3IQOBo9OFDzgC+/nioYw136p1xn/DRvEQBOrrCe4nUHShEwE9zan1rroDdHgCdYS92Ukb8p9/B0g5GgH9ZfN7JZxFyhJjRt5izqHRyJf5Yf7FE5p0Qt2Doptf/zPffqWoTQTZMBFgb/eg2l531ploTfkmoHNIvS402DfB/iI8omWH2v/hPTkofs3vgzRYUo+LnoCHtFtRmSrlyyNUtP4+hH6yDIHus88EnKX6nUzWfumE7JkTarFHAOhQ4eXOjlfuwhxwuC7aIBeMIfKxfVPS8kAyC/AxdtawsXqXVy1UfrVUxLZZ8fL2XOvZRciug3TUCUJA7Sy01x5lkuTdZZQD1YVV033cASmRNyhKoFhHU7oBHijvslcEAfe2mQRJ4bafGkDp3hVbwGAMJp3yZIsgotmhvfp/agh25C4kKFBIrJ7YM+2Tbj4/Vm0ZkIemd/s176bwL4fjg6IZSTiNoZECOtHLY5iFDjFiVjIjx+dWwJyTQTUIlqYDoaKmP/tkMvSNlibVj1uHtf7+PE4zQ1ynSSZ8r7BKMtyocWqh2i0Squuup7xvLC6mSP1oZoD5U9WLoknJuouZTycbcEstHcqlTxc6nnhEYgi27tOixl6qfiF7neObfMNYyanhWX1pFbQTZs+RrYCimPWnINhR9g95Oj+hHjz4KRuvBiK12NV93D5H9L5zsI1VGMiMfz12fmhys6BAIIpIscYhPbTv4fCz753m7WWX5JxFJHESrOyUl+ebMxCa/4JBQb3apX+soREDqwWVVIzt9oxUkmC5ETA492BDB6Bg5xm8RQh2Hia+IqghkJhbHu4HMJSqemsq4H8vYwwbuRF6Fa6u85cMDma1BjQuy9h2tXtl+Kx/bC17eQ76ucT+QINsoK7mxCdE7GrMmSMy7dhKNcQTjSIwCTgSXJYfgv4xb3PuvN0cSFlt0d75n3B1/llCalHBJv+EBjmyVX3wgBRxM9udzjuf1gPW7BiDvalpjQbi+9lseNkX7YseJ6SBnuy1KvADk6NHk30DKlJ1YoNz3vCJgBhhMZsyBGRgA0XfJW9DfuKC/RFSJmL7gDXnOqD8/lfLePiQEMR5pyFdic4YMQh+wc6dxpGMMy3NLCxOgkEgOxVnJpMP0aspY5p490PDG83R5IFZucFL9bb49LAgn2XnnuZdImBPbdRozrTx+qTwb8N4HQlIFrz/+XqaGfVt85hujN/3VrfcP5RcKN3uQnlvUaKPja2B1SZld/PZK0Bn8wnCB8ukdUaIdKzl/QAGQySGQcL1LNur8OwKKOOooM+mv5jfypJSZzvPMLLaWEINmHvUnA83N6NCt9v7PEq9mkqbeZuQU/TtaW4GIsUPyOru3pEdrZdrPe4QzTksNY/AKJi0eJbYHScMSbTSDqOnuF7/BmK03EsaziO3dwPTJOBEdRqVwF06Dw/vKyg1exuG8WFVWXiqwbZHA7mdfSaUj10ZnBkTuOrTPq9tE5Z9b2Mr+iFie3VC2REocigswKsuMbwx+mTG0m1DFnfqSyVfdGvJAJGKojDZdPHetIwrCaQlSxOiNup7wr/OJW0WCkU8xvBfTcjaqs1EtpjT2swYkCD/fuMQ7P2k820HvYtJDxriei6/R+gWWAMuuRMuadMTKvEhTjowoQI/VkgGX09m2hBeoY6CO4tqwFdIc9i5xADteLeqDxIfA756BQIDMa8R+XEUc9kOz2eLkoUI1eA4dNeFQIG+VlUMEl3nJgyDAcW2yQkxP4GSyuqujMD2gQfFVKBy0TPAucvnUo5M0UW2E42M8Sz8wbaxMuDLBbwX6vyGwam1sZ2Mp/HZ9fwHbXTAx79//HaTJPxdCOuI6A4QAFZrSWXu1SQlfcBbgkdId8Ut5VQCZ0oWMtcm/7sgcuU3GEeE6CihsxQEeqcuItAiJonVEytqSs46XcPb5clCOJpKEbAy9wiVTCdk2OsZSIPfocbdg+E/QxNbh4OYjtp5ZVrvLVRXyGliSmrlCXSIuVwuI+WPIbEFwZdtBy3AkkyXSCzQ0WMSpiV7tv+lwe/n5QZlsdKfy8XqOTkIEoArBiQM2uByOAtDDJ6Q3xdOCNsOgdJXHTZ9ETQuzXCfxDsS4QofqJibIbD8VzXrWUrBgTjiiAFJEfno5zedPbmhoCZLGA0FTCnDEbsprygYQqtxHqgASsyH4HhvlmMxvmg1ce8TwmGnhnnr+1Rm1EMYFAd3qBqpTL5r1EJNBFlxQrNnhDhVeViw39bQL3P8hl21SDN3XUtKIkMGuj7/OWiyXgJQiGI1huhAXnNCuW34nzHcMUm1x6EqtvI7oH+P6HTLgnIJmuIqoN3QVj1qUiDKGPezTnp4MmzLtOBa28o1tG1CgTofaALoo5whW6UMzsuZhIvvAWQ4IiofX5TaJ9nybC09umTA/0AjeuYmtNWDFa3xvnRCLExDiyYPGOt3ayjSoWb6mxgs1rJx3v37Z0Mn3zI284FehKSdJCpbU28ZtD21x84kwEcTRKxB7XxSAOGXXK5F0KgQGbf+/0PBZGKCdG61kCtDPmvKZkHYw48rtCdON6ap8/g3W7Ek+wd+VDJu0YXmH8O6xMR0P0yHa1XXIWfaJ1UwBh9DRrgtMP4ckCtn1mvb1oXbii4WOnvm5539Eiu0a7MsSKzrESq/52ml0/2EXPuM+QNnIL2bhxApMF/gJBuu1C3Ebg4B8Qu6O8n2j8JF5cCUM9nmK8t4GjX7z5jzqOhD5a0lFQ3Mpm3H6z75e1kRxC1L3LiBYzZzK2B6EE+ME3Rlviq2o1iF6kJwrwt1/0XxNNHd3x3w5XBSuQNrvGhpaC7dVs70+GbQ++brKjpBJj4uSiFwqRIHeaib0OyrmRr2LFNtwNY0xdn566RlVShMxUKisVRT5SMgzngl2lczM3ZEudf7wfQ2kzEkV1qsXI3otlsujWceQN5TUCaURAIMfQnjBwCGrtUPyygfw2oj3/LuZsG8HYcPMuqnbaG3bgALDyTbwlmaFiuns64PE9GUsVszRI4CpuuWZeqrRTbam5dioONOWw9syVUXNL8Xs1t8bwxbNSEs/EwhI3O0pxGQM8NY2s9TM9S7/xsKwMX1gkJTtg2m68D7bUP/o2FlIHjkzqDSRZZs6XKrMqnjcn91GVq0VEihODUbNVJujuKod87hpHDmt6UvAQhDpjK+HxuzdytPZFgy/nviH2uy7Db0wKfMrVWbd+O7LCCLDhOia15tfi815ANVGSSznF26U57fX0H1zRmeEIHIWCNZNSXxQKVybDWc1Ov83+Nj4oIkLC6yarcg9Avef7+7RW6klQPTan+1AmVRvLjaDxGDI6M8JVLTorQoJ2hxiDCLRYUvvfPZlUecxA6zit0RpeWmvTBYt9nCB19ZLvT21kOvIqSTBKSQPDlv9Yr4zS9LGhghxIdHpQegOAAd9ySzkSS39/+ZiWKThmuDmqMmeKxmPyGxYL5b52bp6r03jFzSMgb5UIcSTKQcfobOR7ovPJxSzpK2FvjPibf5NQqeXUfpAcGKnyBEb331915m4LwDnv+9wf+yzUOL1k78kKn4Xty05gU8JBW3UMz8DDZDaNblSZ+fJrMSyStiHKE0hZ4TOW6bxNESuCYqWv7VkswhhlCdJcLp/PVHni27SkU+h3IKqHZcr90xw6zpvwFm3ER8i08EmADjvgQQqM/IN7un+j6hXcgdw62nAbRJZafB9fH5uJBewQfAd6M9wyJQDqiBjGm06IecMyG5Q6j57O9YJe/oWjSkb8mr0DVcf7XiaPZAQfn6vt2CGEjTjDBmWsoXXUi9eFJuyEj5uGvYARqDaKJYdWmYRTBE90At6LjFJLu95EWHu6Q5KAxKHs3h1Op/bxvOumwZ61WuxOyB+YeF35KSIOgsRvtBxN0MwQiWtUb/HQK+eMhe6kqtIBq95EkKK8z18Y3F93dG6TZvFD2AdjNs74finQLDJiQYCaOI2StmbgzQcm05rgZUoJgeD0A3YUV00qg+m3RqpEw4KYhDlVhVES/eMFmJflc6/76UVBiPncc091SxBNmQ3Y7ZUatkjfxW18Fhju00Ggy5V1CzdWlrpM7uvPFRbyL9UVCxxVkNiiqOUdyZq14xtWTXuepPYK1PUYcSSTu7LOTZh2NfL38WltyS/pByaYl8m6WKiaqU6QOvY8DZmX06gVz29TQh9u1pfRGqOZZVhebBCQfApkgkJ3Kwd5Sg44TaFKv2gay+yvQuRwpgag6su3uEz46zDYjwPaPCgkF/Tc8q1liLQsToXhE55GxTV0iWN72vXBVehjk3zuEJJQ9EeqKmo2UcjNr58ktG3EbTjMtTIrlqVYGrvAjdJDgfoWmnl8UV34geEOT0NpjI7wnJsVkmW3Fjl3QI+2t0RswZIHg6MrubGnH9v0eVHMkxvirxXSSDTqYRNozIsU6G76rlZCZ1iqq/RXa0Bf3tos9UrpJ5Rq1X95LhbU6R6ww+NcmhAJpOC3nBrlDkqlzyYTh2mtB48IIbgsgEfpkRgaGk/oOPTicTqv9Ft4rEVg6ZGwGdJ2xPQ4VXkQU32s66J5ilRt1KJYr+HmRcHDmol12ZQxrNBxS2aofKrxDo5Ywn8+6DMO+0qS6AERJ01qBQFesYAEIX7zu7u+jkpIHtjTiZzY/p6zhGNd7UHC7sXVWg4bhvJiMMCTDuSBuRTKCuE4Yj0uf1EC3+wTTAOryRt8csnTKFTttbv6qeueB3Fp+VpqPlipPTkS69++aXyz4hqjJZf1JYrKWeo1mJm5zepYg5l12n8ASe4DNEXTk7UWUWEbvJAcIOsa6ckuJw+JqTgXIF6LPFTKbRq/gAOxHKmrEA/EOjJLG0G7mp4W+jaHDfKFIBQtCSIHvHU722K72ygKJzIQRzpkAoG9mIDmKlhaf7wf+ZKp1YcPSsMwgI2Zd7PkT1JzJmS2mCwqSwS2NH6ElMEBJkZta1vcsKujqnKqzpPirbO0kxuN8hwR6LxSfju0J2/X3hP9Ov63ZrM7U7+H6MtSOGVlpHMHpCzkdnrZKmUH5wl1AZHkQUZu1b0G/5ViE2XwNV8sjuvvcfjW0zraLO2DeRQjuBtjl5oMROVGJJ/+MW0VcJnVCSG4ltbuDHMxqjYPdy303fmKIe2KjUr30vnjaHGw7D7TSMryYaYIQuLCQe+8qPKqiVOv66mTW2pnXIxg7BWfhxEZ9b+oinNfigXQkkwWoGRMdounp/4XmBqb2+Dnm/pj/QWf/WseXNf7jG9auC/FIeB7qDnj+XL2X8G1ImMgMuT79su3jrszlL5RG+mHSAVX9CYvAGVvDl+aVSiK1KmuCgL74UnGBcg45DhoqiZJQWs98W2JnBllNlgFfK+829011Z7K+XrqBgJ5/6JbF90Xj8nbu5XD5wH2REfhsBTneHrrUc+YBy5+zelVnsn2gAhonhL+mE9gmWvRtAXsOYu9WITYGfHy0lxVmuV0aqdWUWBqeFjGZquXlFvW3LaY0ahS1S5oo3PJIAx8VsLNVkKWBlyEY8UhQTM+5YB7KCuMaYEoryhFvzgi1+DsivmFOetyIBuB1BE8igWkscOeaRgkHlDqODf/WyY5kqZ8MJ+MLr1hDGOyTt5LiyjsGuDOb+fL/LPhOFe2caAVYqaWgpODsi2+BkoFPH/GCmMsC/F+fCoEBzGwFECeHaHxG4T4mq/n8/29jKpulxAqRnCbEOV9uWOmaZggnl0hJ9OYrbWFQQOIgS8j3j+G0ourZnl1Qw6lrhoomsr55hJgdYWem3/uo2tWY5lLkOvKC+VNwubLsGcTmkjYD6LW6SBghnUPU1vB4nZ82SyHxkElYw1X88nRaLy029IeiZTcArlNUcJuyH5KFya5I+4pBBm4TAeVrph1UHF7HRPSyeWj3oSrMj/GghWqoCdC/UCVjfaHLt51zorInvZDCe6FB2cXF0WgTYxeRMos9+HEMHGRfjskCNgejqiXIYkFNcZiiI49vT/jYNCrd1eV5zHc4eR4JgTAwyjP34mSX2La2XFwyx1BtLd8x5hhiP58VtMy6wCtrqWgQ8JqSupXzj+M+xFBIo0cVFJQCuRcwqGUMzCKL2xsfjop6E391cjTwi4dWVcTjopydKEB9dSUt/YG9xEieDKgPQo7Z1IGae5EqvJcT3e38+22D2dUNeyDALVBZz9l66YY/2wlxB/wG2SsR+1uXwQjuBDQi3vqBqkPtcumpWTUsXft2w3PlPDYPJ6sbox55SKxXJjwaC27BkFIh8kfdsAEpnl0hnx7Y7TBFeMEnOaoAR1hzrY9IEnTbee1jCM9e2x3DYv6zwQc8XSD/6B55oQJCZPV9dcmV3rIfT+Bn+PzY5cebe0/L763BIFMeEVM/+nkMSVCjszMILQaO5vMPmwvijg4zUf23AxmPcohMBbRLqarZ6z87oks277OeG3mLBfRrrE5DFlu4/R+6q+BF+KEKPJth8qM3M/oKzsSOWqQrQCh5qqu/QOZzml23yilY/LfxKPzqHl4Ay4iEUi5ove0AqWn4ld5qRUp7qfKKHHhl/vAxPoQ4awMNE6hEeJaqr+kjPpUlsGxfPRnEZaOzK+TR9048pJTllMmYMKrIxvqEAVZpaSBwuKSR9+KYrXgAHeq7JILKfI/TfqLWXf93bKVwXMO3almtqz67V0s/F9tkw2Jl2h4r7Lt4Sy2dJJyEQ+HDrGO3vABIRBrAwxSTXCWIczl8WBm+KR+n0cTu9u1HWJyijrbN7lVrt6XjJ1+R8Qhd4pW7Mc05QdayyudB5aACi+fQJfYWdzRQymlc+FOgbSxJPhm2TkbJEp7Xne0N03mG5ALEVc56jvgs94/DLRbo4OD2+57G+fCl7AJJZH0cC6gQQOL5CYYxNNXc+3AOekKBWljSmenif5TBmXEPz9EohaQjoZr6FjM9ngZuQDgo3fxFcBJdfo/nfMOXPW0NGO9dtjwEi+JsmJnj/ADgDu4d8ip4OLourd3ziRh7Kuxq/FrT","recovery_checkpoint":"wiki_generation_completed","last_commit_id":"36c6ca276628c62822c5b35e3772f1e2f1340f71","last_commit_update":"2026-05-27T18:36:41.119769+08:00","gmt_create":"2026-05-27T15:32:45.7755498+08:00","gmt_modified":"2026-05-27T18:36:41.119769+08:00","extend_info":"{\"language\":\"zh\",\"active\":true,\"branch\":\"main\",\"shareStatus\":\"\",\"server_error_code\":\"\",\"cosy_version\":\"1.2.3\"}"}} \ No newline at end of file +{"code_snippets":[{"id":"333405ee9924108619cd8443f735d754","path":"internal/router/router.go","line_range":"16-52","gmt_create":"2026-05-27T18:35:29.892946+08:00","gmt_modified":"2026-05-27T18:35:29.892946+08:00"},{"id":"6eda76d6eb6015250ec186fdafd0b3c9","path":"cmd/server/main.go","line_range":"59-70","gmt_create":"2026-05-27T18:35:29.8934805+08:00","gmt_modified":"2026-05-27T18:35:29.8934805+08:00"},{"id":"553e943cfb2f6b7752122999084a80a5","path":"internal/cache/brand_cache.go","line_range":"18-44","gmt_create":"2026-05-27T18:35:29.8940514+08:00","gmt_modified":"2026-05-27T18:35:29.8940514+08:00"},{"id":"d7c4ecf9c38df06865431d0dcd796162","path":"internal/cache/model_cache.go","line_range":"19-69","gmt_create":"2026-05-27T18:35:29.8940514+08:00","gmt_modified":"2026-05-27T18:35:29.8940514+08:00"},{"id":"5ec84f3864f3fa2c3ab1d97fe69d5529","path":"internal/repository/brand.go","line_range":"14-52","gmt_create":"2026-05-27T18:35:29.8940514+08:00","gmt_modified":"2026-05-27T18:35:29.8940514+08:00"},{"id":"468dd8105671ed478ff86ca97c0609ba","path":"internal/repository/model.go","line_range":"14-79","gmt_create":"2026-05-27T18:35:29.8946006+08:00","gmt_modified":"2026-05-27T18:35:29.8946006+08:00"},{"id":"a0b3e000a5b789bf08d2d996fc17d8df","path":"cmd/server/main.go","line_range":"25-101","gmt_create":"2026-05-27T18:35:29.895175+08:00","gmt_modified":"2026-05-27T18:35:29.895175+08:00"},{"id":"111557d31227afead72d0f01becea3bc","path":"README.md","line_range":"19-123","gmt_create":"2026-05-27T18:35:29.895175+08:00","gmt_modified":"2026-05-27T18:35:29.895175+08:00"},{"id":"5db111a430cac488cabeb543494fb917","path":"internal/response/response.go","line_range":"15-36","gmt_create":"2026-05-27T18:35:29.895702+08:00","gmt_modified":"2026-05-27T18:35:29.895702+08:00"},{"id":"891c848d9153926513b9005f2d61382e","path":"internal/middleware/logger.go","line_range":"10-44","gmt_create":"2026-05-27T18:35:29.8962367+08:00","gmt_modified":"2026-05-27T18:35:29.8962367+08:00"},{"id":"8a6a9ea04bb9b0de8fd0195ca491b154","path":"internal/middleware/request_id.go","line_range":"20-29","gmt_create":"2026-05-27T18:35:29.8962367+08:00","gmt_modified":"2026-05-27T18:35:29.8962367+08:00"},{"id":"99d2500a6a0922c50675ed247c6777e5","path":"internal/middleware/cors.go","line_range":"7-19","gmt_create":"2026-05-27T18:35:29.8962367+08:00","gmt_modified":"2026-05-27T18:35:29.8962367+08:00"},{"id":"c86c8f1c951956c0397e6c938ccc641c","path":"internal/router/router.go","line_range":"23-36","gmt_create":"2026-05-27T18:35:29.897306+08:00","gmt_modified":"2026-05-27T18:35:29.897306+08:00"},{"id":"99701e03d9c9476a15f742b82e5adfa5","path":"internal/cache/brand_cache.go","line_range":"13-44","gmt_create":"2026-05-27T18:35:29.8978401+08:00","gmt_modified":"2026-05-27T18:35:29.8978401+08:00"},{"id":"a072f4ebff3b6cc9eaf8025737ca42d3","path":"internal/cache/model_cache.go","line_range":"13-69","gmt_create":"2026-05-27T18:35:29.8978401+08:00","gmt_modified":"2026-05-27T18:35:29.8978401+08:00"},{"id":"d4f94a6e4a0cd46ebc0c5f03e96c6232","path":"internal/router/router.go","line_range":"38-49","gmt_create":"2026-05-27T18:35:29.8983769+08:00","gmt_modified":"2026-05-27T18:35:29.8983769+08:00"},{"id":"0a2840d641ba5dccfff95a35d7317004","path":"README.md","line_range":"83-110","gmt_create":"2026-05-27T18:35:29.8983769+08:00","gmt_modified":"2026-05-27T18:35:29.8983769+08:00"},{"id":"491bd71f42db0fd5bf1d4851b9c4aaa9","path":"internal/handler/health.go","line_range":"14-18","gmt_create":"2026-05-27T18:35:29.8994388+08:00","gmt_modified":"2026-05-27T18:35:29.8994388+08:00"},{"id":"fce5662f14aa6386a5036b5241e00b1c","path":"internal/response/response.go","line_range":"15-21","gmt_create":"2026-05-27T18:35:29.8999721+08:00","gmt_modified":"2026-05-27T18:35:29.8999721+08:00"},{"id":"7e3954c3e70a9252de9cfdec52ed93c8","path":"internal/handler/brand.go","line_range":"25-48","gmt_create":"2026-05-27T18:35:29.8999721+08:00","gmt_modified":"2026-05-27T18:35:29.8999721+08:00"},{"id":"79304ed9558f17f9ecb0dc7d24add547","path":"pkg/encode/base64.go","line_range":"44-51","gmt_create":"2026-05-27T18:35:29.9005171+08:00","gmt_modified":"2026-05-27T18:35:29.9005171+08:00"},{"id":"a6d16b8965ed7f207f19f8f915ad53a4","path":"internal/handler/model.go","line_range":"25-49","gmt_create":"2026-05-27T18:35:29.9005171+08:00","gmt_modified":"2026-05-27T18:35:29.9005171+08:00"},{"id":"fce0c17d6c03e511c3afeaee662ad34f","path":"internal/handler/model_list.go","line_range":"26-56","gmt_create":"2026-05-27T18:35:29.9010627+08:00","gmt_modified":"2026-05-27T18:35:29.9010627+08:00"},{"id":"d4bd0610a0ad3d8fd8d33ac5f4aa83b5","path":"internal/handler/device.go","line_range":"26-84","gmt_create":"2026-05-27T18:35:29.901596+08:00","gmt_modified":"2026-05-27T18:35:29.901596+08:00"},{"id":"1be2a5a025cb64eeb20d5e54d293203f","path":"internal/middleware/logger.go","line_range":"33-43","gmt_create":"2026-05-27T18:35:29.9037303+08:00","gmt_modified":"2026-05-27T18:35:29.9037303+08:00"},{"id":"5f4eb9799d6c811ddcc430f51e299cf6","path":"internal/middleware/request_id.go","line_range":"22-27","gmt_create":"2026-05-27T18:35:29.9037303+08:00","gmt_modified":"2026-05-27T18:35:29.9037303+08:00"},{"id":"be85f7cf4e9dd0c2460475b95efb085d","path":"internal/middleware/cors.go","line_range":"9-12","gmt_create":"2026-05-27T18:35:29.9042675+08:00","gmt_modified":"2026-05-27T18:35:29.9042675+08:00"},{"id":"730d8469648c9599ccbc091a9496d2a1","path":"internal/response/response.go","line_range":"23-36","gmt_create":"2026-05-27T18:35:29.9042675+08:00","gmt_modified":"2026-05-27T18:35:29.9042675+08:00"},{"id":"d48bcd5374602483c104c7d50c7224fb","path":"internal/router/router.go","line_range":"18-21","gmt_create":"2026-05-27T18:35:29.9062656+08:00","gmt_modified":"2026-05-27T18:35:29.9062656+08:00"},{"id":"798bc9e7f1a3902993b3aa9acba73022","path":"internal/middleware/logger.go","line_range":"16","gmt_create":"2026-05-27T18:35:29.9067927+08:00","gmt_modified":"2026-05-27T18:35:29.9067927+08:00"},{"id":"ed43fe99536e371ce908f167a68124f8","path":"internal/middleware/request_id.go","line_range":"28","gmt_create":"2026-05-27T18:35:29.9073213+08:00","gmt_modified":"2026-05-27T18:35:29.9073213+08:00"},{"id":"08c02a0d77d871b6c9650cbfcdf84c94","path":"internal/middleware/cors.go","line_range":"18","gmt_create":"2026-05-27T18:35:29.9073213+08:00","gmt_modified":"2026-05-27T18:35:29.9073213+08:00"},{"id":"e88b0ee062bd02dd7acdf8e2e945b270","path":"cmd/server/main.go","line_range":"103-130","gmt_create":"2026-05-27T18:35:29.9078603+08:00","gmt_modified":"2026-05-27T18:35:29.9078603+08:00"},{"id":"64381887b12f6927d8b0481a55c2dcf1","path":"internal/router/router.go","line_range":"22-25","gmt_create":"2026-05-27T18:35:41.7314752+08:00","gmt_modified":"2026-05-27T18:35:41.7314752+08:00"},{"id":"1503a99bb2f2ab96e4a3a830d8834e45","path":"internal/handler/brand.go","line_range":"19-24","gmt_create":"2026-05-27T18:35:41.7314752+08:00","gmt_modified":"2026-05-27T18:35:41.7314752+08:00"},{"id":"f74cdc773e62a1a9f5a4bf940b5961e3","path":"internal/handler/model.go","line_range":"19-24","gmt_create":"2026-05-27T18:35:41.7320175+08:00","gmt_modified":"2026-05-27T18:35:41.7320175+08:00"},{"id":"8b0db394a538b6652de2e6634277ad0f","path":"internal/repository/brand.go","line_range":"14-21","gmt_create":"2026-05-27T18:35:41.7320175+08:00","gmt_modified":"2026-05-27T18:35:41.7320175+08:00"},{"id":"03f26c7c55e18e6266ea8e543a032229","path":"internal/repository/model.go","line_range":"14-21","gmt_create":"2026-05-27T18:35:41.7325394+08:00","gmt_modified":"2026-05-27T18:35:41.7325394+08:00"},{"id":"8fab617bba600779abac7805723180a0","path":"internal/cache/brand_cache.go","line_range":"18-24","gmt_create":"2026-05-27T18:35:41.7325394+08:00","gmt_modified":"2026-05-27T18:35:41.7325394+08:00"},{"id":"006d91f2f5f75fd7cd586165c200ba98","path":"internal/cache/model_cache.go","line_range":"19-25","gmt_create":"2026-05-27T18:35:41.7325394+08:00","gmt_modified":"2026-05-27T18:35:41.7325394+08:00"},{"id":"509525e0463c03c509709a6bd1765d4f","path":"internal/cache/redis.go","line_range":"10-16","gmt_create":"2026-05-27T18:35:41.7330685+08:00","gmt_modified":"2026-05-27T18:35:41.7330685+08:00"},{"id":"57b8aed283762226a00482b42a8acf5b","path":"internal/database/mysql.go","line_range":"14-46","gmt_create":"2026-05-27T18:35:41.7330685+08:00","gmt_modified":"2026-05-27T18:35:41.7330685+08:00"},{"id":"4ab082407b96e18f67a65d07eb4a331d","path":"internal/config/database.go","line_range":"17-40","gmt_create":"2026-05-27T18:35:41.7330685+08:00","gmt_modified":"2026-05-27T18:35:41.7330685+08:00"},{"id":"fd2a12d243b52512003ae067f53a7548","path":"internal/config/redis.go","line_range":"9-57","gmt_create":"2026-05-27T18:35:41.7335924+08:00","gmt_modified":"2026-05-27T18:35:41.7335924+08:00"},{"id":"61d69bf4d3c8c548eecfd677394486d6","path":"internal/config/config.go","line_range":"18-52","gmt_create":"2026-05-27T18:35:41.7335924+08:00","gmt_modified":"2026-05-27T18:35:41.7335924+08:00"},{"id":"e87c932ace50951cb91aa66877ad6f81","path":"sql/model.sql","line_range":"24-35","gmt_create":"2026-05-27T18:35:41.7341274+08:00","gmt_modified":"2026-05-27T18:35:41.7341274+08:00"},{"id":"9918f39149aaf1f5c3ec03275d6e3673","path":"internal/repository/brand.go","line_range":"23-52","gmt_create":"2026-05-27T18:35:41.7373036+08:00","gmt_modified":"2026-05-27T18:35:41.7373036+08:00"},{"id":"a19fb2ac137e43d92d2ef93e8d79f0a7","path":"internal/repository/model.go","line_range":"23-79","gmt_create":"2026-05-27T18:35:41.7378291+08:00","gmt_modified":"2026-05-27T18:35:41.7378291+08:00"},{"id":"72322f320f907b6eec72e885e30759eb","path":"internal/cache/brand_cache.go","line_range":"26-44","gmt_create":"2026-05-27T18:35:41.7385763+08:00","gmt_modified":"2026-05-27T18:35:41.7385763+08:00"},{"id":"d0f658c42abae9b6dc0baaa8fc7d0694","path":"internal/cache/model_cache.go","line_range":"31-69","gmt_create":"2026-05-27T18:35:41.7385763+08:00","gmt_modified":"2026-05-27T18:35:41.7385763+08:00"},{"id":"a952e5d5b625754a2e9249983bb8abaa","path":"internal/config/database.go","line_range":"17-72","gmt_create":"2026-05-27T18:35:41.7391229+08:00","gmt_modified":"2026-05-27T18:35:41.7391229+08:00"},{"id":"f7af3a1998c24f922aa650a69b252734","path":"internal/config/redis.go","line_range":"16-57","gmt_create":"2026-05-27T18:35:41.739651+08:00","gmt_modified":"2026-05-27T18:35:41.739651+08:00"},{"id":"c7bf654a5faf00b02953d2e56747a669","path":"internal/database/mysql.go","line_range":"28-43","gmt_create":"2026-05-27T18:35:41.7417727+08:00","gmt_modified":"2026-05-27T18:35:41.7417727+08:00"},{"id":"1d3714bd55d5d3f773f1ab7fdb8c9b53","path":"internal/model/brand.go","line_range":"3-6","gmt_create":"2026-05-27T18:35:41.7422949+08:00","gmt_modified":"2026-05-27T18:35:41.7422949+08:00"},{"id":"8d92ac14c6257462a15eb6990dd44596","path":"internal/model/model.go","line_range":"5-14","gmt_create":"2026-05-27T18:35:41.7439044+08:00","gmt_modified":"2026-05-27T18:35:41.7439044+08:00"},{"id":"8b134235408cf40b9d6351d54591b3c4","path":"sql/model.sql","line_range":"34","gmt_create":"2026-05-27T18:35:41.7449566+08:00","gmt_modified":"2026-05-27T18:35:41.7449566+08:00"},{"id":"62d02336da9111eec3c5696aabf71927","path":"internal/cache/brand_cache.go","line_range":"13-16","gmt_create":"2026-05-27T18:35:41.746537+08:00","gmt_modified":"2026-05-27T18:35:41.746537+08:00"},{"id":"a60ecb63d9ab3bda0c5042f26916def3","path":"internal/cache/model_cache.go","line_range":"13-16","gmt_create":"2026-05-27T18:35:41.7475474+08:00","gmt_modified":"2026-05-27T18:35:41.7475474+08:00"},{"id":"5859dc43ab95b589fc2cada49ab59a86","path":"go.mod","line_range":"5-11","gmt_create":"2026-05-27T18:35:41.7475474+08:00","gmt_modified":"2026-05-27T18:35:41.7475474+08:00"},{"id":"dcc3acd0529002f62657a37922318e37","path":"cmd/server/main.go","line_range":"25-69","gmt_create":"2026-05-27T18:35:41.7475474+08:00","gmt_modified":"2026-05-27T18:35:41.7475474+08:00"},{"id":"99ead368ce42f1081e05c800c65b176f","path":"internal/database/mysql.go","line_range":"33-43","gmt_create":"2026-05-27T18:35:41.7539267+08:00","gmt_modified":"2026-05-27T18:35:41.7539267+08:00"},{"id":"a5fb1691af5646ea8b4306ae97288e36","path":"internal/handler/health.go","line_range":"10","gmt_create":"2026-05-27T18:35:49.7681131+08:00","gmt_modified":"2026-05-27T18:35:49.7681131+08:00"},{"id":"de87fa33e6add38c027478dd3d0cebda","path":"internal/handler/brand.go","line_range":"18","gmt_create":"2026-05-27T18:35:49.7681131+08:00","gmt_modified":"2026-05-27T18:35:49.7681131+08:00"},{"id":"09427d743a4be750f874418ab3e8504d","path":"internal/handler/model.go","line_range":"18","gmt_create":"2026-05-27T18:35:49.76864+08:00","gmt_modified":"2026-05-27T18:35:49.76864+08:00"},{"id":"9ebb4688793526b520ec263ebf651be7","path":"internal/handler/model_list.go","line_range":"19","gmt_create":"2026-05-27T18:35:49.76864+08:00","gmt_modified":"2026-05-27T18:35:49.76864+08:00"},{"id":"5e813130e7885527f77be92dbbaee9b6","path":"internal/handler/device.go","line_range":"19","gmt_create":"2026-05-27T18:35:49.769172+08:00","gmt_modified":"2026-05-27T18:35:49.769172+08:00"},{"id":"1992aa29a2869c31fe69ac701541c6ff","path":"internal/handler/health.go","line_range":"8-19","gmt_create":"2026-05-27T18:35:49.7696957+08:00","gmt_modified":"2026-05-27T18:35:49.7696957+08:00"},{"id":"692a2c6d49d4eb62f58600908dff9f60","path":"internal/handler/brand.go","line_range":"13-23","gmt_create":"2026-05-27T18:35:49.7696957+08:00","gmt_modified":"2026-05-27T18:35:49.7696957+08:00"},{"id":"c9df5e7b8533af65ce97cf085b6589a9","path":"internal/handler/model.go","line_range":"13-23","gmt_create":"2026-05-27T18:35:49.7702757+08:00","gmt_modified":"2026-05-27T18:35:49.7702757+08:00"},{"id":"d2fd0586bf019047d2adbcdf90e09224","path":"internal/handler/model_list.go","line_range":"14-24","gmt_create":"2026-05-27T18:35:49.7702757+08:00","gmt_modified":"2026-05-27T18:35:49.7702757+08:00"},{"id":"bf1f0d1dece713e866e4a46be7784473","path":"internal/handler/device.go","line_range":"14-24","gmt_create":"2026-05-27T18:35:49.7708+08:00","gmt_modified":"2026-05-27T18:35:49.7708+08:00"},{"id":"bc6f53b403231c0f908654d3fea2102a","path":"internal/handler/brand.go","line_range":"29","gmt_create":"2026-05-27T18:35:49.7708+08:00","gmt_modified":"2026-05-27T18:35:49.7708+08:00"},{"id":"7b39881baafeaea08adce31120b7c1e1","path":"internal/handler/model.go","line_range":"30","gmt_create":"2026-05-27T18:35:49.7713218+08:00","gmt_modified":"2026-05-27T18:35:49.7713218+08:00"},{"id":"dbe385204072d26c84bf169842961690","path":"internal/handler/model_list.go","line_range":"37","gmt_create":"2026-05-27T18:35:49.7713218+08:00","gmt_modified":"2026-05-27T18:35:49.7713218+08:00"},{"id":"2a723ed48cd9855068a04da6a33cb5e4","path":"internal/handler/device.go","line_range":"71","gmt_create":"2026-05-27T18:35:49.7718468+08:00","gmt_modified":"2026-05-27T18:35:49.7718468+08:00"},{"id":"d72b0eafdb65d1d946060cf944359251","path":"internal/search/meilisearch.go","line_range":"22-45","gmt_create":"2026-05-27T18:35:49.7723711+08:00","gmt_modified":"2026-05-27T18:35:49.7723711+08:00"},{"id":"72195f4e7a76b584cbdfbaba23db2a1a","path":"internal/model/brand.go","line_range":"3-7","gmt_create":"2026-05-27T18:35:49.7739534+08:00","gmt_modified":"2026-05-27T18:35:49.7739534+08:00"},{"id":"3e3a148f4095f6d36c64b1cfb3d1702a","path":"internal/handler/brand.go","line_range":"13-48","gmt_create":"2026-05-27T18:35:49.7739534+08:00","gmt_modified":"2026-05-27T18:35:49.7739534+08:00"},{"id":"3c27d9274287839faa5269c34b98b6a9","path":"internal/model/model.go","line_range":"5-15","gmt_create":"2026-05-27T18:35:49.7755123+08:00","gmt_modified":"2026-05-27T18:35:49.7755123+08:00"},{"id":"e0ca219542426b9141a89063f7052b0c","path":"internal/handler/model.go","line_range":"13-49","gmt_create":"2026-05-27T18:35:49.7755123+08:00","gmt_modified":"2026-05-27T18:35:49.7755123+08:00"},{"id":"270fee7aef8f38c42409050388865f6d","path":"pkg/encode/base64.go","line_range":"35-51","gmt_create":"2026-05-27T18:35:49.7765552+08:00","gmt_modified":"2026-05-27T18:35:49.7765552+08:00"},{"id":"8cf065ea198e4e0d88af1863fcd6ac11","path":"internal/handler/model_list.go","line_range":"14-57","gmt_create":"2026-05-27T18:35:49.7770826+08:00","gmt_modified":"2026-05-27T18:35:49.7770826+08:00"},{"id":"b62090b5a8fe0cd95b332a46bb8eac3c","path":"internal/handler/device.go","line_range":"14-85","gmt_create":"2026-05-27T18:35:49.7775979+08:00","gmt_modified":"2026-05-27T18:35:49.7775979+08:00"},{"id":"bdfbf7d6f851540dee549606f7aca9d4","path":"internal/repository/brand.go","line_range":"19","gmt_create":"2026-05-27T18:35:49.7808022+08:00","gmt_modified":"2026-05-27T18:35:49.7808022+08:00"},{"id":"ba4653c42534e9835fb3db39fbfd5c06","path":"internal/repository/model.go","line_range":"19","gmt_create":"2026-05-27T18:35:49.7808022+08:00","gmt_modified":"2026-05-27T18:35:49.7808022+08:00"},{"id":"e5c6898e570c67346c0858cfeaa98fae","path":"internal/search/meilisearch.go","line_range":"17","gmt_create":"2026-05-27T18:35:49.7808022+08:00","gmt_modified":"2026-05-27T18:35:49.7808022+08:00"},{"id":"90b60f9dc283b0c2610ad113bc211315","path":"pkg/encode/base64.go","line_range":"8","gmt_create":"2026-05-27T18:35:49.7813263+08:00","gmt_modified":"2026-05-27T18:35:49.7813263+08:00"},{"id":"85820118c846a111e112dc705c071116","path":"internal/response/response.go","line_range":"9","gmt_create":"2026-05-27T18:35:49.7813263+08:00","gmt_modified":"2026-05-27T18:35:49.7813263+08:00"},{"id":"1041284bd46edf16a19f024c113d10b4","path":"internal/handler/brand.go","line_range":"30-34","gmt_create":"2026-05-27T18:35:49.7826173+08:00","gmt_modified":"2026-05-27T18:35:49.7826173+08:00"},{"id":"84be9fdffe58ef8cd5e77e0d3c37313b","path":"internal/handler/model.go","line_range":"31-35","gmt_create":"2026-05-27T18:35:49.7826173+08:00","gmt_modified":"2026-05-27T18:35:49.7826173+08:00"},{"id":"f034e5c72872862a675dd11e32404854","path":"internal/handler/model_list.go","line_range":"38-42","gmt_create":"2026-05-27T18:35:49.7831513+08:00","gmt_modified":"2026-05-27T18:35:49.7831513+08:00"},{"id":"df50e47a5b6541093011bb59b1ec831d","path":"internal/handler/device.go","line_range":"61-78","gmt_create":"2026-05-27T18:35:49.7831513+08:00","gmt_modified":"2026-05-27T18:35:49.7831513+08:00"},{"id":"0a425d8fed248deb7202bc7e8d531ca1","path":"internal/middleware/logger.go","line_range":"10-45","gmt_create":"2026-05-27T18:35:49.7836872+08:00","gmt_modified":"2026-05-27T18:35:49.7836872+08:00"},{"id":"d6d27b00ae4ab42348e74a7e7bf688b2","path":"internal/middleware/request_id.go","line_range":"20-31","gmt_create":"2026-05-27T18:35:49.7836872+08:00","gmt_modified":"2026-05-27T18:35:49.7836872+08:00"},{"id":"e9390185152783a55f55e277d45e6948","path":"cmd/server/main.go","line_range":"25-131","gmt_create":"2026-05-27T18:36:40.5088629+08:00","gmt_modified":"2026-05-27T18:36:40.5088629+08:00"},{"id":"a3cbc373dacd9d032ed0c72bca1e51e9","path":"internal/cache/brand_cache.go","line_range":"1-45","gmt_create":"2026-05-27T18:36:40.5088629+08:00","gmt_modified":"2026-05-27T18:36:40.5088629+08:00"},{"id":"d65e653afb8b211f2e5a7845f72b45dd","path":"internal/cache/model_cache.go","line_range":"1-70","gmt_create":"2026-05-27T18:36:40.5093857+08:00","gmt_modified":"2026-05-27T18:36:40.5093857+08:00"},{"id":"a26d903ac77196fac97ddebf48638ab3","path":"internal/repository/brand.go","line_range":"1-100","gmt_create":"2026-05-27T18:36:40.5093857+08:00","gmt_modified":"2026-05-27T18:36:40.5093857+08:00"},{"id":"7ffaf7b06ea96ca93862aa0dae926ff5","path":"internal/repository/model.go","line_range":"1-181","gmt_create":"2026-05-27T18:36:40.5093857+08:00","gmt_modified":"2026-05-27T18:36:40.5093857+08:00"},{"id":"187b4628003859e3da78f3937c686803","path":"internal/cache/brand_cache.go","line_range":"18-45","gmt_create":"2026-05-27T18:36:40.5109436+08:00","gmt_modified":"2026-05-27T18:36:40.5109436+08:00"},{"id":"a6c526ea58aabee86ae3010b00441c69","path":"internal/cache/model_cache.go","line_range":"19-70","gmt_create":"2026-05-27T18:36:40.5114567+08:00","gmt_modified":"2026-05-27T18:36:40.5114567+08:00"},{"id":"a364a8daa183eaf86417b4c1bd2cc719","path":"internal/repository/brand.go","line_range":"14-100","gmt_create":"2026-05-27T18:36:40.5114567+08:00","gmt_modified":"2026-05-27T18:36:40.5114567+08:00"},{"id":"2e040aabeb8e907eaddc6bbf2ee493ac","path":"internal/repository/model.go","line_range":"14-181","gmt_create":"2026-05-27T18:36:40.5114567+08:00","gmt_modified":"2026-05-27T18:36:40.5114567+08:00"},{"id":"3d315320639ece8212fd138420d94be5","path":"internal/handler/brand.go","line_range":"13-49","gmt_create":"2026-05-27T18:36:40.5120123+08:00","gmt_modified":"2026-05-27T18:36:40.5120123+08:00"},{"id":"fbf36e29345cd3e53fd3a6e8234ad2de","path":"internal/handler/model.go","line_range":"13-50","gmt_create":"2026-05-27T18:36:40.5120123+08:00","gmt_modified":"2026-05-27T18:36:40.5120123+08:00"},{"id":"32b7267a28b0347d59500c38ffa96a7b","path":"internal/cache/brand_cache.go","line_range":"13-45","gmt_create":"2026-05-27T18:36:40.5135974+08:00","gmt_modified":"2026-05-27T18:36:40.5135974+08:00"},{"id":"b9c3c517ffd917351757137ca1338574","path":"internal/cache/model_cache.go","line_range":"27-69","gmt_create":"2026-05-27T18:36:40.5141244+08:00","gmt_modified":"2026-05-27T18:36:40.5141244+08:00"},{"id":"df7d264896976fc8c5475257994c707e","path":"internal/cache/model_cache.go","line_range":"13-70","gmt_create":"2026-05-27T18:36:40.5141244+08:00","gmt_modified":"2026-05-27T18:36:40.5141244+08:00"},{"id":"a3b89d2e56d589f8d902fb9389004bf0","path":"cmd/server/main.go","line_range":"103-131","gmt_create":"2026-05-27T18:36:40.5141244+08:00","gmt_modified":"2026-05-27T18:36:40.5141244+08:00"},{"id":"f76ee32725201731512db1e0e7951586","path":"cmd/server/main.go","line_range":"67-68","gmt_create":"2026-05-27T18:36:40.5146452+08:00","gmt_modified":"2026-05-27T18:36:40.5146452+08:00"},{"id":"251d1b1dc197a1dc242f5384adb1555c","path":"internal/repository/brand.go","line_range":"34-52","gmt_create":"2026-05-27T18:36:40.5146452+08:00","gmt_modified":"2026-05-27T18:36:40.5146452+08:00"},{"id":"a51abc6a6d80413bf60f143cd1f46ee4","path":"internal/repository/model.go","line_range":"27-79","gmt_create":"2026-05-27T18:36:40.5146452+08:00","gmt_modified":"2026-05-27T18:36:40.5146452+08:00"},{"id":"f0b044854c85d50b2d1ba4b9d3e6a6cb","path":"internal/cache/model_cache.go","line_range":"13-17","gmt_create":"2026-05-27T18:36:40.5151635+08:00","gmt_modified":"2026-05-27T18:36:40.5151635+08:00"},{"id":"3f0d637bef43d636594a4816c9da037e","path":"internal/cache/brand_cache.go","line_range":"38-44","gmt_create":"2026-05-27T18:36:40.5151635+08:00","gmt_modified":"2026-05-27T18:36:40.5151635+08:00"},{"id":"3f945faea776f513b5294aa60759fb15","path":"internal/cache/model_cache.go","line_range":"43-69","gmt_create":"2026-05-27T18:36:40.5156806+08:00","gmt_modified":"2026-05-27T18:36:40.5156806+08:00"},{"id":"a272829cfc9c48e8063d8bca53cdebc8","path":"cmd/server/main.go","line_range":"13-23","gmt_create":"2026-05-27T18:36:40.5156806+08:00","gmt_modified":"2026-05-27T18:36:40.5156806+08:00"},{"id":"6d2fece0c97147748fd0269a356e4802","path":"internal/repository/brand.go","line_range":"3-12","gmt_create":"2026-05-27T18:36:40.5156806+08:00","gmt_modified":"2026-05-27T18:36:40.5156806+08:00"},{"id":"282a046f62f9715bfef882f5a4a6a362","path":"internal/router/router.go","line_range":"3-14","gmt_create":"2026-05-27T18:36:40.516202+08:00","gmt_modified":"2026-05-27T18:36:40.516202+08:00"},{"id":"436a5d37fbeaadb1394559a23e5633e3","path":"cmd/server/main.go","line_range":"27-76","gmt_create":"2026-05-28T18:57:12.1548181+08:00","gmt_modified":"2026-05-28T18:57:12.1548181+08:00"},{"id":"6eea881f59ef13b1dd4c56cfec810c13","path":"internal/handler/device.go","line_range":"15-25","gmt_create":"2026-05-28T18:57:12.1554446+08:00","gmt_modified":"2026-05-28T18:57:12.1554446+08:00"},{"id":"ccf4922f5428b8f0159ce891bcc0cfb1","path":"internal/task/device_persist.go","line_range":"14-22","gmt_create":"2026-05-28T18:57:12.1561595+08:00","gmt_modified":"2026-05-28T18:57:12.1561595+08:00"},{"id":"b485eea69fa28d3e2b66f0d91fa8e9fc","path":"cmd/server/main.go","line_range":"1-156","gmt_create":"2026-05-28T18:57:12.1569153+08:00","gmt_modified":"2026-05-28T18:57:12.1569153+08:00"},{"id":"b27f65a687bda17d5ed88a31726192a9","path":"internal/router/router.go","line_range":"1-42","gmt_create":"2026-05-28T18:57:12.158417+08:00","gmt_modified":"2026-05-28T18:57:12.158417+08:00"},{"id":"47b04c12479e04825b7f54c8912d5322","path":"internal/handler/device.go","line_range":"27-83","gmt_create":"2026-05-28T18:57:12.1592297+08:00","gmt_modified":"2026-05-28T18:57:12.1592297+08:00"},{"id":"05c701828e7a6751805539a7bdd0fb1b","path":"internal/router/router.go","line_range":"32-38","gmt_create":"2026-05-28T18:57:12.1599052+08:00","gmt_modified":"2026-05-28T18:57:12.1599052+08:00"},{"id":"46f122a322e257db9d295df514f3a0eb","path":"internal/task/device_persist.go","line_range":"37-91","gmt_create":"2026-05-28T18:57:12.162084+08:00","gmt_modified":"2026-05-28T18:57:12.162084+08:00"},{"id":"5a0a9163cad4fb940b31bf2bc7ed7c9a","path":"internal/handler/device.go","line_range":"50-77","gmt_create":"2026-05-28T18:57:12.1677918+08:00","gmt_modified":"2026-05-28T18:57:12.1677918+08:00"},{"id":"49f1730acf3c48a4b99824ea4c37c488","path":"internal/middleware/cors.go","line_range":"7-20","gmt_create":"2026-05-28T18:57:12.1691064+08:00","gmt_modified":"2026-05-28T18:57:12.1691064+08:00"},{"id":"8aa692daaaaec7b3cb63b9f7e45285ff","path":"internal/task/device_persist.go","line_range":"24-35","gmt_create":"2026-05-28T18:57:12.1699245+08:00","gmt_modified":"2026-05-28T18:57:12.1699245+08:00"},{"id":"6c0f43ccd27e99dc7451fce4025b4922","path":"sql/user_device.sql","line_range":"24-32","gmt_create":"2026-05-28T18:57:12.1726804+08:00","gmt_modified":"2026-05-28T18:57:12.1726804+08:00"},{"id":"55bdc917e2b5c06a063571e8ba54919d","path":"sql/user_active.sql","line_range":"24-33","gmt_create":"2026-05-28T18:57:12.1740937+08:00","gmt_modified":"2026-05-28T18:57:12.1740937+08:00"},{"id":"ac513b415a9c6c676fc89d9ee804e0e5","path":"internal/task/device_persist.go","line_range":"93-131","gmt_create":"2026-05-28T18:57:12.1747895+08:00","gmt_modified":"2026-05-28T18:57:12.1747895+08:00"},{"id":"09816af084e58fcafb8acecc2aeb7fdf","path":"internal/task/device_persist.go","line_range":"133-166","gmt_create":"2026-05-28T18:57:12.1755492+08:00","gmt_modified":"2026-05-28T18:57:12.1755492+08:00"},{"id":"04de5aef1ac4054770a1dc2f321e84e0","path":"internal/task/device_persist.go","line_range":"70-73","gmt_create":"2026-05-28T18:57:12.1762988+08:00","gmt_modified":"2026-05-28T18:57:12.1762988+08:00"},{"id":"1e39af3b295124dd3e0b741f3673d73a","path":"internal/task/device_persist.go","line_range":"101-128","gmt_create":"2026-05-28T18:57:12.1770398+08:00","gmt_modified":"2026-05-28T18:57:12.1770398+08:00"},{"id":"4785fe804268b84800489006489ab351","path":"internal/task/device_persist.go","line_range":"141-163","gmt_create":"2026-05-28T18:57:12.1803883+08:00","gmt_modified":"2026-05-28T18:57:12.1803883+08:00"},{"id":"7e27200f273d8472b343ca0147ef4395","path":"internal/handler/device.go","line_range":"3-13","gmt_create":"2026-05-28T18:57:12.1811284+08:00","gmt_modified":"2026-05-28T18:57:12.1811284+08:00"},{"id":"c4031c64b5fd75673a62928438dd0c86","path":"internal/task/device_persist.go","line_range":"3-12","gmt_create":"2026-05-28T18:57:12.182561+08:00","gmt_modified":"2026-05-28T18:57:12.182561+08:00"},{"id":"0017aeb9dcc60a0e37392e83bbc51a05","path":"internal/router/router.go","line_range":"6-12","gmt_create":"2026-05-28T18:57:12.1841436+08:00","gmt_modified":"2026-05-28T18:57:12.1841436+08:00"},{"id":"4479003cf02c0690374f9f1bcaaf1505","path":"internal/config/config.go","line_range":"1-64","gmt_create":"2026-05-28T18:57:12.1855298+08:00","gmt_modified":"2026-05-28T18:57:12.1855298+08:00"},{"id":"447b10c5efa18658d41d37a56693098e","path":"internal/handler/device.go","line_range":"33-39","gmt_create":"2026-05-28T18:57:12.1862391+08:00","gmt_modified":"2026-05-28T18:57:12.1862391+08:00"},{"id":"f35be7f328a7ad7a64ca3a75a47a46fe","path":"internal/handler/device.go","line_range":"69-76","gmt_create":"2026-05-28T18:57:12.1868975+08:00","gmt_modified":"2026-05-28T18:57:12.1868975+08:00"},{"id":"a7ae5a8957a835d81092a8e9c582706d","path":"internal/task/device_persist.go","line_range":"43-46","gmt_create":"2026-05-28T18:57:12.1875143+08:00","gmt_modified":"2026-05-28T18:57:12.1875143+08:00"},{"id":"9bbbd9d83a113fbbda2d1a69b1438661","path":"cmd/server/main.go","line_range":"27-108","gmt_create":"2026-05-28T18:57:39.8353312+08:00","gmt_modified":"2026-05-28T18:57:39.8353312+08:00"},{"id":"7276e457b543f75825c9e741472e998d","path":"internal/router/router.go","line_range":"16-56","gmt_create":"2026-05-28T18:57:39.8358632+08:00","gmt_modified":"2026-05-28T18:57:39.8358632+08:00"},{"id":"8785d501dfce0bd258e4df37afd89055","path":"internal/handler/ota.go","line_range":"19","gmt_create":"2026-05-28T18:57:39.8380774+08:00","gmt_modified":"2026-05-28T18:57:39.8380774+08:00"},{"id":"0d14524abb861634cb9cb31154728013","path":"internal/handler/ota.go","line_range":"14-21","gmt_create":"2026-05-28T18:57:39.8416901+08:00","gmt_modified":"2026-05-28T18:57:39.8416901+08:00"},{"id":"1a416066a4f46116deac1ca86b956c76","path":"internal/router/router.go","line_range":"45-52","gmt_create":"2026-05-28T18:57:39.8416901+08:00","gmt_modified":"2026-05-28T18:57:39.8416901+08:00"},{"id":"4db7bd1f13a681def5b5588fd2e94047","path":"internal/handler/ota.go","line_range":"57-131","gmt_create":"2026-05-28T18:57:39.8427232+08:00","gmt_modified":"2026-05-28T18:57:39.8427232+08:00"},{"id":"20129ee27519ce09da97cb149d224c3f","path":"internal/repository/ota.go","line_range":"20-158","gmt_create":"2026-05-28T18:57:39.8427232+08:00","gmt_modified":"2026-05-28T18:57:39.8427232+08:00"},{"id":"019fb6aa1e6ae1b643cd4ab92d2888ad","path":"internal/router/router.go","line_range":"42","gmt_create":"2026-05-28T18:57:39.8482242+08:00","gmt_modified":"2026-05-28T18:57:39.8482242+08:00"},{"id":"9ca535f7325768d0789ea05267c44143","path":"internal/handler/ota.go","line_range":"25-132","gmt_create":"2026-05-28T18:57:39.8586565+08:00","gmt_modified":"2026-05-28T18:57:39.8586565+08:00"},{"id":"83234161f284b4fd592045de95771e46","path":"internal/handler/ota.go","line_range":"14-132","gmt_create":"2026-05-28T18:57:39.8586565+08:00","gmt_modified":"2026-05-28T18:57:39.8586565+08:00"},{"id":"1e57d4023212b9b9ffb93fc0adf1a2dc","path":"internal/model/ota.go","line_range":"6-42","gmt_create":"2026-05-28T18:57:39.8586565+08:00","gmt_modified":"2026-05-28T18:57:39.8586565+08:00"},{"id":"ea28bb5431ebda8361d2e0c3df935805","path":"cmd/server/main.go","line_range":"77","gmt_create":"2026-05-28T18:57:39.8586565+08:00","gmt_modified":"2026-05-28T18:57:39.8586565+08:00"},{"id":"5f44f3a2c10a86e7a9c3e7b2836e352d","path":"internal/repository/ota.go","line_range":"11-17","gmt_create":"2026-05-28T18:57:39.8586565+08:00","gmt_modified":"2026-05-28T18:57:39.8586565+08:00"},{"id":"2e2366309b15db45b8d14e3e11f2ac87","path":"internal/repository/ota.go","line_range":"15","gmt_create":"2026-05-28T18:57:39.8613227+08:00","gmt_modified":"2026-05-28T18:57:39.8613227+08:00"},{"id":"d5d67e2167eea6a56d03ce17f78d7c15","path":"internal/handler/ota.go","line_range":"58-94","gmt_create":"2026-05-28T18:57:39.8613227+08:00","gmt_modified":"2026-05-28T18:57:39.8613227+08:00"},{"id":"eefeaf126e13951935424f7f3c210854","path":"internal/repository/brand.go","line_range":"44-51","gmt_create":"2026-05-28T18:58:12.5297678+08:00","gmt_modified":"2026-05-28T18:58:12.5297678+08:00"},{"id":"96c652126052e611e9602571014fb2fe","path":"internal/repository/model.go","line_range":"44-74","gmt_create":"2026-05-28T18:58:12.5297678+08:00","gmt_modified":"2026-05-28T18:58:12.5297678+08:00"},{"id":"b799030cefcf1745645d8e74f4bd2042","path":"internal/repository/device.go","line_range":"11-17","gmt_create":"2026-05-28T18:58:34.7875205+08:00","gmt_modified":"2026-05-28T18:58:34.7875205+08:00"},{"id":"90cda5d453d8a36d34f0bb16bf3b22d4","path":"sql/user_device.sql","line_range":"23-32","gmt_create":"2026-05-28T18:58:34.7958397+08:00","gmt_modified":"2026-05-28T18:58:34.7958397+08:00"},{"id":"169d98ec7c47a41d541c28ef27876ab1","path":"sql/user_active.sql","line_range":"23-32","gmt_create":"2026-05-28T18:58:34.7958397+08:00","gmt_modified":"2026-05-28T18:58:34.7958397+08:00"},{"id":"3e86caf95903a24c6393bc96880f7951","path":"sql/ota.sql","line_range":"23-44","gmt_create":"2026-05-28T18:58:34.7978084+08:00","gmt_modified":"2026-05-28T18:58:34.7978084+08:00"},{"id":"59f1d79949230d387b6ad48a329cc0f7","path":"sql/ota_target_device.sql","line_range":"23-31","gmt_create":"2026-05-28T18:58:34.7978084+08:00","gmt_modified":"2026-05-28T18:58:34.7978084+08:00"},{"id":"c73149ce118775bda8abbe6ef4cfd663","path":"internal/router/router.go","line_range":"14-56","gmt_create":"2026-05-28T18:58:34.7978084+08:00","gmt_modified":"2026-05-28T18:58:34.7978084+08:00"},{"id":"ebe1ad8e2e447d1c8784d0338fb5ff44","path":"internal/repository/device.go","line_range":"11-88","gmt_create":"2026-05-28T18:58:34.8081733+08:00","gmt_modified":"2026-05-28T18:58:34.8081733+08:00"},{"id":"8fff9ab89b194aaf50c08418f14e7d5d","path":"internal/repository/ota.go","line_range":"11-159","gmt_create":"2026-05-28T18:58:34.8081733+08:00","gmt_modified":"2026-05-28T18:58:34.8081733+08:00"},{"id":"3cab00ffcb36143e0a8fa39bc345dc5b","path":"internal/task/device_persist.go","line_range":"14-167","gmt_create":"2026-05-28T18:58:34.810182+08:00","gmt_modified":"2026-05-28T18:58:34.810182+08:00"},{"id":"a60b5eaffad0d59addb5be3ce07dcfe8","path":"internal/handler/device.go","line_range":"27-82","gmt_create":"2026-05-28T18:58:34.8121909+08:00","gmt_modified":"2026-05-28T18:58:34.8121909+08:00"},{"id":"7dda8c14930e069827e3ba2382731089","path":"internal/handler/ota.go","line_range":"23-132","gmt_create":"2026-05-28T18:58:34.8121909+08:00","gmt_modified":"2026-05-28T18:58:34.8121909+08:00"},{"id":"8ef952b9859313cbfc946824f3307d9d","path":"internal/repository/device.go","line_range":"19-87","gmt_create":"2026-05-28T18:58:34.8121909+08:00","gmt_modified":"2026-05-28T18:58:34.8121909+08:00"},{"id":"51316f98b99990e17b496035eb09f026","path":"internal/repository/ota.go","line_range":"19-158","gmt_create":"2026-05-28T18:58:34.8141995+08:00","gmt_modified":"2026-05-28T18:58:34.8141995+08:00"},{"id":"3086af04dfecbda4da76dc885b16803c","path":"internal/model/user_device.go","line_range":"5-11","gmt_create":"2026-05-28T18:58:34.8187553+08:00","gmt_modified":"2026-05-28T18:58:34.8187553+08:00"},{"id":"37797d6a2ea3a02b54e63ae9da6d2538","path":"internal/model/user_active.go","line_range":"5-12","gmt_create":"2026-05-28T18:58:34.8187553+08:00","gmt_modified":"2026-05-28T18:58:34.8187553+08:00"},{"id":"cd00b1806e2c98e0bb5dffa98190dcc9","path":"internal/task/device_persist.go","line_range":"24-91","gmt_create":"2026-05-28T18:58:34.8187553+08:00","gmt_modified":"2026-05-28T18:58:34.8187553+08:00"},{"id":"e1ebf7d9c7e51f6e897d985f8ee6c72d","path":"cmd/server/main.go","line_range":"1-96","gmt_create":"2026-05-28T19:00:07.113259+08:00","gmt_modified":"2026-05-28T19:00:07.113259+08:00"},{"id":"69055b7e39d8b5d596ead1dc41f98c6e","path":"internal/config/database.go","line_range":"1-72","gmt_create":"2026-05-28T19:00:07.113259+08:00","gmt_modified":"2026-05-28T19:00:07.113259+08:00"},{"id":"c377b29231ed9b2f9403faac5b050cb8","path":"internal/config/meilisearch.go","line_range":"1-51","gmt_create":"2026-05-28T19:00:07.1152686+08:00","gmt_modified":"2026-05-28T19:00:07.1152686+08:00"},{"id":"29a90b3c32979664ded642e5896eb3d5","path":"internal/config/redis.go","line_range":"1-57","gmt_create":"2026-05-28T19:00:07.1152686+08:00","gmt_modified":"2026-05-28T19:00:07.1152686+08:00"},{"id":"2bc32e7e8a7fa666b1c1222c91819271","path":"internal/database/mysql.go","line_range":"1-47","gmt_create":"2026-05-28T19:00:07.1152686+08:00","gmt_modified":"2026-05-28T19:00:07.1152686+08:00"},{"id":"52819729078f1597788b1933d6801b93","path":"internal/cache/redis.go","line_range":"1-17","gmt_create":"2026-05-28T19:00:07.1152686+08:00","gmt_modified":"2026-05-28T19:00:07.1152686+08:00"},{"id":"3ff5e86040da68833bd5c5647fe9a6cd","path":"internal/search/meilisearch.go","line_range":"1-46","gmt_create":"2026-05-28T19:00:07.1152686+08:00","gmt_modified":"2026-05-28T19:00:07.1152686+08:00"},{"id":"01e3125f22f4408593f798e93b6afa99","path":"internal/handler/brand.go","line_range":"1-50","gmt_create":"2026-05-28T19:00:07.1172789+08:00","gmt_modified":"2026-05-28T19:00:07.1172789+08:00"},{"id":"90c875f5593a84b9f61436b4333ef578","path":"internal/handler/model.go","line_range":"1-51","gmt_create":"2026-05-28T19:00:07.1172789+08:00","gmt_modified":"2026-05-28T19:00:07.1172789+08:00"},{"id":"d5e4d174e9dd68b5069c37d7733a5167","path":"internal/handler/device.go","line_range":"1-83","gmt_create":"2026-05-28T19:00:07.1172789+08:00","gmt_modified":"2026-05-28T19:00:07.1172789+08:00"},{"id":"c4a01c8fb0a60cc8518b952d5d6f388e","path":"internal/handler/ota.go","line_range":"1-133","gmt_create":"2026-05-28T19:00:07.1172789+08:00","gmt_modified":"2026-05-28T19:00:07.1172789+08:00"},{"id":"021df456dabca2ae78c2106e52f86eba","path":"internal/repository/brand.go","line_range":"1-51","gmt_create":"2026-05-28T19:00:07.1192872+08:00","gmt_modified":"2026-05-28T19:00:07.1192872+08:00"},{"id":"28606623cd3bd5204b730a9c10136e0c","path":"internal/repository/model.go","line_range":"1-95","gmt_create":"2026-05-28T19:00:07.1192872+08:00","gmt_modified":"2026-05-28T19:00:07.1192872+08:00"},{"id":"d6366e178901bd9fc56d24ac3f2dc536","path":"internal/repository/device.go","line_range":"1-88","gmt_create":"2026-05-28T19:00:07.1192872+08:00","gmt_modified":"2026-05-28T19:00:07.1192872+08:00"},{"id":"32ab616a01ce2ab4964a112c6f6c9289","path":"internal/repository/ota.go","line_range":"1-159","gmt_create":"2026-05-28T19:00:07.1192872+08:00","gmt_modified":"2026-05-28T19:00:07.1192872+08:00"},{"id":"ef189d2cfcacc36b1ab99c2bdf638ee5","path":"internal/model/brand.go","line_range":"1-7","gmt_create":"2026-05-28T19:00:07.1212964+08:00","gmt_modified":"2026-05-28T19:00:07.1212964+08:00"},{"id":"23a3c0da18126f224be977fec0de5a8a","path":"internal/model/model.go","line_range":"1-15","gmt_create":"2026-05-28T19:00:07.1212964+08:00","gmt_modified":"2026-05-28T19:00:07.1212964+08:00"},{"id":"4713f841d280d4ac330d47e32c6743e0","path":"internal/model/user_device.go","line_range":"1-12","gmt_create":"2026-05-28T19:00:07.1220682+08:00","gmt_modified":"2026-05-28T19:00:07.1220682+08:00"},{"id":"cb0b6a35cfc889254c2aa49bedb440a9","path":"internal/model/user_active.go","line_range":"1-13","gmt_create":"2026-05-28T19:00:07.1224144+08:00","gmt_modified":"2026-05-28T19:00:07.1224144+08:00"},{"id":"da73920ba8bbbc909db36618a7310458","path":"internal/model/ota.go","line_range":"1-43","gmt_create":"2026-05-28T19:00:07.1229239+08:00","gmt_modified":"2026-05-28T19:00:07.1229239+08:00"},{"id":"4ffb5c0e60dd5865fd0dbd17cefc0f01","path":"internal/task/device_persist.go","line_range":"1-167","gmt_create":"2026-05-28T19:00:07.1234534+08:00","gmt_modified":"2026-05-28T19:00:07.1234534+08:00"},{"id":"d367077ab4548a916c111572cada1c71","path":"sql/model.sql","line_range":"20-38","gmt_create":"2026-05-28T19:00:07.1257743+08:00","gmt_modified":"2026-05-28T19:00:07.1257743+08:00"},{"id":"189257df07b32be947dabfa695f66fdd","path":"sql/user_device.sql","line_range":"20-35","gmt_create":"2026-05-28T19:00:07.1263096+08:00","gmt_modified":"2026-05-28T19:00:07.1263096+08:00"},{"id":"a47ac166b0702b174fb7ed6f2297137d","path":"sql/user_active.sql","line_range":"20-208","gmt_create":"2026-05-28T19:00:07.1263096+08:00","gmt_modified":"2026-05-28T19:00:07.1263096+08:00"},{"id":"897c377e81e0702f2d0e4f13dfceb693","path":"sql/ota.sql","line_range":"20-47","gmt_create":"2026-05-28T19:00:07.1268483+08:00","gmt_modified":"2026-05-28T19:00:07.1268483+08:00"},{"id":"efaa25ae5bf7399c81644b39a89a1fed","path":"sql/black_list.sql","line_range":"20-33","gmt_create":"2026-05-28T19:00:07.1268483+08:00","gmt_modified":"2026-05-28T19:00:07.1268483+08:00"},{"id":"b64c46283e5e53a0d132ca029b9b86d3","path":"sql/ota_target_device.sql","line_range":"20-34","gmt_create":"2026-05-28T19:00:07.1274229+08:00","gmt_modified":"2026-05-28T19:00:07.1274229+08:00"},{"id":"819f2b92f6d3118bb4914a7b9510805d","path":"internal/handler/brand.go","line_range":"26-49","gmt_create":"2026-05-28T19:00:07.1332909+08:00","gmt_modified":"2026-05-28T19:00:07.1332909+08:00"},{"id":"ace2343343d8f2d41c786a71fea9fd11","path":"internal/handler/model.go","line_range":"26-50","gmt_create":"2026-05-28T19:00:07.1332909+08:00","gmt_modified":"2026-05-28T19:00:07.1332909+08:00"},{"id":"5eaf58cb10abd95debc641aecfcd4505","path":"internal/repository/brand.go","line_range":"20-50","gmt_create":"2026-05-28T19:00:07.134345+08:00","gmt_modified":"2026-05-28T19:00:07.134345+08:00"},{"id":"e218f68a16be9c08d06be61a712f8c65","path":"internal/repository/model.go","line_range":"20-61","gmt_create":"2026-05-28T19:00:07.134345+08:00","gmt_modified":"2026-05-28T19:00:07.134345+08:00"},{"id":"658a6f642eff1517af95aca1e7beebc1","path":"internal/model/ota.go","line_range":"6-25","gmt_create":"2026-05-28T19:00:07.1370186+08:00","gmt_modified":"2026-05-28T19:00:07.1370186+08:00"},{"id":"a3818b4d67a7d92f60e660730d921ec6","path":"internal/model/ota.go","line_range":"28-42","gmt_create":"2026-05-28T19:00:07.1370186+08:00","gmt_modified":"2026-05-28T19:00:07.1370186+08:00"},{"id":"49415256ad706e7e14218f5042331053","path":"sql/user_active.sql","line_range":"24-32","gmt_create":"2026-05-28T19:00:07.137594+08:00","gmt_modified":"2026-05-28T19:00:07.137594+08:00"},{"id":"062377182bb42d6f58aa521f520b8c98","path":"sql/ota.sql","line_range":"24-44","gmt_create":"2026-05-28T19:00:07.138122+08:00","gmt_modified":"2026-05-28T19:00:07.138122+08:00"},{"id":"fac408f6f57051f68ce0b47131e53046","path":"sql/black_list.sql","line_range":"24-30","gmt_create":"2026-05-28T19:00:07.138122+08:00","gmt_modified":"2026-05-28T19:00:07.138122+08:00"},{"id":"88e6e16d8b92be5bc0b42fd6336337cc","path":"sql/ota_target_device.sql","line_range":"24-31","gmt_create":"2026-05-28T19:00:07.138122+08:00","gmt_modified":"2026-05-28T19:00:07.138122+08:00"},{"id":"741e7392ea4f07ed0a9dce54ecfb8c9a","path":"internal/database/mysql.go","line_range":"14-47","gmt_create":"2026-05-28T19:00:07.1469361+08:00","gmt_modified":"2026-05-28T19:00:07.1469361+08:00"},{"id":"3fd4ae470b961a44d194f1190b8b846b","path":"internal/config/database.go","line_range":"42-55","gmt_create":"2026-05-28T19:00:07.1474642+08:00","gmt_modified":"2026-05-28T19:00:07.1474642+08:00"},{"id":"5b834ee16ae7f75ed77618c74567730f","path":"internal/config/meilisearch.go","line_range":"14-37","gmt_create":"2026-05-28T19:00:07.1474642+08:00","gmt_modified":"2026-05-28T19:00:07.1474642+08:00"},{"id":"c3ac950bf39b216bad9886dc9f5b55d2","path":"internal/config/redis.go","line_range":"39-49","gmt_create":"2026-05-28T19:00:07.1479902+08:00","gmt_modified":"2026-05-28T19:00:07.1479902+08:00"},{"id":"c0d0fd3a31ad005fada5134f30fddfd8","path":"internal/task/device_persist.go","line_range":"24-167","gmt_create":"2026-05-28T19:00:07.1485151+08:00","gmt_modified":"2026-05-28T19:00:07.1485151+08:00"},{"id":"41e1053e37b8d366a4788eb4e50c3316","path":"internal/database/mysql.go","line_range":"33-36","gmt_create":"2026-05-28T19:00:07.1533658+08:00","gmt_modified":"2026-05-28T19:00:07.1533658+08:00"},{"id":"53cc4b9b52692b204c90364113429f04","path":"internal/repository/brand.go","line_range":"24-27","gmt_create":"2026-05-28T19:00:07.1533658+08:00","gmt_modified":"2026-05-28T19:00:07.1533658+08:00"},{"id":"6db6f65d20e506da19a61778ed708068","path":"internal/repository/model.go","line_range":"31-40","gmt_create":"2026-05-28T19:00:07.1533658+08:00","gmt_modified":"2026-05-28T19:00:07.1533658+08:00"},{"id":"6425001a8d84168af2d38efa689eee25","path":"internal/search/meilisearch.go","line_range":"22-26","gmt_create":"2026-05-28T19:00:07.1533658+08:00","gmt_modified":"2026-05-28T19:00:07.1533658+08:00"},{"id":"8d8c4ed8e4263a8b7679488df7ff3272","path":"sql/user_active.sql","line_range":"33-204","gmt_create":"2026-05-28T19:00:07.1533658+08:00","gmt_modified":"2026-05-28T19:00:07.1533658+08:00"},{"id":"3c8c105b618476c1dff60821fe977ba2","path":"internal/config/database.go","line_range":"57-71","gmt_create":"2026-05-28T19:00:07.1533658+08:00","gmt_modified":"2026-05-28T19:00:07.1533658+08:00"},{"id":"7824c130bd204768245b2ef1e2326e5d","path":"internal/database/mysql.go","line_range":"40-43","gmt_create":"2026-05-28T19:00:07.1556723+08:00","gmt_modified":"2026-05-28T19:00:07.1556723+08:00"},{"id":"93d77b956265768d24c0f3e807cae3f6","path":"internal/repository/brand.go","line_range":"32-47","gmt_create":"2026-05-28T19:00:07.1556723+08:00","gmt_modified":"2026-05-28T19:00:07.1556723+08:00"},{"id":"8a027ed1f8af1f5bfec4eb28de4c8d5b","path":"internal/repository/model.go","line_range":"43-58","gmt_create":"2026-05-28T19:00:07.1556723+08:00","gmt_modified":"2026-05-28T19:00:07.1556723+08:00"},{"id":"b6b8e91265e76c9b7982364854d6d521","path":"internal/handler/brand.go","line_range":"31-43","gmt_create":"2026-05-28T19:00:07.1556723+08:00","gmt_modified":"2026-05-28T19:00:07.1556723+08:00"},{"id":"9cdccaf24e4bb2ebeda989e652cbb590","path":"internal/handler/model.go","line_range":"33-43","gmt_create":"2026-05-28T19:00:07.1556723+08:00","gmt_modified":"2026-05-28T19:00:07.1556723+08:00"},{"id":"93b1b8f6a4dee4e1ddf80984e2ad4f07","path":"internal/handler/device.go","line_range":"45-82","gmt_create":"2026-05-28T19:00:07.1556723+08:00","gmt_modified":"2026-05-28T19:00:07.1556723+08:00"},{"id":"1757787c6693e053fe8996b15c11536e","path":"internal/handler/ota.go","line_range":"56-132","gmt_create":"2026-05-28T19:00:07.1556723+08:00","gmt_modified":"2026-05-28T19:00:07.1556723+08:00"},{"id":"62a2f3176fec72cd937d12bdd85b8023","path":"internal/search/meilisearch.go","line_range":"17-20","gmt_create":"2026-05-28T19:00:07.1556723+08:00","gmt_modified":"2026-05-28T19:00:07.1556723+08:00"},{"id":"0b9d497db6c6913d0f143b9c1a6e1bad","path":"internal/model/brand.go","line_range":"4-5","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":"be4c653a27c4d4270505763c428135f7","path":"internal/model/model.go","line_range":"6-13","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":"5178a0682867f422c7fd0847372d79c0","path":"internal/config/database.go","line_range":"67-69","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":"7622937a1ed63808bc23509e6bf502d7","path":"internal/config/meilisearch.go","line_range":"39-50","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":"c36202d0e142efb3373377cd5fc6d146","path":"internal/config/redis.go","line_range":"51-56","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":"3327fdfd4099f053f8dd4cc2a04ad710","path":"internal/handler/device.go","line_range":"33-48","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":"e3adf341667ef4784dcd76b3b8240f33","path":"internal/handler/ota.go","line_range":"32-48","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":"7b484a5ae829eeda00870c3f1e212152","path":"cmd/server/main.go","line_range":"22-64","gmt_create":"2026-05-28T19:00:48.645212+08:00","gmt_modified":"2026-05-28T19:00:48.645212+08:00"},{"id":"d81273f13e44b61321fec0ce3006f5c1","path":"internal/handler/brand.go","line_range":"19-50","gmt_create":"2026-05-28T19:00:48.6457361+08:00","gmt_modified":"2026-05-28T19:00:48.6457361+08:00"},{"id":"482a26438e7a2ce9d7cfbf86ace40f32","path":"internal/handler/model.go","line_range":"19-51","gmt_create":"2026-05-28T19:00:48.6457361+08:00","gmt_modified":"2026-05-28T19:00:48.6457361+08:00"},{"id":"3d711f613bfd2e37cae891628729b534","path":"internal/handler/model_list.go","line_range":"19-57","gmt_create":"2026-05-28T19:00:48.6464056+08:00","gmt_modified":"2026-05-28T19:00:48.6464056+08:00"},{"id":"aa25d38d1ff2b629566d1fae5ca04f7f","path":"internal/handler/ota.go","line_range":"14-133","gmt_create":"2026-05-28T19:00:48.6464056+08:00","gmt_modified":"2026-05-28T19:00:48.6464056+08:00"},{"id":"0bbf6adb379e3658025de484d5b76c97","path":"internal/handler/device.go","line_range":"15-83","gmt_create":"2026-05-28T19:00:48.6464056+08:00","gmt_modified":"2026-05-28T19:00:48.6464056+08:00"},{"id":"3b1b16fc1f259913d34a3025a9856837","path":"internal/repository/brand.go","line_range":"16-51","gmt_create":"2026-05-28T19:00:48.6469286+08:00","gmt_modified":"2026-05-28T19:00:48.6469286+08:00"},{"id":"93265e1e6c0c0c869df702008b681e01","path":"internal/repository/model.go","line_range":"16-95","gmt_create":"2026-05-28T19:00:48.6469286+08:00","gmt_modified":"2026-05-28T19:00:48.6469286+08:00"},{"id":"068719fc1a0d9314d8021756c98217da","path":"internal/model/ota.go","line_range":"5-43","gmt_create":"2026-05-28T19:00:48.6480292+08:00","gmt_modified":"2026-05-28T19:00:48.6480292+08:00"},{"id":"bb96f52067e8e086b30d9c30821c5584","path":"internal/model/user_device.go","line_range":"5-12","gmt_create":"2026-05-28T19:00:48.6480292+08:00","gmt_modified":"2026-05-28T19:00:48.6480292+08:00"},{"id":"d4e3d54fc92d9bf0a306c8222cabb8a8","path":"internal/model/user_active.go","line_range":"5-13","gmt_create":"2026-05-28T19:00:48.6480292+08:00","gmt_modified":"2026-05-28T19:00:48.6480292+08:00"},{"id":"c264094331c357056119bca99357640d","path":"internal/response/response.go","line_range":"9-37","gmt_create":"2026-05-28T19:00:48.6485848+08:00","gmt_modified":"2026-05-28T19:00:48.6485848+08:00"},{"id":"74cc6302b70bcea6621f5bfb0763076b","path":"pkg/encode/base64.go","line_range":"21-52","gmt_create":"2026-05-28T19:00:48.6485848+08:00","gmt_modified":"2026-05-28T19:00:48.6485848+08:00"},{"id":"26fa07962aa58dc300b27f1cc7f3f984","path":"internal/repository/brand.go","line_range":"20-51","gmt_create":"2026-05-28T19:00:48.6512441+08:00","gmt_modified":"2026-05-28T19:00:48.6512441+08:00"},{"id":"07061497ffd00747ff422a65693ddfc5","path":"internal/repository/model.go","line_range":"20-95","gmt_create":"2026-05-28T19:00:48.6517963+08:00","gmt_modified":"2026-05-28T19:00:48.6517963+08:00"},{"id":"88f3a0de90be87baf1799c9d1d77d814","path":"internal/repository/ota.go","line_range":"19-159","gmt_create":"2026-05-28T19:00:48.6517963+08:00","gmt_modified":"2026-05-28T19:00:48.6517963+08:00"},{"id":"a70c6a1aa995213e0b9785c73215f03d","path":"internal/repository/device.go","line_range":"19-88","gmt_create":"2026-05-28T19:00:48.6517963+08:00","gmt_modified":"2026-05-28T19:00:48.6517963+08:00"},{"id":"ac531f924fff62d1ae6d87fb20ee8b5b","path":"internal/handler/brand.go","line_range":"26-50","gmt_create":"2026-05-28T19:00:48.6523341+08:00","gmt_modified":"2026-05-28T19:00:48.6523341+08:00"},{"id":"4baa32d2509ec9cea1ff6d469146dc73","path":"internal/handler/model.go","line_range":"26-51","gmt_create":"2026-05-28T19:00:48.6523341+08:00","gmt_modified":"2026-05-28T19:00:48.6523341+08:00"},{"id":"2680759f452df990edc59ce5ce169032","path":"internal/handler/model_list.go","line_range":"26-57","gmt_create":"2026-05-28T19:00:48.6523341+08:00","gmt_modified":"2026-05-28T19:00:48.6523341+08:00"},{"id":"02c681361cdf45307d027e067cf32b85","path":"internal/handler/ota.go","line_range":"23-133","gmt_create":"2026-05-28T19:00:48.6528889+08:00","gmt_modified":"2026-05-28T19:00:48.6528889+08:00"},{"id":"f739c0f56b921999850449a934b246fb","path":"internal/router/router.go","line_range":"51","gmt_create":"2026-05-28T19:00:48.6535196+08:00","gmt_modified":"2026-05-28T19:00:48.6535196+08:00"},{"id":"a554f667fa82536a73b1255c88583088","path":"internal/handler/ota.go","line_range":"25-133","gmt_create":"2026-05-28T19:00:48.6535196+08:00","gmt_modified":"2026-05-28T19:00:48.6535196+08:00"},{"id":"dcccb8807bc578cdadf9bec126c8ffe9","path":"pkg/encode/base64.go","line_range":"35-52","gmt_create":"2026-05-28T19:00:48.6540452+08:00","gmt_modified":"2026-05-28T19:00:48.6540452+08:00"},{"id":"64183de83183797057473b5ee67ba4c9","path":"internal/repository/brand.go","line_range":"12-51","gmt_create":"2026-05-28T19:00:48.6545855+08:00","gmt_modified":"2026-05-28T19:00:48.6545855+08:00"},{"id":"4693351138ccb8e9d6210c80375b0f84","path":"internal/repository/model.go","line_range":"12-95","gmt_create":"2026-05-28T19:00:48.6551141+08:00","gmt_modified":"2026-05-28T19:00:48.6551141+08:00"},{"id":"6f5bb52b78380275d195a29a2a4f95e5","path":"internal/handler/brand.go","line_range":"14-50","gmt_create":"2026-05-28T19:00:48.6631523+08:00","gmt_modified":"2026-05-28T19:00:48.6631523+08:00"},{"id":"7b5fdc856dd6809973d5baa959e27fee","path":"internal/handler/model.go","line_range":"14-51","gmt_create":"2026-05-28T19:00:48.6631523+08:00","gmt_modified":"2026-05-28T19:00:48.6631523+08:00"},{"id":"d720265bcfafa36ea6088932e1b64cbb","path":"sql/model.sql","line_range":"34-35","gmt_create":"2026-05-28T19:00:48.6631523+08:00","gmt_modified":"2026-05-28T19:00:48.6631523+08:00"},{"id":"ae6067ec7ce193f2a0f441884cab8879","path":"internal/repository/model.go","line_range":"63-95","gmt_create":"2026-05-28T19:00:48.6661916+08:00","gmt_modified":"2026-05-28T19:00:48.6661916+08:00"},{"id":"eed5fae41d5e3dedf1a6cf48e3714329","path":"internal/repository/ota.go","line_range":"20-159","gmt_create":"2026-05-28T19:00:48.6661916+08:00","gmt_modified":"2026-05-28T19:00:48.6661916+08:00"},{"id":"c100a3cbfc9d8f23656202b88fa6afd1","path":"cmd/server/main.go","line_range":"66-95","gmt_create":"2026-05-28T19:00:48.6661916+08:00","gmt_modified":"2026-05-28T19:00:48.6661916+08:00"},{"id":"66a4c4386d79ac88e1703c28c4cd145b","path":"internal/config/database.go","line_range":"57-72","gmt_create":"2026-05-28T19:00:48.6661916+08:00","gmt_modified":"2026-05-28T19:00:48.6661916+08:00"},{"id":"203b91618d1657c9507385082e51de6e","path":"internal/handler/brand.go","line_range":"31-35","gmt_create":"2026-05-28T19:00:48.6661916+08:00","gmt_modified":"2026-05-28T19:00:48.6661916+08:00"},{"id":"d73169aa9d1bce60664d575f3b21b1d7","path":"internal/handler/model.go","line_range":"33-36","gmt_create":"2026-05-28T19:00:48.6661916+08:00","gmt_modified":"2026-05-28T19:00:48.6661916+08:00"},{"id":"a9580521a05ba65f89553c7d22ca9e68","path":"internal/handler/model_list.go","line_range":"39-42","gmt_create":"2026-05-28T19:00:48.6661916+08:00","gmt_modified":"2026-05-28T19:00:48.6661916+08:00"},{"id":"4d001351d513017ae0410443015c4fdf","path":"internal/handler/ota.go","line_range":"31-48","gmt_create":"2026-05-28T19:00:48.668705+08:00","gmt_modified":"2026-05-28T19:00:48.668705+08:00"},{"id":"1862d9cadc2f4c8f0f2f11fa22854f28","path":"internal/response/response.go","line_range":"30-37","gmt_create":"2026-05-28T19:00:48.668705+08:00","gmt_modified":"2026-05-28T19:00:48.668705+08:00"}],"knowledge_relations":[{"id":1,"source_id":"ab98c251-c5f7-40df-bba1-21b2edf5d220","target_id":"523107ca-244f-43c5-a4fe-4649e36a88ad","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab98c251-c5f7-40df-bba1-21b2edf5d220 -\u003e 523107ca-244f-43c5-a4fe-4649e36a88ad","gmt_create":"2026-05-27T16:00:38.0397713+08:00","gmt_modified":"2026-05-27T16:00:38.0397713+08:00"},{"id":3,"source_id":"ab98c251-c5f7-40df-bba1-21b2edf5d220","target_id":"5910d326-0408-450d-b403-06a19f3da81b","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab98c251-c5f7-40df-bba1-21b2edf5d220 -\u003e 5910d326-0408-450d-b403-06a19f3da81b","gmt_create":"2026-05-27T16:00:38.0417677+08:00","gmt_modified":"2026-05-27T16:00:38.0417677+08:00"},{"id":4,"source_id":"ab98c251-c5f7-40df-bba1-21b2edf5d220","target_id":"e8e5fe7e-cc7c-4259-95d0-f6b46d888ed8","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab98c251-c5f7-40df-bba1-21b2edf5d220 -\u003e e8e5fe7e-cc7c-4259-95d0-f6b46d888ed8","gmt_create":"2026-05-27T16:00:38.0417677+08:00","gmt_modified":"2026-05-27T16:00:38.0417677+08:00"},{"id":5,"source_id":"ab98c251-c5f7-40df-bba1-21b2edf5d220","target_id":"5a04f737-b877-4908-a4fc-67a88614aafc","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab98c251-c5f7-40df-bba1-21b2edf5d220 -\u003e 5a04f737-b877-4908-a4fc-67a88614aafc","gmt_create":"2026-05-27T16:00:38.0427691+08:00","gmt_modified":"2026-05-27T16:00:38.0427691+08:00"},{"id":9,"source_id":"7563e383-3ea0-4630-baeb-e86efcaeefb8","target_id":"699a84c5-5140-4267-861e-62bffbffccb4","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7563e383-3ea0-4630-baeb-e86efcaeefb8 -\u003e 699a84c5-5140-4267-861e-62bffbffccb4","gmt_create":"2026-05-27T16:00:38.0442739+08:00","gmt_modified":"2026-05-27T16:00:38.0442739+08:00"},{"id":10,"source_id":"6159e8a9-0f6e-43af-b097-bfcd16c8b223","target_id":"6f1fe170-ae35-4660-91dc-ab89735274b7","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6159e8a9-0f6e-43af-b097-bfcd16c8b223 -\u003e 6f1fe170-ae35-4660-91dc-ab89735274b7","gmt_create":"2026-05-27T16:00:38.0452805+08:00","gmt_modified":"2026-05-27T16:00:38.0452805+08:00"},{"id":11,"source_id":"6159e8a9-0f6e-43af-b097-bfcd16c8b223","target_id":"6af33e3a-220d-4e68-87ed-bfb96bda4c3a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6159e8a9-0f6e-43af-b097-bfcd16c8b223 -\u003e 6af33e3a-220d-4e68-87ed-bfb96bda4c3a","gmt_create":"2026-05-27T16:00:38.0452805+08:00","gmt_modified":"2026-05-27T16:00:38.0452805+08:00"},{"id":13,"source_id":"6159e8a9-0f6e-43af-b097-bfcd16c8b223","target_id":"0fc3d59c-d219-4f97-af10-473ee62f4de5","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6159e8a9-0f6e-43af-b097-bfcd16c8b223 -\u003e 0fc3d59c-d219-4f97-af10-473ee62f4de5","gmt_create":"2026-05-27T16:00:38.0462819+08:00","gmt_modified":"2026-05-27T16:00:38.0462819+08:00"},{"id":15,"source_id":"cfbcaa79-26f5-402f-8746-9fe524993684","target_id":"d0c2dea0-a71a-4f16-9889-b37e1e7996e3","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: cfbcaa79-26f5-402f-8746-9fe524993684 -\u003e d0c2dea0-a71a-4f16-9889-b37e1e7996e3","gmt_create":"2026-05-27T16:00:38.0462819+08:00","gmt_modified":"2026-05-27T16:00:38.0462819+08:00"},{"id":16,"source_id":"cfbcaa79-26f5-402f-8746-9fe524993684","target_id":"23a2ffc3-fa50-41ba-b7a6-55354d68a95a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: cfbcaa79-26f5-402f-8746-9fe524993684 -\u003e 23a2ffc3-fa50-41ba-b7a6-55354d68a95a","gmt_create":"2026-05-27T16:00:38.0472824+08:00","gmt_modified":"2026-05-27T16:00:38.0472824+08:00"},{"id":17,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"d2654fb48612d74ab0ccc06a3aede80b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/router/router.go","gmt_create":"2026-05-27T18:35:29.9094769+08:00","gmt_modified":"2026-05-27T18:35:29.9094769+08:00"},{"id":18,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"fd613068059c593ac4df9eaef2918055","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: cmd/server/main.go","gmt_create":"2026-05-27T18:35:29.9094769+08:00","gmt_modified":"2026-05-27T18:35:29.9094769+08:00"},{"id":19,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"336527cad207564e9ea86fcc4e0ec240","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/cors.go","gmt_create":"2026-05-27T18:35:29.9100157+08:00","gmt_modified":"2026-05-27T18:35:29.9100157+08:00"},{"id":20,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"f8a733666ceab6a73ba2bf3234e91222","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/logger.go","gmt_create":"2026-05-27T18:35:29.9100157+08:00","gmt_modified":"2026-05-27T18:35:29.9100157+08:00"},{"id":21,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"2ba2f740fa3334f7c6d51f74470ec4b7","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/request_id.go","gmt_create":"2026-05-27T18:35:29.9105584+08:00","gmt_modified":"2026-05-27T18:35:29.9105584+08:00"},{"id":22,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"a7b9800e6fc68baa0cfda9c8f327b423","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/health.go","gmt_create":"2026-05-27T18:35:29.9111006+08:00","gmt_modified":"2026-05-27T18:35:29.9111006+08:00"},{"id":23,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/brand.go","gmt_create":"2026-05-27T18:35:29.9111006+08:00","gmt_modified":"2026-05-27T18:35:29.9111006+08:00"},{"id":24,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"b18d19ca2c60406b9cd28010df12296d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model.go","gmt_create":"2026-05-27T18:35:29.9116443+08:00","gmt_modified":"2026-05-27T18:35:29.9116443+08:00"},{"id":25,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model_list.go","gmt_create":"2026-05-27T18:35:29.9116443+08:00","gmt_modified":"2026-05-27T18:35:29.9116443+08:00"},{"id":26,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"3a1babcf090301072327433866c0d7d0","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/device.go","gmt_create":"2026-05-27T18:35:29.9121832+08:00","gmt_modified":"2026-05-27T18:35:29.9121832+08:00"},{"id":27,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"703706c059a41213d3dbfbddc03fab12","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/response/response.go","gmt_create":"2026-05-27T18:35:29.9121832+08:00","gmt_modified":"2026-05-27T18:35:29.9121832+08:00"},{"id":28,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"0bba4121c12e2cf427dc805016fade40","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/config.go","gmt_create":"2026-05-27T18:35:29.9127279+08:00","gmt_modified":"2026-05-27T18:35:29.9127279+08:00"},{"id":29,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"80d716769cf67cd05b504a3bc0a06a92","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: pkg/encode/base64.go","gmt_create":"2026-05-27T18:35:29.9127279+08:00","gmt_modified":"2026-05-27T18:35:29.9127279+08:00"},{"id":30,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"67d9f7c1be7ff64bb9bca0a5f2492621","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: README.md","gmt_create":"2026-05-27T18:35:29.9127279+08:00","gmt_modified":"2026-05-27T18:35:29.9127279+08:00"},{"id":31,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"7bfaa93c0d23eed2727039a5bd3d9a07","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/redis.go","gmt_create":"2026-05-27T18:35:29.9127279+08:00","gmt_modified":"2026-05-27T18:35:29.9127279+08:00"},{"id":32,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"67d3253845127f03f1f9ebe3f6a6aaa3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/brand_cache.go","gmt_create":"2026-05-27T18:35:29.9137674+08:00","gmt_modified":"2026-05-27T18:35:29.9137674+08:00"},{"id":33,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"018b14cbce05561cfb50fe7e6e3835a3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/model_cache.go","gmt_create":"2026-05-27T18:35:29.9137674+08:00","gmt_modified":"2026-05-27T18:35:29.9137674+08:00"},{"id":34,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"276b4d58e492bc3f7c258914abb959e4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/brand.go","gmt_create":"2026-05-27T18:35:29.9137674+08:00","gmt_modified":"2026-05-27T18:35:29.9137674+08:00"},{"id":35,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"4ca752eb084c575a36939921aeeb9984","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/model.go","gmt_create":"2026-05-27T18:35:29.9137674+08:00","gmt_modified":"2026-05-27T18:35:29.9137674+08:00"},{"id":36,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"ac542a8b31381c132de78b921e3216d4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/redis.go","gmt_create":"2026-05-27T18:35:29.9137674+08:00","gmt_modified":"2026-05-27T18:35:29.9137674+08:00"},{"id":37,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"d2c7a50459a83c5ef23e809b0f194aba","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/meilisearch.go","gmt_create":"2026-05-27T18:35:29.9137674+08:00","gmt_modified":"2026-05-27T18:35:29.9137674+08:00"},{"id":38,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"333405ee9924108619cd8443f735d754","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#16-52","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":39,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"333405ee9924108619cd8443f735d754","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 16-52","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":40,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"6eda76d6eb6015250ec186fdafd0b3c9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#59-70","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":41,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"6eda76d6eb6015250ec186fdafd0b3c9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 59-70","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":42,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"553e943cfb2f6b7752122999084a80a5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#18-44","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":43,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"553e943cfb2f6b7752122999084a80a5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18-44","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":44,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"d7c4ecf9c38df06865431d0dcd796162","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#19-69","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":45,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"d7c4ecf9c38df06865431d0dcd796162","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-69","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":46,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"5ec84f3864f3fa2c3ab1d97fe69d5529","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#14-52","gmt_create":"2026-05-27T18:35:29.9152992+08:00","gmt_modified":"2026-05-27T18:35:29.9152992+08:00"},{"id":47,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"5ec84f3864f3fa2c3ab1d97fe69d5529","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-52","gmt_create":"2026-05-27T18:35:29.9181432+08:00","gmt_modified":"2026-05-27T18:35:29.9181432+08:00"},{"id":48,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"468dd8105671ed478ff86ca97c0609ba","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#14-79","gmt_create":"2026-05-27T18:35:29.9181432+08:00","gmt_modified":"2026-05-27T18:35:29.9181432+08:00"},{"id":49,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"468dd8105671ed478ff86ca97c0609ba","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-79","gmt_create":"2026-05-27T18:35:29.9186699+08:00","gmt_modified":"2026-05-27T18:35:29.9186699+08:00"},{"id":50,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"a0b3e000a5b789bf08d2d996fc17d8df","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#25-101","gmt_create":"2026-05-27T18:35:29.9191948+08:00","gmt_modified":"2026-05-27T18:35:29.9191948+08:00"},{"id":51,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"a0b3e000a5b789bf08d2d996fc17d8df","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 25-101","gmt_create":"2026-05-27T18:35:29.9191948+08:00","gmt_modified":"2026-05-27T18:35:29.9191948+08:00"},{"id":52,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"111557d31227afead72d0f01becea3bc","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: README.md#19-123","gmt_create":"2026-05-27T18:35:29.9197286+08:00","gmt_modified":"2026-05-27T18:35:29.9197286+08:00"},{"id":53,"source_id":"67d9f7c1be7ff64bb9bca0a5f2492621","target_id":"111557d31227afead72d0f01becea3bc","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-123","gmt_create":"2026-05-27T18:35:29.9197286+08:00","gmt_modified":"2026-05-27T18:35:29.9197286+08:00"},{"id":54,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"5db111a430cac488cabeb543494fb917","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#15-36","gmt_create":"2026-05-27T18:35:29.9202582+08:00","gmt_modified":"2026-05-27T18:35:29.9202582+08:00"},{"id":55,"source_id":"703706c059a41213d3dbfbddc03fab12","target_id":"5db111a430cac488cabeb543494fb917","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 15-36","gmt_create":"2026-05-27T18:35:29.9209575+08:00","gmt_modified":"2026-05-27T18:35:29.9209575+08:00"},{"id":56,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"891c848d9153926513b9005f2d61382e","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/logger.go#10-44","gmt_create":"2026-05-27T18:35:29.9214708+08:00","gmt_modified":"2026-05-27T18:35:29.9214708+08:00"},{"id":57,"source_id":"f8a733666ceab6a73ba2bf3234e91222","target_id":"891c848d9153926513b9005f2d61382e","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 10-44","gmt_create":"2026-05-27T18:35:29.9220086+08:00","gmt_modified":"2026-05-27T18:35:29.9220086+08:00"},{"id":58,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"8a6a9ea04bb9b0de8fd0195ca491b154","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/request_id.go#20-29","gmt_create":"2026-05-27T18:35:29.9220086+08:00","gmt_modified":"2026-05-27T18:35:29.9220086+08:00"},{"id":59,"source_id":"2ba2f740fa3334f7c6d51f74470ec4b7","target_id":"8a6a9ea04bb9b0de8fd0195ca491b154","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-29","gmt_create":"2026-05-27T18:35:29.9225391+08:00","gmt_modified":"2026-05-27T18:35:29.9225391+08:00"},{"id":60,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"99d2500a6a0922c50675ed247c6777e5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/cors.go#7-19","gmt_create":"2026-05-27T18:35:29.9225391+08:00","gmt_modified":"2026-05-27T18:35:29.9225391+08:00"},{"id":61,"source_id":"336527cad207564e9ea86fcc4e0ec240","target_id":"99d2500a6a0922c50675ed247c6777e5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 7-19","gmt_create":"2026-05-27T18:35:29.9230634+08:00","gmt_modified":"2026-05-27T18:35:29.9230634+08:00"},{"id":62,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"c86c8f1c951956c0397e6c938ccc641c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#23-36","gmt_create":"2026-05-27T18:35:29.9241149+08:00","gmt_modified":"2026-05-27T18:35:29.9241149+08:00"},{"id":63,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"c86c8f1c951956c0397e6c938ccc641c","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-36","gmt_create":"2026-05-27T18:35:29.9241149+08:00","gmt_modified":"2026-05-27T18:35:29.9241149+08:00"},{"id":64,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"99701e03d9c9476a15f742b82e5adfa5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#13-44","gmt_create":"2026-05-27T18:35:29.9241149+08:00","gmt_modified":"2026-05-27T18:35:29.9241149+08:00"},{"id":65,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"99701e03d9c9476a15f742b82e5adfa5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-44","gmt_create":"2026-05-27T18:35:29.9246449+08:00","gmt_modified":"2026-05-27T18:35:29.9246449+08:00"},{"id":66,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"a072f4ebff3b6cc9eaf8025737ca42d3","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#13-69","gmt_create":"2026-05-27T18:35:29.9251757+08:00","gmt_modified":"2026-05-27T18:35:29.9251757+08:00"},{"id":67,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"a072f4ebff3b6cc9eaf8025737ca42d3","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-69","gmt_create":"2026-05-27T18:35:29.9251757+08:00","gmt_modified":"2026-05-27T18:35:29.9251757+08:00"},{"id":68,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"d4f94a6e4a0cd46ebc0c5f03e96c6232","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#38-49","gmt_create":"2026-05-27T18:35:29.9257015+08:00","gmt_modified":"2026-05-27T18:35:29.9257015+08:00"},{"id":69,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"d4f94a6e4a0cd46ebc0c5f03e96c6232","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 38-49","gmt_create":"2026-05-27T18:35:29.9257015+08:00","gmt_modified":"2026-05-27T18:35:29.9257015+08:00"},{"id":70,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"0a2840d641ba5dccfff95a35d7317004","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: README.md#83-110","gmt_create":"2026-05-27T18:35:29.9262333+08:00","gmt_modified":"2026-05-27T18:35:29.9262333+08:00"},{"id":71,"source_id":"67d9f7c1be7ff64bb9bca0a5f2492621","target_id":"0a2840d641ba5dccfff95a35d7317004","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 83-110","gmt_create":"2026-05-27T18:35:29.9262333+08:00","gmt_modified":"2026-05-27T18:35:29.9262333+08:00"},{"id":72,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"491bd71f42db0fd5bf1d4851b9c4aaa9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/health.go#14-18","gmt_create":"2026-05-27T18:35:29.9273021+08:00","gmt_modified":"2026-05-27T18:35:29.9273021+08:00"},{"id":73,"source_id":"a7b9800e6fc68baa0cfda9c8f327b423","target_id":"491bd71f42db0fd5bf1d4851b9c4aaa9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-18","gmt_create":"2026-05-27T18:35:29.9273021+08:00","gmt_modified":"2026-05-27T18:35:29.9273021+08:00"},{"id":74,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"fce5662f14aa6386a5036b5241e00b1c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#15-21","gmt_create":"2026-05-27T18:35:29.9278475+08:00","gmt_modified":"2026-05-27T18:35:29.9278475+08:00"},{"id":75,"source_id":"703706c059a41213d3dbfbddc03fab12","target_id":"fce5662f14aa6386a5036b5241e00b1c","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 15-21","gmt_create":"2026-05-27T18:35:29.9278475+08:00","gmt_modified":"2026-05-27T18:35:29.9278475+08:00"},{"id":76,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"7e3954c3e70a9252de9cfdec52ed93c8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#25-48","gmt_create":"2026-05-27T18:35:29.9278475+08:00","gmt_modified":"2026-05-27T18:35:29.9278475+08:00"},{"id":77,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"7e3954c3e70a9252de9cfdec52ed93c8","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 25-48","gmt_create":"2026-05-27T18:35:29.9283823+08:00","gmt_modified":"2026-05-27T18:35:29.9283823+08:00"},{"id":78,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"79304ed9558f17f9ecb0dc7d24add547","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: pkg/encode/base64.go#44-51","gmt_create":"2026-05-27T18:35:29.9283823+08:00","gmt_modified":"2026-05-27T18:35:29.9283823+08:00"},{"id":79,"source_id":"80d716769cf67cd05b504a3bc0a06a92","target_id":"79304ed9558f17f9ecb0dc7d24add547","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 44-51","gmt_create":"2026-05-27T18:35:29.9289151+08:00","gmt_modified":"2026-05-27T18:35:29.9289151+08:00"},{"id":80,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"a6d16b8965ed7f207f19f8f915ad53a4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#25-49","gmt_create":"2026-05-27T18:35:29.9289151+08:00","gmt_modified":"2026-05-27T18:35:29.9289151+08:00"},{"id":81,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"a6d16b8965ed7f207f19f8f915ad53a4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 25-49","gmt_create":"2026-05-27T18:35:29.9289151+08:00","gmt_modified":"2026-05-27T18:35:29.9289151+08:00"},{"id":82,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"fce0c17d6c03e511c3afeaee662ad34f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#26-56","gmt_create":"2026-05-27T18:35:29.930006+08:00","gmt_modified":"2026-05-27T18:35:29.930006+08:00"},{"id":83,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"fce0c17d6c03e511c3afeaee662ad34f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 26-56","gmt_create":"2026-05-27T18:35:29.930006+08:00","gmt_modified":"2026-05-27T18:35:29.930006+08:00"},{"id":84,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"d4bd0610a0ad3d8fd8d33ac5f4aa83b5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#26-84","gmt_create":"2026-05-27T18:35:29.930538+08:00","gmt_modified":"2026-05-27T18:35:29.930538+08:00"},{"id":85,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"d4bd0610a0ad3d8fd8d33ac5f4aa83b5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 26-84","gmt_create":"2026-05-27T18:35:29.930538+08:00","gmt_modified":"2026-05-27T18:35:29.930538+08:00"},{"id":86,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"1be2a5a025cb64eeb20d5e54d293203f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/logger.go#33-43","gmt_create":"2026-05-27T18:35:29.9321249+08:00","gmt_modified":"2026-05-27T18:35:29.9321249+08:00"},{"id":87,"source_id":"f8a733666ceab6a73ba2bf3234e91222","target_id":"1be2a5a025cb64eeb20d5e54d293203f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 33-43","gmt_create":"2026-05-27T18:35:29.9326589+08:00","gmt_modified":"2026-05-27T18:35:29.9326589+08:00"},{"id":88,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"5f4eb9799d6c811ddcc430f51e299cf6","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/request_id.go#22-27","gmt_create":"2026-05-27T18:35:29.9326589+08:00","gmt_modified":"2026-05-27T18:35:29.9326589+08:00"},{"id":89,"source_id":"2ba2f740fa3334f7c6d51f74470ec4b7","target_id":"5f4eb9799d6c811ddcc430f51e299cf6","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 22-27","gmt_create":"2026-05-27T18:35:29.9331872+08:00","gmt_modified":"2026-05-27T18:35:29.9331872+08:00"},{"id":90,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"be85f7cf4e9dd0c2460475b95efb085d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/cors.go#9-12","gmt_create":"2026-05-27T18:35:29.9331872+08:00","gmt_modified":"2026-05-27T18:35:29.9331872+08:00"},{"id":91,"source_id":"336527cad207564e9ea86fcc4e0ec240","target_id":"be85f7cf4e9dd0c2460475b95efb085d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 9-12","gmt_create":"2026-05-27T18:35:29.9337179+08:00","gmt_modified":"2026-05-27T18:35:29.9337179+08:00"},{"id":92,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"730d8469648c9599ccbc091a9496d2a1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#23-36","gmt_create":"2026-05-27T18:35:29.9337179+08:00","gmt_modified":"2026-05-27T18:35:29.9337179+08:00"},{"id":93,"source_id":"703706c059a41213d3dbfbddc03fab12","target_id":"730d8469648c9599ccbc091a9496d2a1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-36","gmt_create":"2026-05-27T18:35:29.9337179+08:00","gmt_modified":"2026-05-27T18:35:29.9337179+08:00"},{"id":94,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"d48bcd5374602483c104c7d50c7224fb","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#18-21","gmt_create":"2026-05-27T18:35:29.9354707+08:00","gmt_modified":"2026-05-27T18:35:29.9354707+08:00"},{"id":95,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"d48bcd5374602483c104c7d50c7224fb","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18-21","gmt_create":"2026-05-27T18:35:29.936015+08:00","gmt_modified":"2026-05-27T18:35:29.936015+08:00"},{"id":96,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"798bc9e7f1a3902993b3aa9acba73022","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/logger.go#16","gmt_create":"2026-05-27T18:35:29.936015+08:00","gmt_modified":"2026-05-27T18:35:29.936015+08:00"},{"id":97,"source_id":"f8a733666ceab6a73ba2bf3234e91222","target_id":"798bc9e7f1a3902993b3aa9acba73022","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 16","gmt_create":"2026-05-27T18:35:29.9365406+08:00","gmt_modified":"2026-05-27T18:35:29.9365406+08:00"},{"id":98,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"ed43fe99536e371ce908f167a68124f8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/request_id.go#28","gmt_create":"2026-05-27T18:35:29.9370715+08:00","gmt_modified":"2026-05-27T18:35:29.9370715+08:00"},{"id":99,"source_id":"2ba2f740fa3334f7c6d51f74470ec4b7","target_id":"ed43fe99536e371ce908f167a68124f8","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 28","gmt_create":"2026-05-27T18:35:29.9375945+08:00","gmt_modified":"2026-05-27T18:35:29.9375945+08:00"},{"id":100,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"08c02a0d77d871b6c9650cbfcdf84c94","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/cors.go#18","gmt_create":"2026-05-27T18:35:29.9375945+08:00","gmt_modified":"2026-05-27T18:35:29.9375945+08:00"},{"id":101,"source_id":"336527cad207564e9ea86fcc4e0ec240","target_id":"08c02a0d77d871b6c9650cbfcdf84c94","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18","gmt_create":"2026-05-27T18:35:29.938135+08:00","gmt_modified":"2026-05-27T18:35:29.938135+08:00"},{"id":102,"source_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","target_id":"e88b0ee062bd02dd7acdf8e2e945b270","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#103-130","gmt_create":"2026-05-27T18:35:29.938135+08:00","gmt_modified":"2026-05-27T18:35:29.938135+08:00"},{"id":103,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"e88b0ee062bd02dd7acdf8e2e945b270","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 103-130","gmt_create":"2026-05-27T18:35:29.938674+08:00","gmt_modified":"2026-05-27T18:35:29.938674+08:00"},{"id":123,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"64381887b12f6927d8b0481a55c2dcf1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 22-25","gmt_create":"2026-05-27T18:35:41.7750027+08:00","gmt_modified":"2026-05-27T18:35:41.7750027+08:00"},{"id":125,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"1503a99bb2f2ab96e4a3a830d8834e45","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-24","gmt_create":"2026-05-27T18:35:41.7755529+08:00","gmt_modified":"2026-05-27T18:35:41.7755529+08:00"},{"id":127,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"f74cdc773e62a1a9f5a4bf940b5961e3","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-24","gmt_create":"2026-05-27T18:35:41.7760825+08:00","gmt_modified":"2026-05-27T18:35:41.7760825+08:00"},{"id":129,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"8b0db394a538b6652de2e6634277ad0f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-21","gmt_create":"2026-05-27T18:35:41.7766018+08:00","gmt_modified":"2026-05-27T18:35:41.7766018+08:00"},{"id":131,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"03f26c7c55e18e6266ea8e543a032229","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-21","gmt_create":"2026-05-27T18:35:41.7771345+08:00","gmt_modified":"2026-05-27T18:35:41.7771345+08:00"},{"id":133,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"8fab617bba600779abac7805723180a0","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18-24","gmt_create":"2026-05-27T18:35:41.7777054+08:00","gmt_modified":"2026-05-27T18:35:41.7777054+08:00"},{"id":135,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"006d91f2f5f75fd7cd586165c200ba98","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-25","gmt_create":"2026-05-27T18:35:41.7782257+08:00","gmt_modified":"2026-05-27T18:35:41.7782257+08:00"},{"id":137,"source_id":"7bfaa93c0d23eed2727039a5bd3d9a07","target_id":"509525e0463c03c509709a6bd1765d4f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 10-16","gmt_create":"2026-05-27T18:35:41.7787495+08:00","gmt_modified":"2026-05-27T18:35:41.7787495+08:00"},{"id":139,"source_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","target_id":"57b8aed283762226a00482b42a8acf5b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-46","gmt_create":"2026-05-27T18:35:41.7792726+08:00","gmt_modified":"2026-05-27T18:35:41.7792726+08:00"},{"id":141,"source_id":"a0a3a762dc85a8d8c5bb359f5c523def","target_id":"4ab082407b96e18f67a65d07eb4a331d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 17-40","gmt_create":"2026-05-27T18:35:41.7792726+08:00","gmt_modified":"2026-05-27T18:35:41.7792726+08:00"},{"id":143,"source_id":"ac542a8b31381c132de78b921e3216d4","target_id":"fd2a12d243b52512003ae067f53a7548","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 9-57","gmt_create":"2026-05-27T18:35:41.7797862+08:00","gmt_modified":"2026-05-27T18:35:41.7797862+08:00"},{"id":145,"source_id":"0bba4121c12e2cf427dc805016fade40","target_id":"61d69bf4d3c8c548eecfd677394486d6","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18-52","gmt_create":"2026-05-27T18:35:41.7803146+08:00","gmt_modified":"2026-05-27T18:35:41.7803146+08:00"},{"id":147,"source_id":"c56e5254bd7f42350c5261822fa135bb","target_id":"e87c932ace50951cb91aa66877ad6f81","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 24-35","gmt_create":"2026-05-27T18:35:41.78084+08:00","gmt_modified":"2026-05-27T18:35:41.78084+08:00"},{"id":149,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"90226e287e9b66f5a36ba2316d7a7cd7","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-41","gmt_create":"2026-05-27T18:35:41.7813615+08:00","gmt_modified":"2026-05-27T18:35:41.7813615+08:00"},{"id":151,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"9918f39149aaf1f5c3ec03275d6e3673","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-52","gmt_create":"2026-05-27T18:35:41.7842961+08:00","gmt_modified":"2026-05-27T18:35:41.7842961+08:00"},{"id":153,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"a19fb2ac137e43d92d2ef93e8d79f0a7","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-79","gmt_create":"2026-05-27T18:35:41.7848355+08:00","gmt_modified":"2026-05-27T18:35:41.7848355+08:00"},{"id":155,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"72322f320f907b6eec72e885e30759eb","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 26-44","gmt_create":"2026-05-27T18:35:41.7848355+08:00","gmt_modified":"2026-05-27T18:35:41.7848355+08:00"},{"id":157,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"d0f658c42abae9b6dc0baaa8fc7d0694","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 31-69","gmt_create":"2026-05-27T18:35:41.7853732+08:00","gmt_modified":"2026-05-27T18:35:41.7853732+08:00"},{"id":159,"source_id":"a0a3a762dc85a8d8c5bb359f5c523def","target_id":"a952e5d5b625754a2e9249983bb8abaa","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 17-72","gmt_create":"2026-05-27T18:35:41.7864448+08:00","gmt_modified":"2026-05-27T18:35:41.7864448+08:00"},{"id":161,"source_id":"ac542a8b31381c132de78b921e3216d4","target_id":"f7af3a1998c24f922aa650a69b252734","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 16-57","gmt_create":"2026-05-27T18:35:41.786982+08:00","gmt_modified":"2026-05-27T18:35:41.786982+08:00"},{"id":165,"source_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","target_id":"c7bf654a5faf00b02953d2e56747a669","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 28-43","gmt_create":"2026-05-27T18:35:41.7896921+08:00","gmt_modified":"2026-05-27T18:35:41.7896921+08:00"},{"id":167,"source_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","target_id":"1d3714bd55d5d3f773f1ab7fdb8c9b53","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 3-6","gmt_create":"2026-05-27T18:35:41.7907502+08:00","gmt_modified":"2026-05-27T18:35:41.7907502+08:00"},{"id":169,"source_id":"e9902bfcef1f5908b5123648ae6b07c6","target_id":"8d92ac14c6257462a15eb6990dd44596","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 5-14","gmt_create":"2026-05-27T18:35:41.7923122+08:00","gmt_modified":"2026-05-27T18:35:41.7923122+08:00"},{"id":171,"source_id":"c56e5254bd7f42350c5261822fa135bb","target_id":"8b134235408cf40b9d6351d54591b3c4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 34","gmt_create":"2026-05-27T18:35:41.7933596+08:00","gmt_modified":"2026-05-27T18:35:41.7933596+08:00"},{"id":173,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"62d02336da9111eec3c5696aabf71927","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-16","gmt_create":"2026-05-27T18:35:41.7959791+08:00","gmt_modified":"2026-05-27T18:35:41.7959791+08:00"},{"id":175,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"a60ecb63d9ab3bda0c5042f26916def3","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-16","gmt_create":"2026-05-27T18:35:41.7959791+08:00","gmt_modified":"2026-05-27T18:35:41.7959791+08:00"},{"id":177,"source_id":"47165ac2566e8b2d3796014bdb75361f","target_id":"5859dc43ab95b589fc2cada49ab59a86","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 5-11","gmt_create":"2026-05-27T18:35:41.7970218+08:00","gmt_modified":"2026-05-27T18:35:41.7970218+08:00"},{"id":179,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"dcc3acd0529002f62657a37922318e37","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 25-69","gmt_create":"2026-05-27T18:35:41.7976793+08:00","gmt_modified":"2026-05-27T18:35:41.7976793+08:00"},{"id":181,"source_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","target_id":"99ead368ce42f1081e05c800c65b176f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 33-43","gmt_create":"2026-05-27T18:35:41.802505+08:00","gmt_modified":"2026-05-27T18:35:41.802505+08:00"},{"id":205,"source_id":"a7b9800e6fc68baa0cfda9c8f327b423","target_id":"a5fb1691af5646ea8b4306ae97288e36","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 10","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":207,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"de87fa33e6add38c027478dd3d0cebda","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":209,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"09427d743a4be750f874418ab3e8504d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":211,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"9ebb4688793526b520ec263ebf651be7","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":213,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"5e813130e7885527f77be92dbbaee9b6","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19","gmt_create":"2026-05-27T18:35:49.7892834+08:00","gmt_modified":"2026-05-27T18:35:49.7892834+08:00"},{"id":215,"source_id":"a7b9800e6fc68baa0cfda9c8f327b423","target_id":"1992aa29a2869c31fe69ac701541c6ff","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 8-19","gmt_create":"2026-05-27T18:35:49.7913083+08:00","gmt_modified":"2026-05-27T18:35:49.7913083+08:00"},{"id":217,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"692a2c6d49d4eb62f58600908dff9f60","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-23","gmt_create":"2026-05-27T18:35:49.7913083+08:00","gmt_modified":"2026-05-27T18:35:49.7913083+08:00"},{"id":219,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"c9df5e7b8533af65ce97cf085b6589a9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-23","gmt_create":"2026-05-27T18:35:49.7913083+08:00","gmt_modified":"2026-05-27T18:35:49.7913083+08:00"},{"id":221,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"d2fd0586bf019047d2adbcdf90e09224","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-24","gmt_create":"2026-05-27T18:35:49.7933132+08:00","gmt_modified":"2026-05-27T18:35:49.7933132+08:00"},{"id":223,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"bf1f0d1dece713e866e4a46be7784473","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-24","gmt_create":"2026-05-27T18:35:49.7933132+08:00","gmt_modified":"2026-05-27T18:35:49.7933132+08:00"},{"id":225,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"c600af69dac497c7cf059a4bb2f033fc","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 32-36","gmt_create":"2026-05-27T18:35:49.7933132+08:00","gmt_modified":"2026-05-27T18:35:49.7933132+08:00"},{"id":227,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"bc6f53b403231c0f908654d3fea2102a","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 29","gmt_create":"2026-05-27T18:35:49.7948171+08:00","gmt_modified":"2026-05-27T18:35:49.7948171+08:00"},{"id":229,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"7b39881baafeaea08adce31120b7c1e1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 30","gmt_create":"2026-05-27T18:35:49.7948171+08:00","gmt_modified":"2026-05-27T18:35:49.7948171+08:00"},{"id":231,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"dbe385204072d26c84bf169842961690","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 37","gmt_create":"2026-05-27T18:35:49.7948171+08:00","gmt_modified":"2026-05-27T18:35:49.7948171+08:00"},{"id":233,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"2a723ed48cd9855068a04da6a33cb5e4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 71","gmt_create":"2026-05-27T18:35:49.7948171+08:00","gmt_modified":"2026-05-27T18:35:49.7948171+08:00"},{"id":237,"source_id":"a1ff50cc5809d0d712db343ab0befe3b","target_id":"d72b0eafdb65d1d946060cf944359251","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 22-45","gmt_create":"2026-05-27T18:35:49.7970098+08:00","gmt_modified":"2026-05-27T18:35:49.7970098+08:00"},{"id":240,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"1eb8f107de13e2ad7eaed3bd6cf20a3a","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 40","gmt_create":"2026-05-27T18:35:49.8048985+08:00","gmt_modified":"2026-05-27T18:35:49.8048985+08:00"},{"id":244,"source_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","target_id":"72195f4e7a76b584cbdfbaba23db2a1a","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 3-7","gmt_create":"2026-05-27T18:35:49.8048985+08:00","gmt_modified":"2026-05-27T18:35:49.8048985+08:00"},{"id":246,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"3e3a148f4095f6d36c64b1cfb3d1702a","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-48","gmt_create":"2026-05-27T18:35:49.8120366+08:00","gmt_modified":"2026-05-27T18:35:49.8120366+08:00"},{"id":250,"source_id":"e9902bfcef1f5908b5123648ae6b07c6","target_id":"3c27d9274287839faa5269c34b98b6a9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 5-15","gmt_create":"2026-05-27T18:35:49.8127781+08:00","gmt_modified":"2026-05-27T18:35:49.8127781+08:00"},{"id":252,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"e0ca219542426b9141a89063f7052b0c","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-49","gmt_create":"2026-05-27T18:35:49.8127781+08:00","gmt_modified":"2026-05-27T18:35:49.8127781+08:00"},{"id":255,"source_id":"80d716769cf67cd05b504a3bc0a06a92","target_id":"270fee7aef8f38c42409050388865f6d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 35-51","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":258,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"8cf065ea198e4e0d88af1863fcd6ac11","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-57","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":261,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"b62090b5a8fe0cd95b332a46bb8eac3c","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-85","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":263,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"3f830fae511ccf076a0f04192c9b4cbe","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 53-69","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":265,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"d0f6f695e8187267487ad6b6fb8559b0","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 16-36","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":269,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"1b6991f54b135de9969d4b357dcce8e4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 67-70","gmt_create":"2026-05-27T18:35:49.8152938+08:00","gmt_modified":"2026-05-27T18:35:49.8152938+08:00"},{"id":271,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"86ac1fc7361002fc5d2c9f7b9b1ea754","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 27-36","gmt_create":"2026-05-27T18:35:49.821585+08:00","gmt_modified":"2026-05-27T18:35:49.821585+08:00"},{"id":273,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"bdfbf7d6f851540dee549606f7aca9d4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19","gmt_create":"2026-05-27T18:35:49.821585+08:00","gmt_modified":"2026-05-27T18:35:49.821585+08:00"},{"id":275,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"ba4653c42534e9835fb3db39fbfd5c06","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19","gmt_create":"2026-05-27T18:35:49.8235965+08:00","gmt_modified":"2026-05-27T18:35:49.8235965+08:00"},{"id":277,"source_id":"a1ff50cc5809d0d712db343ab0befe3b","target_id":"e5c6898e570c67346c0858cfeaa98fae","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 17","gmt_create":"2026-05-27T18:35:49.8235965+08:00","gmt_modified":"2026-05-27T18:35:49.8235965+08:00"},{"id":279,"source_id":"80d716769cf67cd05b504a3bc0a06a92","target_id":"90b60f9dc283b0c2610ad113bc211315","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 8","gmt_create":"2026-05-27T18:35:49.8235965+08:00","gmt_modified":"2026-05-27T18:35:49.8235965+08:00"},{"id":281,"source_id":"703706c059a41213d3dbfbddc03fab12","target_id":"85820118c846a111e112dc705c071116","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 9","gmt_create":"2026-05-27T18:35:49.8235965+08:00","gmt_modified":"2026-05-27T18:35:49.8235965+08:00"},{"id":284,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"1041284bd46edf16a19f024c113d10b4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 30-34","gmt_create":"2026-05-27T18:35:49.8256014+08:00","gmt_modified":"2026-05-27T18:35:49.8256014+08:00"},{"id":286,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"84be9fdffe58ef8cd5e77e0d3c37313b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 31-35","gmt_create":"2026-05-27T18:35:49.8256014+08:00","gmt_modified":"2026-05-27T18:35:49.8256014+08:00"},{"id":288,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"f034e5c72872862a675dd11e32404854","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 38-42","gmt_create":"2026-05-27T18:35:49.827349+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00"},{"id":290,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"df50e47a5b6541093011bb59b1ec831d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 61-78","gmt_create":"2026-05-27T18:35:49.827349+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00"},{"id":292,"source_id":"f8a733666ceab6a73ba2bf3234e91222","target_id":"0a425d8fed248deb7202bc7e8d531ca1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 10-45","gmt_create":"2026-05-27T18:35:49.827349+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00"},{"id":294,"source_id":"2ba2f740fa3334f7c6d51f74470ec4b7","target_id":"d6d27b00ae4ab42348e74a7e7bf688b2","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-31","gmt_create":"2026-05-27T18:35:49.827349+08:00","gmt_modified":"2026-05-27T18:35:49.827349+08:00"},{"id":310,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"e9390185152783a55f55e277d45e6948","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 25-131","gmt_create":"2026-05-27T18:36:40.5235889+08:00","gmt_modified":"2026-05-27T18:36:40.5235889+08:00"},{"id":312,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"a3cbc373dacd9d032ed0c72bca1e51e9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-45","gmt_create":"2026-05-27T18:36:40.5246891+08:00","gmt_modified":"2026-05-27T18:36:40.5246891+08:00"},{"id":314,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"d65e653afb8b211f2e5a7845f72b45dd","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-70","gmt_create":"2026-05-27T18:36:40.5252193+08:00","gmt_modified":"2026-05-27T18:36:40.5252193+08:00"},{"id":316,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"a26d903ac77196fac97ddebf48638ab3","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-100","gmt_create":"2026-05-27T18:36:40.5257547+08:00","gmt_modified":"2026-05-27T18:36:40.5257547+08:00"},{"id":318,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"7ffaf7b06ea96ca93862aa0dae926ff5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-181","gmt_create":"2026-05-27T18:36:40.5263036+08:00","gmt_modified":"2026-05-27T18:36:40.5263036+08:00"},{"id":320,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"187b4628003859e3da78f3937c686803","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 18-45","gmt_create":"2026-05-27T18:36:40.5278728+08:00","gmt_modified":"2026-05-27T18:36:40.5278728+08:00"},{"id":322,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"a6c526ea58aabee86ae3010b00441c69","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-70","gmt_create":"2026-05-27T18:36:40.5283937+08:00","gmt_modified":"2026-05-27T18:36:40.5283937+08:00"},{"id":324,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"a364a8daa183eaf86417b4c1bd2cc719","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-100","gmt_create":"2026-05-27T18:36:40.5289418+08:00","gmt_modified":"2026-05-27T18:36:40.5289418+08:00"},{"id":326,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"2e040aabeb8e907eaddc6bbf2ee493ac","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-181","gmt_create":"2026-05-27T18:36:40.5294767+08:00","gmt_modified":"2026-05-27T18:36:40.5294767+08:00"},{"id":328,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"3d315320639ece8212fd138420d94be5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-49","gmt_create":"2026-05-27T18:36:40.5294767+08:00","gmt_modified":"2026-05-27T18:36:40.5294767+08:00"},{"id":330,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"fbf36e29345cd3e53fd3a6e8234ad2de","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-50","gmt_create":"2026-05-27T18:36:40.5304957+08:00","gmt_modified":"2026-05-27T18:36:40.5304957+08:00"},{"id":334,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"32b7267a28b0347d59500c38ffa96a7b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-45","gmt_create":"2026-05-27T18:36:40.5320145+08:00","gmt_modified":"2026-05-27T18:36:40.5320145+08:00"},{"id":336,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"b9c3c517ffd917351757137ca1338574","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 27-69","gmt_create":"2026-05-27T18:36:40.5320145+08:00","gmt_modified":"2026-05-27T18:36:40.5320145+08:00"},{"id":338,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"df7d264896976fc8c5475257994c707e","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-70","gmt_create":"2026-05-27T18:36:40.5330386+08:00","gmt_modified":"2026-05-27T18:36:40.5330386+08:00"},{"id":340,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"a3b89d2e56d589f8d902fb9389004bf0","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 103-131","gmt_create":"2026-05-27T18:36:40.5330386+08:00","gmt_modified":"2026-05-27T18:36:40.5330386+08:00"},{"id":342,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"f76ee32725201731512db1e0e7951586","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 67-68","gmt_create":"2026-05-27T18:36:40.5330386+08:00","gmt_modified":"2026-05-27T18:36:40.5330386+08:00"},{"id":344,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"251d1b1dc197a1dc242f5384adb1555c","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 34-52","gmt_create":"2026-05-27T18:36:40.5350514+08:00","gmt_modified":"2026-05-27T18:36:40.5350514+08:00"},{"id":346,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"a51abc6a6d80413bf60f143cd1f46ee4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 27-79","gmt_create":"2026-05-27T18:36:40.5350514+08:00","gmt_modified":"2026-05-27T18:36:40.5350514+08:00"},{"id":349,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"f0b044854c85d50b2d1ba4b9d3e6a6cb","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-17","gmt_create":"2026-05-27T18:36:40.5350514+08:00","gmt_modified":"2026-05-27T18:36:40.5350514+08:00"},{"id":351,"source_id":"67d3253845127f03f1f9ebe3f6a6aaa3","target_id":"3f0d637bef43d636594a4816c9da037e","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 38-44","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":353,"source_id":"018b14cbce05561cfb50fe7e6e3835a3","target_id":"3f945faea776f513b5294aa60759fb15","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 43-69","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":355,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"a272829cfc9c48e8063d8bca53cdebc8","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 13-23","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":357,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"6d2fece0c97147748fd0269a356e4802","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 3-12","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":359,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"282a046f62f9715bfef882f5a4a6a362","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 3-14","gmt_create":"2026-05-27T18:36:40.5371702+08:00","gmt_modified":"2026-05-27T18:36:40.5371702+08:00"},{"id":362,"source_id":"ab98c251-c5f7-40df-bba1-21b2edf5d220","target_id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab98c251-c5f7-40df-bba1-21b2edf5d220 -\u003e f4014d47-467e-4cfe-8549-1dfb69cbc325","gmt_create":"2026-05-27T18:36:41.1100061+08:00","gmt_modified":"2026-05-27T18:36:41.1100061+08:00"},{"id":366,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"3a1babcf090301072327433866c0d7d0","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/device.go","gmt_create":"2026-05-28T18:57:12.1875143+08:00","gmt_modified":"2026-05-28T18:57:12.1875143+08:00"},{"id":367,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"d2654fb48612d74ab0ccc06a3aede80b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/router/router.go","gmt_create":"2026-05-28T18:57:12.1881198+08:00","gmt_modified":"2026-05-28T18:57:12.1881198+08:00"},{"id":368,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"7bfaa93c0d23eed2727039a5bd3d9a07","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/redis.go","gmt_create":"2026-05-28T18:57:12.1887415+08:00","gmt_modified":"2026-05-28T18:57:12.1887415+08:00"},{"id":369,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"ac542a8b31381c132de78b921e3216d4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/redis.go","gmt_create":"2026-05-28T18:57:12.1893279+08:00","gmt_modified":"2026-05-28T18:57:12.1893279+08:00"},{"id":370,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"a0a3a762dc85a8d8c5bb359f5c523def","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/database.go","gmt_create":"2026-05-28T18:57:12.1899754+08:00","gmt_modified":"2026-05-28T18:57:12.1899754+08:00"},{"id":371,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/database/mysql.go","gmt_create":"2026-05-28T18:57:12.190595+08:00","gmt_modified":"2026-05-28T18:57:12.190595+08:00"},{"id":372,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"40076534e5136a5edb8c4665ebafe2bd","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/user_device.go","gmt_create":"2026-05-28T18:57:12.190595+08:00","gmt_modified":"2026-05-28T18:57:12.190595+08:00"},{"id":373,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"7667f4c1d3eabf712a8e93d02391fbaa","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/user_active.go","gmt_create":"2026-05-28T18:57:12.1911823+08:00","gmt_modified":"2026-05-28T18:57:12.1911823+08:00"},{"id":374,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"9889a3ce458e1d193f3188d12fb4ffe8","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/device.go","gmt_create":"2026-05-28T18:57:12.1917673+08:00","gmt_modified":"2026-05-28T18:57:12.1917673+08:00"},{"id":375,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"7578d2fdc704b288be4b4a6cf9f8a192","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/task/device_persist.go","gmt_create":"2026-05-28T18:57:12.1924532+08:00","gmt_modified":"2026-05-28T18:57:12.1924532+08:00"},{"id":376,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"703706c059a41213d3dbfbddc03fab12","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/response/response.go","gmt_create":"2026-05-28T18:57:12.1939261+08:00","gmt_modified":"2026-05-28T18:57:12.1939261+08:00"},{"id":377,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"f8a733666ceab6a73ba2bf3234e91222","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/logger.go","gmt_create":"2026-05-28T18:57:12.194491+08:00","gmt_modified":"2026-05-28T18:57:12.194491+08:00"},{"id":378,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"336527cad207564e9ea86fcc4e0ec240","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/cors.go","gmt_create":"2026-05-28T18:57:12.195124+08:00","gmt_modified":"2026-05-28T18:57:12.195124+08:00"},{"id":379,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"fd613068059c593ac4df9eaef2918055","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: cmd/server/main.go","gmt_create":"2026-05-28T18:57:12.1958318+08:00","gmt_modified":"2026-05-28T18:57:12.1958318+08:00"},{"id":380,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"2c0dedcdaa9c3a7a39fa12d838894bd4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/user_device.sql","gmt_create":"2026-05-28T18:57:12.1970425+08:00","gmt_modified":"2026-05-28T18:57:12.1970425+08:00"},{"id":381,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"0c676c4075ac3b554f5c006c4ac29b24","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/user_active.sql","gmt_create":"2026-05-28T18:57:12.1977067+08:00","gmt_modified":"2026-05-28T18:57:12.1977067+08:00"},{"id":382,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"67d9f7c1be7ff64bb9bca0a5f2492621","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: README.md","gmt_create":"2026-05-28T18:57:12.1977067+08:00","gmt_modified":"2026-05-28T18:57:12.1977067+08:00"},{"id":383,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"436a5d37fbeaadb1394559a23e5633e3","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#27-76","gmt_create":"2026-05-28T18:57:12.2213801+08:00","gmt_modified":"2026-05-28T18:57:12.2213801+08:00"},{"id":384,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"436a5d37fbeaadb1394559a23e5633e3","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 27-76","gmt_create":"2026-05-28T18:57:12.2236476+08:00","gmt_modified":"2026-05-28T18:57:12.2236476+08:00"},{"id":385,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"6eea881f59ef13b1dd4c56cfec810c13","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#15-25","gmt_create":"2026-05-28T18:57:12.224953+08:00","gmt_modified":"2026-05-28T18:57:12.224953+08:00"},{"id":386,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"6eea881f59ef13b1dd4c56cfec810c13","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 15-25","gmt_create":"2026-05-28T18:57:12.2256785+08:00","gmt_modified":"2026-05-28T18:57:12.2256785+08:00"},{"id":387,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"ccf4922f5428b8f0159ce891bcc0cfb1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#14-22","gmt_create":"2026-05-28T18:57:12.226272+08:00","gmt_modified":"2026-05-28T18:57:12.226272+08:00"},{"id":388,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"ccf4922f5428b8f0159ce891bcc0cfb1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-22","gmt_create":"2026-05-28T18:57:12.2269582+08:00","gmt_modified":"2026-05-28T18:57:12.2269582+08:00"},{"id":389,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"b485eea69fa28d3e2b66f0d91fa8e9fc","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#1-156","gmt_create":"2026-05-28T18:57:12.2275873+08:00","gmt_modified":"2026-05-28T18:57:12.2275873+08:00"},{"id":390,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"b485eea69fa28d3e2b66f0d91fa8e9fc","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-156","gmt_create":"2026-05-28T18:57:12.2282764+08:00","gmt_modified":"2026-05-28T18:57:12.2282764+08:00"},{"id":391,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"b27f65a687bda17d5ed88a31726192a9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#1-42","gmt_create":"2026-05-28T18:57:12.2289683+08:00","gmt_modified":"2026-05-28T18:57:12.2289683+08:00"},{"id":392,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"b27f65a687bda17d5ed88a31726192a9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-42","gmt_create":"2026-05-28T18:57:12.2295569+08:00","gmt_modified":"2026-05-28T18:57:12.2295569+08:00"},{"id":393,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"47b04c12479e04825b7f54c8912d5322","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#27-83","gmt_create":"2026-05-28T18:57:12.230272+08:00","gmt_modified":"2026-05-28T18:57:12.230272+08:00"},{"id":394,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"47b04c12479e04825b7f54c8912d5322","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 27-83","gmt_create":"2026-05-28T18:57:12.2308943+08:00","gmt_modified":"2026-05-28T18:57:12.2308943+08:00"},{"id":395,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"05c701828e7a6751805539a7bdd0fb1b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#32-38","gmt_create":"2026-05-28T18:57:12.231584+08:00","gmt_modified":"2026-05-28T18:57:12.231584+08:00"},{"id":396,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"05c701828e7a6751805539a7bdd0fb1b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 32-38","gmt_create":"2026-05-28T18:57:12.231584+08:00","gmt_modified":"2026-05-28T18:57:12.231584+08:00"},{"id":397,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"46f122a322e257db9d295df514f3a0eb","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#37-91","gmt_create":"2026-05-28T18:57:12.2328609+08:00","gmt_modified":"2026-05-28T18:57:12.2328609+08:00"},{"id":398,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"46f122a322e257db9d295df514f3a0eb","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 37-91","gmt_create":"2026-05-28T18:57:12.2334842+08:00","gmt_modified":"2026-05-28T18:57:12.2334842+08:00"},{"id":399,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"5a0a9163cad4fb940b31bf2bc7ed7c9a","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#50-77","gmt_create":"2026-05-28T18:57:12.2359812+08:00","gmt_modified":"2026-05-28T18:57:12.2359812+08:00"},{"id":400,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"5a0a9163cad4fb940b31bf2bc7ed7c9a","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 50-77","gmt_create":"2026-05-28T18:57:12.2376009+08:00","gmt_modified":"2026-05-28T18:57:12.2376009+08:00"},{"id":401,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"0a425d8fed248deb7202bc7e8d531ca1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/logger.go#10-45","gmt_create":"2026-05-28T18:57:12.2382113+08:00","gmt_modified":"2026-05-28T18:57:12.2382113+08:00"},{"id":402,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"49f1730acf3c48a4b99824ea4c37c488","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/cors.go#7-20","gmt_create":"2026-05-28T18:57:12.2394764+08:00","gmt_modified":"2026-05-28T18:57:12.2394764+08:00"},{"id":403,"source_id":"336527cad207564e9ea86fcc4e0ec240","target_id":"49f1730acf3c48a4b99824ea4c37c488","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 7-20","gmt_create":"2026-05-28T18:57:12.2400716+08:00","gmt_modified":"2026-05-28T18:57:12.2400716+08:00"},{"id":404,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"8aa692daaaaec7b3cb63b9f7e45285ff","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#24-35","gmt_create":"2026-05-28T18:57:12.2407142+08:00","gmt_modified":"2026-05-28T18:57:12.2407142+08:00"},{"id":405,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"8aa692daaaaec7b3cb63b9f7e45285ff","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 24-35","gmt_create":"2026-05-28T18:57:12.2413986+08:00","gmt_modified":"2026-05-28T18:57:12.2413986+08:00"},{"id":406,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"6c0f43ccd27e99dc7451fce4025b4922","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_device.sql#24-32","gmt_create":"2026-05-28T18:57:12.2427026+08:00","gmt_modified":"2026-05-28T18:57:12.2427026+08:00"},{"id":407,"source_id":"2c0dedcdaa9c3a7a39fa12d838894bd4","target_id":"6c0f43ccd27e99dc7451fce4025b4922","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 24-32","gmt_create":"2026-05-28T18:57:12.2433221+08:00","gmt_modified":"2026-05-28T18:57:12.2433221+08:00"},{"id":408,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"55bdc917e2b5c06a063571e8ba54919d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_active.sql#24-33","gmt_create":"2026-05-28T18:57:12.2439019+08:00","gmt_modified":"2026-05-28T18:57:12.2439019+08:00"},{"id":409,"source_id":"0c676c4075ac3b554f5c006c4ac29b24","target_id":"55bdc917e2b5c06a063571e8ba54919d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 24-33","gmt_create":"2026-05-28T18:57:12.2439019+08:00","gmt_modified":"2026-05-28T18:57:12.2439019+08:00"},{"id":410,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"ac513b415a9c6c676fc89d9ee804e0e5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#93-131","gmt_create":"2026-05-28T18:57:12.2445101+08:00","gmt_modified":"2026-05-28T18:57:12.2445101+08:00"},{"id":411,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"ac513b415a9c6c676fc89d9ee804e0e5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 93-131","gmt_create":"2026-05-28T18:57:12.2451027+08:00","gmt_modified":"2026-05-28T18:57:12.2451027+08:00"},{"id":412,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"09816af084e58fcafb8acecc2aeb7fdf","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#133-166","gmt_create":"2026-05-28T18:57:12.2451027+08:00","gmt_modified":"2026-05-28T18:57:12.2451027+08:00"},{"id":413,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"09816af084e58fcafb8acecc2aeb7fdf","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 133-166","gmt_create":"2026-05-28T18:57:12.2456943+08:00","gmt_modified":"2026-05-28T18:57:12.2456943+08:00"},{"id":414,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"04de5aef1ac4054770a1dc2f321e84e0","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#70-73","gmt_create":"2026-05-28T18:57:12.2462468+08:00","gmt_modified":"2026-05-28T18:57:12.2462468+08:00"},{"id":415,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"04de5aef1ac4054770a1dc2f321e84e0","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 70-73","gmt_create":"2026-05-28T18:57:12.2462468+08:00","gmt_modified":"2026-05-28T18:57:12.2462468+08:00"},{"id":416,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"1e39af3b295124dd3e0b741f3673d73a","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#101-128","gmt_create":"2026-05-28T18:57:12.2468047+08:00","gmt_modified":"2026-05-28T18:57:12.2468047+08:00"},{"id":417,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"1e39af3b295124dd3e0b741f3673d73a","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 101-128","gmt_create":"2026-05-28T18:57:12.2473483+08:00","gmt_modified":"2026-05-28T18:57:12.2473483+08:00"},{"id":418,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"4785fe804268b84800489006489ab351","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#141-163","gmt_create":"2026-05-28T18:57:12.2473483+08:00","gmt_modified":"2026-05-28T18:57:12.2473483+08:00"},{"id":419,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"4785fe804268b84800489006489ab351","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 141-163","gmt_create":"2026-05-28T18:57:12.2478823+08:00","gmt_modified":"2026-05-28T18:57:12.2478823+08:00"},{"id":420,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"7e27200f273d8472b343ca0147ef4395","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#3-13","gmt_create":"2026-05-28T18:57:12.2486046+08:00","gmt_modified":"2026-05-28T18:57:12.2486046+08:00"},{"id":421,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"7e27200f273d8472b343ca0147ef4395","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 3-13","gmt_create":"2026-05-28T18:57:12.2492154+08:00","gmt_modified":"2026-05-28T18:57:12.2492154+08:00"},{"id":422,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"c4031c64b5fd75673a62928438dd0c86","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#3-12","gmt_create":"2026-05-28T18:57:12.2498022+08:00","gmt_modified":"2026-05-28T18:57:12.2498022+08:00"},{"id":423,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"c4031c64b5fd75673a62928438dd0c86","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 3-12","gmt_create":"2026-05-28T18:57:12.2498022+08:00","gmt_modified":"2026-05-28T18:57:12.2498022+08:00"},{"id":424,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"0017aeb9dcc60a0e37392e83bbc51a05","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#6-12","gmt_create":"2026-05-28T18:57:12.2508741+08:00","gmt_modified":"2026-05-28T18:57:12.2508741+08:00"},{"id":425,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"0017aeb9dcc60a0e37392e83bbc51a05","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 6-12","gmt_create":"2026-05-28T18:57:12.2508741+08:00","gmt_modified":"2026-05-28T18:57:12.2508741+08:00"},{"id":426,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"0bba4121c12e2cf427dc805016fade40","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/config.go","gmt_create":"2026-05-28T18:57:12.2522309+08:00","gmt_modified":"2026-05-28T18:57:12.2522309+08:00"},{"id":427,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"4479003cf02c0690374f9f1bcaaf1505","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/config.go#1-64","gmt_create":"2026-05-28T18:57:12.2527862+08:00","gmt_modified":"2026-05-28T18:57:12.2527862+08:00"},{"id":428,"source_id":"0bba4121c12e2cf427dc805016fade40","target_id":"4479003cf02c0690374f9f1bcaaf1505","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-64","gmt_create":"2026-05-28T18:57:12.2533411+08:00","gmt_modified":"2026-05-28T18:57:12.2533411+08:00"},{"id":429,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"447b10c5efa18658d41d37a56693098e","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#33-39","gmt_create":"2026-05-28T18:57:12.2533411+08:00","gmt_modified":"2026-05-28T18:57:12.2533411+08:00"},{"id":430,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"447b10c5efa18658d41d37a56693098e","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 33-39","gmt_create":"2026-05-28T18:57:12.2538998+08:00","gmt_modified":"2026-05-28T18:57:12.2538998+08:00"},{"id":431,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"f35be7f328a7ad7a64ca3a75a47a46fe","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#69-76","gmt_create":"2026-05-28T18:57:12.2544573+08:00","gmt_modified":"2026-05-28T18:57:12.2544573+08:00"},{"id":432,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"f35be7f328a7ad7a64ca3a75a47a46fe","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 69-76","gmt_create":"2026-05-28T18:57:12.2544573+08:00","gmt_modified":"2026-05-28T18:57:12.2544573+08:00"},{"id":433,"source_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","target_id":"a7ae5a8957a835d81092a8e9c582706d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#43-46","gmt_create":"2026-05-28T18:57:12.255074+08:00","gmt_modified":"2026-05-28T18:57:12.255074+08:00"},{"id":434,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"a7ae5a8957a835d81092a8e9c582706d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 43-46","gmt_create":"2026-05-28T18:57:12.255074+08:00","gmt_modified":"2026-05-28T18:57:12.255074+08:00"},{"id":435,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/brand.go","gmt_create":"2026-05-28T18:57:39.8613227+08:00","gmt_modified":"2026-05-28T18:57:39.8613227+08:00"},{"id":436,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"b18d19ca2c60406b9cd28010df12296d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model.go","gmt_create":"2026-05-28T18:57:39.8613227+08:00","gmt_modified":"2026-05-28T18:57:39.8613227+08:00"},{"id":437,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model_list.go","gmt_create":"2026-05-28T18:57:39.8613227+08:00","gmt_modified":"2026-05-28T18:57:39.8613227+08:00"},{"id":438,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"3a1babcf090301072327433866c0d7d0","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/device.go","gmt_create":"2026-05-28T18:57:39.8613227+08:00","gmt_modified":"2026-05-28T18:57:39.8613227+08:00"},{"id":439,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"a7b9800e6fc68baa0cfda9c8f327b423","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/health.go","gmt_create":"2026-05-28T18:57:39.8613227+08:00","gmt_modified":"2026-05-28T18:57:39.8613227+08:00"},{"id":440,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d9221643d906c5ec348eb3dd51aa5536","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/ota.go","gmt_create":"2026-05-28T18:57:39.8690733+08:00","gmt_modified":"2026-05-28T18:57:39.8690733+08:00"},{"id":441,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"276b4d58e492bc3f7c258914abb959e4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/brand.go","gmt_create":"2026-05-28T18:57:39.8690733+08:00","gmt_modified":"2026-05-28T18:57:39.8690733+08:00"},{"id":442,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"4ca752eb084c575a36939921aeeb9984","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/model.go","gmt_create":"2026-05-28T18:57:39.8690733+08:00","gmt_modified":"2026-05-28T18:57:39.8690733+08:00"},{"id":443,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"88cea44c14b93a3923b010e834c82611","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/ota.go","gmt_create":"2026-05-28T18:57:39.8690733+08:00","gmt_modified":"2026-05-28T18:57:39.8690733+08:00"},{"id":444,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"703706c059a41213d3dbfbddc03fab12","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/response/response.go","gmt_create":"2026-05-28T18:57:39.8690733+08:00","gmt_modified":"2026-05-28T18:57:39.8690733+08:00"},{"id":445,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"80d716769cf67cd05b504a3bc0a06a92","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: pkg/encode/base64.go","gmt_create":"2026-05-28T18:57:39.8690733+08:00","gmt_modified":"2026-05-28T18:57:39.8690733+08:00"},{"id":446,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"a1ff50cc5809d0d712db343ab0befe3b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/search/meilisearch.go","gmt_create":"2026-05-28T18:57:39.8690733+08:00","gmt_modified":"2026-05-28T18:57:39.8690733+08:00"},{"id":447,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d2654fb48612d74ab0ccc06a3aede80b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/router/router.go","gmt_create":"2026-05-28T18:57:39.8690733+08:00","gmt_modified":"2026-05-28T18:57:39.8690733+08:00"},{"id":448,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"fd613068059c593ac4df9eaef2918055","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: cmd/server/main.go","gmt_create":"2026-05-28T18:57:39.8690733+08:00","gmt_modified":"2026-05-28T18:57:39.8690733+08:00"},{"id":449,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"0bba4121c12e2cf427dc805016fade40","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/config.go","gmt_create":"2026-05-28T18:57:39.8690733+08:00","gmt_modified":"2026-05-28T18:57:39.8690733+08:00"},{"id":450,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"f8a733666ceab6a73ba2bf3234e91222","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/logger.go","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":451,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"336527cad207564e9ea86fcc4e0ec240","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/cors.go","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":452,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"2ba2f740fa3334f7c6d51f74470ec4b7","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/middleware/request_id.go","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":453,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/brand.go","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":454,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"e9902bfcef1f5908b5123648ae6b07c6","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/model.go","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":455,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"4bac6353bbcbdf06bef53efb2db41064","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/ota.go","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":456,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"67d3253845127f03f1f9ebe3f6a6aaa3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/brand_cache.go","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":457,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"018b14cbce05561cfb50fe7e6e3835a3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/model_cache.go","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":458,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"cc70195006b7310e16886ba71ae56a22","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/ota.sql","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":459,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"44e39bd5e8e7e72cb18dae1f7aed79ce","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/black_list.sql","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":460,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"db487a51c6053d3d7a39af0bb06a5490","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/ota_target_device.sql","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":461,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"9bbbd9d83a113fbbda2d1a69b1438661","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#27-108","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":462,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"9bbbd9d83a113fbbda2d1a69b1438661","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 27-108","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":463,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"7276e457b543f75825c9e741472e998d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#16-56","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":464,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"7276e457b543f75825c9e741472e998d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 16-56","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":465,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"a5fb1691af5646ea8b4306ae97288e36","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/health.go#10","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":466,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"de87fa33e6add38c027478dd3d0cebda","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#18","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":467,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"09427d743a4be750f874418ab3e8504d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#18","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":468,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"9ebb4688793526b520ec263ebf651be7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#19","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":469,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"5e813130e7885527f77be92dbbaee9b6","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#19","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":470,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"8785d501dfce0bd258e4df37afd89055","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#19","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":471,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"8785d501dfce0bd258e4df37afd89055","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":472,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"1992aa29a2869c31fe69ac701541c6ff","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/health.go#8-19","gmt_create":"2026-05-28T18:57:39.8711227+08:00","gmt_modified":"2026-05-28T18:57:39.8711227+08:00"},{"id":473,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"692a2c6d49d4eb62f58600908dff9f60","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#13-23","gmt_create":"2026-05-28T18:57:39.8766754+08:00","gmt_modified":"2026-05-28T18:57:39.8766754+08:00"},{"id":474,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"c9df5e7b8533af65ce97cf085b6589a9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#13-23","gmt_create":"2026-05-28T18:57:39.8766754+08:00","gmt_modified":"2026-05-28T18:57:39.8766754+08:00"},{"id":475,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d2fd0586bf019047d2adbcdf90e09224","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#14-24","gmt_create":"2026-05-28T18:57:39.8766754+08:00","gmt_modified":"2026-05-28T18:57:39.8766754+08:00"},{"id":476,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"bf1f0d1dece713e866e4a46be7784473","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#14-24","gmt_create":"2026-05-28T18:57:39.8766754+08:00","gmt_modified":"2026-05-28T18:57:39.8766754+08:00"},{"id":477,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"0d14524abb861634cb9cb31154728013","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#14-21","gmt_create":"2026-05-28T18:57:39.8766754+08:00","gmt_modified":"2026-05-28T18:57:39.8766754+08:00"},{"id":478,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"0d14524abb861634cb9cb31154728013","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-21","gmt_create":"2026-05-28T18:57:39.8766754+08:00","gmt_modified":"2026-05-28T18:57:39.8766754+08:00"},{"id":479,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"1a416066a4f46116deac1ca86b956c76","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#45-52","gmt_create":"2026-05-28T18:57:39.8766754+08:00","gmt_modified":"2026-05-28T18:57:39.8766754+08:00"},{"id":480,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"1a416066a4f46116deac1ca86b956c76","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 45-52","gmt_create":"2026-05-28T18:57:39.8791862+08:00","gmt_modified":"2026-05-28T18:57:39.8791862+08:00"},{"id":481,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"bc6f53b403231c0f908654d3fea2102a","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#29","gmt_create":"2026-05-28T18:57:39.8791862+08:00","gmt_modified":"2026-05-28T18:57:39.8791862+08:00"},{"id":482,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"7b39881baafeaea08adce31120b7c1e1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#30","gmt_create":"2026-05-28T18:57:39.8797296+08:00","gmt_modified":"2026-05-28T18:57:39.8797296+08:00"},{"id":483,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"dbe385204072d26c84bf169842961690","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#37","gmt_create":"2026-05-28T18:57:39.8797296+08:00","gmt_modified":"2026-05-28T18:57:39.8797296+08:00"},{"id":484,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"2a723ed48cd9855068a04da6a33cb5e4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#71","gmt_create":"2026-05-28T18:57:39.8802716+08:00","gmt_modified":"2026-05-28T18:57:39.8802716+08:00"},{"id":485,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"4db7bd1f13a681def5b5588fd2e94047","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#57-131","gmt_create":"2026-05-28T18:57:39.8802716+08:00","gmt_modified":"2026-05-28T18:57:39.8802716+08:00"},{"id":486,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"4db7bd1f13a681def5b5588fd2e94047","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 57-131","gmt_create":"2026-05-28T18:57:39.8808032+08:00","gmt_modified":"2026-05-28T18:57:39.8808032+08:00"},{"id":487,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"9918f39149aaf1f5c3ec03275d6e3673","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#23-52","gmt_create":"2026-05-28T18:57:39.8808032+08:00","gmt_modified":"2026-05-28T18:57:39.8808032+08:00"},{"id":488,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"a19fb2ac137e43d92d2ef93e8d79f0a7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#23-79","gmt_create":"2026-05-28T18:57:39.8813299+08:00","gmt_modified":"2026-05-28T18:57:39.8813299+08:00"},{"id":489,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"20129ee27519ce09da97cb149d224c3f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/ota.go#20-158","gmt_create":"2026-05-28T18:57:39.8813299+08:00","gmt_modified":"2026-05-28T18:57:39.8813299+08:00"},{"id":490,"source_id":"88cea44c14b93a3923b010e834c82611","target_id":"20129ee27519ce09da97cb149d224c3f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-158","gmt_create":"2026-05-28T18:57:39.8813299+08:00","gmt_modified":"2026-05-28T18:57:39.8813299+08:00"},{"id":491,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d72b0eafdb65d1d946060cf944359251","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/search/meilisearch.go#22-45","gmt_create":"2026-05-28T18:57:39.881864+08:00","gmt_modified":"2026-05-28T18:57:39.881864+08:00"},{"id":492,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"fce5662f14aa6386a5036b5241e00b1c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#15-21","gmt_create":"2026-05-28T18:57:39.882384+08:00","gmt_modified":"2026-05-28T18:57:39.882384+08:00"},{"id":493,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"019fb6aa1e6ae1b643cd4ab92d2888ad","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#42","gmt_create":"2026-05-28T18:57:39.8829047+08:00","gmt_modified":"2026-05-28T18:57:39.8829047+08:00"},{"id":494,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"019fb6aa1e6ae1b643cd4ab92d2888ad","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 42","gmt_create":"2026-05-28T18:57:39.8829047+08:00","gmt_modified":"2026-05-28T18:57:39.8829047+08:00"},{"id":495,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"7e3954c3e70a9252de9cfdec52ed93c8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#25-48","gmt_create":"2026-05-28T18:57:39.8834392+08:00","gmt_modified":"2026-05-28T18:57:39.8834392+08:00"},{"id":496,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"8b0db394a538b6652de2e6634277ad0f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#14-21","gmt_create":"2026-05-28T18:57:39.8834392+08:00","gmt_modified":"2026-05-28T18:57:39.8834392+08:00"},{"id":497,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"72195f4e7a76b584cbdfbaba23db2a1a","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/brand.go#3-7","gmt_create":"2026-05-28T18:57:39.8839732+08:00","gmt_modified":"2026-05-28T18:57:39.8839732+08:00"},{"id":498,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"3e3a148f4095f6d36c64b1cfb3d1702a","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#13-48","gmt_create":"2026-05-28T18:57:39.8844989+08:00","gmt_modified":"2026-05-28T18:57:39.8844989+08:00"},{"id":499,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"a6d16b8965ed7f207f19f8f915ad53a4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#25-49","gmt_create":"2026-05-28T18:57:39.8850209+08:00","gmt_modified":"2026-05-28T18:57:39.8850209+08:00"},{"id":500,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"03f26c7c55e18e6266ea8e543a032229","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#14-21","gmt_create":"2026-05-28T18:57:39.8855454+08:00","gmt_modified":"2026-05-28T18:57:39.8855454+08:00"},{"id":501,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"3c27d9274287839faa5269c34b98b6a9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/model.go#5-15","gmt_create":"2026-05-28T18:57:39.8860804+08:00","gmt_modified":"2026-05-28T18:57:39.8860804+08:00"},{"id":502,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"e0ca219542426b9141a89063f7052b0c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#13-49","gmt_create":"2026-05-28T18:57:39.8866095+08:00","gmt_modified":"2026-05-28T18:57:39.8866095+08:00"},{"id":503,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"fce0c17d6c03e511c3afeaee662ad34f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#26-56","gmt_create":"2026-05-28T18:57:39.8871449+08:00","gmt_modified":"2026-05-28T18:57:39.8871449+08:00"},{"id":504,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"270fee7aef8f38c42409050388865f6d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: pkg/encode/base64.go#35-51","gmt_create":"2026-05-28T18:57:39.8871449+08:00","gmt_modified":"2026-05-28T18:57:39.8871449+08:00"},{"id":505,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"5db111a430cac488cabeb543494fb917","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#15-36","gmt_create":"2026-05-28T18:57:39.8876737+08:00","gmt_modified":"2026-05-28T18:57:39.8876737+08:00"},{"id":506,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"8cf065ea198e4e0d88af1863fcd6ac11","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#14-57","gmt_create":"2026-05-28T18:57:39.8876737+08:00","gmt_modified":"2026-05-28T18:57:39.8876737+08:00"},{"id":507,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d4bd0610a0ad3d8fd8d33ac5f4aa83b5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#26-84","gmt_create":"2026-05-28T18:57:39.8881994+08:00","gmt_modified":"2026-05-28T18:57:39.8881994+08:00"},{"id":508,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"b62090b5a8fe0cd95b332a46bb8eac3c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#14-85","gmt_create":"2026-05-28T18:57:39.8887279+08:00","gmt_modified":"2026-05-28T18:57:39.8887279+08:00"},{"id":509,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"9ca535f7325768d0789ea05267c44143","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#25-132","gmt_create":"2026-05-28T18:57:39.8974893+08:00","gmt_modified":"2026-05-28T18:57:39.8974893+08:00"},{"id":510,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"9ca535f7325768d0789ea05267c44143","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 25-132","gmt_create":"2026-05-28T18:57:39.898646+08:00","gmt_modified":"2026-05-28T18:57:39.898646+08:00"},{"id":511,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"83234161f284b4fd592045de95771e46","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#14-132","gmt_create":"2026-05-28T18:57:39.8992285+08:00","gmt_modified":"2026-05-28T18:57:39.8992285+08:00"},{"id":512,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"83234161f284b4fd592045de95771e46","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-132","gmt_create":"2026-05-28T18:57:39.8992285+08:00","gmt_modified":"2026-05-28T18:57:39.8992285+08:00"},{"id":513,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"1e57d4023212b9b9ffb93fc0adf1a2dc","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/ota.go#6-42","gmt_create":"2026-05-28T18:57:39.8999068+08:00","gmt_modified":"2026-05-28T18:57:39.8999068+08:00"},{"id":514,"source_id":"4bac6353bbcbdf06bef53efb2db41064","target_id":"1e57d4023212b9b9ffb93fc0adf1a2dc","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 6-42","gmt_create":"2026-05-28T18:57:39.8999068+08:00","gmt_modified":"2026-05-28T18:57:39.8999068+08:00"},{"id":515,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"ea28bb5431ebda8361d2e0c3df935805","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#77","gmt_create":"2026-05-28T18:57:39.9005351+08:00","gmt_modified":"2026-05-28T18:57:39.9005351+08:00"},{"id":516,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"ea28bb5431ebda8361d2e0c3df935805","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 77","gmt_create":"2026-05-28T18:57:39.9005351+08:00","gmt_modified":"2026-05-28T18:57:39.9005351+08:00"},{"id":517,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"5f44f3a2c10a86e7a9c3e7b2836e352d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/ota.go#11-17","gmt_create":"2026-05-28T18:57:39.9016302+08:00","gmt_modified":"2026-05-28T18:57:39.9016302+08:00"},{"id":518,"source_id":"88cea44c14b93a3923b010e834c82611","target_id":"5f44f3a2c10a86e7a9c3e7b2836e352d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 11-17","gmt_create":"2026-05-28T18:57:39.9016302+08:00","gmt_modified":"2026-05-28T18:57:39.9016302+08:00"},{"id":519,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"8fab617bba600779abac7805723180a0","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#18-24","gmt_create":"2026-05-28T18:57:39.9021542+08:00","gmt_modified":"2026-05-28T18:57:39.9021542+08:00"},{"id":520,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"006d91f2f5f75fd7cd586165c200ba98","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#19-25","gmt_create":"2026-05-28T18:57:39.9021542+08:00","gmt_modified":"2026-05-28T18:57:39.9021542+08:00"},{"id":521,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"bdfbf7d6f851540dee549606f7aca9d4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#19","gmt_create":"2026-05-28T18:57:39.9042337+08:00","gmt_modified":"2026-05-28T18:57:39.9042337+08:00"},{"id":522,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"ba4653c42534e9835fb3db39fbfd5c06","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#19","gmt_create":"2026-05-28T18:57:39.9042337+08:00","gmt_modified":"2026-05-28T18:57:39.9042337+08:00"},{"id":523,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"2e2366309b15db45b8d14e3e11f2ac87","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/ota.go#15","gmt_create":"2026-05-28T18:57:39.9047777+08:00","gmt_modified":"2026-05-28T18:57:39.9047777+08:00"},{"id":524,"source_id":"88cea44c14b93a3923b010e834c82611","target_id":"2e2366309b15db45b8d14e3e11f2ac87","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 15","gmt_create":"2026-05-28T18:57:39.9047777+08:00","gmt_modified":"2026-05-28T18:57:39.9047777+08:00"},{"id":525,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"e5c6898e570c67346c0858cfeaa98fae","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/search/meilisearch.go#17","gmt_create":"2026-05-28T18:57:39.9053048+08:00","gmt_modified":"2026-05-28T18:57:39.9053048+08:00"},{"id":526,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"90b60f9dc283b0c2610ad113bc211315","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: pkg/encode/base64.go#8","gmt_create":"2026-05-28T18:57:39.9053048+08:00","gmt_modified":"2026-05-28T18:57:39.9053048+08:00"},{"id":527,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"85820118c846a111e112dc705c071116","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#9","gmt_create":"2026-05-28T18:57:39.9058309+08:00","gmt_modified":"2026-05-28T18:57:39.9058309+08:00"},{"id":528,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"491bd71f42db0fd5bf1d4851b9c4aaa9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/health.go#14-18","gmt_create":"2026-05-28T18:57:39.9070161+08:00","gmt_modified":"2026-05-28T18:57:39.9070161+08:00"},{"id":529,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"1041284bd46edf16a19f024c113d10b4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#30-34","gmt_create":"2026-05-28T18:57:39.9075606+08:00","gmt_modified":"2026-05-28T18:57:39.9075606+08:00"},{"id":530,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"84be9fdffe58ef8cd5e77e0d3c37313b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#31-35","gmt_create":"2026-05-28T18:57:39.9075606+08:00","gmt_modified":"2026-05-28T18:57:39.9075606+08:00"},{"id":531,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"f034e5c72872862a675dd11e32404854","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#38-42","gmt_create":"2026-05-28T18:57:39.9080868+08:00","gmt_modified":"2026-05-28T18:57:39.9080868+08:00"},{"id":532,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"df50e47a5b6541093011bb59b1ec831d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#61-78","gmt_create":"2026-05-28T18:57:39.9086206+08:00","gmt_modified":"2026-05-28T18:57:39.9086206+08:00"},{"id":533,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d5d67e2167eea6a56d03ce17f78d7c15","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#58-94","gmt_create":"2026-05-28T18:57:39.9091628+08:00","gmt_modified":"2026-05-28T18:57:39.9091628+08:00"},{"id":534,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"d5d67e2167eea6a56d03ce17f78d7c15","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 58-94","gmt_create":"2026-05-28T18:57:39.9091628+08:00","gmt_modified":"2026-05-28T18:57:39.9091628+08:00"},{"id":535,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"0a425d8fed248deb7202bc7e8d531ca1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/logger.go#10-45","gmt_create":"2026-05-28T18:57:39.9096935+08:00","gmt_modified":"2026-05-28T18:57:39.9096935+08:00"},{"id":536,"source_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","target_id":"d6d27b00ae4ab42348e74a7e7bf688b2","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/middleware/request_id.go#20-31","gmt_create":"2026-05-28T18:57:39.9096935+08:00","gmt_modified":"2026-05-28T18:57:39.9096935+08:00"},{"id":537,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"fd613068059c593ac4df9eaef2918055","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: cmd/server/main.go","gmt_create":"2026-05-28T18:58:12.5335521+08:00","gmt_modified":"2026-05-28T18:58:12.5335521+08:00"},{"id":538,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"67d3253845127f03f1f9ebe3f6a6aaa3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/brand_cache.go","gmt_create":"2026-05-28T18:58:12.5335521+08:00","gmt_modified":"2026-05-28T18:58:12.5335521+08:00"},{"id":539,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"018b14cbce05561cfb50fe7e6e3835a3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/model_cache.go","gmt_create":"2026-05-28T18:58:12.5343091+08:00","gmt_modified":"2026-05-28T18:58:12.5343091+08:00"},{"id":540,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"7bfaa93c0d23eed2727039a5bd3d9a07","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/redis.go","gmt_create":"2026-05-28T18:58:12.5343091+08:00","gmt_modified":"2026-05-28T18:58:12.5343091+08:00"},{"id":541,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"0bba4121c12e2cf427dc805016fade40","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/config.go","gmt_create":"2026-05-28T18:58:12.5348215+08:00","gmt_modified":"2026-05-28T18:58:12.5348215+08:00"},{"id":542,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"ac542a8b31381c132de78b921e3216d4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/redis.go","gmt_create":"2026-05-28T18:58:12.5348215+08:00","gmt_modified":"2026-05-28T18:58:12.5348215+08:00"},{"id":543,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"d2654fb48612d74ab0ccc06a3aede80b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/router/router.go","gmt_create":"2026-05-28T18:58:12.535333+08:00","gmt_modified":"2026-05-28T18:58:12.535333+08:00"},{"id":544,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"276b4d58e492bc3f7c258914abb959e4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/brand.go","gmt_create":"2026-05-28T18:58:12.535333+08:00","gmt_modified":"2026-05-28T18:58:12.535333+08:00"},{"id":545,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"4ca752eb084c575a36939921aeeb9984","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/model.go","gmt_create":"2026-05-28T18:58:12.5358687+08:00","gmt_modified":"2026-05-28T18:58:12.5358687+08:00"},{"id":546,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/brand.go","gmt_create":"2026-05-28T18:58:12.5358687+08:00","gmt_modified":"2026-05-28T18:58:12.5358687+08:00"},{"id":547,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"b18d19ca2c60406b9cd28010df12296d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model.go","gmt_create":"2026-05-28T18:58:12.5358687+08:00","gmt_modified":"2026-05-28T18:58:12.5358687+08:00"},{"id":548,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/brand.go","gmt_create":"2026-05-28T18:58:12.5364244+08:00","gmt_modified":"2026-05-28T18:58:12.5364244+08:00"},{"id":549,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"e9902bfcef1f5908b5123648ae6b07c6","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/model.go","gmt_create":"2026-05-28T18:58:12.5364244+08:00","gmt_modified":"2026-05-28T18:58:12.5364244+08:00"},{"id":550,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"47165ac2566e8b2d3796014bdb75361f","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: go.mod","gmt_create":"2026-05-28T18:58:12.5364244+08:00","gmt_modified":"2026-05-28T18:58:12.5364244+08:00"},{"id":551,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"e9390185152783a55f55e277d45e6948","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#25-131","gmt_create":"2026-05-28T18:58:12.5369746+08:00","gmt_modified":"2026-05-28T18:58:12.5369746+08:00"},{"id":552,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a3cbc373dacd9d032ed0c72bca1e51e9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#1-45","gmt_create":"2026-05-28T18:58:12.5369746+08:00","gmt_modified":"2026-05-28T18:58:12.5369746+08:00"},{"id":553,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"d65e653afb8b211f2e5a7845f72b45dd","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#1-70","gmt_create":"2026-05-28T18:58:12.537526+08:00","gmt_modified":"2026-05-28T18:58:12.537526+08:00"},{"id":554,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a26d903ac77196fac97ddebf48638ab3","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#1-100","gmt_create":"2026-05-28T18:58:12.537526+08:00","gmt_modified":"2026-05-28T18:58:12.537526+08:00"},{"id":555,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"7ffaf7b06ea96ca93862aa0dae926ff5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#1-181","gmt_create":"2026-05-28T18:58:12.5380638+08:00","gmt_modified":"2026-05-28T18:58:12.5380638+08:00"},{"id":556,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"187b4628003859e3da78f3937c686803","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#18-45","gmt_create":"2026-05-28T18:58:12.539131+08:00","gmt_modified":"2026-05-28T18:58:12.539131+08:00"},{"id":557,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a6c526ea58aabee86ae3010b00441c69","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#19-70","gmt_create":"2026-05-28T18:58:12.5396676+08:00","gmt_modified":"2026-05-28T18:58:12.5396676+08:00"},{"id":558,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a364a8daa183eaf86417b4c1bd2cc719","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#14-100","gmt_create":"2026-05-28T18:58:12.5396676+08:00","gmt_modified":"2026-05-28T18:58:12.5396676+08:00"},{"id":559,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"2e040aabeb8e907eaddc6bbf2ee493ac","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#14-181","gmt_create":"2026-05-28T18:58:12.540194+08:00","gmt_modified":"2026-05-28T18:58:12.540194+08:00"},{"id":560,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"3d315320639ece8212fd138420d94be5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#13-49","gmt_create":"2026-05-28T18:58:12.540194+08:00","gmt_modified":"2026-05-28T18:58:12.540194+08:00"},{"id":561,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"fbf36e29345cd3e53fd3a6e8234ad2de","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#13-50","gmt_create":"2026-05-28T18:58:12.5407198+08:00","gmt_modified":"2026-05-28T18:58:12.5407198+08:00"},{"id":562,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"9918f39149aaf1f5c3ec03275d6e3673","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#23-52","gmt_create":"2026-05-28T18:58:12.5412471+08:00","gmt_modified":"2026-05-28T18:58:12.5412471+08:00"},{"id":563,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a19fb2ac137e43d92d2ef93e8d79f0a7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#23-79","gmt_create":"2026-05-28T18:58:12.5412471+08:00","gmt_modified":"2026-05-28T18:58:12.5412471+08:00"},{"id":564,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"32b7267a28b0347d59500c38ffa96a7b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#13-45","gmt_create":"2026-05-28T18:58:12.5423027+08:00","gmt_modified":"2026-05-28T18:58:12.5423027+08:00"},{"id":565,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"b9c3c517ffd917351757137ca1338574","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#27-69","gmt_create":"2026-05-28T18:58:12.5423027+08:00","gmt_modified":"2026-05-28T18:58:12.5423027+08:00"},{"id":566,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"df7d264896976fc8c5475257994c707e","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#13-70","gmt_create":"2026-05-28T18:58:12.5428249+08:00","gmt_modified":"2026-05-28T18:58:12.5428249+08:00"},{"id":567,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a3b89d2e56d589f8d902fb9389004bf0","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#103-131","gmt_create":"2026-05-28T18:58:12.5428249+08:00","gmt_modified":"2026-05-28T18:58:12.5428249+08:00"},{"id":568,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"f76ee32725201731512db1e0e7951586","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#67-68","gmt_create":"2026-05-28T18:58:12.5433511+08:00","gmt_modified":"2026-05-28T18:58:12.5433511+08:00"},{"id":569,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"251d1b1dc197a1dc242f5384adb1555c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#34-52","gmt_create":"2026-05-28T18:58:12.5438732+08:00","gmt_modified":"2026-05-28T18:58:12.5438732+08:00"},{"id":570,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a51abc6a6d80413bf60f143cd1f46ee4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#27-79","gmt_create":"2026-05-28T18:58:12.5438732+08:00","gmt_modified":"2026-05-28T18:58:12.5438732+08:00"},{"id":571,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"eefeaf126e13951935424f7f3c210854","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#44-51","gmt_create":"2026-05-28T18:58:12.5443946+08:00","gmt_modified":"2026-05-28T18:58:12.5443946+08:00"},{"id":572,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"eefeaf126e13951935424f7f3c210854","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 44-51","gmt_create":"2026-05-28T18:58:12.5443946+08:00","gmt_modified":"2026-05-28T18:58:12.5443946+08:00"},{"id":573,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"96c652126052e611e9602571014fb2fe","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#44-74","gmt_create":"2026-05-28T18:58:12.5443946+08:00","gmt_modified":"2026-05-28T18:58:12.5443946+08:00"},{"id":574,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"96c652126052e611e9602571014fb2fe","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 44-74","gmt_create":"2026-05-28T18:58:12.5449147+08:00","gmt_modified":"2026-05-28T18:58:12.5449147+08:00"},{"id":575,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"62d02336da9111eec3c5696aabf71927","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#13-16","gmt_create":"2026-05-28T18:58:12.5449147+08:00","gmt_modified":"2026-05-28T18:58:12.5449147+08:00"},{"id":576,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"f0b044854c85d50b2d1ba4b9d3e6a6cb","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#13-17","gmt_create":"2026-05-28T18:58:12.5455095+08:00","gmt_modified":"2026-05-28T18:58:12.5455095+08:00"},{"id":577,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"3f0d637bef43d636594a4816c9da037e","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#38-44","gmt_create":"2026-05-28T18:58:12.5455095+08:00","gmt_modified":"2026-05-28T18:58:12.5455095+08:00"},{"id":578,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"3f945faea776f513b5294aa60759fb15","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#43-69","gmt_create":"2026-05-28T18:58:12.5455095+08:00","gmt_modified":"2026-05-28T18:58:12.5455095+08:00"},{"id":579,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a272829cfc9c48e8063d8bca53cdebc8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#13-23","gmt_create":"2026-05-28T18:58:12.5465301+08:00","gmt_modified":"2026-05-28T18:58:12.5465301+08:00"},{"id":580,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"6d2fece0c97147748fd0269a356e4802","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#3-12","gmt_create":"2026-05-28T18:58:12.5465301+08:00","gmt_modified":"2026-05-28T18:58:12.5465301+08:00"},{"id":581,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"282a046f62f9715bfef882f5a4a6a362","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#3-14","gmt_create":"2026-05-28T18:58:12.5465301+08:00","gmt_modified":"2026-05-28T18:58:12.5465301+08:00"},{"id":582,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"7e3954c3e70a9252de9cfdec52ed93c8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#25-48","gmt_create":"2026-05-28T18:58:12.5480638+08:00","gmt_modified":"2026-05-28T18:58:12.5480638+08:00"},{"id":583,"source_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","target_id":"a6d16b8965ed7f207f19f8f915ad53a4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#25-49","gmt_create":"2026-05-28T18:58:12.5480638+08:00","gmt_modified":"2026-05-28T18:58:12.5480638+08:00"},{"id":584,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"276b4d58e492bc3f7c258914abb959e4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/brand.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":585,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"4ca752eb084c575a36939921aeeb9984","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/model.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":586,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"9889a3ce458e1d193f3188d12fb4ffe8","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/device.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":587,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"88cea44c14b93a3923b010e834c82611","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/ota.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":588,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"67d3253845127f03f1f9ebe3f6a6aaa3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/brand_cache.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":589,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"018b14cbce05561cfb50fe7e6e3835a3","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/model_cache.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":590,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"7bfaa93c0d23eed2727039a5bd3d9a07","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/redis.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":591,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/database/mysql.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":592,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"a0a3a762dc85a8d8c5bb359f5c523def","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/database.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":593,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"ac542a8b31381c132de78b921e3216d4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/redis.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":594,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"0bba4121c12e2cf427dc805016fade40","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/config.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":595,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/brand.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":596,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"e9902bfcef1f5908b5123648ae6b07c6","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/model.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":597,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"40076534e5136a5edb8c4665ebafe2bd","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/user_device.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":598,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"7667f4c1d3eabf712a8e93d02391fbaa","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/user_active.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":599,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"4bac6353bbcbdf06bef53efb2db41064","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/ota.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":600,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/brand.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":601,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"b18d19ca2c60406b9cd28010df12296d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":602,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"3a1babcf090301072327433866c0d7d0","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/device.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":603,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"d9221643d906c5ec348eb3dd51aa5536","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/ota.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":604,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"d2654fb48612d74ab0ccc06a3aede80b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/router/router.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":605,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"7578d2fdc704b288be4b4a6cf9f8a192","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/task/device_persist.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":606,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"fd613068059c593ac4df9eaef2918055","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: cmd/server/main.go","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":607,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"c56e5254bd7f42350c5261822fa135bb","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/model.sql","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":608,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"2c0dedcdaa9c3a7a39fa12d838894bd4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/user_device.sql","gmt_create":"2026-05-28T18:58:34.8408194+08:00","gmt_modified":"2026-05-28T18:58:34.8408194+08:00"},{"id":609,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"0c676c4075ac3b554f5c006c4ac29b24","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/user_active.sql","gmt_create":"2026-05-28T18:58:34.8473819+08:00","gmt_modified":"2026-05-28T18:58:34.8473819+08:00"},{"id":610,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"cc70195006b7310e16886ba71ae56a22","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/ota.sql","gmt_create":"2026-05-28T18:58:34.8473819+08:00","gmt_modified":"2026-05-28T18:58:34.8473819+08:00"},{"id":611,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"db487a51c6053d3d7a39af0bb06a5490","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/ota_target_device.sql","gmt_create":"2026-05-28T18:58:34.8473819+08:00","gmt_modified":"2026-05-28T18:58:34.8473819+08:00"},{"id":612,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"47165ac2566e8b2d3796014bdb75361f","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: go.mod","gmt_create":"2026-05-28T18:58:34.8473819+08:00","gmt_modified":"2026-05-28T18:58:34.8473819+08:00"},{"id":613,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"e88b0ee062bd02dd7acdf8e2e945b270","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#103-130","gmt_create":"2026-05-28T18:58:34.8473819+08:00","gmt_modified":"2026-05-28T18:58:34.8473819+08:00"},{"id":614,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"64381887b12f6927d8b0481a55c2dcf1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#22-25","gmt_create":"2026-05-28T18:58:34.8484111+08:00","gmt_modified":"2026-05-28T18:58:34.8484111+08:00"},{"id":615,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"1503a99bb2f2ab96e4a3a830d8834e45","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#19-24","gmt_create":"2026-05-28T18:58:34.8484111+08:00","gmt_modified":"2026-05-28T18:58:34.8484111+08:00"},{"id":616,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"f74cdc773e62a1a9f5a4bf940b5961e3","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#19-24","gmt_create":"2026-05-28T18:58:34.8484111+08:00","gmt_modified":"2026-05-28T18:58:34.8484111+08:00"},{"id":617,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"6eea881f59ef13b1dd4c56cfec810c13","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#15-25","gmt_create":"2026-05-28T18:58:34.8484111+08:00","gmt_modified":"2026-05-28T18:58:34.8484111+08:00"},{"id":618,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"0d14524abb861634cb9cb31154728013","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#14-21","gmt_create":"2026-05-28T18:58:34.8605896+08:00","gmt_modified":"2026-05-28T18:58:34.8605896+08:00"},{"id":619,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"8b0db394a538b6652de2e6634277ad0f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#14-21","gmt_create":"2026-05-28T18:58:34.8623518+08:00","gmt_modified":"2026-05-28T18:58:34.8623518+08:00"},{"id":620,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"03f26c7c55e18e6266ea8e543a032229","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#14-21","gmt_create":"2026-05-28T18:58:34.8623518+08:00","gmt_modified":"2026-05-28T18:58:34.8623518+08:00"},{"id":621,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"b799030cefcf1745645d8e74f4bd2042","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/device.go#11-17","gmt_create":"2026-05-28T18:58:34.8628933+08:00","gmt_modified":"2026-05-28T18:58:34.8628933+08:00"},{"id":622,"source_id":"9889a3ce458e1d193f3188d12fb4ffe8","target_id":"b799030cefcf1745645d8e74f4bd2042","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 11-17","gmt_create":"2026-05-28T18:58:34.8628933+08:00","gmt_modified":"2026-05-28T18:58:34.8628933+08:00"},{"id":623,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"5f44f3a2c10a86e7a9c3e7b2836e352d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/ota.go#11-17","gmt_create":"2026-05-28T18:58:34.8634497+08:00","gmt_modified":"2026-05-28T18:58:34.8634497+08:00"},{"id":624,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"8fab617bba600779abac7805723180a0","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#18-24","gmt_create":"2026-05-28T18:58:34.8641283+08:00","gmt_modified":"2026-05-28T18:58:34.8641283+08:00"},{"id":625,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"006d91f2f5f75fd7cd586165c200ba98","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#19-25","gmt_create":"2026-05-28T18:58:34.8641283+08:00","gmt_modified":"2026-05-28T18:58:34.8641283+08:00"},{"id":626,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"509525e0463c03c509709a6bd1765d4f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/redis.go#10-16","gmt_create":"2026-05-28T18:58:34.8646751+08:00","gmt_modified":"2026-05-28T18:58:34.8646751+08:00"},{"id":627,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"57b8aed283762226a00482b42a8acf5b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/database/mysql.go#14-46","gmt_create":"2026-05-28T18:58:34.8651997+08:00","gmt_modified":"2026-05-28T18:58:34.8651997+08:00"},{"id":628,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"4ab082407b96e18f67a65d07eb4a331d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/database.go#17-40","gmt_create":"2026-05-28T18:58:34.8651997+08:00","gmt_modified":"2026-05-28T18:58:34.8651997+08:00"},{"id":629,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"fd2a12d243b52512003ae067f53a7548","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/redis.go#9-57","gmt_create":"2026-05-28T18:58:34.8657256+08:00","gmt_modified":"2026-05-28T18:58:34.8657256+08:00"},{"id":630,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"61d69bf4d3c8c548eecfd677394486d6","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/config.go#18-52","gmt_create":"2026-05-28T18:58:34.8662517+08:00","gmt_modified":"2026-05-28T18:58:34.8662517+08:00"},{"id":631,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"ccf4922f5428b8f0159ce891bcc0cfb1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#14-22","gmt_create":"2026-05-28T18:58:34.8662517+08:00","gmt_modified":"2026-05-28T18:58:34.8662517+08:00"},{"id":632,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"e87c932ace50951cb91aa66877ad6f81","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/model.sql#24-35","gmt_create":"2026-05-28T18:58:34.8667742+08:00","gmt_modified":"2026-05-28T18:58:34.8667742+08:00"},{"id":633,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"90cda5d453d8a36d34f0bb16bf3b22d4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_device.sql#23-32","gmt_create":"2026-05-28T18:58:34.8673082+08:00","gmt_modified":"2026-05-28T18:58:34.8673082+08:00"},{"id":634,"source_id":"2c0dedcdaa9c3a7a39fa12d838894bd4","target_id":"90cda5d453d8a36d34f0bb16bf3b22d4","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-32","gmt_create":"2026-05-28T18:58:34.8673082+08:00","gmt_modified":"2026-05-28T18:58:34.8673082+08:00"},{"id":635,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"169d98ec7c47a41d541c28ef27876ab1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_active.sql#23-32","gmt_create":"2026-05-28T18:58:34.8678332+08:00","gmt_modified":"2026-05-28T18:58:34.8678332+08:00"},{"id":636,"source_id":"0c676c4075ac3b554f5c006c4ac29b24","target_id":"169d98ec7c47a41d541c28ef27876ab1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-32","gmt_create":"2026-05-28T18:58:34.8678332+08:00","gmt_modified":"2026-05-28T18:58:34.8678332+08:00"},{"id":637,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"3e86caf95903a24c6393bc96880f7951","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/ota.sql#23-44","gmt_create":"2026-05-28T18:58:34.8678332+08:00","gmt_modified":"2026-05-28T18:58:34.8678332+08:00"},{"id":638,"source_id":"cc70195006b7310e16886ba71ae56a22","target_id":"3e86caf95903a24c6393bc96880f7951","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-44","gmt_create":"2026-05-28T18:58:34.8683555+08:00","gmt_modified":"2026-05-28T18:58:34.8683555+08:00"},{"id":639,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"59f1d79949230d387b6ad48a329cc0f7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/ota_target_device.sql#23-31","gmt_create":"2026-05-28T18:58:34.8683555+08:00","gmt_modified":"2026-05-28T18:58:34.8683555+08:00"},{"id":640,"source_id":"db487a51c6053d3d7a39af0bb06a5490","target_id":"59f1d79949230d387b6ad48a329cc0f7","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-31","gmt_create":"2026-05-28T18:58:34.8688771+08:00","gmt_modified":"2026-05-28T18:58:34.8688771+08:00"},{"id":641,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"c73149ce118775bda8abbe6ef4cfd663","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#14-56","gmt_create":"2026-05-28T18:58:34.8688771+08:00","gmt_modified":"2026-05-28T18:58:34.8688771+08:00"},{"id":642,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"c73149ce118775bda8abbe6ef4cfd663","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-56","gmt_create":"2026-05-28T18:58:34.8693994+08:00","gmt_modified":"2026-05-28T18:58:34.8693994+08:00"},{"id":643,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"9918f39149aaf1f5c3ec03275d6e3673","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#23-52","gmt_create":"2026-05-28T18:58:34.8730733+08:00","gmt_modified":"2026-05-28T18:58:34.8730733+08:00"},{"id":644,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"a19fb2ac137e43d92d2ef93e8d79f0a7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#23-79","gmt_create":"2026-05-28T18:58:34.873598+08:00","gmt_modified":"2026-05-28T18:58:34.873598+08:00"},{"id":645,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"ebe1ad8e2e447d1c8784d0338fb5ff44","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/device.go#11-88","gmt_create":"2026-05-28T18:58:34.874123+08:00","gmt_modified":"2026-05-28T18:58:34.874123+08:00"},{"id":646,"source_id":"9889a3ce458e1d193f3188d12fb4ffe8","target_id":"ebe1ad8e2e447d1c8784d0338fb5ff44","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 11-88","gmt_create":"2026-05-28T18:58:34.874123+08:00","gmt_modified":"2026-05-28T18:58:34.874123+08:00"},{"id":647,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"8fff9ab89b194aaf50c08418f14e7d5d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/ota.go#11-159","gmt_create":"2026-05-28T18:58:34.874123+08:00","gmt_modified":"2026-05-28T18:58:34.874123+08:00"},{"id":648,"source_id":"88cea44c14b93a3923b010e834c82611","target_id":"8fff9ab89b194aaf50c08418f14e7d5d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 11-159","gmt_create":"2026-05-28T18:58:34.8746432+08:00","gmt_modified":"2026-05-28T18:58:34.8746432+08:00"},{"id":649,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"72322f320f907b6eec72e885e30759eb","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#26-44","gmt_create":"2026-05-28T18:58:34.8746432+08:00","gmt_modified":"2026-05-28T18:58:34.8746432+08:00"},{"id":650,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"d0f658c42abae9b6dc0baaa8fc7d0694","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#31-69","gmt_create":"2026-05-28T18:58:34.8751688+08:00","gmt_modified":"2026-05-28T18:58:34.8751688+08:00"},{"id":651,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"3cab00ffcb36143e0a8fa39bc345dc5b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#14-167","gmt_create":"2026-05-28T18:58:34.8751688+08:00","gmt_modified":"2026-05-28T18:58:34.8751688+08:00"},{"id":652,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"3cab00ffcb36143e0a8fa39bc345dc5b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-167","gmt_create":"2026-05-28T18:58:34.8756906+08:00","gmt_modified":"2026-05-28T18:58:34.8756906+08:00"},{"id":653,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"a952e5d5b625754a2e9249983bb8abaa","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/database.go#17-72","gmt_create":"2026-05-28T18:58:34.8762196+08:00","gmt_modified":"2026-05-28T18:58:34.8762196+08:00"},{"id":654,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"f7af3a1998c24f922aa650a69b252734","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/redis.go#16-57","gmt_create":"2026-05-28T18:58:34.8762196+08:00","gmt_modified":"2026-05-28T18:58:34.8762196+08:00"},{"id":655,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"a60b5eaffad0d59addb5be3ce07dcfe8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#27-82","gmt_create":"2026-05-28T18:58:34.8772904+08:00","gmt_modified":"2026-05-28T18:58:34.8772904+08:00"},{"id":656,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"a60b5eaffad0d59addb5be3ce07dcfe8","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 27-82","gmt_create":"2026-05-28T18:58:34.8778152+08:00","gmt_modified":"2026-05-28T18:58:34.8778152+08:00"},{"id":657,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"7dda8c14930e069827e3ba2382731089","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#23-132","gmt_create":"2026-05-28T18:58:34.8778152+08:00","gmt_modified":"2026-05-28T18:58:34.8778152+08:00"},{"id":658,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"7dda8c14930e069827e3ba2382731089","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-132","gmt_create":"2026-05-28T18:58:34.8783365+08:00","gmt_modified":"2026-05-28T18:58:34.8783365+08:00"},{"id":659,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"8ef952b9859313cbfc946824f3307d9d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/device.go#19-87","gmt_create":"2026-05-28T18:58:34.8783365+08:00","gmt_modified":"2026-05-28T18:58:34.8783365+08:00"},{"id":660,"source_id":"9889a3ce458e1d193f3188d12fb4ffe8","target_id":"8ef952b9859313cbfc946824f3307d9d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-87","gmt_create":"2026-05-28T18:58:34.8790931+08:00","gmt_modified":"2026-05-28T18:58:34.8790931+08:00"},{"id":661,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"51316f98b99990e17b496035eb09f026","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/ota.go#19-158","gmt_create":"2026-05-28T18:58:34.8790931+08:00","gmt_modified":"2026-05-28T18:58:34.8790931+08:00"},{"id":662,"source_id":"88cea44c14b93a3923b010e834c82611","target_id":"51316f98b99990e17b496035eb09f026","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-158","gmt_create":"2026-05-28T18:58:34.8790931+08:00","gmt_modified":"2026-05-28T18:58:34.8790931+08:00"},{"id":663,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"46f122a322e257db9d295df514f3a0eb","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#37-91","gmt_create":"2026-05-28T18:58:34.8796191+08:00","gmt_modified":"2026-05-28T18:58:34.8796191+08:00"},{"id":664,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"c7bf654a5faf00b02953d2e56747a669","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/database/mysql.go#28-43","gmt_create":"2026-05-28T18:58:34.8801355+08:00","gmt_modified":"2026-05-28T18:58:34.8801355+08:00"},{"id":665,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"1d3714bd55d5d3f773f1ab7fdb8c9b53","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/brand.go#3-6","gmt_create":"2026-05-28T18:58:34.8806748+08:00","gmt_modified":"2026-05-28T18:58:34.8806748+08:00"},{"id":666,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"8d92ac14c6257462a15eb6990dd44596","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/model.go#5-14","gmt_create":"2026-05-28T18:58:34.882294+08:00","gmt_modified":"2026-05-28T18:58:34.882294+08:00"},{"id":667,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"8b134235408cf40b9d6351d54591b3c4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/model.sql#34","gmt_create":"2026-05-28T18:58:34.8828291+08:00","gmt_modified":"2026-05-28T18:58:34.8828291+08:00"},{"id":668,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"3086af04dfecbda4da76dc885b16803c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/user_device.go#5-11","gmt_create":"2026-05-28T18:58:34.8833656+08:00","gmt_modified":"2026-05-28T18:58:34.8833656+08:00"},{"id":669,"source_id":"40076534e5136a5edb8c4665ebafe2bd","target_id":"3086af04dfecbda4da76dc885b16803c","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 5-11","gmt_create":"2026-05-28T18:58:34.8838893+08:00","gmt_modified":"2026-05-28T18:58:34.8838893+08:00"},{"id":670,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"37797d6a2ea3a02b54e63ae9da6d2538","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/user_active.go#5-12","gmt_create":"2026-05-28T18:58:34.8838893+08:00","gmt_modified":"2026-05-28T18:58:34.8838893+08:00"},{"id":671,"source_id":"7667f4c1d3eabf712a8e93d02391fbaa","target_id":"37797d6a2ea3a02b54e63ae9da6d2538","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 5-12","gmt_create":"2026-05-28T18:58:34.8838893+08:00","gmt_modified":"2026-05-28T18:58:34.8838893+08:00"},{"id":672,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"1e57d4023212b9b9ffb93fc0adf1a2dc","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/ota.go#6-42","gmt_create":"2026-05-28T18:58:34.8860424+08:00","gmt_modified":"2026-05-28T18:58:34.8860424+08:00"},{"id":673,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"cd00b1806e2c98e0bb5dffa98190dcc9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#24-91","gmt_create":"2026-05-28T18:58:34.8871595+08:00","gmt_modified":"2026-05-28T18:58:34.8871595+08:00"},{"id":674,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"cd00b1806e2c98e0bb5dffa98190dcc9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 24-91","gmt_create":"2026-05-28T18:58:34.8871595+08:00","gmt_modified":"2026-05-28T18:58:34.8871595+08:00"},{"id":675,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"7e3954c3e70a9252de9cfdec52ed93c8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#25-48","gmt_create":"2026-05-28T18:58:34.8893561+08:00","gmt_modified":"2026-05-28T18:58:34.8893561+08:00"},{"id":676,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"a6d16b8965ed7f207f19f8f915ad53a4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#25-49","gmt_create":"2026-05-28T18:58:34.8893561+08:00","gmt_modified":"2026-05-28T18:58:34.8893561+08:00"},{"id":677,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"62d02336da9111eec3c5696aabf71927","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/brand_cache.go#13-16","gmt_create":"2026-05-28T18:58:34.8904043+08:00","gmt_modified":"2026-05-28T18:58:34.8904043+08:00"},{"id":678,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"a60ecb63d9ab3bda0c5042f26916def3","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/model_cache.go#13-16","gmt_create":"2026-05-28T18:58:34.8904043+08:00","gmt_modified":"2026-05-28T18:58:34.8904043+08:00"},{"id":679,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"5859dc43ab95b589fc2cada49ab59a86","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: go.mod#5-11","gmt_create":"2026-05-28T18:58:34.8919222+08:00","gmt_modified":"2026-05-28T18:58:34.8919222+08:00"},{"id":680,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"dcc3acd0529002f62657a37922318e37","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#25-69","gmt_create":"2026-05-28T18:58:34.8919222+08:00","gmt_modified":"2026-05-28T18:58:34.8919222+08:00"},{"id":681,"source_id":"599c0bda-3332-415c-a535-362503079473","target_id":"99ead368ce42f1081e05c800c65b176f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/database/mysql.go#33-43","gmt_create":"2026-05-28T18:58:34.8948442+08:00","gmt_modified":"2026-05-28T18:58:34.8948442+08:00"},{"id":682,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/brand.go","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":683,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"e9902bfcef1f5908b5123648ae6b07c6","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/model.go","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":684,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"c56e5254bd7f42350c5261822fa135bb","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/model.sql","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":685,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"276b4d58e492bc3f7c258914abb959e4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/brand.go","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":686,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"4ca752eb084c575a36939921aeeb9984","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/model.go","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":687,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/brand.go","gmt_create":"2026-05-28T19:00:07.1584814+08:00","gmt_modified":"2026-05-28T19:00:07.1584814+08:00"},{"id":688,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"b18d19ca2c60406b9cd28010df12296d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model.go","gmt_create":"2026-05-28T19:00:07.1638589+08:00","gmt_modified":"2026-05-28T19:00:07.1638589+08:00"},{"id":689,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"0bba4121c12e2cf427dc805016fade40","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/config.go","gmt_create":"2026-05-28T19:00:07.1638589+08:00","gmt_modified":"2026-05-28T19:00:07.1638589+08:00"},{"id":690,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"a0a3a762dc85a8d8c5bb359f5c523def","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/database.go","gmt_create":"2026-05-28T19:00:07.1638589+08:00","gmt_modified":"2026-05-28T19:00:07.1638589+08:00"},{"id":691,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"d2c7a50459a83c5ef23e809b0f194aba","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/meilisearch.go","gmt_create":"2026-05-28T19:00:07.1638589+08:00","gmt_modified":"2026-05-28T19:00:07.1638589+08:00"},{"id":692,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"ac542a8b31381c132de78b921e3216d4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/redis.go","gmt_create":"2026-05-28T19:00:07.1638589+08:00","gmt_modified":"2026-05-28T19:00:07.1638589+08:00"},{"id":693,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/database/mysql.go","gmt_create":"2026-05-28T19:00:07.1638589+08:00","gmt_modified":"2026-05-28T19:00:07.1638589+08:00"},{"id":694,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"7bfaa93c0d23eed2727039a5bd3d9a07","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/cache/redis.go","gmt_create":"2026-05-28T19:00:07.1638589+08:00","gmt_modified":"2026-05-28T19:00:07.1638589+08:00"},{"id":695,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"a1ff50cc5809d0d712db343ab0befe3b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/search/meilisearch.go","gmt_create":"2026-05-28T19:00:07.1638589+08:00","gmt_modified":"2026-05-28T19:00:07.1638589+08:00"},{"id":696,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"fd613068059c593ac4df9eaef2918055","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: cmd/server/main.go","gmt_create":"2026-05-28T19:00:07.1638589+08:00","gmt_modified":"2026-05-28T19:00:07.1638589+08:00"},{"id":697,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"2c0dedcdaa9c3a7a39fa12d838894bd4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/user_device.sql","gmt_create":"2026-05-28T19:00:07.1656614+08:00","gmt_modified":"2026-05-28T19:00:07.1656614+08:00"},{"id":698,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"0c676c4075ac3b554f5c006c4ac29b24","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/user_active.sql","gmt_create":"2026-05-28T19:00:07.1656614+08:00","gmt_modified":"2026-05-28T19:00:07.1656614+08:00"},{"id":699,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"cc70195006b7310e16886ba71ae56a22","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/ota.sql","gmt_create":"2026-05-28T19:00:07.1656614+08:00","gmt_modified":"2026-05-28T19:00:07.1656614+08:00"},{"id":700,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"44e39bd5e8e7e72cb18dae1f7aed79ce","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/black_list.sql","gmt_create":"2026-05-28T19:00:07.1656614+08:00","gmt_modified":"2026-05-28T19:00:07.1656614+08:00"},{"id":701,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"db487a51c6053d3d7a39af0bb06a5490","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/ota_target_device.sql","gmt_create":"2026-05-28T19:00:07.1656614+08:00","gmt_modified":"2026-05-28T19:00:07.1656614+08:00"},{"id":702,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"40076534e5136a5edb8c4665ebafe2bd","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/user_device.go","gmt_create":"2026-05-28T19:00:07.1656614+08:00","gmt_modified":"2026-05-28T19:00:07.1656614+08:00"},{"id":703,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"7667f4c1d3eabf712a8e93d02391fbaa","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/user_active.go","gmt_create":"2026-05-28T19:00:07.1656614+08:00","gmt_modified":"2026-05-28T19:00:07.1656614+08:00"},{"id":704,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"4bac6353bbcbdf06bef53efb2db41064","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/ota.go","gmt_create":"2026-05-28T19:00:07.1656614+08:00","gmt_modified":"2026-05-28T19:00:07.1656614+08:00"},{"id":705,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"9889a3ce458e1d193f3188d12fb4ffe8","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/device.go","gmt_create":"2026-05-28T19:00:07.1656614+08:00","gmt_modified":"2026-05-28T19:00:07.1656614+08:00"},{"id":706,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"88cea44c14b93a3923b010e834c82611","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/ota.go","gmt_create":"2026-05-28T19:00:07.1656614+08:00","gmt_modified":"2026-05-28T19:00:07.1656614+08:00"},{"id":707,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"3a1babcf090301072327433866c0d7d0","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/device.go","gmt_create":"2026-05-28T19:00:07.1676661+08:00","gmt_modified":"2026-05-28T19:00:07.1676661+08:00"},{"id":708,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"d9221643d906c5ec348eb3dd51aa5536","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/ota.go","gmt_create":"2026-05-28T19:00:07.1676661+08:00","gmt_modified":"2026-05-28T19:00:07.1676661+08:00"},{"id":709,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"7578d2fdc704b288be4b4a6cf9f8a192","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/task/device_persist.go","gmt_create":"2026-05-28T19:00:07.1676661+08:00","gmt_modified":"2026-05-28T19:00:07.1676661+08:00"},{"id":710,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"e1ebf7d9c7e51f6e897d985f8ee6c72d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#1-96","gmt_create":"2026-05-28T19:00:07.1676661+08:00","gmt_modified":"2026-05-28T19:00:07.1676661+08:00"},{"id":711,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"e1ebf7d9c7e51f6e897d985f8ee6c72d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-96","gmt_create":"2026-05-28T19:00:07.1686735+08:00","gmt_modified":"2026-05-28T19:00:07.1686735+08:00"},{"id":712,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"4479003cf02c0690374f9f1bcaaf1505","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/config.go#1-64","gmt_create":"2026-05-28T19:00:07.1686735+08:00","gmt_modified":"2026-05-28T19:00:07.1686735+08:00"},{"id":713,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"69055b7e39d8b5d596ead1dc41f98c6e","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/database.go#1-72","gmt_create":"2026-05-28T19:00:07.1692636+08:00","gmt_modified":"2026-05-28T19:00:07.1692636+08:00"},{"id":714,"source_id":"a0a3a762dc85a8d8c5bb359f5c523def","target_id":"69055b7e39d8b5d596ead1dc41f98c6e","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-72","gmt_create":"2026-05-28T19:00:07.1692636+08:00","gmt_modified":"2026-05-28T19:00:07.1692636+08:00"},{"id":715,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"c377b29231ed9b2f9403faac5b050cb8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/meilisearch.go#1-51","gmt_create":"2026-05-28T19:00:07.1692636+08:00","gmt_modified":"2026-05-28T19:00:07.1692636+08:00"},{"id":716,"source_id":"d2c7a50459a83c5ef23e809b0f194aba","target_id":"c377b29231ed9b2f9403faac5b050cb8","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-51","gmt_create":"2026-05-28T19:00:07.1692636+08:00","gmt_modified":"2026-05-28T19:00:07.1692636+08:00"},{"id":717,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"29a90b3c32979664ded642e5896eb3d5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/redis.go#1-57","gmt_create":"2026-05-28T19:00:07.174785+08:00","gmt_modified":"2026-05-28T19:00:07.174785+08:00"},{"id":718,"source_id":"ac542a8b31381c132de78b921e3216d4","target_id":"29a90b3c32979664ded642e5896eb3d5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-57","gmt_create":"2026-05-28T19:00:07.174785+08:00","gmt_modified":"2026-05-28T19:00:07.174785+08:00"},{"id":719,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"2bc32e7e8a7fa666b1c1222c91819271","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/database/mysql.go#1-47","gmt_create":"2026-05-28T19:00:07.174785+08:00","gmt_modified":"2026-05-28T19:00:07.174785+08:00"},{"id":720,"source_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","target_id":"2bc32e7e8a7fa666b1c1222c91819271","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-47","gmt_create":"2026-05-28T19:00:07.1838938+08:00","gmt_modified":"2026-05-28T19:00:07.1838938+08:00"},{"id":721,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"52819729078f1597788b1933d6801b93","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/redis.go#1-17","gmt_create":"2026-05-28T19:00:07.1838938+08:00","gmt_modified":"2026-05-28T19:00:07.1838938+08:00"},{"id":722,"source_id":"7bfaa93c0d23eed2727039a5bd3d9a07","target_id":"52819729078f1597788b1933d6801b93","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-17","gmt_create":"2026-05-28T19:00:07.1849048+08:00","gmt_modified":"2026-05-28T19:00:07.1849048+08:00"},{"id":723,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"3ff5e86040da68833bd5c5647fe9a6cd","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/search/meilisearch.go#1-46","gmt_create":"2026-05-28T19:00:07.1849048+08:00","gmt_modified":"2026-05-28T19:00:07.1849048+08:00"},{"id":724,"source_id":"a1ff50cc5809d0d712db343ab0befe3b","target_id":"3ff5e86040da68833bd5c5647fe9a6cd","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-46","gmt_create":"2026-05-28T19:00:07.1854871+08:00","gmt_modified":"2026-05-28T19:00:07.1854871+08:00"},{"id":725,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"01e3125f22f4408593f798e93b6afa99","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#1-50","gmt_create":"2026-05-28T19:00:07.1854871+08:00","gmt_modified":"2026-05-28T19:00:07.1854871+08:00"},{"id":726,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"01e3125f22f4408593f798e93b6afa99","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-50","gmt_create":"2026-05-28T19:00:07.1860485+08:00","gmt_modified":"2026-05-28T19:00:07.1860485+08:00"},{"id":727,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"90c875f5593a84b9f61436b4333ef578","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#1-51","gmt_create":"2026-05-28T19:00:07.1860485+08:00","gmt_modified":"2026-05-28T19:00:07.1860485+08:00"},{"id":728,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"90c875f5593a84b9f61436b4333ef578","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-51","gmt_create":"2026-05-28T19:00:07.1865891+08:00","gmt_modified":"2026-05-28T19:00:07.1865891+08:00"},{"id":729,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"d5e4d174e9dd68b5069c37d7733a5167","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#1-83","gmt_create":"2026-05-28T19:00:07.1865891+08:00","gmt_modified":"2026-05-28T19:00:07.1865891+08:00"},{"id":730,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"d5e4d174e9dd68b5069c37d7733a5167","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-83","gmt_create":"2026-05-28T19:00:07.1871204+08:00","gmt_modified":"2026-05-28T19:00:07.1871204+08:00"},{"id":731,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"c4a01c8fb0a60cc8518b952d5d6f388e","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#1-133","gmt_create":"2026-05-28T19:00:07.1871204+08:00","gmt_modified":"2026-05-28T19:00:07.1871204+08:00"},{"id":732,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"c4a01c8fb0a60cc8518b952d5d6f388e","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-133","gmt_create":"2026-05-28T19:00:07.1871204+08:00","gmt_modified":"2026-05-28T19:00:07.1871204+08:00"},{"id":733,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"021df456dabca2ae78c2106e52f86eba","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#1-51","gmt_create":"2026-05-28T19:00:07.1876539+08:00","gmt_modified":"2026-05-28T19:00:07.1876539+08:00"},{"id":734,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"021df456dabca2ae78c2106e52f86eba","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-51","gmt_create":"2026-05-28T19:00:07.1876539+08:00","gmt_modified":"2026-05-28T19:00:07.1876539+08:00"},{"id":735,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"28606623cd3bd5204b730a9c10136e0c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#1-95","gmt_create":"2026-05-28T19:00:07.1881844+08:00","gmt_modified":"2026-05-28T19:00:07.1881844+08:00"},{"id":736,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"28606623cd3bd5204b730a9c10136e0c","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-95","gmt_create":"2026-05-28T19:00:07.1881844+08:00","gmt_modified":"2026-05-28T19:00:07.1881844+08:00"},{"id":737,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"d6366e178901bd9fc56d24ac3f2dc536","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/device.go#1-88","gmt_create":"2026-05-28T19:00:07.1887149+08:00","gmt_modified":"2026-05-28T19:00:07.1887149+08:00"},{"id":738,"source_id":"9889a3ce458e1d193f3188d12fb4ffe8","target_id":"d6366e178901bd9fc56d24ac3f2dc536","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-88","gmt_create":"2026-05-28T19:00:07.1887149+08:00","gmt_modified":"2026-05-28T19:00:07.1887149+08:00"},{"id":739,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"32ab616a01ce2ab4964a112c6f6c9289","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/ota.go#1-159","gmt_create":"2026-05-28T19:00:07.1887149+08:00","gmt_modified":"2026-05-28T19:00:07.1887149+08:00"},{"id":740,"source_id":"88cea44c14b93a3923b010e834c82611","target_id":"32ab616a01ce2ab4964a112c6f6c9289","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-159","gmt_create":"2026-05-28T19:00:07.1892457+08:00","gmt_modified":"2026-05-28T19:00:07.1892457+08:00"},{"id":741,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"ef189d2cfcacc36b1ab99c2bdf638ee5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/brand.go#1-7","gmt_create":"2026-05-28T19:00:07.1892457+08:00","gmt_modified":"2026-05-28T19:00:07.1892457+08:00"},{"id":742,"source_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","target_id":"ef189d2cfcacc36b1ab99c2bdf638ee5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-7","gmt_create":"2026-05-28T19:00:07.1892457+08:00","gmt_modified":"2026-05-28T19:00:07.1892457+08:00"},{"id":743,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"23a3c0da18126f224be977fec0de5a8a","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/model.go#1-15","gmt_create":"2026-05-28T19:00:07.1892457+08:00","gmt_modified":"2026-05-28T19:00:07.1892457+08:00"},{"id":744,"source_id":"e9902bfcef1f5908b5123648ae6b07c6","target_id":"23a3c0da18126f224be977fec0de5a8a","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-15","gmt_create":"2026-05-28T19:00:07.1892457+08:00","gmt_modified":"2026-05-28T19:00:07.1892457+08:00"},{"id":745,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"4713f841d280d4ac330d47e32c6743e0","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/user_device.go#1-12","gmt_create":"2026-05-28T19:00:07.1902629+08:00","gmt_modified":"2026-05-28T19:00:07.1902629+08:00"},{"id":746,"source_id":"40076534e5136a5edb8c4665ebafe2bd","target_id":"4713f841d280d4ac330d47e32c6743e0","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-12","gmt_create":"2026-05-28T19:00:07.1902629+08:00","gmt_modified":"2026-05-28T19:00:07.1902629+08:00"},{"id":747,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"cb0b6a35cfc889254c2aa49bedb440a9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/user_active.go#1-13","gmt_create":"2026-05-28T19:00:07.1908047+08:00","gmt_modified":"2026-05-28T19:00:07.1908047+08:00"},{"id":748,"source_id":"7667f4c1d3eabf712a8e93d02391fbaa","target_id":"cb0b6a35cfc889254c2aa49bedb440a9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-13","gmt_create":"2026-05-28T19:00:07.1908047+08:00","gmt_modified":"2026-05-28T19:00:07.1908047+08:00"},{"id":749,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"da73920ba8bbbc909db36618a7310458","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/ota.go#1-43","gmt_create":"2026-05-28T19:00:07.1908047+08:00","gmt_modified":"2026-05-28T19:00:07.1908047+08:00"},{"id":750,"source_id":"4bac6353bbcbdf06bef53efb2db41064","target_id":"da73920ba8bbbc909db36618a7310458","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-43","gmt_create":"2026-05-28T19:00:07.1913407+08:00","gmt_modified":"2026-05-28T19:00:07.1913407+08:00"},{"id":751,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"4ffb5c0e60dd5865fd0dbd17cefc0f01","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#1-167","gmt_create":"2026-05-28T19:00:07.1913407+08:00","gmt_modified":"2026-05-28T19:00:07.1913407+08:00"},{"id":752,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"4ffb5c0e60dd5865fd0dbd17cefc0f01","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 1-167","gmt_create":"2026-05-28T19:00:07.1918749+08:00","gmt_modified":"2026-05-28T19:00:07.1918749+08:00"},{"id":753,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"d367077ab4548a916c111572cada1c71","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/model.sql#20-38","gmt_create":"2026-05-28T19:00:07.1924104+08:00","gmt_modified":"2026-05-28T19:00:07.1924104+08:00"},{"id":754,"source_id":"c56e5254bd7f42350c5261822fa135bb","target_id":"d367077ab4548a916c111572cada1c71","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-38","gmt_create":"2026-05-28T19:00:07.1924104+08:00","gmt_modified":"2026-05-28T19:00:07.1924104+08:00"},{"id":755,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"189257df07b32be947dabfa695f66fdd","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_device.sql#20-35","gmt_create":"2026-05-28T19:00:07.1929457+08:00","gmt_modified":"2026-05-28T19:00:07.1929457+08:00"},{"id":756,"source_id":"2c0dedcdaa9c3a7a39fa12d838894bd4","target_id":"189257df07b32be947dabfa695f66fdd","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-35","gmt_create":"2026-05-28T19:00:07.1929457+08:00","gmt_modified":"2026-05-28T19:00:07.1929457+08:00"},{"id":757,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"a47ac166b0702b174fb7ed6f2297137d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_active.sql#20-208","gmt_create":"2026-05-28T19:00:07.1935196+08:00","gmt_modified":"2026-05-28T19:00:07.1935196+08:00"},{"id":758,"source_id":"0c676c4075ac3b554f5c006c4ac29b24","target_id":"a47ac166b0702b174fb7ed6f2297137d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-208","gmt_create":"2026-05-28T19:00:07.1935196+08:00","gmt_modified":"2026-05-28T19:00:07.1935196+08:00"},{"id":759,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"897c377e81e0702f2d0e4f13dfceb693","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/ota.sql#20-47","gmt_create":"2026-05-28T19:00:07.1935196+08:00","gmt_modified":"2026-05-28T19:00:07.1935196+08:00"},{"id":760,"source_id":"cc70195006b7310e16886ba71ae56a22","target_id":"897c377e81e0702f2d0e4f13dfceb693","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-47","gmt_create":"2026-05-28T19:00:07.1935196+08:00","gmt_modified":"2026-05-28T19:00:07.1935196+08:00"},{"id":761,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"efaa25ae5bf7399c81644b39a89a1fed","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/black_list.sql#20-33","gmt_create":"2026-05-28T19:00:07.1941019+08:00","gmt_modified":"2026-05-28T19:00:07.1941019+08:00"},{"id":762,"source_id":"44e39bd5e8e7e72cb18dae1f7aed79ce","target_id":"efaa25ae5bf7399c81644b39a89a1fed","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-33","gmt_create":"2026-05-28T19:00:07.1941019+08:00","gmt_modified":"2026-05-28T19:00:07.1941019+08:00"},{"id":763,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"b64c46283e5e53a0d132ca029b9b86d3","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/ota_target_device.sql#20-34","gmt_create":"2026-05-28T19:00:07.194701+08:00","gmt_modified":"2026-05-28T19:00:07.194701+08:00"},{"id":764,"source_id":"db487a51c6053d3d7a39af0bb06a5490","target_id":"b64c46283e5e53a0d132ca029b9b86d3","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-34","gmt_create":"2026-05-28T19:00:07.194701+08:00","gmt_modified":"2026-05-28T19:00:07.194701+08:00"},{"id":765,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"819f2b92f6d3118bb4914a7b9510805d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#26-49","gmt_create":"2026-05-28T19:00:07.1975094+08:00","gmt_modified":"2026-05-28T19:00:07.1975094+08:00"},{"id":766,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"819f2b92f6d3118bb4914a7b9510805d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 26-49","gmt_create":"2026-05-28T19:00:07.1980607+08:00","gmt_modified":"2026-05-28T19:00:07.1980607+08:00"},{"id":767,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"ace2343343d8f2d41c786a71fea9fd11","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#26-50","gmt_create":"2026-05-28T19:00:07.1980607+08:00","gmt_modified":"2026-05-28T19:00:07.1980607+08:00"},{"id":768,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"ace2343343d8f2d41c786a71fea9fd11","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 26-50","gmt_create":"2026-05-28T19:00:07.1986342+08:00","gmt_modified":"2026-05-28T19:00:07.1986342+08:00"},{"id":769,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"a60b5eaffad0d59addb5be3ce07dcfe8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#27-82","gmt_create":"2026-05-28T19:00:07.1986342+08:00","gmt_modified":"2026-05-28T19:00:07.1986342+08:00"},{"id":770,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"7dda8c14930e069827e3ba2382731089","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#23-132","gmt_create":"2026-05-28T19:00:07.1993947+08:00","gmt_modified":"2026-05-28T19:00:07.1993947+08:00"},{"id":771,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"5eaf58cb10abd95debc641aecfcd4505","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#20-50","gmt_create":"2026-05-28T19:00:07.1993947+08:00","gmt_modified":"2026-05-28T19:00:07.1993947+08:00"},{"id":772,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"5eaf58cb10abd95debc641aecfcd4505","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-50","gmt_create":"2026-05-28T19:00:07.1999672+08:00","gmt_modified":"2026-05-28T19:00:07.1999672+08:00"},{"id":773,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"e218f68a16be9c08d06be61a712f8c65","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#20-61","gmt_create":"2026-05-28T19:00:07.1999672+08:00","gmt_modified":"2026-05-28T19:00:07.1999672+08:00"},{"id":774,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"e218f68a16be9c08d06be61a712f8c65","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-61","gmt_create":"2026-05-28T19:00:07.2005186+08:00","gmt_modified":"2026-05-28T19:00:07.2005186+08:00"},{"id":775,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"8ef952b9859313cbfc946824f3307d9d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/device.go#19-87","gmt_create":"2026-05-28T19:00:07.2005186+08:00","gmt_modified":"2026-05-28T19:00:07.2005186+08:00"},{"id":776,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"51316f98b99990e17b496035eb09f026","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/ota.go#19-158","gmt_create":"2026-05-28T19:00:07.2010705+08:00","gmt_modified":"2026-05-28T19:00:07.2010705+08:00"},{"id":777,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"d72b0eafdb65d1d946060cf944359251","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/search/meilisearch.go#22-45","gmt_create":"2026-05-28T19:00:07.2010705+08:00","gmt_modified":"2026-05-28T19:00:07.2010705+08:00"},{"id":778,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"509525e0463c03c509709a6bd1765d4f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/cache/redis.go#10-16","gmt_create":"2026-05-28T19:00:07.2016049+08:00","gmt_modified":"2026-05-28T19:00:07.2016049+08:00"},{"id":779,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"1d3714bd55d5d3f773f1ab7fdb8c9b53","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/brand.go#3-6","gmt_create":"2026-05-28T19:00:07.2021336+08:00","gmt_modified":"2026-05-28T19:00:07.2021336+08:00"},{"id":780,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"8d92ac14c6257462a15eb6990dd44596","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/model.go#5-14","gmt_create":"2026-05-28T19:00:07.2021336+08:00","gmt_modified":"2026-05-28T19:00:07.2021336+08:00"},{"id":781,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"3086af04dfecbda4da76dc885b16803c","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/user_device.go#5-11","gmt_create":"2026-05-28T19:00:07.2026841+08:00","gmt_modified":"2026-05-28T19:00:07.2026841+08:00"},{"id":782,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"37797d6a2ea3a02b54e63ae9da6d2538","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/user_active.go#5-12","gmt_create":"2026-05-28T19:00:07.2026841+08:00","gmt_modified":"2026-05-28T19:00:07.2026841+08:00"},{"id":783,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"658a6f642eff1517af95aca1e7beebc1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/ota.go#6-25","gmt_create":"2026-05-28T19:00:07.2032175+08:00","gmt_modified":"2026-05-28T19:00:07.2032175+08:00"},{"id":784,"source_id":"4bac6353bbcbdf06bef53efb2db41064","target_id":"658a6f642eff1517af95aca1e7beebc1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 6-25","gmt_create":"2026-05-28T19:00:07.2032175+08:00","gmt_modified":"2026-05-28T19:00:07.2032175+08:00"},{"id":785,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"a3818b4d67a7d92f60e660730d921ec6","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/ota.go#28-42","gmt_create":"2026-05-28T19:00:07.2037658+08:00","gmt_modified":"2026-05-28T19:00:07.2037658+08:00"},{"id":786,"source_id":"4bac6353bbcbdf06bef53efb2db41064","target_id":"a3818b4d67a7d92f60e660730d921ec6","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 28-42","gmt_create":"2026-05-28T19:00:07.2037658+08:00","gmt_modified":"2026-05-28T19:00:07.2037658+08:00"},{"id":787,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"e87c932ace50951cb91aa66877ad6f81","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/model.sql#24-35","gmt_create":"2026-05-28T19:00:07.2037658+08:00","gmt_modified":"2026-05-28T19:00:07.2037658+08:00"},{"id":788,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"6c0f43ccd27e99dc7451fce4025b4922","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_device.sql#24-32","gmt_create":"2026-05-28T19:00:07.2043164+08:00","gmt_modified":"2026-05-28T19:00:07.2043164+08:00"},{"id":789,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"49415256ad706e7e14218f5042331053","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_active.sql#24-32","gmt_create":"2026-05-28T19:00:07.2048631+08:00","gmt_modified":"2026-05-28T19:00:07.2048631+08:00"},{"id":790,"source_id":"0c676c4075ac3b554f5c006c4ac29b24","target_id":"49415256ad706e7e14218f5042331053","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 24-32","gmt_create":"2026-05-28T19:00:07.2048631+08:00","gmt_modified":"2026-05-28T19:00:07.2048631+08:00"},{"id":791,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"062377182bb42d6f58aa521f520b8c98","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/ota.sql#24-44","gmt_create":"2026-05-28T19:00:07.2048631+08:00","gmt_modified":"2026-05-28T19:00:07.2048631+08:00"},{"id":792,"source_id":"cc70195006b7310e16886ba71ae56a22","target_id":"062377182bb42d6f58aa521f520b8c98","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 24-44","gmt_create":"2026-05-28T19:00:07.2054069+08:00","gmt_modified":"2026-05-28T19:00:07.2054069+08:00"},{"id":793,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"fac408f6f57051f68ce0b47131e53046","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/black_list.sql#24-30","gmt_create":"2026-05-28T19:00:07.2054069+08:00","gmt_modified":"2026-05-28T19:00:07.2054069+08:00"},{"id":794,"source_id":"44e39bd5e8e7e72cb18dae1f7aed79ce","target_id":"fac408f6f57051f68ce0b47131e53046","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 24-30","gmt_create":"2026-05-28T19:00:07.2054069+08:00","gmt_modified":"2026-05-28T19:00:07.2054069+08:00"},{"id":795,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"88e6e16d8b92be5bc0b42fd6336337cc","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/ota_target_device.sql#24-31","gmt_create":"2026-05-28T19:00:07.2059502+08:00","gmt_modified":"2026-05-28T19:00:07.2059502+08:00"},{"id":796,"source_id":"db487a51c6053d3d7a39af0bb06a5490","target_id":"88e6e16d8b92be5bc0b42fd6336337cc","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 24-31","gmt_create":"2026-05-28T19:00:07.2059502+08:00","gmt_modified":"2026-05-28T19:00:07.2059502+08:00"},{"id":797,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"46f122a322e257db9d295df514f3a0eb","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#37-91","gmt_create":"2026-05-28T19:00:07.2102649+08:00","gmt_modified":"2026-05-28T19:00:07.2102649+08:00"},{"id":798,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"a952e5d5b625754a2e9249983bb8abaa","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/database.go#17-72","gmt_create":"2026-05-28T19:00:07.213031+08:00","gmt_modified":"2026-05-28T19:00:07.213031+08:00"},{"id":799,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"741e7392ea4f07ed0a9dce54ecfb8c9a","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/database/mysql.go#14-47","gmt_create":"2026-05-28T19:00:07.213615+08:00","gmt_modified":"2026-05-28T19:00:07.213615+08:00"},{"id":800,"source_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","target_id":"741e7392ea4f07ed0a9dce54ecfb8c9a","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-47","gmt_create":"2026-05-28T19:00:07.213615+08:00","gmt_modified":"2026-05-28T19:00:07.213615+08:00"},{"id":801,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"61d69bf4d3c8c548eecfd677394486d6","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/config.go#18-52","gmt_create":"2026-05-28T19:00:07.2142662+08:00","gmt_modified":"2026-05-28T19:00:07.2142662+08:00"},{"id":802,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"3fd4ae470b961a44d194f1190b8b846b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/database.go#42-55","gmt_create":"2026-05-28T19:00:07.2147904+08:00","gmt_modified":"2026-05-28T19:00:07.2147904+08:00"},{"id":803,"source_id":"a0a3a762dc85a8d8c5bb359f5c523def","target_id":"3fd4ae470b961a44d194f1190b8b846b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 42-55","gmt_create":"2026-05-28T19:00:07.2147904+08:00","gmt_modified":"2026-05-28T19:00:07.2147904+08:00"},{"id":804,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"5b834ee16ae7f75ed77618c74567730f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/meilisearch.go#14-37","gmt_create":"2026-05-28T19:00:07.2153108+08:00","gmt_modified":"2026-05-28T19:00:07.2153108+08:00"},{"id":805,"source_id":"d2c7a50459a83c5ef23e809b0f194aba","target_id":"5b834ee16ae7f75ed77618c74567730f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-37","gmt_create":"2026-05-28T19:00:07.2153108+08:00","gmt_modified":"2026-05-28T19:00:07.2153108+08:00"},{"id":806,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"c3ac950bf39b216bad9886dc9f5b55d2","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/redis.go#39-49","gmt_create":"2026-05-28T19:00:07.2153108+08:00","gmt_modified":"2026-05-28T19:00:07.2153108+08:00"},{"id":807,"source_id":"ac542a8b31381c132de78b921e3216d4","target_id":"c3ac950bf39b216bad9886dc9f5b55d2","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 39-49","gmt_create":"2026-05-28T19:00:07.2158413+08:00","gmt_modified":"2026-05-28T19:00:07.2158413+08:00"},{"id":808,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"c0d0fd3a31ad005fada5134f30fddfd8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#24-167","gmt_create":"2026-05-28T19:00:07.2163576+08:00","gmt_modified":"2026-05-28T19:00:07.2163576+08:00"},{"id":809,"source_id":"7578d2fdc704b288be4b4a6cf9f8a192","target_id":"c0d0fd3a31ad005fada5134f30fddfd8","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 24-167","gmt_create":"2026-05-28T19:00:07.2163576+08:00","gmt_modified":"2026-05-28T19:00:07.2163576+08:00"},{"id":810,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"1e57d4023212b9b9ffb93fc0adf1a2dc","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/ota.go#6-42","gmt_create":"2026-05-28T19:00:07.216892+08:00","gmt_modified":"2026-05-28T19:00:07.216892+08:00"},{"id":811,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"41e1053e37b8d366a4788eb4e50c3316","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/database/mysql.go#33-36","gmt_create":"2026-05-28T19:00:07.2213008+08:00","gmt_modified":"2026-05-28T19:00:07.2213008+08:00"},{"id":812,"source_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","target_id":"41e1053e37b8d366a4788eb4e50c3316","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 33-36","gmt_create":"2026-05-28T19:00:07.2213008+08:00","gmt_modified":"2026-05-28T19:00:07.2213008+08:00"},{"id":813,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"53cc4b9b52692b204c90364113429f04","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#24-27","gmt_create":"2026-05-28T19:00:07.2213008+08:00","gmt_modified":"2026-05-28T19:00:07.2213008+08:00"},{"id":814,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"53cc4b9b52692b204c90364113429f04","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 24-27","gmt_create":"2026-05-28T19:00:07.2218615+08:00","gmt_modified":"2026-05-28T19:00:07.2218615+08:00"},{"id":815,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"6db6f65d20e506da19a61778ed708068","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#31-40","gmt_create":"2026-05-28T19:00:07.2218615+08:00","gmt_modified":"2026-05-28T19:00:07.2218615+08:00"},{"id":816,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"6db6f65d20e506da19a61778ed708068","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 31-40","gmt_create":"2026-05-28T19:00:07.2224363+08:00","gmt_modified":"2026-05-28T19:00:07.2224363+08:00"},{"id":817,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"6425001a8d84168af2d38efa689eee25","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/search/meilisearch.go#22-26","gmt_create":"2026-05-28T19:00:07.2230177+08:00","gmt_modified":"2026-05-28T19:00:07.2230177+08:00"},{"id":818,"source_id":"a1ff50cc5809d0d712db343ab0befe3b","target_id":"6425001a8d84168af2d38efa689eee25","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 22-26","gmt_create":"2026-05-28T19:00:07.2230177+08:00","gmt_modified":"2026-05-28T19:00:07.2230177+08:00"},{"id":819,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"8d8c4ed8e4263a8b7679488df7ff3272","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_active.sql#33-204","gmt_create":"2026-05-28T19:00:07.223566+08:00","gmt_modified":"2026-05-28T19:00:07.223566+08:00"},{"id":820,"source_id":"0c676c4075ac3b554f5c006c4ac29b24","target_id":"8d8c4ed8e4263a8b7679488df7ff3272","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 33-204","gmt_create":"2026-05-28T19:00:07.223566+08:00","gmt_modified":"2026-05-28T19:00:07.223566+08:00"},{"id":821,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"3c8c105b618476c1dff60821fe977ba2","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/database.go#57-71","gmt_create":"2026-05-28T19:00:07.2241779+08:00","gmt_modified":"2026-05-28T19:00:07.2241779+08:00"},{"id":822,"source_id":"a0a3a762dc85a8d8c5bb359f5c523def","target_id":"3c8c105b618476c1dff60821fe977ba2","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 57-71","gmt_create":"2026-05-28T19:00:07.2241779+08:00","gmt_modified":"2026-05-28T19:00:07.2241779+08:00"},{"id":823,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"7824c130bd204768245b2ef1e2326e5d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/database/mysql.go#40-43","gmt_create":"2026-05-28T19:00:07.2247923+08:00","gmt_modified":"2026-05-28T19:00:07.2247923+08:00"},{"id":824,"source_id":"0b4d10e2e0a550819cadaa7dbef9ecd1","target_id":"7824c130bd204768245b2ef1e2326e5d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 40-43","gmt_create":"2026-05-28T19:00:07.2247923+08:00","gmt_modified":"2026-05-28T19:00:07.2247923+08:00"},{"id":825,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"93d77b956265768d24c0f3e807cae3f6","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#32-47","gmt_create":"2026-05-28T19:00:07.2253264+08:00","gmt_modified":"2026-05-28T19:00:07.2253264+08:00"},{"id":826,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"93d77b956265768d24c0f3e807cae3f6","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 32-47","gmt_create":"2026-05-28T19:00:07.2253264+08:00","gmt_modified":"2026-05-28T19:00:07.2253264+08:00"},{"id":827,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"8a027ed1f8af1f5bfec4eb28de4c8d5b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#43-58","gmt_create":"2026-05-28T19:00:07.2253264+08:00","gmt_modified":"2026-05-28T19:00:07.2253264+08:00"},{"id":828,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"8a027ed1f8af1f5bfec4eb28de4c8d5b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 43-58","gmt_create":"2026-05-28T19:00:07.2259074+08:00","gmt_modified":"2026-05-28T19:00:07.2259074+08:00"},{"id":829,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"b6b8e91265e76c9b7982364854d6d521","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#31-43","gmt_create":"2026-05-28T19:00:07.2259074+08:00","gmt_modified":"2026-05-28T19:00:07.2259074+08:00"},{"id":830,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"b6b8e91265e76c9b7982364854d6d521","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 31-43","gmt_create":"2026-05-28T19:00:07.2264716+08:00","gmt_modified":"2026-05-28T19:00:07.2264716+08:00"},{"id":831,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"9cdccaf24e4bb2ebeda989e652cbb590","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#33-43","gmt_create":"2026-05-28T19:00:07.2264716+08:00","gmt_modified":"2026-05-28T19:00:07.2264716+08:00"},{"id":832,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"9cdccaf24e4bb2ebeda989e652cbb590","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 33-43","gmt_create":"2026-05-28T19:00:07.2264716+08:00","gmt_modified":"2026-05-28T19:00:07.2264716+08:00"},{"id":833,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"93b1b8f6a4dee4e1ddf80984e2ad4f07","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#45-82","gmt_create":"2026-05-28T19:00:07.2264716+08:00","gmt_modified":"2026-05-28T19:00:07.2264716+08:00"},{"id":834,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"93b1b8f6a4dee4e1ddf80984e2ad4f07","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 45-82","gmt_create":"2026-05-28T19:00:07.2264716+08:00","gmt_modified":"2026-05-28T19:00:07.2264716+08:00"},{"id":835,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"1757787c6693e053fe8996b15c11536e","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#56-132","gmt_create":"2026-05-28T19:00:07.227513+08:00","gmt_modified":"2026-05-28T19:00:07.227513+08:00"},{"id":836,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"1757787c6693e053fe8996b15c11536e","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 56-132","gmt_create":"2026-05-28T19:00:07.227513+08:00","gmt_modified":"2026-05-28T19:00:07.227513+08:00"},{"id":837,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"62a2f3176fec72cd937d12bdd85b8023","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/search/meilisearch.go#17-20","gmt_create":"2026-05-28T19:00:07.227513+08:00","gmt_modified":"2026-05-28T19:00:07.227513+08:00"},{"id":838,"source_id":"a1ff50cc5809d0d712db343ab0befe3b","target_id":"62a2f3176fec72cd937d12bdd85b8023","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 17-20","gmt_create":"2026-05-28T19:00:07.227513+08:00","gmt_modified":"2026-05-28T19:00:07.227513+08:00"},{"id":839,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"0b9d497db6c6913d0f143b9c1a6e1bad","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/brand.go#4-5","gmt_create":"2026-05-28T19:00:07.2291035+08:00","gmt_modified":"2026-05-28T19:00:07.2291035+08:00"},{"id":840,"source_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","target_id":"0b9d497db6c6913d0f143b9c1a6e1bad","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 4-5","gmt_create":"2026-05-28T19:00:07.2291035+08:00","gmt_modified":"2026-05-28T19:00:07.2291035+08:00"},{"id":841,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"be4c653a27c4d4270505763c428135f7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/model.go#6-13","gmt_create":"2026-05-28T19:00:07.2291035+08:00","gmt_modified":"2026-05-28T19:00:07.2291035+08:00"},{"id":842,"source_id":"e9902bfcef1f5908b5123648ae6b07c6","target_id":"be4c653a27c4d4270505763c428135f7","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 6-13","gmt_create":"2026-05-28T19:00:07.2291035+08:00","gmt_modified":"2026-05-28T19:00:07.2291035+08:00"},{"id":843,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"5178a0682867f422c7fd0847372d79c0","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/database.go#67-69","gmt_create":"2026-05-28T19:00:07.2323183+08:00","gmt_modified":"2026-05-28T19:00:07.2323183+08:00"},{"id":844,"source_id":"a0a3a762dc85a8d8c5bb359f5c523def","target_id":"5178a0682867f422c7fd0847372d79c0","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 67-69","gmt_create":"2026-05-28T19:00:07.2323183+08:00","gmt_modified":"2026-05-28T19:00:07.2323183+08:00"},{"id":845,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"7622937a1ed63808bc23509e6bf502d7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/meilisearch.go#39-50","gmt_create":"2026-05-28T19:00:07.2323183+08:00","gmt_modified":"2026-05-28T19:00:07.2323183+08:00"},{"id":846,"source_id":"d2c7a50459a83c5ef23e809b0f194aba","target_id":"7622937a1ed63808bc23509e6bf502d7","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 39-50","gmt_create":"2026-05-28T19:00:07.2377201+08:00","gmt_modified":"2026-05-28T19:00:07.2377201+08:00"},{"id":847,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"c36202d0e142efb3373377cd5fc6d146","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/redis.go#51-56","gmt_create":"2026-05-28T19:00:07.2377201+08:00","gmt_modified":"2026-05-28T19:00:07.2377201+08:00"},{"id":848,"source_id":"ac542a8b31381c132de78b921e3216d4","target_id":"c36202d0e142efb3373377cd5fc6d146","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 51-56","gmt_create":"2026-05-28T19:00:07.2377201+08:00","gmt_modified":"2026-05-28T19:00:07.2377201+08:00"},{"id":849,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"3327fdfd4099f053f8dd4cc2a04ad710","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#33-48","gmt_create":"2026-05-28T19:00:07.2377201+08:00","gmt_modified":"2026-05-28T19:00:07.2377201+08:00"},{"id":850,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"3327fdfd4099f053f8dd4cc2a04ad710","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 33-48","gmt_create":"2026-05-28T19:00:07.2377201+08:00","gmt_modified":"2026-05-28T19:00:07.2377201+08:00"},{"id":851,"source_id":"120f3824-43f7-4a38-9680-43b5b2f59e05","target_id":"e3adf341667ef4784dcd76b3b8240f33","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#32-48","gmt_create":"2026-05-28T19:00:07.2377201+08:00","gmt_modified":"2026-05-28T19:00:07.2377201+08:00"},{"id":852,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"e3adf341667ef4784dcd76b3b8240f33","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 32-48","gmt_create":"2026-05-28T19:00:07.2377201+08:00","gmt_modified":"2026-05-28T19:00:07.2377201+08:00"},{"id":853,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/brand.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":854,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"e9902bfcef1f5908b5123648ae6b07c6","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/model.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":855,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"4bac6353bbcbdf06bef53efb2db41064","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/ota.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":856,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"40076534e5136a5edb8c4665ebafe2bd","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/user_device.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":857,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"7667f4c1d3eabf712a8e93d02391fbaa","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/model/user_active.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":858,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"276b4d58e492bc3f7c258914abb959e4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/brand.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":859,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"4ca752eb084c575a36939921aeeb9984","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/model.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":860,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"88cea44c14b93a3923b010e834c82611","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/ota.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":861,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"9889a3ce458e1d193f3188d12fb4ffe8","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/repository/device.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":862,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/brand.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":863,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"b18d19ca2c60406b9cd28010df12296d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":864,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/model_list.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":865,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"d9221643d906c5ec348eb3dd51aa5536","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/ota.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":866,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"3a1babcf090301072327433866c0d7d0","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/handler/device.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":867,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"d2654fb48612d74ab0ccc06a3aede80b","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/router/router.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":868,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"a0a3a762dc85a8d8c5bb359f5c523def","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/config/database.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":869,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"703706c059a41213d3dbfbddc03fab12","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/response/response.go","gmt_create":"2026-05-28T19:00:48.6717193+08:00","gmt_modified":"2026-05-28T19:00:48.6717193+08:00"},{"id":870,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"7578d2fdc704b288be4b4a6cf9f8a192","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: internal/task/device_persist.go","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":871,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"80d716769cf67cd05b504a3bc0a06a92","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: pkg/encode/base64.go","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":872,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"c56e5254bd7f42350c5261822fa135bb","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/model.sql","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":873,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"cc70195006b7310e16886ba71ae56a22","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/ota.sql","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":874,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"2c0dedcdaa9c3a7a39fa12d838894bd4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/user_device.sql","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":875,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"0c676c4075ac3b554f5c006c4ac29b24","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/user_active.sql","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":876,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"db487a51c6053d3d7a39af0bb06a5490","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: sql/ota_target_device.sql","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":877,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"fd613068059c593ac4df9eaef2918055","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: cmd/server/main.go","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":878,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"7b484a5ae829eeda00870c3f1e212152","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#22-64","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":879,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"7b484a5ae829eeda00870c3f1e212152","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 22-64","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":880,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"c73149ce118775bda8abbe6ef4cfd663","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#14-56","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":881,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"d81273f13e44b61321fec0ce3006f5c1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#19-50","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":882,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"d81273f13e44b61321fec0ce3006f5c1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-50","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":883,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"482a26438e7a2ce9d7cfbf86ace40f32","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#19-51","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":884,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"482a26438e7a2ce9d7cfbf86ace40f32","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-51","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":885,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"3d711f613bfd2e37cae891628729b534","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#19-57","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":886,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"3d711f613bfd2e37cae891628729b534","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-57","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":887,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"aa25d38d1ff2b629566d1fae5ca04f7f","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#14-133","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":888,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"aa25d38d1ff2b629566d1fae5ca04f7f","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-133","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":889,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"0bbf6adb379e3658025de484d5b76c97","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#15-83","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":890,"source_id":"3a1babcf090301072327433866c0d7d0","target_id":"0bbf6adb379e3658025de484d5b76c97","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 15-83","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":891,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"3b1b16fc1f259913d34a3025a9856837","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#16-51","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":892,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"3b1b16fc1f259913d34a3025a9856837","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 16-51","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":893,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"93265e1e6c0c0c869df702008b681e01","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#16-95","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":894,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"93265e1e6c0c0c869df702008b681e01","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 16-95","gmt_create":"2026-05-28T19:00:48.6757728+08:00","gmt_modified":"2026-05-28T19:00:48.6757728+08:00"},{"id":895,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"8fff9ab89b194aaf50c08418f14e7d5d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/ota.go#11-159","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":896,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"ebe1ad8e2e447d1c8784d0338fb5ff44","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/device.go#11-88","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":897,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"72195f4e7a76b584cbdfbaba23db2a1a","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/brand.go#3-7","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":898,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"3c27d9274287839faa5269c34b98b6a9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/model.go#5-15","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":899,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"068719fc1a0d9314d8021756c98217da","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/ota.go#5-43","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":900,"source_id":"4bac6353bbcbdf06bef53efb2db41064","target_id":"068719fc1a0d9314d8021756c98217da","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 5-43","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":901,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"bb96f52067e8e086b30d9c30821c5584","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/user_device.go#5-12","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":902,"source_id":"40076534e5136a5edb8c4665ebafe2bd","target_id":"bb96f52067e8e086b30d9c30821c5584","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 5-12","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":903,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"d4e3d54fc92d9bf0a306c8222cabb8a8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/user_active.go#5-13","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":904,"source_id":"7667f4c1d3eabf712a8e93d02391fbaa","target_id":"d4e3d54fc92d9bf0a306c8222cabb8a8","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 5-13","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":905,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"c264094331c357056119bca99357640d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#9-37","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":906,"source_id":"703706c059a41213d3dbfbddc03fab12","target_id":"c264094331c357056119bca99357640d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 9-37","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":907,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"74cc6302b70bcea6621f5bfb0763076b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: pkg/encode/base64.go#21-52","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":908,"source_id":"80d716769cf67cd05b504a3bc0a06a92","target_id":"74cc6302b70bcea6621f5bfb0763076b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 21-52","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":909,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"a952e5d5b625754a2e9249983bb8abaa","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/database.go#17-72","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":910,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"d367077ab4548a916c111572cada1c71","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/model.sql#20-38","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":911,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"3e86caf95903a24c6393bc96880f7951","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/ota.sql#23-44","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":912,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"90cda5d453d8a36d34f0bb16bf3b22d4","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_device.sql#23-32","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":913,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"169d98ec7c47a41d541c28ef27876ab1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_active.sql#23-32","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":914,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"59f1d79949230d387b6ad48a329cc0f7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/ota_target_device.sql#23-31","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":915,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"3cab00ffcb36143e0a8fa39bc345dc5b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#14-167","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":916,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"26fa07962aa58dc300b27f1cc7f3f984","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#20-51","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":917,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"26fa07962aa58dc300b27f1cc7f3f984","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-51","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":918,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"07061497ffd00747ff422a65693ddfc5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#20-95","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":919,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"07061497ffd00747ff422a65693ddfc5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-95","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":920,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"88f3a0de90be87baf1799c9d1d77d814","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/ota.go#19-159","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":921,"source_id":"88cea44c14b93a3923b010e834c82611","target_id":"88f3a0de90be87baf1799c9d1d77d814","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-159","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":922,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"a70c6a1aa995213e0b9785c73215f03d","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/device.go#19-88","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":923,"source_id":"9889a3ce458e1d193f3188d12fb4ffe8","target_id":"a70c6a1aa995213e0b9785c73215f03d","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 19-88","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":924,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"ac531f924fff62d1ae6d87fb20ee8b5b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#26-50","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":925,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"ac531f924fff62d1ae6d87fb20ee8b5b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 26-50","gmt_create":"2026-05-28T19:00:48.6818315+08:00","gmt_modified":"2026-05-28T19:00:48.6818315+08:00"},{"id":926,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"4baa32d2509ec9cea1ff6d469146dc73","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#26-51","gmt_create":"2026-05-28T19:00:48.6910498+08:00","gmt_modified":"2026-05-28T19:00:48.6910498+08:00"},{"id":927,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"4baa32d2509ec9cea1ff6d469146dc73","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 26-51","gmt_create":"2026-05-28T19:00:48.6910498+08:00","gmt_modified":"2026-05-28T19:00:48.6910498+08:00"},{"id":928,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"2680759f452df990edc59ce5ce169032","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#26-57","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":929,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"2680759f452df990edc59ce5ce169032","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 26-57","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":930,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"02c681361cdf45307d027e067cf32b85","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#23-133","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":931,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"02c681361cdf45307d027e067cf32b85","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 23-133","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":932,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"47b04c12479e04825b7f54c8912d5322","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#27-83","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":933,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"c0d0fd3a31ad005fada5134f30fddfd8","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#24-167","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":934,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"f739c0f56b921999850449a934b246fb","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#51","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":935,"source_id":"d2654fb48612d74ab0ccc06a3aede80b","target_id":"f739c0f56b921999850449a934b246fb","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 51","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":936,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"a554f667fa82536a73b1255c88583088","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#25-133","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":937,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"a554f667fa82536a73b1255c88583088","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 25-133","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":938,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"dcccb8807bc578cdadf9bec126c8ffe9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: pkg/encode/base64.go#35-52","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":939,"source_id":"80d716769cf67cd05b504a3bc0a06a92","target_id":"dcccb8807bc578cdadf9bec126c8ffe9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 35-52","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":940,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"64183de83183797057473b5ee67ba4c9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/brand.go#12-51","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":941,"source_id":"276b4d58e492bc3f7c258914abb959e4","target_id":"64183de83183797057473b5ee67ba4c9","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 12-51","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":942,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"4693351138ccb8e9d6210c80375b0f84","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#12-95","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":943,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"4693351138ccb8e9d6210c80375b0f84","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 12-95","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":944,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"e87c932ace50951cb91aa66877ad6f81","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/model.sql#24-35","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":945,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"1e57d4023212b9b9ffb93fc0adf1a2dc","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/model/ota.go#6-42","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":946,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"062377182bb42d6f58aa521f520b8c98","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/ota.sql#24-44","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":947,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"88e6e16d8b92be5bc0b42fd6336337cc","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/ota_target_device.sql#24-31","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":948,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"6c0f43ccd27e99dc7451fce4025b4922","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_device.sql#24-32","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":949,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"49415256ad706e7e14218f5042331053","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/user_active.sql#24-32","gmt_create":"2026-05-28T19:00:48.6920693+08:00","gmt_modified":"2026-05-28T19:00:48.6920693+08:00"},{"id":950,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"e218f68a16be9c08d06be61a712f8c65","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#20-61","gmt_create":"2026-05-28T19:00:48.7026226+08:00","gmt_modified":"2026-05-28T19:00:48.7026226+08:00"},{"id":951,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"6f5bb52b78380275d195a29a2a4f95e5","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#14-50","gmt_create":"2026-05-28T19:00:48.7026226+08:00","gmt_modified":"2026-05-28T19:00:48.7026226+08:00"},{"id":952,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"6f5bb52b78380275d195a29a2a4f95e5","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-50","gmt_create":"2026-05-28T19:00:48.7026226+08:00","gmt_modified":"2026-05-28T19:00:48.7026226+08:00"},{"id":953,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"7b5fdc856dd6809973d5baa959e27fee","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#14-51","gmt_create":"2026-05-28T19:00:48.7026226+08:00","gmt_modified":"2026-05-28T19:00:48.7026226+08:00"},{"id":954,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"7b5fdc856dd6809973d5baa959e27fee","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 14-51","gmt_create":"2026-05-28T19:00:48.7026226+08:00","gmt_modified":"2026-05-28T19:00:48.7026226+08:00"},{"id":955,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"8cf065ea198e4e0d88af1863fcd6ac11","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#14-57","gmt_create":"2026-05-28T19:00:48.7026226+08:00","gmt_modified":"2026-05-28T19:00:48.7026226+08:00"},{"id":956,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"d720265bcfafa36ea6088932e1b64cbb","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: sql/model.sql#34-35","gmt_create":"2026-05-28T19:00:48.7071913+08:00","gmt_modified":"2026-05-28T19:00:48.7071913+08:00"},{"id":957,"source_id":"c56e5254bd7f42350c5261822fa135bb","target_id":"d720265bcfafa36ea6088932e1b64cbb","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 34-35","gmt_create":"2026-05-28T19:00:48.7071913+08:00","gmt_modified":"2026-05-28T19:00:48.7071913+08:00"},{"id":958,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"ae6067ec7ce193f2a0f441884cab8879","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/model.go#63-95","gmt_create":"2026-05-28T19:00:48.7071913+08:00","gmt_modified":"2026-05-28T19:00:48.7071913+08:00"},{"id":959,"source_id":"4ca752eb084c575a36939921aeeb9984","target_id":"ae6067ec7ce193f2a0f441884cab8879","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 63-95","gmt_create":"2026-05-28T19:00:48.7071913+08:00","gmt_modified":"2026-05-28T19:00:48.7071913+08:00"},{"id":960,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"eed5fae41d5e3dedf1a6cf48e3714329","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/repository/ota.go#20-159","gmt_create":"2026-05-28T19:00:48.7071913+08:00","gmt_modified":"2026-05-28T19:00:48.7071913+08:00"},{"id":961,"source_id":"88cea44c14b93a3923b010e834c82611","target_id":"eed5fae41d5e3dedf1a6cf48e3714329","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 20-159","gmt_create":"2026-05-28T19:00:48.7071913+08:00","gmt_modified":"2026-05-28T19:00:48.7071913+08:00"},{"id":962,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"c100a3cbfc9d8f23656202b88fa6afd1","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: cmd/server/main.go#66-95","gmt_create":"2026-05-28T19:00:48.7211968+08:00","gmt_modified":"2026-05-28T19:00:48.7211968+08:00"},{"id":963,"source_id":"fd613068059c593ac4df9eaef2918055","target_id":"c100a3cbfc9d8f23656202b88fa6afd1","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 66-95","gmt_create":"2026-05-28T19:00:48.7211968+08:00","gmt_modified":"2026-05-28T19:00:48.7211968+08:00"},{"id":964,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"cd00b1806e2c98e0bb5dffa98190dcc9","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/task/device_persist.go#24-91","gmt_create":"2026-05-28T19:00:48.7232039+08:00","gmt_modified":"2026-05-28T19:00:48.7232039+08:00"},{"id":965,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"66a4c4386d79ac88e1703c28c4cd145b","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/config/database.go#57-72","gmt_create":"2026-05-28T19:00:48.7232039+08:00","gmt_modified":"2026-05-28T19:00:48.7232039+08:00"},{"id":966,"source_id":"a0a3a762dc85a8d8c5bb359f5c523def","target_id":"66a4c4386d79ac88e1703c28c4cd145b","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 57-72","gmt_create":"2026-05-28T19:00:48.7232039+08:00","gmt_modified":"2026-05-28T19:00:48.7232039+08:00"},{"id":967,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"203b91618d1657c9507385082e51de6e","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/brand.go#31-35","gmt_create":"2026-05-28T19:00:48.7237656+08:00","gmt_modified":"2026-05-28T19:00:48.7237656+08:00"},{"id":968,"source_id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","target_id":"203b91618d1657c9507385082e51de6e","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 31-35","gmt_create":"2026-05-28T19:00:48.7237656+08:00","gmt_modified":"2026-05-28T19:00:48.7237656+08:00"},{"id":969,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"d73169aa9d1bce60664d575f3b21b1d7","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model.go#33-36","gmt_create":"2026-05-28T19:00:48.7243183+08:00","gmt_modified":"2026-05-28T19:00:48.7243183+08:00"},{"id":970,"source_id":"b18d19ca2c60406b9cd28010df12296d","target_id":"d73169aa9d1bce60664d575f3b21b1d7","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 33-36","gmt_create":"2026-05-28T19:00:48.7243183+08:00","gmt_modified":"2026-05-28T19:00:48.7243183+08:00"},{"id":971,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"a9580521a05ba65f89553c7d22ca9e68","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/model_list.go#39-42","gmt_create":"2026-05-28T19:00:48.724882+08:00","gmt_modified":"2026-05-28T19:00:48.724882+08:00"},{"id":972,"source_id":"75f8ef5ebd7eeb0cf2346b392f877e1a","target_id":"a9580521a05ba65f89553c7d22ca9e68","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 39-42","gmt_create":"2026-05-28T19:00:48.724882+08:00","gmt_modified":"2026-05-28T19:00:48.724882+08:00"},{"id":973,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"4d001351d513017ae0410443015c4fdf","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/ota.go#31-48","gmt_create":"2026-05-28T19:00:48.724882+08:00","gmt_modified":"2026-05-28T19:00:48.724882+08:00"},{"id":974,"source_id":"d9221643d906c5ec348eb3dd51aa5536","target_id":"4d001351d513017ae0410443015c4fdf","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 31-48","gmt_create":"2026-05-28T19:00:48.7254309+08:00","gmt_modified":"2026-05-28T19:00:48.7254309+08:00"},{"id":975,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"447b10c5efa18658d41d37a56693098e","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/handler/device.go#33-39","gmt_create":"2026-05-28T19:00:48.7254309+08:00","gmt_modified":"2026-05-28T19:00:48.7254309+08:00"},{"id":976,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"1862d9cadc2f4c8f0f2f11fa22854f28","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/response/response.go#30-37","gmt_create":"2026-05-28T19:00:48.7259878+08:00","gmt_modified":"2026-05-28T19:00:48.7259878+08:00"},{"id":977,"source_id":"703706c059a41213d3dbfbddc03fab12","target_id":"1862d9cadc2f4c8f0f2f11fa22854f28","source_type":"SOURCE_FILE","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Source file contains code snippet: 30-37","gmt_create":"2026-05-28T19:00:48.7259878+08:00","gmt_modified":"2026-05-28T19:00:48.7259878+08:00"},{"id":978,"source_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","target_id":"1a416066a4f46116deac1ca86b956c76","source_type":"WIKI_ITEM","target_type":"CODE_SNIPPET","relationship_type":"CONTAINS","extra":"Wiki contains code snippet: internal/router/router.go#45-52","gmt_create":"2026-05-28T19:00:48.7281189+08:00","gmt_modified":"2026-05-28T19:00:48.7281189+08:00"},{"id":979,"source_id":"7563e383-3ea0-4630-baeb-e86efcaeefb8","target_id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7563e383-3ea0-4630-baeb-e86efcaeefb8 -\u003e d1a696b8-5a9e-4ad2-8777-04eecc0bb424","gmt_create":"2026-05-28T19:00:49.3512963+08:00","gmt_modified":"2026-05-28T19:00:49.3512963+08:00"},{"id":980,"source_id":"7563e383-3ea0-4630-baeb-e86efcaeefb8","target_id":"599c0bda-3332-415c-a535-362503079473","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7563e383-3ea0-4630-baeb-e86efcaeefb8 -\u003e 599c0bda-3332-415c-a535-362503079473","gmt_create":"2026-05-28T19:00:49.3520117+08:00","gmt_modified":"2026-05-28T19:00:49.3520117+08:00"},{"id":981,"source_id":"7563e383-3ea0-4630-baeb-e86efcaeefb8","target_id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7563e383-3ea0-4630-baeb-e86efcaeefb8 -\u003e 97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","gmt_create":"2026-05-28T19:00:49.3526667+08:00","gmt_modified":"2026-05-28T19:00:49.3526667+08:00"},{"id":982,"source_id":"6159e8a9-0f6e-43af-b097-bfcd16c8b223","target_id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6159e8a9-0f6e-43af-b097-bfcd16c8b223 -\u003e e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","gmt_create":"2026-05-28T19:00:49.3544268+08:00","gmt_modified":"2026-05-28T19:00:49.3544268+08:00"},{"id":983,"source_id":"cfbcaa79-26f5-402f-8746-9fe524993684","target_id":"795a5202-49be-4c11-a2b4-44312eca8ae7","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: cfbcaa79-26f5-402f-8746-9fe524993684 -\u003e 795a5202-49be-4c11-a2b4-44312eca8ae7","gmt_create":"2026-05-28T19:00:49.3544268+08:00","gmt_modified":"2026-05-28T19:00:49.3544268+08:00"}],"source_files":[{"id":"d2654fb48612d74ab0ccc06a3aede80b","path":"internal/router/router.go","filename":"router.go","gmt_create":"2026-05-27T18:35:29.8906012+08:00","gmt_modified":"2026-05-27T18:35:29.8906012+08:00"},{"id":"fd613068059c593ac4df9eaef2918055","path":"cmd/server/main.go","filename":"main.go","gmt_create":"2026-05-27T18:35:29.8906012+08:00","gmt_modified":"2026-05-27T18:35:29.8906012+08:00"},{"id":"336527cad207564e9ea86fcc4e0ec240","path":"internal/middleware/cors.go","filename":"cors.go","gmt_create":"2026-05-27T18:35:29.8912536+08:00","gmt_modified":"2026-05-27T18:35:29.8912536+08:00"},{"id":"f8a733666ceab6a73ba2bf3234e91222","path":"internal/middleware/logger.go","filename":"logger.go","gmt_create":"2026-05-27T18:35:29.8912536+08:00","gmt_modified":"2026-05-27T18:35:29.8912536+08:00"},{"id":"2ba2f740fa3334f7c6d51f74470ec4b7","path":"internal/middleware/request_id.go","filename":"request_id.go","gmt_create":"2026-05-27T18:35:29.8912536+08:00","gmt_modified":"2026-05-27T18:35:29.8912536+08:00"},{"id":"a7b9800e6fc68baa0cfda9c8f327b423","path":"internal/handler/health.go","filename":"health.go","gmt_create":"2026-05-27T18:35:29.8912536+08:00","gmt_modified":"2026-05-27T18:35:29.8912536+08:00"},{"id":"4d2b98c1d0a7fa8cf9725fb65019ae0e","path":"internal/handler/brand.go","filename":"brand.go","gmt_create":"2026-05-27T18:35:29.8912536+08:00","gmt_modified":"2026-05-27T18:35:29.8912536+08:00"},{"id":"b18d19ca2c60406b9cd28010df12296d","path":"internal/handler/model.go","filename":"model.go","gmt_create":"2026-05-27T18:35:29.8917986+08:00","gmt_modified":"2026-05-27T18:35:29.8917986+08:00"},{"id":"75f8ef5ebd7eeb0cf2346b392f877e1a","path":"internal/handler/model_list.go","filename":"model_list.go","gmt_create":"2026-05-27T18:35:29.8917986+08:00","gmt_modified":"2026-05-27T18:35:29.8917986+08:00"},{"id":"3a1babcf090301072327433866c0d7d0","path":"internal/handler/device.go","filename":"device.go","gmt_create":"2026-05-27T18:35:29.8917986+08:00","gmt_modified":"2026-05-27T18:35:29.8917986+08:00"},{"id":"703706c059a41213d3dbfbddc03fab12","path":"internal/response/response.go","filename":"response.go","gmt_create":"2026-05-27T18:35:29.8917986+08:00","gmt_modified":"2026-05-27T18:35:29.8917986+08:00"},{"id":"0bba4121c12e2cf427dc805016fade40","path":"internal/config/config.go","filename":"config.go","gmt_create":"2026-05-27T18:35:29.8917986+08:00","gmt_modified":"2026-05-27T18:35:29.8917986+08:00"},{"id":"80d716769cf67cd05b504a3bc0a06a92","path":"pkg/encode/base64.go","filename":"base64.go","gmt_create":"2026-05-27T18:35:29.8923362+08:00","gmt_modified":"2026-05-27T18:35:29.8923362+08:00"},{"id":"67d9f7c1be7ff64bb9bca0a5f2492621","path":"README.md","filename":"README.md","gmt_create":"2026-05-27T18:35:29.8923362+08:00","gmt_modified":"2026-05-27T18:35:29.8923362+08:00"},{"id":"7bfaa93c0d23eed2727039a5bd3d9a07","path":"internal/cache/redis.go","filename":"redis.go","gmt_create":"2026-05-27T18:35:29.8923362+08:00","gmt_modified":"2026-05-27T18:35:29.8923362+08:00"},{"id":"67d3253845127f03f1f9ebe3f6a6aaa3","path":"internal/cache/brand_cache.go","filename":"brand_cache.go","gmt_create":"2026-05-27T18:35:29.8923362+08:00","gmt_modified":"2026-05-27T18:35:29.8923362+08:00"},{"id":"018b14cbce05561cfb50fe7e6e3835a3","path":"internal/cache/model_cache.go","filename":"model_cache.go","gmt_create":"2026-05-27T18:35:29.8923362+08:00","gmt_modified":"2026-05-27T18:35:29.8923362+08:00"},{"id":"276b4d58e492bc3f7c258914abb959e4","path":"internal/repository/brand.go","filename":"brand.go","gmt_create":"2026-05-27T18:35:29.8923362+08:00","gmt_modified":"2026-05-27T18:35:29.8923362+08:00"},{"id":"4ca752eb084c575a36939921aeeb9984","path":"internal/repository/model.go","filename":"model.go","gmt_create":"2026-05-27T18:35:29.892946+08:00","gmt_modified":"2026-05-27T18:35:29.892946+08:00"},{"id":"ac542a8b31381c132de78b921e3216d4","path":"internal/config/redis.go","filename":"redis.go","gmt_create":"2026-05-27T18:35:29.892946+08:00","gmt_modified":"2026-05-27T18:35:29.892946+08:00"},{"id":"d2c7a50459a83c5ef23e809b0f194aba","path":"internal/config/meilisearch.go","filename":"meilisearch.go","gmt_create":"2026-05-27T18:35:29.892946+08:00","gmt_modified":"2026-05-27T18:35:29.892946+08:00"},{"id":"0b4d10e2e0a550819cadaa7dbef9ecd1","path":"internal/database/mysql.go","filename":"mysql.go","gmt_create":"2026-05-27T18:35:41.7298499+08:00","gmt_modified":"2026-05-27T18:35:41.7298499+08:00"},{"id":"a0a3a762dc85a8d8c5bb359f5c523def","path":"internal/config/database.go","filename":"database.go","gmt_create":"2026-05-27T18:35:41.7298499+08:00","gmt_modified":"2026-05-27T18:35:41.7298499+08:00"},{"id":"6e3fd9bdc8a1ccaaa905d91772ecca2c","path":"internal/model/brand.go","filename":"brand.go","gmt_create":"2026-05-27T18:35:41.7304145+08:00","gmt_modified":"2026-05-27T18:35:41.7304145+08:00"},{"id":"e9902bfcef1f5908b5123648ae6b07c6","path":"internal/model/model.go","filename":"model.go","gmt_create":"2026-05-27T18:35:41.7304145+08:00","gmt_modified":"2026-05-27T18:35:41.7304145+08:00"},{"id":"c56e5254bd7f42350c5261822fa135bb","path":"sql/model.sql","filename":"model.sql","gmt_create":"2026-05-27T18:35:41.7309531+08:00","gmt_modified":"2026-05-27T18:35:41.7309531+08:00"},{"id":"47165ac2566e8b2d3796014bdb75361f","path":"go.mod","filename":"go.mod","gmt_create":"2026-05-27T18:35:41.7309531+08:00","gmt_modified":"2026-05-27T18:35:41.7309531+08:00"},{"id":"a1ff50cc5809d0d712db343ab0befe3b","path":"internal/search/meilisearch.go","filename":"meilisearch.go","gmt_create":"2026-05-27T18:35:49.7652632+08:00","gmt_modified":"2026-05-27T18:35:49.7652632+08:00"},{"id":"40076534e5136a5edb8c4665ebafe2bd","path":"internal/model/user_device.go","filename":"user_device.go","gmt_create":"2026-05-28T18:57:12.147106+08:00","gmt_modified":"2026-05-28T18:57:12.147106+08:00"},{"id":"7667f4c1d3eabf712a8e93d02391fbaa","path":"internal/model/user_active.go","filename":"user_active.go","gmt_create":"2026-05-28T18:57:12.1479103+08:00","gmt_modified":"2026-05-28T18:57:12.1479103+08:00"},{"id":"9889a3ce458e1d193f3188d12fb4ffe8","path":"internal/repository/device.go","filename":"device.go","gmt_create":"2026-05-28T18:57:12.1487862+08:00","gmt_modified":"2026-05-28T18:57:12.1487862+08:00"},{"id":"7578d2fdc704b288be4b4a6cf9f8a192","path":"internal/task/device_persist.go","filename":"device_persist.go","gmt_create":"2026-05-28T18:57:12.1494162+08:00","gmt_modified":"2026-05-28T18:57:12.1494162+08:00"},{"id":"2c0dedcdaa9c3a7a39fa12d838894bd4","path":"sql/user_device.sql","filename":"user_device.sql","gmt_create":"2026-05-28T18:57:12.1526422+08:00","gmt_modified":"2026-05-28T18:57:12.1526422+08:00"},{"id":"0c676c4075ac3b554f5c006c4ac29b24","path":"sql/user_active.sql","filename":"user_active.sql","gmt_create":"2026-05-28T18:57:12.1532648+08:00","gmt_modified":"2026-05-28T18:57:12.1532648+08:00"},{"id":"d9221643d906c5ec348eb3dd51aa5536","path":"internal/handler/ota.go","filename":"ota.go","gmt_create":"2026-05-28T18:57:39.8298956+08:00","gmt_modified":"2026-05-28T18:57:39.8298956+08:00"},{"id":"88cea44c14b93a3923b010e834c82611","path":"internal/repository/ota.go","filename":"ota.go","gmt_create":"2026-05-28T18:57:39.830483+08:00","gmt_modified":"2026-05-28T18:57:39.830483+08:00"},{"id":"4bac6353bbcbdf06bef53efb2db41064","path":"internal/model/ota.go","filename":"ota.go","gmt_create":"2026-05-28T18:57:39.8341695+08:00","gmt_modified":"2026-05-28T18:57:39.8341695+08:00"},{"id":"cc70195006b7310e16886ba71ae56a22","path":"sql/ota.sql","filename":"ota.sql","gmt_create":"2026-05-28T18:57:39.8347529+08:00","gmt_modified":"2026-05-28T18:57:39.8347529+08:00"},{"id":"44e39bd5e8e7e72cb18dae1f7aed79ce","path":"sql/black_list.sql","filename":"black_list.sql","gmt_create":"2026-05-28T18:57:39.8347529+08:00","gmt_modified":"2026-05-28T18:57:39.8347529+08:00"},{"id":"db487a51c6053d3d7a39af0bb06a5490","path":"sql/ota_target_device.sql","filename":"ota_target_device.sql","gmt_create":"2026-05-28T18:57:39.8347529+08:00","gmt_modified":"2026-05-28T18:57:39.8347529+08:00"}],"wiki_catalogs":[{"id":"78b906f9-f81c-4bb2-b076-5c5609c7eb41","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"项目概述","description":"project-overview","prompt":"为 Luxsin 应用 API 项目创建全面的项目概述内容。详细介绍项目的目标、核心功能和技术架构。解释这是一个基于 Gin 框架的 Go 语言 Web API 服务,专注于音频设备(耳机)数据管理。阐述项目的整体设计理念、分层架构模式和设计原则。包含技术栈概览(Go 1.22+、Gin、MySQL、Redis、Meilisearch),项目结构说明,以及与其他组件的关系。提供适合初学者的概念性介绍和面向经验丰富开发者的技术细节。使用与代码库一致的术语,展示常见使用场景的实际示例。","progress_status":"completed","dependent_files":"README.md,cmd/server/main.go,go.mod","gmt_create":"2026-05-27T15:42:25.0250549+08:00","gmt_modified":"2026-05-27T15:44:16.3667749+08:00","raw_data":"WikiEncrypted:0MI1/XkBoMl0lTbK6t0Cn/+8FdvqrJ62ianMLvZj02elJtBUgH0Ns0veIx1WPtM9wwkxI+/XAqHLxJLlHB8wV7ojrH0+b4JMz5OewwhBN1HmP/0rRww9hUnTCEZmNJO3yBTSwzDP2RxlM1vNSo2miB47OWpHJe/fbeK8YpuBtRbc1xpai4QWWh4AweGy0HEvW9apev3dOSAiTr8UoRTgRToJyEaxWrqZcs+MtHKRAsIrcUTt6ZOh39uAbnNwRxK9M2/DiD+kawezpj/AwiANKfd4KpHSMbzYKq9YTP0ksJkGEAjH/XwM331T75uP1oZ/psvBENTK57EgxUJQIxxl/qi9stybX0Smmey1LJ+iJDAfMqZYbs5BbkxPPLpvmXX8GX/lHaSvSv8bbbhTLnYiN+DawAvAhSIRex/qStKvjVXbzHUwrLiXLR5XSvCX75e6L5cIB4b+Mx86121DipgZvZjF7zEMzArfk0N5yZkwD5XI7a3kzfmH2BaXJoEdULrvDFX7ssODrPjklVgc2gbh9DYJXJ/eua5QA3Xx1lsmOuAQB7a98gCmD6wgY1fk9B5rsKGk7vjeRpn+VjuxS6i0t9dcHlhvXCrR7IAI7ElFcmatn18jtjyzt08iJ/2HJB3lwVKEHvC/D131ZrYoMax215Ho63ABv5IhWhlOacH3EHlX6kLvYaCiaCq7fkoW8IUfIUEJGPYMNiPdNXw8BHHJaE8Emy4eKyw7+C0K//+SPmGgkpVUXe5QBHZUCVde9qeHWFvjX7tIKhxv6DuRjUgaCTjlup8gJ49u24zpnUWcnA8qT/jl0wsGHfJi8eD0LLh0kE8XKQQ/x7QONSqCBwUYpVE0TaFITaD9jPqrfRmH7pcAVggsg7CrxVJKwukwntI7yyj4r0gvzmECsd41Q9FYOoPHu3IjRxN+OlXsp7yXlO8Bk3HtmqmpIVzy3rg5kNXkrwf98MEdjBWvI1SfpRXoliuppIkKLvshYbDq9zj7Gt5l1fDkWJrFTA59HAAa3qxQ1UvtlTV3x563VZo0DZofv2rHQaWxyL8gslH21B3jt1SClPzpPPC2ERp1waFgf/K6NltgqZg+qvCivqr8SOjn4ASj8olJuvcUYIqGIh4Glws6tboVkX7ItQuueGikKKhSflv4RIB28KosR6Y5EvB8oDFTNknPtjjj8fDMAdLye5AhzMlBtH3Ozvd7tR8DbP77ZPX3WIncMv8HHSXGmn8IwwggXYIKJ5fpuepkStOcJLSafRsijI2Jji/9y8ULNSvIJgGHlfsd+ytl0t8xFik3QfYqBtbBaYKauIWmP3opbaM="},{"id":"67d62b58-6970-45ca-a17f-f48cb2ea679a","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"业务处理器","description":"business-handlers","prompt":"为 Luxsin 应用 API 项目的业务处理器模块创建详细文档。深入解释各个处理器的职责分工、接口设计和实现细节。详细说明 BrandHandler、ModelHandler、ModelListHandler、DeviceHandler 和 HealthHandler 的具体功能和使用方法。包含依赖注入模式的实现、错误处理机制和响应格式化。提供具体的代码示例展示如何调用各个处理器,以及它们与 Gin 框架的集成方式。解释处理器之间的协作关系和数据流转过程。涵盖性能优化建议、并发安全考虑和最佳实践。确保内容对初学者易懂,同时为高级开发者提供深入的技术细节。","parent_id":"8d7c257e-b299-4adb-adfe-bc0ddbf112b7","progress_status":"completed","dependent_files":"internal/handler/ota.go,internal/repository/ota.go,internal/model/ota.go,internal/handler/brand.go,internal/handler/model.go,internal/handler/model_list.go,internal/handler/device.go,internal/handler/health.go","gmt_create":"2026-05-27T15:42:38.0124453+08:00","gmt_modified":"2026-05-28T18:57:39.9102608+08:00","raw_data":"WikiEncrypted:nTJcmZGR4n7nsIYUWzxCEHR9BTHxs+LY0EgcqY6ozHnPPg0CLCttcCJZTpOx5+g2+gyrhHkzQ3Oi3lFEBAWcJwtBf3fcUwrFRJbk5e8EGX4xcsGxfS1/pXhYYf16TfYAUYDw9jp4npuj0X/rYLfkfR9WdQpmYMlWQlikEdvKgrAqbPUGal54099u9it/2OLgpo7dWCzOJZ60JhGbb8ZIyUq42LJn+LYcEw192NQhanKyGAAaYtFXP2R1zlCMBZa87QeIgD18xJMF/J10njSiONATTboppzvRNe7sy3Azx9omSpTaVsNSD1kv4pz79fUP3+3KNtqLw/MG/HeiVmkakG/a8B53QLh6HvOWpu5JSTiWx+UH/KPvbrA4jMntoDuQQkhlvVONqn6QKmu/58PpEMOqc2f5gdCPHzjTlb0HMwAz58Fb51FAYTt3mGQAqcC1g0lG1vXW43Co3bTH1K8+ws9DmU7iVBsQ2rpK8H/KrgbClvD/xcIY5InMXX8M0qgF6dYzk5OksCsj2A8wGVjr3Gk5S2qNRukh4QDoaA1dobwhu6IpSfQl6zey8CqgDnxhVXUA3a1iSTwDxFmrVgHq3D4qgj+6yy5ym3tvMWDnMv0QV7Mbe3bOoRIVpEqhH+4aSxj+3GBIw+O0/iw5354hBBnmsYCxjx2vZbTzXnpmoLsEhW3nlT2JOy5tGLdSIwgqSJW9o9p6f7NkBP+dRX5uSkvEHh6C6QD2iLOyiodsN99IImRWzUvJ1/hghX/l4hYjdT+oEQrRF4e/AMtJkz2xJ54Zm/2WNz3vy98JSS2UOuP4RbAmNXw8SxY+vazfSwT9Btb1Jgp8xdYIeaYGxHpZrzec5fi6SHaOQ1IMqq9wXaWY7cf8p2s8We8G+aPqT8NoAB64mIxapPavHZH2qB9w85nvAvQonieJibtyUlklz5astrNv9lx4ZHAe4pOGVWt33ioQWv+RbNE0tsv58NnVNXCH+4bbXk8oj61AC7Vc6DGTHHtX62qI+T2L3P6mOrv5yRUqAP+eFmIk9+k8kVr3nKRK3H9scVsla65/AaaGKdHd3999F3ZK9zRUNqKnUOZziS1hvgxR5R8Cbtf5A/Dql61HGRxvGcy9KdRByHAScwNc6++RP+yHgcE458mZkWytdFDFYcvFaBX6WazycLRGULyr2Hwwsu+yGfRykDDLDlXUGOZOKCan8yP0dsBilHKo04c83HzqUMoXpHnCyLnhpKBc5L52qreausX2d9jrG4TQnzJEGrQbw3R4PtUnjh9Jp9Ryu7ELKJ6Ka7zb0s3zu+LYoQcuX8UdyZWyAquTCL08TtWbQGdgokRdtYpWkdsYLciMP/XvT405GLn9Tcbi5MrlclhCbgk7i/XgKtbllnDeZz+S78pQOeldVp7AvWV8FVn92nW9D2eOHxQGQJa3j82S7+4LIjlccLSCYWdsjYB5pOPpqGxo0oehIgfdiMvmVloWaRMA6493fOTqxxfrtB86Bk0ERFZ0ACmOQP6WhEiuGR2p6BSxRD3LxvxoawalVMWO3MiVP9mdxWEZtLeTaydO8+aSUwyqlNbJQM4ePZLssHBxjAoHdjZ/7HuGMMWWD5C00yJBozC0oyxXB+gF6NIE159eQGCXkdRCEzHM1jqSpjzgWXvLfEJWzVnXttu7yGVgzsvUcAfIKDGt2/Tw3H+MvAruSlc0mPJwEjtSKBfRsT8cZT621tSw/uEk+pbjy0UEzsDxwyJmYrR67b9+jrTw5cUzWcAQvtASeuEwcuI=","layer_level":1},{"id":"591ea147-ba05-4d86-a671-941af668ca2f","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"品牌管理接口","description":"brand-management-api","prompt":"为品牌管理接口创建详细的 API 文档。记录获取品牌列表的接口规范,包括 HTTP 方法、URL 模式、请求参数(brandName 查询参数)、响应格式和错误处理。提供具体的请求示例和响应示例,说明如何查询特定品牌或所有品牌信息。详细说明 Base64 编码响应选项的使用方法和适用场景。包含常见的使用场景、客户端实现指南和性能优化建议。提供错误处理策略和调试方法。","parent_id":"8085e1b7-3658-4490-8b52-9a61f3e79976","progress_status":"completed","dependent_files":"internal/handler/brand.go","gmt_create":"2026-05-27T15:42:40.190927+08:00","gmt_modified":"2026-05-27T15:52:20.2742155+08:00","raw_data":"WikiEncrypted:MpYke5d2PXdqtxI+drCrLtTQMJR2qutlXYM1eplHCPm9/Q2P6fWxhBRJ5bi1YZPWaHS/NqlGVpUFmW1DTLhf/76xGG0D1/eLqVfyND560PlQohHkNSJ7tG8q8rNN0PSoYa8X/dNeOTyE1A+uNuvpiB8VEfTp3tDUy+z3wJjo7Mac9XZxl3yz7HAEroJflv+CMaOLDNpuuFAizP+9X1/8yMamdkg455SQiJ4MA3tO8lvrplKeDtAsHnZMOuRb1k8H2J1Okf9ERLFkl/hajhx/ErZkMXJcVDAafq7dea3WDtuhkapO0hPBNT0jBx23jA9D7bdwpP8HUMhRQofKSrXSGWsNkOXGoTUbtKPcvqSXhQc/9ZnwEEWeVTez5dnt0TzIm14zjRSuX8WW7fn2EC5NSDXky9F0+kI+r1SW0lJAbI3S7/PzXMppdYjT5CIvUr4oUNfXpKuj0hpO8TqMLZU7tVSVTfLxNXN9GhtdNUotltCy+fTfIRE9oX+iVuqgGtGw1XfkviF0TKtN2+lC3tYHFIpPZl0lv2u1hS9qg5UQt86ZqNo0oyYG4iMTW1/PcJjvEh+ZouSCdeb1/NZXAghNVhgC+8CAFMY8ARl4571OoYbQgSJas0Ved/ljSKxbViyBTgk/eadCH+WuFgEUJPidhbhNV95LyTxjvd4d98Fz4GQj2038lVoj9NivalyW4v3H3DG7fUSW/wraV29VqX1jG8ICAA3c60Q5kE1oNPSUR1elSjYrLy3on9k9r8INUoZBOoRUyflFm5B6kmZvm44JlzVpRLRlNpa3erHjDw9LI3thWQq/NO7w72+KvFuF8zaQB3H1VyMGzou5eP9dokkthFbhCLnEofzO48Sc+x4zNRb2ub0rcxs3APyeA95SJ/c3J9UaFr94I+ITvJ+DlDyvoZNjoHZ4/PsNi22elB2RuhO7SsbQKIU3Nh9ngyjEqTmG6c+HSPzeLezD9npjOYrsjxTcnZkMSsIAqZRSPeW1VwP+1y42+EAhmnF9vQgYw4YM","layer_level":1},{"id":"fb8ae541-8bbc-4544-9133-e797be1433e0","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"分层架构设计","description":"layered-architecture","prompt":"为 Luxsin 应用 API 项目创建详细的分层架构设计文档。深入解释 MVC 模式的变体实现,包括表现层(Router/Handler)、业务层(Repository)、数据访问层(Database)和基础设施层(Middleware/Cache/Search)的设计理念和职责划分。详细说明各层之间的依赖关系和数据流向。文档化依赖注入模式的实现方式,展示如何通过构造函数注入依赖。解释分层架构的优势、约束和最佳实践。包含具体的代码示例展示层间通信机制。提供架构图表说明组件间的交互关系。","parent_id":"0506348d-993b-48f2-936c-908972f149bc","progress_status":"completed","dependent_files":"internal/router/router.go,internal/handler/brand.go,internal/repository/brand.go,internal/database/mysql.go","gmt_create":"2026-05-27T15:42:44.0573625+08:00","gmt_modified":"2026-05-27T15:53:50.4735252+08:00","raw_data":"WikiEncrypted:Cbw4rSSRJFTkFIVuyRiw4IoOVu9h4U/miV8kuFep2zRCWdjPBNlat3QQ8xqzDjxqnwEXQuPFqO2rdKF2PS2SXAKzDQAtOrwT0N0Bb1cVz1ybTiUFKF4yLIfZkQvmd4aTaafAMRNgGZZmW7p4Ef5Gb7g6VLCa1ky2b8mBvNur7HulgiwcdOzHhqi+XnXEdfba/+4TOqQvhA8OEJsD8r89uJDnH3WUxmiulVTnh8wTsjZ/sG6IRexTh8wnXF2Z3Pp3eoQrztwivE/v2tdi/tM+xK1ZLq6CQH87mEfFjtJjTQg257NwlL8OIUf7otektOR1U4nLWYMIIFT9ZnLxCRer9o+2+pnhIDCkzxWjQGwexhyS9T7Sq09AQ78taySEDIKsmPoPyWrRxYn284OLFkbbnE1kES3YlzGpQ1BX1HzOz4I69saOR3KsmELHh7P7qZT9s8U17TqLBKRo4LWPb9lfHPc2n9CNtaojQSYBresLm4Ta7KRF27FZXJKCUr2Y7A4p1QODq8Xxz7oxjv9ItKra6FFGv7FB+vqalxx2iPAp824obAuXeSRgvdRFeIQJ6R5siQRJFuZpQJW/aigbXEWcoP3A9m/wfRe0jaxEI100Oj9QQGRz3OGUeAoz62DjwUXCX4AUuMqRKjmjvBQP/xSKnA3j/lKtduUs9QoLJ/g3nrBj+jDR9Q6FoGxuKVUCy9+0QH35x8onGEu4z2bXyyujjA6eCclxoq7ck1+KWQfmShbEqnk+bd9dTRVQMaDBv2VgymZnIMvJEvLJFyAlmW6Bqc3qZkv9C8OH+uS90l66JlXniuUHlPinlQ+3/eJiqqMldDvT3oLvYeXLWjHUquxR0LFTQ9XFrzdxuOzsjbxhKaN+FjNZWN1d/J2TdK3LtYlEMaaxGQGsUxdTQuCIQqyQTc6n+yoXpTJ7xGtIitcxvZ6lOtQnLu2VN9ID29ySBKUeNTEDo6F486yfARaPMVjKVssURgEKlt5pEWVPnPPxd5YgYqn0dNm3g+hU3Esrx9pH0r2T8ity7CL28QWZWdthEpldnZLRdQHK7yf5ZTWBjij9h7ozRglKkjrqYtDyBCwmGNGnlUN/zURSFldO1RvnFPaGPmkGSGZaMA5jBaIqKElGCIIeGQcHEvM5reoBNq6Y71tWRTS7ei1SPsvnw2EYGGgUPzY8HealmML7QlT7utxN8WnldmX+B9tvQ0HNKwQBmMzgxPI0ycy7vcx4Pb95uK2tkKZfyxCAqZBZo2/oFspYlsMKwqPF7RMfFxnD5cQi90gF48iJKU/WEb6aXUbCDZrVdhXzg6IMu6iuziM3fdFSU20A8HaJB5hfLpDSE9S7","layer_level":1},{"id":"6e42204e-3d78-4997-a95a-3311c8fcaa43","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"缓存系统","description":"cache-system","prompt":"为 Luxsin 应用 API 项目的缓存系统创建详细文档。深入介绍 Redis 缓存客户端的初始化过程、连接配置和使用方法。详细说明 NewClient 函数的实现原理,包括地址配置、密码认证、数据库选择等参数设置。解释缓存策略的设计思路和应用场景,包括数据过期时间设置、键值命名规范、缓存穿透防护等。提供具体的使用示例,展示如何在业务逻辑中集成缓存操作。包含性能优化建议、连接池配置和故障恢复机制。涵盖缓存失效策略、数据一致性保证和监控告警配置。确保内容既适合初学者快速上手,又为高级用户提供深入的技术细节和最佳实践指导。","parent_id":"0ba3accc-326a-4433-930c-5b951d4e5dcf","progress_status":"completed","dependent_files":"internal/cache/brand_cache.go,internal/cache/model_cache.go,internal/repository/brand.go,internal/repository/model.go,cmd/server/main.go,internal/cache/redis.go,internal/config/redis.go","gmt_create":"2026-05-27T15:42:51.5485979+08:00","gmt_modified":"2026-05-28T18:58:12.5480638+08:00","raw_data":"WikiEncrypted:qF2VoNuQmlFJjqRbYbbhOvcXQhVMYEksE+NeC2wRMGvQM2IjYFDS9siO1iO2s+wXGt5c4G/rGBotfHAKl+KluyLXHEbz0a+A38FZJBcg/xsLVn81ZMr/D2bWrBbJn2fpjSOko3snwikV7KEicvuTRLfGF1uyRD9yizrkBo2nom1DYa52Btkpfo8XnOiULJEWbAkaFXu2qcl1siDC5gqKolWTJSTBKhMSjDJwDoNQKKpm+R7NHopFNeALWz84s/LWjbZeJEzGo6BXkdBrhuWDHDAidSWQcn2YSZClB7F0tUFfHCffuavr8cbuJNFzmzJug/6JPxZd5eCXXQ75W7dB7JuYBzF4iKRL9ZoYmPQaC01R5qRZ6r6C8rVEC7tdT0YriOI3xY+7K0eYAJrcZ3NL8i9YLN3QSkObDeh9n3FKamCCnB4i4XOfIcPIU2JNM90XhHnEplxHL26HO7Rn8PUfJEL7Y3GC5FhqEu2CAumwwl5akz+vBZa6IBaqmeBnr4vqiSis3u7EDMLyn+eJO6QStt40mR1C39sXq5KjKTmEKrH9p2WIhl2hsydcCQ9ew9Zwgjva44D906Z3ZNWkjaZo0JMFOBkBBgEeN6qV7uC45d/qTvqSW872HEE9DN14k/HUf8qa7RYCypXZuwd1TgnbHWpp6SZG93GSFYJwNwiq91C59AQt/u2gCibVEkuaxXruRvw/1x6uoYqbW+dXkPq6/RrG+2vr11rFdhH0jkHUUYtfKuNh5N9eYPz5RXX+2AXK9GRkItlF4xgSpG45NWdC9OOt6DvrJfmOgOFLeGcxg5dC9L1zPlQyEXVijnQizzMlwU1+lBOReVE9ri8JYa1+KEZutCHkl3j1agwcxJSUEo3nBmrUMP1r97CbyvwuyrpYnH2u+YBOKdSiHw3g8NURuh1/pTHA767PhOmyzfUjF+ceLYHrBL1qyb8wUxCVd7uH+GUyGDl1WwTyQPjwOvG+l6qXYlOzXY/bpb859C0H4Vi7WvxGTLFk8z4AugyIluZzBibVPs47purpgAtGUzo+MbdyOSQUORLoDF1UMrfHykrn3hQUGZOOw3lKtcMsMwySgssnfl2vXhmdBeT41SW+/ydXOVdJmXfpDqhzirY9NuMkjxbeBwMLK/8W+A6kTW8SnsCY9UFLlf3TmJ8Y82C1U+cCRSZo2/eQKt1ArSQQL8tmlbUMnrmSK06FrsKo1tHlx5O7SfvpsLJydts5iWeB2T3wuUqiNTeV59Zl4Fz8xK47dCYG9M2DwN/OubpcMEsOMxNABEIE0WJxa49Jf5k/Hkim+d2BHg3R2uWfDluyDLINFmPSVYSVyhbl/ocFUDWfJt5i15p9Lurvb7mvfT/zgcKnaDqm1IoVaFFxsyQUG3Bfp4ZtVgLbLMGd/mdKBg4OcGXjH9xJgifLn3m9TxrOmYE/PqJmgyh/D4LnCq2byP0qzx/yJDdae+CjpTPXOaCtPdRVBtaaIE9UkXl1TkIG3xQ5nH2hpyFVk98m43m3Z6HDZ+JLnp6bGI76VOnCM9JKi4ZULgHePQMMuT+vyX1QmR7pn8p8XIbG4JXHlf32jiHI2yI35pQntlJWnjizGvuKMVfneACj/f+O69RbyQeF95eSNICiRQVHLH+shkvwaFDHLlMrUduUKWRPmmCZY0g59+Qb74l1qRKrRYfmC80Mrg==","layer_level":1},{"id":"6de9a03e-f360-4daa-97ac-dc1cd1937916","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"快速开始","description":"getting-started","prompt":"创建 Luxsin 应用 API 项目的快速开始指南。详细说明环境要求(Go 1.22+)、依赖安装步骤(go mod tidy)、配置设置(.env 文件配置)和运行方法。包含开发环境和生产环境的不同配置方式,数据库连接配置,以及如何使用 Makefile 进行构建和运行。提供具体的命令行示例和配置文件模板。解释 APP_ENV、APP_HOST、APP_PORT 等关键环境变量的作用。包含健康检查、品牌查询等基本 API 接口的使用示例。确保新手开发者能够快速搭建开发环境并运行项目。","order":1,"progress_status":"completed","dependent_files":"README.md,Makefile,cmd/server/main.go","gmt_create":"2026-05-27T15:42:25.0297402+08:00","gmt_modified":"2026-05-27T15:45:02.5503172+08:00","raw_data":"WikiEncrypted:qfgbutC7oyxR6nMxrwk1ODnNMBEQ3/sG78fQT1yXWju83LC7H/jAM8CEAvWT8huE5OClmQiIfNYNxHQ9s7RRS0qKOV1Xow/Q40Lf5w81YuuThtu0J6OFTGB2L0Nm95mISVZMGD73nREHXw2e/m/hzrb+N8ZuuUYDQ1FQZZcmT6YP+CSB9cZx9b8UZDJ08MCgp50aJvLLku23MEdwFc0gj3Vn9X1djLPuceJ7dwpUG3aeQmdLHCtxnEu4d1LuWHOx9SORMidWdUkvBpxZh1Mhj875BKw8zi1Bb10CuOVR0o/umWOKMxS7pa+P+krzS6ZwgQk/HiWvQgzcfGvyyQkIUoEtVfRQGP8gB4azIvJ540SopfP4dNI7lFdjUOwyTR0oyYuzDc8Y4dPgrwjMNGFkwRmsbMB5f9fKw1JT8+BoOVDOPoK1gHP/uXWcZx9Yg92aHtloj/wlf0IvlSbGhTfmFJrO/wjuSVP5sooJD9GCuVzNgSDitGoZkvsycpn320vlVFUPXtnf/VH0JOo5PM7BMj/zshAL+vsXkYjllDwZWM6DYEyETEwa0kfHBm7pTZ2bMQ4goUU1UQAPAjjbYf9VJAWxLZYVJf25SxXbn1u/PDKifLJNxgXRJg5OyBhyIL6jTJf2fuXyNcczL0GyfRvunp1WzofE6bAl15iIFcNABHPqdtKOV347seHgIIbxupRt/eFgrh5u1k/i5XAKbSXEquVhICmh4waR9rf3HeYisd/Nvj/4cpJISkhNXsY6Y4AsIpbPl0jiMSVt6jMRFgTGG51WgeuZoVPzdIDJMhk5Rc9mot1q4rK434Mrv6TJamzkwU5v7z7zy3gNx1C7wf2f4tHTVCj/Gc4KfVU+uuMRKcAAPB9bBC4uoO6zcPRroMIr+NLZN+g2CdsZ3FbJvsw/j0KEtYP8EeQ3bYak8dmhOc3c/A8LN+8UIlfyxmY1xVgbu/fvkIh9NW+GktKxQZcPfzS9ZE4KL1oKMxW9uavN/xE3hjtivmOAdhyqBhchbo6uwaAtv18ZMNOPoWLrgOW58/NlHdF4abXrwuX3YUwJHiMsjsgV6C7ZnTsYDrwXYRETPr7XXOmztvG+nYXkaHujEQtdAh/mf1KjWTbyY9qBthEG3zBTZ4AVcKt15anR6l8x7Of1pepg67m1lo31a+QlxkvmZdH6vV16tMnYHUR/UHYdSIb1yknP96PdGpWChgEZL4bynWLBFveZQSEhM057qMj39UgMZjHQd6YGbwA3ma+BnBwAMHKZSvFAMWN5arlTN9ZP2iLxhhiNniYPMQXdTviDJPYW2mRXPAgEhheln74="},{"id":"948e0792-2de7-47b1-b73b-e7b246e749ff","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"数据访问层","description":"data-access-layer","prompt":"为 Luxsin 应用 API 项目的数据访问层创建综合文档。详细介绍 BrandRepository 和 ModelRepository 的设计模式和实现原理。解释数据访问层在整体架构中的作用和职责边界。深入分析数据库连接管理、SQL 查询优化和事务处理机制。包含具体的代码示例展示如何使用 Repository 进行数据操作,以及错误处理和异常管理策略。说明 Repository 与数据库层的交互模式和性能优化技巧。涵盖并发安全、连接池管理和资源清理的最佳实践。提供扩展新 Repository 的指导原则和注意事项。确保内容既适合初学者理解架构概念,又为经验丰富的开发者提供实现细节。","parent_id":"8d7c257e-b299-4adb-adfe-bc0ddbf112b7","order":1,"progress_status":"completed","dependent_files":"internal/repository/device.go,internal/repository/ota.go,internal/repository/brand.go,internal/repository/model.go","gmt_create":"2026-05-27T15:42:38.0130833+08:00","gmt_modified":"2026-05-28T18:58:34.9036056+08:00","raw_data":"WikiEncrypted:Zb5TNaG1u/mRrgPr+sDyChJtzwIYFTCqYOjGU3g0QRCfpxhFN6jbespPa8XDdb1bDp3AuvsVCECkcjmD8WGzuQA6ZBzaDsg2BTmcYyLiBU8VUMKIiYZkAulrkNr8z5aDxw1+nRS5dBp6nDppqxYM8nto8gq13XMHfuirzYLQK1Pt7b/pje8qQNKFyha2k/a7oIuV5oT67g4XwDGJ7RMm7YEoz6ziicdsvdBHqsPIakD+pjcyctGy7CoFJHtL66l9kjLjFrdGzLMC1ZyrNM/4+krP4Lqi8ECZ4AevaxQT585ftp4sTAVxnFJjXZEDLY2DbSt7bQdj3EqNy7ISber0CZstsx8lUrtf8VIL57l9gJp8T4zKjZVSR6cMuP2jmPjoTesqib69TIc5hOZjKrlvDcY/bFTaU4hZgksLqXFKEqbb+Q/b6pSa0xMNhiitfx0SwnwKzQEZ/mwtTjdlnAZknsOaYTzAA42bL7BjWcKt10phjGWjKqzAebNCxOFcpdwAnUiQBlh06NrVUtrAKL7/tq4GXREudyajHABJqugaupjz5BkTXCQJtsd+BeMoLJjRa3Fu28VbRQKuLchBb0yYky9r6154m7h/xcmJ+QfXrWXImq/wI+3KAldNaUbTgVZQOf+nNheAEczY68YNQOmCbFjMgXrcXQDchJhUarUhFNIwRAry9stv+S84EVsRw69yTECP8LdzDuaOVBG/pdO08fW2mjioFPEuJH2rxC+26SFvvjTvx2mEe5hipMyaA0wdsTBZEobY1U4oSijj83hdOZdRO9jkcs9M/PpOntB7M08EY1eFQ97fHbkDD7TROTPY353QqtS+j4LWOcwCeSkx05Di6zqOy2emh/bxiLyr78FIBqQlO0aN25btc/97tbM8WWLbSt5GVyS/vH6RtiJprVP/qk4vQmk/Z08LZoFbSiek1SB8LRZbecnoqmpFs9wBAgVJZEQlctMnVhcNX48HuJ+eNWj6oDb01Ih/a5CZ6OnkQMY8hcMuxOions/Pmi6kNdZVR8G/jj/JWDNsg2ZafzyOOkMBpzfEAEomlQKVTXaSjNtIdny9yYhw3GpvowWZXvOMYcYysiCG5UVhvfO2PwWZxN3r5gW+a8UX38l7YOSEO/X11tNmlEeA2c8HeuMzcPfbXUT/m+6ZVUlpMJ9fdsWowyLqmycn2BEYs5VZ8wFNSDzOQvfT5A2cKxtKjQvmOtJirUi3eVS7Cnq9mHNs9z4xsc10tyAdpGXqQ7njMOyfM8ibGwh5fP/KV17lU7DdR5cT84a5/nF87jpUllv5Mo8gTCGVQ1DoBOL8f0ukgJtQLvairjb0CGnjfYvKe+PlTX20evEbQhwBPByBzkK1H6VovV43I9BuQYl+u/pLGzaRy+99Ia4fewoijJYypF6u3gXfb2S+B4TE4c8UzQNjAuC6D7mHUfDNUOZ+K5n/sNInAd7WU6jmgpWNGBRu4BxuQCBM8BbkQNiTQMXpBTsR2zY+bfsvRTpa7BtRR0dHZoiskeB4VFde+OxqFWcxP2HLoBTCOxpDsYyUzWNEIPfhf4+fKKDyksU5YWT7ZbYTukQ=","layer_level":1},{"id":"8b3ba473-1cf0-4471-a203-9a87732dc227","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"型号管理接口","description":"model-management-api","prompt":"为型号管理接口创建完整的 API 文档。详细记录获取型号信息和搜索型号列表的接口规范。对于获取型号信息接口,说明 HTTP 方法、URL 模式、请求参数和响应格式。对于搜索型号列表接口,详细说明搜索参数、搜索条件和结果排序规则。提供具体的请求示例和响应示例,展示不同查询场景下的使用方法。包含搜索优化建议、分页处理和性能考虑。说明与其他组件的集成方式和最佳实践。","parent_id":"8085e1b7-3658-4490-8b52-9a61f3e79976","order":1,"progress_status":"completed","dependent_files":"internal/handler/model.go,internal/handler/model_list.go","gmt_create":"2026-05-27T15:42:40.190927+08:00","gmt_modified":"2026-05-27T15:54:37.2236089+08:00","raw_data":"WikiEncrypted:o5cr6Bo4m333A3G+lRdTT5dIP53cxEH82N4y2QAmkutwkd0KP3KAvEyUQN0CgerucfElkuIsDGzyGuldlZZBSDX//XqOqGZKP+QnmlgMLhVVCpCNWw9EHW/qmIVTQJxBtumOVtR8RGgSMrfzxaMVsu0eL8ZY2bOrDST6r17lVTgdrEdY1nQ8/+B+bkzQ65abRsvYiYrspSgJteye8d8XhEaqyOpAsROLv0P50tvHHJp3pH0uNG7lrGmAIe93f1OqwLCINSCxfZ8qPHLxTT/1qsC8mBTfx6bux1+J+Dfuz0Fr25e9dCzBo06yz2oIHMpYHNOV9TTNo0Cb2bY4Etp7T7BAVAWYdmCPqkIp4muaajavVH/dsG3SIH9RE15781XFeLnZpjK3/6SyXbQzhkntGT6UDzd1f7YIF/wsYN+uji3Ytz2tKz+YuJAr2Eu+YAeR5ONhXxZJufNXZqE6lFG0h7UGc4EYAADRkXK2AefSD9qXzxvGet5VJqYDwvW+BBTRWQB3HtSC4RgwTj0pGPjrHyjdXRtYabw+1Z/3qmXraEjCkcBZqY83T3pyfSdpygE/Tp7yYYmPu94xft9AqhG0xbLEJMTwW0ad3sFR22W7PkIMegzWRGtSSosiRq883B7ZAuea6PE+DdpILgCSAnEaNFgOXp9T09825iKyPsJ7V/ePwhLdj5Lg1Sf2Ar4u2WoKKzKmVNMqngve7AIqYVhGA6hn2tryumcq512jTxKeeMrtTR1kI+kuiFb4598z0y5j8dx7XsYW4ySYNYOvKIRMNvH2r3hnqBb5pvFv9gmk5vsVg/gSNlN4VOQsszd/o2lXQfYUaon0zYsdmR73UvkjhZMnufNa5tiCXZIFdcP1BTWDeBT/f2uOsftIky+JZFoyv9ZKzVesewLPArJaSxOT++MD/ggK/zn1vWZEgWgNcONx3sbyJnPoWEw1TiNMe6pxO3VXzMjnyIL0cie5BeVP1kiQ4S3XzkediOL2bQt4hjEMPkSuuLR7ryE23zbkEZpvwV/2TORoBY12Ii6KK5Ezg9F+aFO5SG2MvF2IZyMgpmnH7KIBfag8sIb3o2RSK6zo9lgRYbXsw7lfxPpBtPyHNpHfqIYgOLYptNzC/GBTVdTQYRLULRlp1XeXxGw8mlViYBltq/GwBlmKbMKrLjsczQPuxFX9mgcnTntc2Op+0ITGX/cW8pMa+UlI2Jgvay8k","layer_level":1},{"id":"ccdbaf47-6cde-4ad7-95f8-5b92d33e2440","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"路由系统","description":"routing-system","prompt":"为 Luxsin 应用 API 项目创建详细的路由系统文档。深入解释 Gin 框架的路由配置和中间件机制。详细说明路由组的组织方式(/api/v1 和 /audio),以及各路由端点的功能和参数。文档化中间件的执行顺序和作用,包括 CORS 处理、日志记录、请求 ID 生成等。解释路由工厂模式的实现,展示如何通过 New 函数创建路由实例。提供路由配置的最佳实践和性能优化建议。包含具体的路由注册示例和中间件链路分析。","parent_id":"0506348d-993b-48f2-936c-908972f149bc","order":1,"progress_status":"completed","dependent_files":"internal/router/router.go,internal/middleware/cors.go,internal/middleware/logger.go,internal/middleware/request_id.go","gmt_create":"2026-05-27T15:42:44.0579461+08:00","gmt_modified":"2026-05-27T18:35:29.939743+08:00","raw_data":"WikiEncrypted:awWreJ4vbyDoG0xJzdo9962/EguU7aHgylmLV0bXWudK991xRrNmlNXm6cdg1D0SLArIcaiebnTiIk5ALRoah1F7N/jEqTOdtqzUGvhnHHdkrdGKp1f0p//OiusAVNsUuzORJk8F6itQjg8sAzi99yjPWuxCoN6aFxuU5DDarymBvIgYK0CQgdSWKWpO3FtV08sV53wIddgHlB473zJxslXmlHxrqhCFKsvglAmKSSt22PPeGPXyKfKPXHvsBSLYicPvioimld86vMFqWGCXDSQDW3kmMOB94ARii5vldIVpP03ADv2SZjoL+Ud9+r8ROzHMdV/WpYKBvnC9QosSPRoQEE47mfXwV+eB65JlmVFTrURS9AImcV6aGhHmevyQMUt/dhK8C0eDxkoAXK/A9/yyWUEmd1NjNWqBjaZWVl/pFeEhR2eOKOIeB+UXVP2Lvakdksugbqcl/GylW4s4KtyO8mNHgsSofjrbh9MLgeZ2qIUWCEMflmtGYyeArjX3XihEb7LM+HraWDvkCDlrT82wSLVUnZAuooAhf/6ZhYBx1CnqvUoBquDId870T7PL/zly1HabWTLrWdBirLIjb7LZnJQCxmjhNNZdEXRTin13TqdurI+qSjJE6h6Cr2QEeblZheFaGTOZWdnZfcEoUKSGnr+4lAiU4WKuT5lUjF1337ohm40FiwQ51Vs0wM40mL5oIqfsgBx0dxpM+qoRn04cUb1lQQmdfUgj6AAC0F3JDVGF9/gxPVl/QMZH8QnUrNiDQj+xf67ilGPLibQkxKL9j5a6im9seqxZ+mKLuyJUNV9DRXXY6OXoYdjs5vzWDRXD7eApmYRml9IXGVOV+wXV157vDK8qXansO0wf657i/HImAUGe6NLP4r8a5LN+gBSbhdwweM8Pql/MIHT418oeIoS4h/7XP+wQuNJI3P4P9nk5ABtNRa4FDm5jhYOMC8nseUHuIvsVbaxiuqEdUsphInfeZ3JUjjRr2D73xXesdkqqfWfRQg/Zs95Tgbj5imbFKEbDXsSfz4rXyeMYGU4b8w7/PDmoEtH5YXvjNx7qZ+1CY0EeShg1ct9fD4PRzPgqg3m/DOQtCDJThysXe40MnfEBWVuADAxnUppmXUjv8/7cRgPRwshyXbbH3YknK8n4ghKebDlNyAI3wdT8DmwYzybxkOCLbYuGb+SyIy+7RfDySsj+RxZAhNtDfokTpBWh2B4i7YgNRc2mhzF4cEarUp/xtE+1BGqvxqF2PCg=","layer_level":1},{"id":"5b9847ff-f7b8-488b-821b-6fdfe2dbde40","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"搜索引擎","description":"search-system","prompt":"为 Luxsin 应用 API 项目的搜索引擎创建综合文档。详细介绍 Meilisearch 搜索引擎的集成方式、初始化配置和核心功能。说明搜索客户端的创建过程、连接参数设置和索引管理策略。解释全文搜索的实现原理,包括文本分词、索引构建、查询优化等关键技术。提供搜索 API 的使用示例,展示如何进行设备型号搜索、品牌过滤和结果排序。包含搜索性能优化技巧,如索引预处理、查询缓存、分页策略等。涵盖搜索结果的高亮显示、自动补全和相关性排序等功能。提供故障排除指南,包括连接问题诊断、索引重建和性能调优。确保内容从基础概念到高级应用的完整覆盖,满足不同层次开发者的需求。","parent_id":"0ba3accc-326a-4433-930c-5b951d4e5dcf","order":1,"progress_status":"completed","dependent_files":"internal/search/meilisearch.go,internal/config/meilisearch.go","gmt_create":"2026-05-27T15:42:51.549218+08:00","gmt_modified":"2026-05-27T15:55:50.6500526+08:00","raw_data":"WikiEncrypted:uPtIvUbMezH0ofnqqRSEthHE63LUAQzlPWMsHoJP+/Xvzp1zu9yMhdQo5+5IhHnrHX4ZOoo974Mq5SbaZHfjDGkMYXk9L6JwG6+nNMpoyLz7Yvtg+8V5E/tIsJ5Kc6+iYBU1An8SAJrGuA0Rg8PKKB2Lomw8RjlQO6aFo5tapv4T8ZcTSCEzPetfEDt4Ire/BS8D0NCO9C5peTRlECqqOr+U+OC5BfaXaEvAAPhu0+2LKV5pUWuqhJB8wS0sZ1C5WaKdq3GSgEsQPwvpw2BQ1jRzPp5Gw92/L6CiOkLBRkvHdCH9dpObT+Fc2bTPTxchCzPA1QxWkqYjFOEzIs4+c9QWuFqGuEbrHq+Ferc28nVGyeEv7Tu6l6m0Xe3CTg9tqdBgkd6r9Y4uV4bh0didngLNjO9xEjQiYo/ssQ7aeCgh5CY89JkKjbhy8iWFLtMr0REWD9B4Tb/USBDRMoljXzRJ+rOWL0o28fL4U5wl0ZRerKn1Z4oHbe2uKMx1+wXerr7aDOXN5JCqdJfUuX0X6xn/ZHUrsqiQHGXkRCXBeXGZYjdzLtsrL01/BtT1EzCiD0xUVjPPE9dWXXwHexSANSMPsC/RJmvwwlMon5lzHXlWN+FkX1N1OEax+N8FY1eBxIWLiwUWps0/IwghwilZeXcNGiuUf7skRlvM6iTjpc9QQeyE1h7qrU5x4xCrlcYc2S4pQv+WEFB6Va33skBqhNrCO1vIUjki6nAesFzcnPJkaWwnmEBipsjs1BuIUK3wxXWrnpgcFUZbb6WvFF2WRI15NCO+jImJ4SSo2vAvVRKF5JFtZlABOifDyJCkfMwUyU227ch0TmMp55pYqp3NoLQ7ixrqRxaPvxFda40SlBqKe2Yzuiqm/73r4Oc0T1zXequgzmTkaZtRaq5yqAJ115HA1HLcYITiZngQbSWTnPeVbWsb+DCPd33lIKZ8fXEGiNBs7vdikdYx+6vF+1EsrQeSjHfD0Ihmk87cLn4d9La5SoLzDfOVJEy5iZpWO3AaUZMZ4EcPE1r6ZMeZ8EUGqXQ9Nlpb4InQHP4W7ghwsYHtL5FFeja4OeMJNBxHgnOAypiJ8tPVobpLX600FfUsZDv09Mcr1xhbylBxsRrlqA7Gn3sOfbt0DZUG0uo0Rk1ME1x2rP5Xfa5lQH0t+tS5FpyP34T6dwqMGEtcccz6Je3BiN5IyE+vUyFHw+FdZ7gNtZ0hDEfzwP2qOWZT+c3Qsu+6MyhWHPs437C1isiJNawoEnOiqCV9kWhig5+ztneMD35zhcCTEgPu/Bm/bEThy3Rdd7iZFBdoU4vYaqKC7n7/DByj71DHngfpIkzvddxnNY3z+MxRPwwc3khnmY7jvA+4rooEThszp2Uu51YkzKA3R8OCZX8akGsfWwzUIQK2BB/CZUj5Y837fb7vEzAC6+ILo7N1OoawujgMXPweHQI6XDnpbNfOnLfNxXqPfgUApYzsPZoGGtPp5WSaiLcCw6qMXPNJVzEQq2wysa7phID6rq9Pl1LQxzlIH6h9p8v0IkxQMMloAiN3ufObHM9ygq7zggt971iApCCae3R6XOA=","layer_level":1},{"id":"0506348d-993b-48f2-936c-908972f149bc","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"系统架构","description":"architecture-design","prompt":"为 Luxsin 应用 API 项目创建详细的系统架构文档。描述高层设计、架构模式和系统边界。详细说明分层架构(表现层、业务层、数据访问层、基础设施层)的设计理念和实现方式。解释依赖注入模式、中间件模式和工厂模式的应用。文档化组件交互、数据流和集成模式。说明技术决策、权衡和约束条件。包含基础设施要求、可扩展性考虑和部署拓扑。提供系统上下文图和组件分解图。涉及横切关注点如安全性、监控和灾难恢复。记录技术栈、第三方依赖和版本兼容性。","order":2,"progress_status":"completed","dependent_files":"internal/router/router.go,internal/config/config.go,internal/middleware/logger.go","gmt_create":"2026-05-27T15:42:25.0297402+08:00","gmt_modified":"2026-05-27T15:45:15.0922502+08:00","raw_data":"WikiEncrypted:EPw1VhZSv2AMLpYzHbCG5QXmatSKh1iukhkKRz99kcWlEvnOwuqXvA4ZgQ6tN+ytovQp8yiqJicl84VZMQ0QFU2VsQju8IpcRws9R+O5UqWqyS/p2d/juMO7CcvH5Z71CG7eM55PPWPy+SJ+QNdupFqroK3bd/LSj0CxhfnVajICVNkUN5WBZxRD776A1wRS/9o+f2rU9gRAuwITsrHMLAbGKP2R4CWvSRvdssG+ipznfcduSvnmuao6OKPuV4jqBbRKw4zcI6RvA8OzqjvEzd71LQGHM4pSLSZHCpXNsVLsyx66RKMz2ehGMgRX9mmwX6tatCTNGRawqOaeHsAdZQVRO5F/B6eOmBUnLjBLXMFaj9NiCqZXNSC4hsNcV2NHNsgCUG4d5ZrRt08xhKOHc0qnU6uPcmCoIrcH7BzrDe0ZgsfQ5XPv2VLskL9VH7jP/iok3665UNTbFEMp+0VrHrtj3MGwZoOPjci63/k3b7LG2CemZFYRL/bBs4bMFcslJ5zofo0Udc21Z14UtDMqmtYl8JWFBrQXBiQmeSQ1WnHwlcbw4u7v98svD3w+hug0ZVtbBIzPxwFMvWxUfRg4bYDfaYuu9TTbJDDZVS6Ob7p0LyJNbyCA5QPrEI1J8F8PhZ4Q4jLG7aMJugVeyzmc86juCVMOMHEp/N4hziN6xK/qRiJHM3tNljxXReJi4IufNYJTXLNXYKvDPvBIyDFn2dE2mCCXqEozsEjZ+v1q0e/qlU1dunYg8xPxrsTLDcF9K1BoyCvSx+UQiB4ONUP+JxX64QXTtp+IU0v0seB2KMrqPn0/L+A8OWuXVZTvRwPavFOv5itZOdJAwA/V5N2eufZbLHqMglD8xPwtGKDElVmGnIo3BZVNSoRZySK0fotmIw3xMqHf/TIgp731ZvXaZCaKCnXvHmW1NCCQkqFwBHBcq3S04NwWv8UMSj+HNCHd++vSABXVmaVxgqblXcKffFrA/gNTjqBgt3JGZZI97/WtLhJ5rCuiZXimpuKRBCG9Mt4/TZBFvL8EtkrKKRM7s3qaiXo4+rxMwzBW5q7TSyuCkv7qZLVNg0tvqAaU87jlHeLK1szXHS95TJbbbwjv67i8S5YYoSfZZg4iWUWizvHjGv9xeSfB5oZEfizx8EkEkD6rutxWWUarg7NVOH0fJqslwz3lkocZU2+RLK2kbH+JbCdYfCoZ6SYU+W5JDYAfSxLyvGhW5sDb3XXYFtD9X30uW8TOYGcvIRawRJbAjmJmdlrT+9rFcYHVaBJHtLDAkEnSUMNTxZgsSUCulSQNjxAV66NfhnKRsTJ2+M3dqXj4LldBrlK0CwEZUrmzutKSXsYqB/x3yFnXshPVlWG0HqDXi77z/VH2PwAlmUZi30yCiL3c+D3rtHVruIK0y7+TJeQIcHCK8c8WmqIMeA6Zauq0wgWtGrI4ShyR+BKhcQEtCGA0ZPrOitzD+oByp9nJy/p/jyDoJ2KbQk+UK+DxYjyyeOGMh023Ioq+pZwhbHjNF8MPtVdr/ZTBpHSWIfgC"},{"id":"e81027fa-c24e-4492-8100-f051facb89c9","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"数据模型","description":"data-models","prompt":"为 Luxsin 应用 API 项目的数据模型创建详细文档。全面介绍 Brand 和 Model 数据模型的设计理念和字段定义。详细解释每个字段的数据类型、约束条件和业务含义。包含模型与数据库表结构的映射关系和 ORM 映射配置。提供具体的代码示例展示如何创建、更新和查询模型实例。说明模型验证规则、数据转换和序列化机制。涵盖模型扩展、版本管理和向后兼容性的最佳实践。解释模型在不同层之间的传递方式和性能考虑。确保内容对初学者友好,帮助理解数据建模的基本概念,同时为高级开发者提供深入的设计考量。","parent_id":"8d7c257e-b299-4adb-adfe-bc0ddbf112b7","order":2,"progress_status":"completed","dependent_files":"internal/model/ota.go,internal/model/user_device.go,internal/model/user_active.go,internal/model/brand.go,internal/model/model.go","gmt_create":"2026-05-27T15:42:38.0130833+08:00","gmt_modified":"2026-05-28T19:00:48.7296891+08:00","raw_data":"WikiEncrypted:Zb5TNaG1u/mRrgPr+sDyCr47uD+4y/GruMCqF9C9nxStxKZi2OWvk4ViC2NJmWUO/Jxugi7iel+AeINiHAz9c+8Azb+FwBEWBjeFWcB+CFlZ+I+bn5J4wU81OgX74fadScfRh11af2MELrdjwJB9Oex/zONPQA43mXk9o7Q2OmSfSLYasvxxzQmg4nybBeP4Zak5fCrYMwokRpCcuSx/lZwO4tvJaGNYKZflA9+k1gY7+DT0kYxG9vC8yuFVejlZz7W9EUDf71ZfEMu964tBSBiWqHmySqRsHya4yhssE5kLx2mP+csNBy569P3P464q0wy0aHqg3pfQa4LajFI0YlJy3wzDJsa1/964Ac8D9+zQIreQ5qmepO0zALEVB+rMxzk8T8Mizx3cs/dd38QYdvDDEiYkEnQFs7UIVRPI8hM6tQ9kozWhVlH1kLqgkLqE+p+kB1Ldeg9MKjR6EDPzLWIpLoKqTuAdSXZbVlibXOqAw/slL+TymANDxSJTUdf0MaVBuMmiA+W5lUZXYAomTr5WHl7hJhYBY+hQZsPL+xoWPf1VkhDsVThdWlxkTHFdT4j6jtGcAXQEtUg3ELEADkQvZTN+bD6409J5Iu/dOTHWU7GXmAuaTLZrpu83Ar6cyVZyHgabF2T020pZhDlpM1gqvoJdnmrVCxUosYhQ7AhQFCKJseo7/eKsfQlAbmTkpFe+C1syiOdB6iMMzGXRhP3gRSVJWuxfj155Z7k65FChGjZCVlP12z+LmtXtwPGpS9mrYawOdC0r94TpV+t3EM4AhnOfRbv9ORBBVh/uPp96KhYB+ZDfg5OPo5m1sbimbNhGVuDQYjRwXfV6fSAD1rkAzgWldcPwEueZiAR2mbJmbF8p2Ecm/qLZVWnodhGooeXjRvGB7wZYNwEXaARkASZATgRgrzj69VgH7h3sbLHYILFvn+6BNcEMuaokgfRUXjy6vHwjHJKK52zhUQgvn63yjuo8FGPE1Jmu6or/VqBEBbVgVpMynB7FKO1ivIs5w0X/Q1wNhgDJ8k68YF6wzyDWfvPbQvGduz5nPlBJYlAEZN18XG91OLU6ZnrfAIWUQX8NVDxiGMx+PxPuDxdhsu/crlZSWTb3eOBad39CDpR4DgxjObPviVFcGWb3SQVpCCJb2YX5PNtZhW2wkEDjVkTs88fz/1msiNeXVx37V9t24GCmmodOFU0W6wNZjVd1tAeymMEXEUra5NZidNGpLpFO51SOXBeONvkgb+iUTznCbqgWaXdo/PDUCVocmWFVRt+UDuxxWfut+4FipVjpkNe67bflK3ln2Em+ti4lipv3mC7mFYfbd1fHP/IaF1IO/ei2E8uOqze+CUDLXbW4Z57ELFq4W7KUYVt7BGNzgVPURSyoxQrcNEHp/7KsXNIYGIyL3+fLfc4s5cRiFsxV6OjnhmTPrArmbpmhCZiOU73iZt8VpBQljA7B/yJslfs+2JDNxHQyp6UW4ziVYCIIF1NZCxz4qi/TYDEJHZzFuzY=","layer_level":1},{"id":"8b7558c2-be32-47b8-99e2-1964009b4337","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"设备管理接口","description":"device-management-api","prompt":"为设备管理接口创建详细的 API 文档。记录设备信息上报接口的完整规范,包括 HTTP 方法、URL 模式、请求参数结构、响应格式和错误处理。详细说明设备信息的数据格式要求、必填字段和可选字段。提供具体的上报示例和验证示例,展示不同类型设备的上报流程。包含数据验证规则、重复上报处理和数据一致性保证。说明与 Redis 缓存系统的交互方式和性能优化策略。提供故障排除指南和监控建议。","parent_id":"8085e1b7-3658-4490-8b52-9a61f3e79976","order":2,"progress_status":"completed","dependent_files":"internal/task/device_persist.go,internal/repository/device.go,sql/user_device.sql,sql/user_active.sql,internal/handler/device.go","gmt_create":"2026-05-27T15:42:40.190927+08:00","gmt_modified":"2026-05-28T18:57:12.255636+08:00","raw_data":"WikiEncrypted:XzYAbY6mtEss96Ce2Ix9pdxXR2iPSSalvpoh12HKdAF/wswNSuHT7M9LgBzNQYibDL1Vr5NrG+T/0RbP/BaCvx+5y+McCDI4SbpXj5FEdn5E5t44p2wMFENuXAy5rxcJ3M8SCzp02eZWRn/KWOutnQOxcFS/at6G2XL0Gqxvfm/cCh5J3nUhWhMTyZFk1dKNOJoT33AYO+laGQo5qRvhxIRnAQl1SlGa5E9AK3V4+S2RzszkCvlL+ilt9mza9MeTU8GHxz9Fn6rKll8/ysPJEi+WTHr3lWeixDO2rU2FpMq30T8i6ulk7Bnj7Ea/lroYASs71zk7AHyTcQjgPJ9Bg6xxN8IB2WhrF/PcWAlVX0GqdCY95jMVZQgcjK3yUjJYNmZmJuj4TQBXlnY9yJQkp8yaKNCwpKEJdwBYVgjmnBHsafI7UCBMOKyNuRs48kRUrnfy2oV4gktpc2hfOWmoNDhQjt1Kv99ubLeuVJihwhqJtKOfHE2LgeF8tflzowGR9I1Z5x2GtRwjAMfTbHF4ps6+SxNq5iYDdYPpf68IG9V5ydiNEwzFQh/0A2onQkftJGQzQGGBaG4Yd6jskanhrVdTtBhJzB+JBFWEVLsp/pW8v2FXou6bPwkx0JkRWZXsem2i/J+gHylXX5QA700oYNkiT2lthaLFl2iEGK03bSr2onjzOyoRntLM2WbYFTU4M3OK+6v8rTU6AiJHHvr6IAs/2OWbgJ9Y3tfmfyYuMQauW2h6X4tujmH2ol2u+ut21aoU+HYNJtJCMir6Ul0LsijRVfGDAYxrfSra39SfXygeCuGc9y8hb/L2n6l6o2xkjRTtdMxYmRqdkEQQ6y4c+V7EGhFrqlYanoZfxVcwGu8rgy6u2d5wXAfR30xofdslPGvv/T0aIFeCcE5gGItMjn+4blaT+Q0tRFAN8teA8QMNnD3Cqms9m/x2jUF6I3/ROwwFtsxl5iB7TTQWZjZxPLhk8/ke0A68moJIAmrompxvwPkgdNQxrmG6JCmzRz9PzIpMhFEVJ+W0wACec7gpymDy9IlwJkCfqH+xq3AUqSNE896v/NHY3tcKWfJgjk43cOzg2GRFxJB6YtQEjWfFZ8dzpC2cVq61sEm4jmvhlL9SfGE2vllnFDO4h5i6C+NwJxz109Ic0bGBn5qrHLHJHbBiBzPY/X0Ni6wGA6pXr+fbHzEgmbSoo8ZQ47LoaDPP","layer_level":1},{"id":"bc6825c8-9aa3-4f0e-96ca-ef4925af0570","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"依赖注入模式","description":"dependency-injection","prompt":"为 Luxsin 应用 API 项目创建详细的依赖注入模式文档。深入解释构造函数注入的实现方式,展示如何在路由初始化时注入数据库连接、日志记录器、Redis 客户端和搜索客户端。详细说明依赖注入容器的替代方案,即手动依赖注入的工厂模式实现。解释依赖注入带来的好处,包括测试性增强、松耦合设计和配置灵活性。提供具体的代码示例展示不同组件的依赖注入过程。文档化依赖生命周期管理和循环依赖的避免策略。","parent_id":"0506348d-993b-48f2-936c-908972f149bc","order":2,"progress_status":"completed","dependent_files":"internal/router/router.go,internal/handler/brand.go,internal/config/config.go,internal/database/mysql.go","gmt_create":"2026-05-27T15:42:44.058506+08:00","gmt_modified":"2026-05-27T15:57:20.0074643+08:00","raw_data":"WikiEncrypted:Mh1qeXd3vDrFfJakTA2LVPk895/C8yZ/nxc225NJgc/vaOsdHkI/4otOCFkjHjzGbvDeu3NfvNrTVuHfsGzx3dTon6sTOx2eqYzt8f1TpTMBkynZ464lQq/2wtKdG64LJ046YBidJFw0ZIeaCnDrSGq0XciHKDBtepVmFvc3BWHO81I8gofhmEgiJhls+KdsMfDjsRa7M0G749YeIbqdVds5ERm7uOgH8tBY2YpTkxOsuOlArfwWtnc/XtjHNW1JrezQd9Mid0eOpxaMqgE8yaFeTmGavv8vNNdwkPtoQaRIZjrbbiqxTvEUceUQYbCYQRtN8pZ3IPUSyl/t5LmjfI8kcvGH9WDuz9YzeYHPRMxg8qhmGItUtY5Mpls5ivH/EIhLrZokNcrV5iUHEjmqb+XCRa4yG0StkWI/9ZNKERgMX67LixsijqQn0vqlkUufnCRPCP87EnYdQqECcP+43/+HHmvfgNL2YqVlrJqTwAbRfkIOiR3RzC77UVxXk9TDkvoSu55Qg5T1DUnOUSH3YHIkfOdMt11bVZaQveJDn8eKF6fBu1S2w0nsgVRJUYN4xWDBb67St1qj/284vBE3o80iLbKGZuKALFUmDfFJrRWZxKz0EkrEzGEHLZlY8gqCMlDvpIDasl1U8U3c4akb4qk+YO/zjLohUFROnbeKRIrU66oQ5vJmycIgrt6M4+rjAVUkaEguxq+ntt2xZNdA99vs2cNQGXIFbb3h6nnwxQfKvVVV//1SMfISmnCs34BYxkwVXBcadfbrEOM6CtcYBMqCXvzWJ33/FXvJZmH/A2KAbLgQ/kpz2RPmPzOUT7cKpJqB9MhC3DXdQfZ4kFUFzF+13sJwXPOJvel1igPgOiAs1rrZV85YJXrrc9ZY46pVGQKQ3yekIrqt0EK0vaAgj5oZyrRLz94KdhvIpCIUMd+M05SmsY00TRk827U95uJFIInVhtoOKMS1CqgSM1yQIa/IIKz/s4LEl2UelFpJEOmaXLT9gan8Bsdu2mXOWE2iDgTUhjhHSx1rYeN5EPajgxJq2tyvfti61Ohcm+s2CPxSV7LBjGbAZq0X/r6myA7lLsQQo8uf5F/GMloMEPtiXUyyLW0EJI19rEx68+ZtpIUPNoESaao/sS5ANWs2d2VH+YVdF+I/ZvuMKKkfIgFbf+JvjYdCHS0qZ94BTAzNJdhWzOqdw0ImHLop6nEwvJI2oJ5GWhZGw9jP0WFmwV65RfKVPOZRZTPvo9W2tCb0ZQo=","layer_level":1},{"id":"f5a7db4b-765d-46e4-9395-af7bbe8d8fd3","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"日志系统","description":"logging-system","prompt":"为 Luxsin 应用 API 项目的日志系统创建全面文档。详细介绍基于 Zap 的结构化日志系统的设计和实现。说明日志客户端的初始化过程、配置选项和输出格式设置。解释不同日志级别的使用场景,包括 Debug、Info、Warn、Error 等级别在系统中的应用。提供日志记录的最佳实践,包括字段命名规范、上下文传递和性能考虑。展示如何在中间件、处理器和业务逻辑中正确使用日志功能。包含日志轮转配置、文件管理和存储策略。涵盖日志聚合、监控告警和故障排查的实际应用。提供调试技巧和常见问题解决方案。确保内容既包含理论概念又提供实用的操作指南,帮助开发者建立完善的日志体系。","parent_id":"0ba3accc-326a-4433-930c-5b951d4e5dcf","order":2,"progress_status":"completed","dependent_files":"pkg/logger/logger.go","gmt_create":"2026-05-27T15:42:51.5497484+08:00","gmt_modified":"2026-05-27T15:58:35.6424946+08:00","raw_data":"WikiEncrypted:U7R4DE1TfAUvjZuFqogRLnOghdG8YONf1+EXGFfCCKN64XPQEDdUeRHtBVRbgq1RTfu+PHdhhtH3Ub4edjV7OQOmQQeOhgljoi3HGtSqPVCQvF+mHbx8hRLjpVdCwHdXLvW1Ns4CDnqx/UVLCA1IVbunG2no8Z4rHywszGt/xnqU1gTE2kg8t6xAVG7XfQvH3irlIr1G7/Y2/+RWxJWLz/5H7tsKGpmrGhw8RSd3hVQPhG3iSp62UpI4Jxk/d+OrEUWPuwqJKtZElc7QKOmFaL2Ou0Xm32XwADHOmjYzJyNTlscSdcecUG5KctRPumjoy0gNP7qCfrs8gUDdHMzL6ttn23qdEEZPNbh+TYWVIWnXigmIb8ZizIpBBvi8lgdSE6OX/M698aF13vXXWYsV/gWx1aMFvyo0U2/RQWwm33tMeBdIwK+36gcgiSFDbE0S4b5hb02VMCuasWvPPhMQloVwTmpRX9jLlSWIxElvqhN6JW9Sj3tn9asGgB2y7sZ5hd9DmoUifCyNwMYaKDr87XcM5YtUgyXFquhGaFcY2+CEND5OlVHePB/BTWoyBiDCLgXpicJborNdI7/Nscjq6w3smcCa0ShFdrQ2c1oxL/nowS+0Np2YD/mGUBQfJGct62LTGIm3ejRTFJcHn9bsk38oD3Cjniur0JFTE+jhM3c2BIpd1A8qaNgOfFPuLR038U+ZzBwSYPk0ujoLLSuHOTfKvppASu1MMZuPFcqe8LG+ceVp0xjkx0BKLaD6HrjbpSDMXXMVbNnJU9shT522RABkZEeCFibRDEdFCO6l4jLtyCPaHZCPmGOvHOj5lizmbQtmuBYHEEG+eGYYgOBv/wev3hPI59DkbhTIXpIUwxQ1+0vjVdabnEPEBVxCuGVGDC1Aea1CzWgqA3FLHFtIDExYaEo5YGKlWQn85tDudAmcoD/Ru2NWdGGcW1Ypp7/NWX/VOzYfaGmEEYVbZm41M/SfkgFawUphZc5M5cRj4OG4/tI8ZvDx7IcwIwu4FwPm+21LyFqD1gm86CbkOJ7lK1BH1kl9o+SMXw9VA3snaZ4GGhpaHvgBFvZLH1oT5ZI8GXrTUvuCfq+i3DrDdnuhElM+h3ewW+lMfyvo6DUCbSK3PvLQbsO8EEhz7rAUVsLkZVc1MS4u5dgtYaZte4H71gQszMPb5kdmZW8ys3JTlZlpjsCOMDj+LregbU7ysvd1xZC+GFB1f9RtMNfyIvB0/60vzV8BkymNhb+K5giaTcSKv94wsV+wIVqxR3DGo/CyCs7AbdIof2wAC5ApaWIxrX7XM87JVZkSCS1I8KGN2fVloq5p/lFHvEn+z0UdPd7f4wsFgOlczB3xEz0FolPe/utaK7QT5lmhGjbdBcGumMq8QwGZYYsZk8z3RCjTxi+NXI9NIx1lGzzdjHtr/l0gIU/8oiKa8KYSVjsH58LX3gtmmM2UImLU6+FrVEaFDK8wBB23SJgK41j/mcvuuwJNAg==","layer_level":1},{"id":"8d7c257e-b299-4adb-adfe-bc0ddbf112b7","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"核心模块","description":"core-modules","prompt":"为 Luxsin 应用 API 项目的核心模块创建综合文档。详细介绍业务处理器(Handler)、数据访问层(Repository)、数据模型(Model)和统一响应(Response)的设计和实现。解释各模块之间的依赖关系和协作模式。包含具体的代码示例、接口定义和使用模式。说明模块的职责分离、依赖注入实现和错误处理机制。提供扩展新模块的最佳实践和注意事项。涉及性能优化、缓存策略和并发安全考虑。确保内容对初学者友好,同时为经验丰富的开发者提供足够的技术深度。","order":3,"progress_status":"completed","dependent_files":"internal/handler,internal/repository,internal/model,internal/response","gmt_create":"2026-05-27T15:42:25.030488+08:00","gmt_modified":"2026-05-27T15:48:30.8195851+08:00","raw_data":"WikiEncrypted:bpQ1QlMq61uqjeQzqQaeFJ8lEiuSQp7TFZGpUgKRJgaf7PT+zt7MmzNkqVEU0hd1ivmcFoQ5NrDuJye6YrJgMhvUC8x94MX9xPrGNOjZI+5X4c+vLlR4Y9di8UWaiF3ePMWFHZ+l5JpFZY14y0Gmj+mg2jg6ynoSHd4F8iD94Ksscd/cHjiFkz5KV1ZDKSVo0Zk43RijuZRD+ZvrVDu0XmtFrZ3alp/u48vDDtq64kS9QZdDuR6Wlu7qiT9NwgX7AiaDJqJ4R7dPgxgm6Mui+BQ08Oeq08iURJiXTO07UxLp+uzs2JqJsTrShJlYr/1DePotYHyji38fNP/IbITC4bmDtRqP/5BMbZ7k9hlh8bGx0EWkS6uNkxCgFDuaNHgykTVXSiKrKRDSWgLmKInyhnzBbCcH73bVc+oVtcoSBXixSUbTl5gP1Ig+Y7wyWeOoPHPDdUn77U/OcrSdTkZNXYm4+/I1eIujWEUg4gc3eye74LI568bySPdOk6ZoKG7u8TBv2E0BC3tLW6pJFD6RRArV26sWYSdHsaCumsfOVUgYjGHkhQhsYwKt6buEJZTy7sv9olRDHoi1qy0k9PbRIDacX2cJll7l0u0jXnnztZGx+9+HQ3H08P26RSQB9mNCVtihrb3zqn+nn/fHaVP6TLlA/fFESM0VIGwPT/3NXgKCrGhgeLaw610W73Kv7Ad4zTf/FWsHJ6uv/LC2qfCo9Zt20Voo8N5CmmqTJah6KgVEvW8v7BoekBUzC7ZPGH4oCJeTk4kIoVfGbX7ACMu5mplivQVLaQWQfMElRG+s7oBrbN95CCShpR7S7J59DpnFX/IbgIScrW6X9QGEyoBrPe4S0LA4tnTBU7d2g8RsZDWloZJZbIBi+isLt1JA6fWqwfZ//t8ItkkzPmQJIFJNOR30i9z3wqQAHliGK0F+EqacD6YYn1Ryvt/d8nhRJJDZ526J2xz8X2pZKja+oeGAwU+edSxkfqjTZ87fqFunqnQMbZ5zjs/JzrFvTHlR43EYFU2vuK9YgZ9UJIHtxvPBAubNcuFc5aP4J6GqrxUrF6h/ZAfD1Zpj43GWztuTnhRy2w8l4xy/B722d+K8VBXpE6k7/b8KNnkM/5fSrqgzE1pAlbi0AWtXWfP8pgWRLo+r+wE+BALUxNC80jMVfYGnnIvWU2rzgcJ1YmWOyznQOZu/mNvoUI5AqEDSCzI/ow+21CW0sEvfypb9HKynhsg0JfiAAPvdBZlGmCYs1rcrjp5RoagygMzTGEu3jQYQqwRC8ctiOr0SIvoGaRfcZ2XBEPnjYwAQv2ZdUT7MB3cDleI6Eevvvz1GwXLldlBytA6hHLrkC3mCCZW0+qJiwahbJ5Ayi4uuem08ScBJFqUVxqndMyTN7+7v98xiEKLumUia0Wn4eDjobEwAEosPbMS2pI94b5xVXHj/QHiBfCTdbnlX+vTiLOFU1YW+322ZmO8m/7EPabziKO20Mgff19WPSw=="},{"id":"e2d8da89-04c9-4fee-8dfe-adfaff79c9c1","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"统一响应","description":"unified-response","prompt":"为 Luxsin 应用 API 项目的统一响应模块创建详细文档。深入解释统一响应格式的设计原则和实现机制。详细介绍响应结构、状态码定义和错误处理策略。包含具体的代码示例展示如何使用统一响应格式,以及如何处理不同类型的业务场景。说明响应格式在 API 设计中的重要性和一致性保证。涵盖错误码定义、国际化支持和调试信息的处理方式。解释响应格式的扩展机制和自定义选项。提供性能优化建议和最佳实践指导。确保内容既适合初学者理解响应设计的重要性,又为高级开发者提供实现细节和扩展方法。","parent_id":"8d7c257e-b299-4adb-adfe-bc0ddbf112b7","order":3,"progress_status":"completed","dependent_files":"internal/response/response.go","gmt_create":"2026-05-27T15:42:38.0136404+08:00","gmt_modified":"2026-05-27T15:58:41.4408299+08:00","raw_data":"WikiEncrypted:iaIcfwdLscso9uJYzNYkBwQmMSDrN359f9FMHjOmg7ClR23tbv3dTo6S+mZPVOhFdDzmxIISHKSsp2mIHtSHucIsRTVIuVJBLVgxbLtBw+vYpBthrkKp7ZsmnvjWGy5He35k2/5gy4bT+0fHVhDxJakT8MktDZ/BR/eSlGlnIY5RrC7zFB41KSVM+DwzGHJ6wFsSBTONLyyruobUVduEU7vzMZj9sgtAiHvFL9P2SHh3KcDKpQJaSF6kzMxfuHz+RjE2JrSS7jCHMh0pHTgddYdXs0A21pKoq1Cz9ewRb59irUcIZIJum0fCoYabjhhlkabgVWpIZZl9yI9tYbNT404kkRaJxst4Jxb567lxVXj7z99S7Tl5HxaCXddNPmiUawv0vJsTzd40DhW2ZDAviR3GRAUDUyfw3/+7dQvIEQR/e/MrQlblG6A55TurcS4CgAI1GLwDIWQneG1pO+BCAgXtQPSmpqB7BgjGxlBSb0Mc7Ozk3IATXCWF2Gz/3rMiwdu/lCfL7wtHHu7F/8j5tAKZVzSyjHmJfXLPZ5kHt6Y7AdIc5TZNDyi/LrJoXnYx7u7cHY15CrJc/tEbrztzQ1iElkaTNZ08r7RV7F32Es2t0ynCOMCVirx+HAUHpAOaAdrSai+26wUse4xRm/FkwNZtv+w2OCnTZs5KwT9H5tUVsmqVWyBhSeXHtGkuvUyqx0IINIHQnBhkIpxCdOwzkXTumXWy8tolLEPQSJECMUeYwxFHpvtC6vAQckxS2amrDMWK/GTvxacGzKQom2peJWZZJ0bUQ3pgm7a7YDJZHCC3jH0cq0BoCXXUU9d95pauWlQP2/IZMyuUcH0X72/xZ5xKYPNJuyeVPVzFTjkaZDzPAbyCCKrXJFs8tjyuNkSuRpPaAh4kSgxL6/G5WXR2Fwe/QG2rpK9IUOEv17HBevzn6Dbty0HUFB3zxObA10u7Kx+3rfpfr6yzO3k7y7wWuKpzPhYJhrIS+TCgBZjcTIteFPYWuoj87paGFovSmvqEB9DkBU7xawc9cRduspe3fMlYvFSHJJnaIDWeejeQuwwFd0JoBgOkeMPtCVTkj/SaZimKyefQLYyw5AAu0rj+5IqJ+HGhiB456prnmou8yIC9ws2NUc/LeK3qMNaM1Tkf4lPPKffZ282PoNA1rMelkw4Vu6gXVHkuVRLdCqcUZteXbuH+Qyr/pATu1oc3mOV34LzJDJs8AC1k47iZmX/sSGNZ957wolJ0WWZow24CiUWZtP4/Pg51r9qwhsqMAp7p602Sup+i5M11Gg09u0cyRanD+hMX7HCnsebpyCyxZVvB9jhaZJ4sNdDLWZKhRcBfm4gGm5v3l1Ep8tABF5fwEQ==","layer_level":1},{"id":"4b0e33d8-28d6-44dd-b90a-57af5c6cfaa9","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"系统监控接口","description":"system-monitoring-api","prompt":"为系统监控接口创建 API 文档。详细记录健康检查接口的规范,包括 HTTP 方法、URL 模式、响应格式和状态码含义。说明健康检查的各个维度,如数据库连接状态、缓存服务状态、搜索引擎状态等。提供具体的请求示例和响应示例,展示正常状态和异常状态的返回格式。包含监控集成指南、告警配置和故障诊断方法。说明与其他监控系统的对接方式和自定义扩展点。","parent_id":"8085e1b7-3658-4490-8b52-9a61f3e79976","order":3,"progress_status":"completed","dependent_files":"internal/handler/health.go","gmt_create":"2026-05-27T15:42:40.1914576+08:00","gmt_modified":"2026-05-27T15:58:27.2611572+08:00","raw_data":"WikiEncrypted:gWB8HBj+8+/15rQhXgtMjCM7vFjnlRAhPoaEN0ftdCdBUTnleag+HHtjerxF8Yo/aNSQCvWghRAmFaNP5Ate+OnNgrZtWxUTlolKrwVliK7qFYneTgLhtk2O0DExsEj8rE3wciXyMoLthA27VSFS1hEh1vYjSsYzEvIq9/P7ebtCx3WZIPnPyfLgw1cXSj9siM5kzk0nmt4Ccf6gZaDZuw0Bp7WplXSset9XbcxKPL+MMIzax7BxVHZuxA+Xr0km0IickRzt8NBUEER7TSRBv327JwCiAS8fQqpTdjIoYZaoZD0fB/NTnHP+9Ak0Q0/FKYlXGSAVzh3CgkU+Bn+Cg5ZTP9yyUsZCouns8PsujUZ2npUR1PLdj9hkBS03HbNE8lSbaX8OU3ViNNk1DL+T4pp2AQ8kjAuM3wbk0fgx0dNKLVy5WY3PlBQ20Fx/tZebK5ym8FUGSHChyldzRq6ZYkNg/glvq7d32Xl8fO5iVdMwkqg1pt1O211CYPFuEOhq+EKjmlkG0WCs/2ee5aQCsJwhqN/Ya6IeDgL+9Db+zeM6x5OiHG8FmYl+N582mzAbn2+xbvZqxlMTJOHjWoHb2LewryAHz2W6QEWwOHKtx09+ET8stLXhUowUkW1gy8qjK+E8U+dj3UNXDeo8cAiAnEvjdmuNwCC15pArY6OHVC9X2U5Vpj5U5NUQu2JMoFgwLq4N3PTIxjJ0A+VzuBk/QcYMjmo7LrfP3y+wJaUZn2vsFEIBQ2eTRD5a1Pe13jvgLYJNHUEI8RJfy1p2pZIQyFO8NTC8GoKJhnSQ+gTu14mmS4S08TCy0fu79yKHrmq1Mxpx9FQeGvkkDg0fwa8pu4D5GP0ERsG/CD6v72/U0UcOO7d7Ncz6OJ+WItEmGuCm3eGoUCNtiJjI5slrLxxlLM3hEF/nte/d/5N2XBVG/xn6/YDvrzqEyAFgYUT/UCUiuGiHkv23qhBSjI24q6ODYIHl3EPfycQLGVtjFwMMFxs=","layer_level":1},{"id":"f351f338-eeb0-4243-921a-eed11d063072","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"中间件模式","description":"middleware-pattern","prompt":"为 Luxsin 应用 API 项目创建详细的中间件模式文档。深入解释 Gin 中间件的工作原理和执行顺序。详细说明 CORS 中间件的安全策略配置,包括跨域请求处理和安全头设置。解释日志中间件的结构化日志记录机制,展示如何统一记录请求信息和响应状态。文档化请求 ID 中间件的分布式追踪支持,说明如何在整个请求链路中保持唯一标识符。提供中间件开发的最佳实践和性能考虑。包含自定义中间件的开发指南和调试技巧。","parent_id":"0506348d-993b-48f2-936c-908972f149bc","order":3,"progress_status":"completed","dependent_files":"internal/middleware/cors.go,internal/middleware/logger.go,internal/middleware/request_id.go","gmt_create":"2026-05-27T15:42:44.058506+08:00","gmt_modified":"2026-05-27T16:00:02.1508768+08:00","raw_data":"WikiEncrypted:KoBWq/Q7Adld3nvKT6YAXjbeYGdbE/D4CStunsqJjgl0jPyMgacfbAcsG69IjV6W+YAUulkiH6yJh6guJ8xsLC0r674enptjON7n1TyvEmDvQ0ts2hwoFwrID/aMzsWc6ykTfCUAJOOlgk4w+ArbzUldUGx6slnJqOHO15q0hPQH7GaO0RDoayr+zF5Md89ka3FMbDJBSe7XpA6zdP+wNXSd04XmKPO4VRjZqmJkxAGC8VFm4yVB97+PFqSyh68UCvChI56FzzpLF/5BFK7vdhB4RKqA66aNRDf4DW25UaKG5whiuqjk/HYzMhxcvIfnxNNQENyjxYlMX1sZy4HsMgkgx/uFM4++tYIvF03t17sV6inMrzPeJGGPuhlz/8276En11T0U+vrBLHt5cuHwwfT9/TbnmX6ii+DQAK6bIQ4TouGACknzbAKKYD527I1FVSQgI9EoSN0pbR8fm6ONx31WoIHCHWp/YV+KoNG4BqHkATQ6ytaki/qaUL/ng+odBZvDmXBjiEPo39VVePVK04bIdD705zKajkzvowecnVXm2AKaMJ69AGERz8Yh8e6TmJNgzoBcYyY4mEun80jcRmapIRl8c8YHgH0NMwaVSwcLqiudxnv3oQr59HZzPqbA2lsjZbIb2PrDETb2QeWum0Fm6rN2Un2jJWVpT0EznojYQrzEaNxrIPMOL2v27AiWIqzQv0GQ3sqciy6SmZiuq2wPG7HlS2A2zZkroeKz2FOR+HQnQPJAYla49YW7f6gn/xufwFLQ2P09Vv1PN1pyxXpNDEuiTqHaVp2kzhv9oqymB7xkMgUWjzJxA3LCPmaLv++QPEBFdy6p8cW4yb4I4EhhEKGmNSkUraKRcmosg4NWFDcipy8qHZXRbF6teMWiB3RRRisWUnfoZUcGgAFFGscCtU6FRbrdh8FZz1dO6dwy+o2iUkSDe5kR8tnRRbjY/fvtiPqMjoBsHuvLo8VgUj/8p4Z2FzifMlFm47HXFcnhNcTyNHadq/BKt32asbZMkyf5mwAazzbaJZ9zE72kKw3V+IXEq2k8PQFilZeDtHzxWba+6jseqSydPEZeopZAtR8inj9373angdQRcahgfTWP2Tu1JM7pp/nx4e/XGXgcV/eAY6K6bheHMiVhe8uqpViCaPM56DFwiJSu8jM4uJ7c2z87Ru/IU7jBjcCel2qrMTwxGrIxl3LJQWNXYmFvWXKFkw1YzGjfH/CiNBiu4ygHy7YalDmDnEePypwhiyZ25shL/pX1OxbV8m/tNZmv4AAk3Q9YjR6tRGu+hpIeQQ==","layer_level":1},{"id":"8085e1b7-3658-4490-8b52-9a61f3e79976","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"API 接口文档","description":"api-documentation","prompt":"为 Luxsin 应用 API 项目创建完整的 API 接口文档。详细记录所有 RESTful API 端点,包括 HTTP 方法、URL 模式、请求参数、响应格式和错误处理。针对每个接口提供具体的请求示例、响应示例和使用场景。包含品牌管理接口(获取品牌列表)、型号管理接口(获取型号信息、搜索型号列表)、设备管理接口(上报设备信息)和系统接口(健康检查)。详细说明认证方法、速率限制和版本信息。提供客户端实现指南和性能优化建议。包含协议特定的调试工具和监控方法。如果适用,提供已弃用功能的迁移指南和向后兼容性说明。","order":4,"progress_status":"completed","dependent_files":"internal/handler/brand.go,internal/handler/model.go,internal/handler/model_list.go,internal/handler/device.go,internal/handler/health.go","gmt_create":"2026-05-27T15:42:25.0310242+08:00","gmt_modified":"2026-05-27T15:49:27.8891715+08:00","raw_data":"WikiEncrypted:aJsVvsatVVT+Oax9nwx6A6Ka1Sy3/Ax3fbdr8CSPsFwpSinOHdKPUiaO43Q3eH/wzCti2uFNYtfdvQWqQWpEsnbUBpqKCbRzHWFAT9Lm270y0Q6B1UE3nx+gx/6onwH05kgU4aSL6Vyf/ZaJTFKBZpR/hASnZEkssdX1yTnZq4HGLCbeLR5p3acQeZtqIab449ZqM5BfhYg1nC4veZGNU0ZbTVY2/+9U92yhi84zrKmyuO7gZe6RpeJW+3R+pbFduijY8FtGcUobIv+f3QcPEH7ZWqwynHO+v7PrlM8OHoMZ4jNowBv+/rK9cg9v/ZMBmZfMQEKxsZsOp3fl4F4qYtSm10mD/w81n+As4xiJhZiEZyEFs5J1d8Z9Vy8wXGEIR7fqm+a9zy8Fsu5byzXecYMhxZS2ERHZx240veYTNST0o1BZbq+K36QEct8vD7FCALNKAcaZ6AOkQ3ZeFQRkF77ySrit0wubK5Y8hJZIiie/lo/zKRe7AcNPttvBv8m/fwMlN9KEVR4OUGV/gJU1svwYIsZZEnrCMvG+y67NRx0KVjqb6L6X54uvguKz7kxDUMczgIfViz8ratyBmUtc4FfEAPRsjCROGGkVoDEN/5w+ZyQXhLxP3xXUKd1/P4J1avMlerh1CuO5ejlxXeucDZUHgRDjHUwBXfwGOMvhjOjwHiCV+WGml1tKFYFwCTMROq63PKS+JNp0RfgSHK+FtVbauDr08rz2vyPg98+5DPKjnqfdczGey2EZtF3aUyS0f+eIwXUXUtiq/w14fn2wmUy4I611KQjjMiUaXGeOEzE6IIDLjUY2tTTxx/aPpqJvhEJsora8N2/6a3xsw6yT6z46cc9FiIhyEApe9UKpdjI1fdeQuYjErjck7jRAWTUhfVXtQU4SeD3ehMV7Y6r1A8qOMU0h/oidZfO1nAE/JYP3YBXGYHS5oK7bg1MAtFEpo1o6sSWrginCktGk52hMNSGoV8nehuwtZxdhXoyY4IXjvpfAFsXH1Hb/mkNuAue8aL73FijK+a6EhDh03TFe0zLWJHxx6x6Auvo7AXWOBCnZmEjakamzlcsky5YeF79LZz5GwUfWnRavEY3T6FwU1CLhWG4vTlOctHSDbxPcek4EYQrGDGh3pm9EKWAbxxjSxaOj+mjfVS/BResVW35tX7QJikLDMO3bAgq1R7pKwJkOq6LKlFGQid7IX3oBWU3vnf68+OZYTo3XbhF1ibJBtGKJo9LJnus5LWKyXL8OlPBZ6O9My/LGSv/u8SgYidk1IqHF9E0GEd1n1XivRudgVPhOyyChOZRTjrfkGYZyCG9JFtb07mHqu1GTttkO+yrSl02PBotGLbcN6fVq9tA+nKBe9hyXj1jRm77qabudCbBq1WfADA3BI1naBKwjd/hkC2WRFu+OobhwEa5BWjLR0S5hhbkX9l8NggWqYhlkNoAGqfQHPfV6TRRUMT+YxiAtQS4xyBRe3hdSlLTfFn2DqhwtS2Lz3mdjaYxot+rBGShwUkEN2YW8NTWAPTsPtxYLGPhsJEGRMeC0e/0pGacNmr/a7f0BDYZipNYXZEpoLO6TRDR2814xSzHlyQHssJNrGjQ7GSSOz1iSfL3l8GvofUZpMwsaNKmd0njucNMBp0oxVTp+o5hLPEwLl45Rkmvpz8NLlhicrw4UvoIUrMW1vLOUsZsH+zfQu//Xuf5MvVE="},{"id":"c79882f1-420e-4d6c-a40c-dff8c7e8988f","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"组件交互机制","description":"component-interaction","prompt":"为 Luxsin 应用 API 项目创建详细的组件交互机制文档。深入解释从请求接收到响应返回的完整数据流路径。详细说明 Router → Handler → Repository → Database 的调用链路和参数传递。解释各组件间的解耦机制和接口设计原则。文档化错误传播机制和异常处理策略。提供组件交互的时序图和数据流图。解释异步处理和并发控制的实现方式。包含组件间通信的性能优化和监控策略。","parent_id":"0506348d-993b-48f2-936c-908972f149bc","order":4,"progress_status":"completed","dependent_files":"internal/router/router.go,internal/handler/brand.go,internal/repository/brand.go,internal/database/mysql.go","gmt_create":"2026-05-27T15:42:44.058506+08:00","gmt_modified":"2026-05-27T16:00:37.8856299+08:00","raw_data":"WikiEncrypted:4Zqjl5aZEo1Vv5NKBpebTvIjOs8PtjUiIDyDFsBcQ7xcxPCSMrQFGywF92hdzdj0/Ns2K9dSEDwOkKxz9EMCD21sNknfTIWpC88CWR1X7WuNlX6UdseDM8NhczwhCNaZN3vgjI2RCnPQ3swJEmcffGwsCSYh9whfm7CRrmT1BsJAsL0IISPTl0j7Dypz7NiXQSwlVYOWLyyU9AbzCZDbJ3PpxFYDDzPxaDuVWPVPXLf/wiv9mA5vqzDDmAe1dkhs/NMef3G3n7dFGNy8bE2Kb89TGY1mWlLXsD5yz8TOX2FASKkcwVpddx7H1G4BCCeVxnXrAcc8YtLwtNLqhtYwO9sMQvaZN2pzzBQEBT+bF1KsPSISX/kKBTBc8lKQzbtXgZmpqxMtrqwNvB4AFvHvruBwy5i5usgPxShB0x2ZSOxEQKepTRqJ0sEJxpCG19CRKrqMYxxZMufZecyJcMUUEey9yDRO/hzyy2/pZqn2ZFzkp5KdT+gamSrlq3mJSAJwW1wr584b5P2Bept3By31QHtVKY46YC4WYYzzF1oCjY4mxHTxeyK3KpEfyLa/UEH4JnKUxpA+XrgAxuGhWNQ1XSDiZSY0bXbpklSWH5wVZx9XrhNt1Uv4/Y71JhvdR+D6xb0dEQGbyblvvsAJ/FVnU0+D7VEY0HA3iF8VkSWyCEqfQ/JIf8Ek9Q5LAgQNfEMhoPlzjGIQgoKYiJiPUQYjn0iYa7VDL7waXMyHlwcRIghsmI3fkNu8lRCggKYPTT7Q5qbf+1dABN8HQfKSQ4G3Fyki8uSSBxsxPNBAv1YZhpejX8VnKJ4bcTlb7j+urjrCDfKdzBS3GxW7JA4R3YybG4pIpCHM1znO6FBc0Vw6nOB3lfGW47z0MjpFN3fcV2sOG8ckI47G7KXLi5mabdHP+LyR6s3mSWlLLu59L/RXid0QNasUkkPc7dDbDL9DeRvMlBo5s/BB0qZ3OplmHq79N7OvD8hC8Exo5pNRlCuQXyk/ki56Z2SI5K/AGP1lMNV0tGKe91nJRDGKcxar2YY7tk+dtyGPslSVCeJXmY6OBED+ODDNJ8Ro8sqnENFk2pjIC2z7i8EinBYXDVCn8Fne/tZy4ylO64uHF66MPf3pwmepe2hwAyEDF06K+eddiX3JlmF9xi7EaZS+y+R6h3ktk3ku4KD0Qd86UyfJ5b+r1X4JFTmE2KfIaTeUpCRtOdXJ","layer_level":1},{"id":"cc6acec0-b687-417f-9c93-00f59162cfed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"数据库设计","description":"database-design","prompt":"为 Luxsin 应用 API 项目创建全面的数据模型文档。详细说明实体关系、字段定义和数据类型。记录主键/外键、索引和约束条件。解释数据验证规则和业务规则。包含数据库模式图和示例数据。说明数据访问模式、缓存策略和性能考虑。指定数据生命周期、保留策略和归档规则。包含数据迁移路径和版本管理。涉及数据安全、隐私要求和访问控制。详细说明 Brand 和 Model 实体的设计理念、字段含义和业务逻辑。提供数据库连接配置和查询优化建议。","order":5,"progress_status":"completed","dependent_files":"sql/user_device.sql,sql/user_active.sql,sql/ota.sql,sql/black_list.sql,sql/ota_target_device.sql,sql/model.sql,internal/model/brand.go,internal/model/model.go,internal/database/mysql.go","gmt_create":"2026-05-27T15:42:25.031564+08:00","gmt_modified":"2026-05-28T19:00:07.241746+08:00","raw_data":"WikiEncrypted:Zb5TNaG1u/mRrgPr+sDyCqW7t7yX8M+Ha+5tSgGfMUOChQVv8Rc8RrXA+lpSqmcv/gkaDzP81agTYjHvX46erkcNbgg7bdT+fvoLj/rc+rqdCK8HPS1dJNQa7pwJgvxoEzP7DmFep8ccbaUJMHpZELB/2HFuk6kEbjnZ4Qlv2yTZ30BQYDU26KGWpZrVIR/mBdrB68nkMk2qLd2gEHgI38K/eqVRE9jrzbHfLqs4colLR4/tDU07XE2a9BiOVZVuEsBkF470QjH3pZNcGPABKUmwykIY5HjsCvfAF2r62uodWkEsKt77Y4x7/LwilLrfWdN4dGKSF5WynXaAGQcU7/pwZUv3nvY2ALvFDShZh6+m6BDeH0xWevJz1r5eYZHjIqFRHsaUn8De2OJg/ROSiXw231hqYql81KvD1Oukumq1737qMrHi1Y5K+yz0ELcgWwSLoxE8hpoFWrO6/n6xaS6zZlvr491Ao/ww/lysgrYoQxmza7na6au5tMkkf2DaHYpWKYhPeAk/0SZdUPjQOa3nju+XnzBx1r920WqBTLrlwCJQ69aiTNan1ggeUve/gDfyl3VTDKymPDJ9p5JX4nSAwMDabG6oS8i+FBvGmDNMNyccX92unl7UekF3ogR0gAezKLAHqKu9Whfx1urwmL9xjgncdJ9OzZIJVFVRQh8Ufg5QgAt6cZ3CrfBZIy4PKhQHAqKvEeqGSPMTMoffcQ/sbXnxR7MF9CGGWTadDTfTni9qs4xkrS5XaskS0ea/4IC8ZQZWvyZUY0AfERf9jrfVMasGd/vGioBGHwF69gBo0gTaucPfDAi55IT5fz9ZXyYdzskqdRU5/R3WZIbUwzP26fAW8pS+0Fi3mSVn/+wV338jBhtHzSpRfr5Zt38gUZSc9UkIA7yGp27dZF/Yf8HoBTwg9hcPm44WYB8oAChd6sgoqCIoVJYCDV1QZQy2ocqn06cX0vMPXHMaED/usv2h2enFcl0Gu8WXiS31qxfVxU/Nr0vHeIR17NAVyWFJaj0ztgLJ2mI2QI42ddi1OD5UwxsQKioYrZIsy8zAMHBrlCaPARFIjkVjjBir5PcMpuNElsqyD6jZRUDsMHFwlqHtNGs+3kYOd/bZSgmogwp+X2LjoVpNF30dO3zXVh4lR77DaACFRV2+opytL+HC73vtDNOhEQYe7JRhwqN1E1PObfWRwFx6eBBejoStP4MSRM12WxIjQ7ayCqeLn9eYYmI33vOdQ9MsBP3AdWmfc6hjyAjJbK1Av0b5EtYYzIwh+muf+Uyhmr0LlQy3Qg175jOkz/PpBMssZOl7fgjwP60IudU8Cdaa030Jg4ArdCXGs/kaSoH9PgsONeYpa31XA8m5VGPH5NzknBQ1wmQxb8XgBIS3nOK+zS8v2AsBOjFjjGSxMTohOkH08wtavKjM3PhjTla47zIiivUMvsZkeHPsZFY1wiu3aZMx6FwhfSziOhvjLEbRVvQTat5TfhtGryjrxkZO6h0SkyRBvmYQfAqM4zB37iD7V6JdXLu0RB9kGjAFlyGFWAHWzmYNJ5ONrw=="},{"id":"0ba3accc-326a-4433-930c-5b951d4e5dcf","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"基础设施","description":"infrastructure","prompt":"为 Luxsin 应用 API 项目创建基础设施组件文档。详细介绍缓存系统(Redis)、搜索引擎(Meilisearch)和日志系统(Zap)的配置和使用。说明各组件的初始化过程、连接管理和配置选项。包含缓存策略、搜索优化和日志记录的具体实现。解释组件间的协作关系和数据流向。提供性能优化建议和故障排除指南。涉及监控告警、扩展性和可靠性设计。包含具体的配置示例、最佳实践和安全考虑。确保内容既适合初学者理解,又为专家提供足够的技术细节。","order":6,"progress_status":"completed","dependent_files":"internal/cache/redis.go,internal/search/meilisearch.go,internal/config/redis.go,internal/config/meilisearch.go,pkg/logger/logger.go","gmt_create":"2026-05-27T15:42:25.031564+08:00","gmt_modified":"2026-05-27T15:49:51.0048099+08:00","raw_data":"WikiEncrypted:sbHxgqwNaIQfuetky2uLRyIOX0QcV4F0AILzzQc9GWKM9RbXWkeyZypYurT6q6/jdshRRky9i8euWVz+RwzDEjLSf/5TBE5hqVfwtdoniolHNIvg/V4U6o0Uy5LnDr8i+8lIxu2oIBTUlsaoAv7w5iNfekHSt0q6goXepa4aMrqdtCXd78BSUFzGGoqTjFCImp9K2wkx2G0tXqpmpVp7tEiupbmaekaydnQiLfWCTsuAhiIixmNf7zhMvQddDdz/vFMxg8EgQjBYCRrLJfa59w1dwNOsh7LD7B0xejH7YnQkazsXQPDc/l1CAXfLcIcNw18T1VJ8pdgRZVu74q4BhQ1oz+mkyNXOXO7uFYyROvZ9+SHCV/p2M5/xkEo3CqCAP+CEI+59/1ozZqaYwitDifyO7wkSXdFb88+pXlAGZCDRQ9iQ/cMLmgrf0UWW3ZQdLAgo9PRlh3nTWGEe+/rkwMoVKFhvAJBooUPS4OIGSMvMAHQrbwvx/poFrNYVDC84lwkm0R3PHjhB1K9cOk9+6tZ/6F7kp3XdCVAhc2U62dBlI8hDoyGxT1Jl75o1y6mLlxFRleUEYQIFasnt0X1GgKG3oeRJfDQBnoW5H7CZ2Q2VQG/Mam6+pMMK/r9diCnIYM5ogiqUj7tr7iypIS+cfkJESScxOnrfQlCN0Qkd8sEGP4K1s0MOXaL2n/I8jL0akBuCdC6r/XwkXXVuwyvONhBo8AKhjlw4Z80l8g9IfCLE516hSHdAvPrqJdQ+uv2kxoDUCbdnki86NLEmUIu9E8Cg/ctAE8bB/3EZ8W0jCiwjkJMG/7zWgjmRnEZEB3qTVgtRa2KlCUd2QJmlRplYoHxZpXr+SKdJwnlA3vad9yfoc20k1McD/WIU1xyYcMO0RlCh7D9YFySaMEU0ajxvhY0IaEzEkSksTTGrckLMEjYGic+cCNwIIo2yh4+RiMTixfUw95/Beb5C6YA4wOzhKhEYwBsyKI1mRNwEf9R87hDhmK7a83qw/cRy9X8q37PVUu4kfKUP00SAvuQVxgyEp5jO+UOmYubsAjFLqt+BLYCvX1BLVs34bTjTZ7UdPkyCewtgeK88zHgLljGSzyR1bspq4eozKjqoiqavFLVqYzTtwTuTtg5HzkqhFBkHceFCQzoxpbcgdyvxHj7rIeuao76nbRqwWFxM0CL/w2bwd3YhIHOUtNX1PHq5deeuo3macM8moQOj2mgBCoh3lJdc8w+9qpT/nooQSlJfOQ8o9+an8h4sgvMbAbGt6Xt34gkJnbQ57qn+h6fXefwWrxaekNiXWaEYYRQlaazmSk/IH+Shr0OZVtpWlkFn7FjYCqe68ScAMyhmZUJ5Pkw+Y1rENFipss0BlI+diw2G12+r1GuERworaWCvas6w5A3FkFKC66BELhQjLk0vsY9c19ea9GihiHshbDr4OSKya8FZ5nM1jK+4vN63WFEnIS/vVAg4NxpzpBa91cZOB3hHRNKWuG9Zv2L5ASdR8D+2EwNxXV+A0vv1YgBt6lCQ/uDGyRePhYr0xyoQ7QfWpRQ+EkUPCA=="},{"id":"f4f8585d-1446-4f49-85b2-efc715bda6cf","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"部署运维","description":"deployment-operations","prompt":"为 Luxsin 应用 API 项目创建部署运维文档。详细说明构建过程、部署配置和环境管理。包含开发环境和生产环境的配置差异、环境变量设置和数据库连接配置。提供 Docker 容器化部署方案和 Kubernetes 部署示例。说明监控告警、日志收集和性能优化策略。包含故障排除指南、备份恢复和版本升级流程。涉及安全配置、权限管理和合规要求。提供自动化部署脚本和 CI/CD 集成方案。确保运维人员能够高效地部署、监控和维护系统。","order":7,"progress_status":"completed","dependent_files":"Makefile,internal/config/config.go,.gitignore","gmt_create":"2026-05-27T15:42:25.0321059+08:00","gmt_modified":"2026-05-27T15:49:39.6683467+08:00","raw_data":"WikiEncrypted:0IKfLNOWe9mZfG1jVts3w2XbjO+yyEmY3ONOjrL5GjA3YcCk7HFAQ1etKc5i1P7UH3oVY8Um0qaAPkZpvBj4kR5+MfLB2lNNE8Rq4eigRbWcSc/FwkPYo+Lgq1jG1nwAdVBamYbeC5rJp9miML32uAYGdDFNBUjcZautOKk/RnMVJbDBhxk06H3YR9uha+agF827jtBxrCN+YUD41ewpmu39XkuD0mIkISY0mw2kTQ3+d3o8egfEhqEtpYEFWDr4W3bjpZzdlqibicqkrLymwjSHLQ25Yk3RDRLQh41MEe9NzR7Dq9pho9nnzV6lVFI/+D3aLuQmEW30BSE9ANU6hjMLS2wzjZI20qiE3EYf9+/cetjKX3PuzziuE6FOa9zkRQET5Avno4lvS+dZE+/NCsoLeLBSpEpHChwy1FLMangpeABL3DMfOcjKBI10Zckgxc6knhlzmH7BYem/MGjE3gGbpXcSOYO91tlzjpTzkA6o8IN0BBKnVEm5ZsnA1/bpvtl8iPNcBLSvEh8r9nsvT61wFloxMMEwoqk4pfGxfYLYpLzHK4/B7kcP2F2ZxPsLNKguH2P+W5Onf/VEoeoeUie2shjfuxNczO0o+tk08s7YDF0suC+hauvXM8A5MtTJFjGAcXk0PepsGbBA15NaUxXQL+T9g4ZmHiM+HpXAVuFUtKMwAoMX7ejSmhK0Uu3abxpuatBFVQMyMn2CtFqbZ7qowCiFy8R+N8iJK+CNvcQX2UDetV403Hy9t8wz9Mb7zjigKo8EExeqBR+6tdzkd2jCxuo8oGTUNED9jyF3yEdLlhvryX6R8fmWeX6XaIUdEfwqd3lefqvppQLJ082CWs43k5Sa3wBYSrhvhINvH+qH2TvKZHwT6jdxjjHkPO23f0RWwLtVr0KwjqIYa2C5ujlLLUzPccXXZozTajzaXs4y1GIXIkjQyN9gkvew0CQdmqcwIakk6B1cd6GSvR2R7jI9aORlvoBPkZZZZaWccD23SJpY8S49pk6J1f4pp8SY58Cs5Tyhzyr9Jx/g0sdQhX5jT4NOD4vFTMDi/QwlxJVK5aAMEoni1Xixkn86Mvy6YO+C0syQmDIeaWwTw3oaJtKkp0rbEph8ikP8GV+vYas27rEHT5ikXy+qKaSpRTrS6pIvqMDTr46wYVA48CocbQCKuCxz+8aN1rxEOyVvF4BZIOGK94UT/86do17dVZDlKWyrMHyapzdcsG77AQVqx3wFdVBRhW+LLPtZ7DjrJ9MbZlWCzqTN+MPtV2pqJpf2QM5tK7xYlv8Yb6jOUmKXAJ+GSoB6Lnv55zJALFR7zYrYJqdnAOfLrd0Tx7cB5v+9"},{"id":"29142a7a-fa93-4a61-8ad8-c35c1b047599","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"开发指南","description":"development-guide","prompt":"为 Luxsin 应用 API 项目创建开发指南文档。详细说明代码规范、测试策略和调试技巧。包含添加新接口的标准流程、代码审查要求和最佳实践。提供单元测试、集成测试和性能测试的编写指南。说明调试工具的使用方法和常见问题的排查步骤。包含扩展开发的指导原则、插件机制和自定义中间件的开发。涉及代码重构、性能优化和安全加固的建议。提供开发环境的配置和团队协作的工作流程。确保新加入的开发者能够快速上手并遵循项目的开发标准。","order":8,"progress_status":"completed","dependent_files":"internal/response/response.go,pkg/encode/base64.go,internal/middleware,Makefile","gmt_create":"2026-05-27T15:42:25.0321059+08:00","gmt_modified":"2026-05-27T15:50:56.1828091+08:00","raw_data":"WikiEncrypted:F3QgleoEfoy16cQggYe9C/ucQxiwh0okVA48AmODs5RKNS8ZgNngqmnHSFcG/1UaJxx+3dUn+EkMTpYUsOg40sht54cXVXsXhnq+u5RoF+QCaIHA1bGkkQVYVJAIxj7oosqEK59VnFAy3/dJV3KPSb/Ak2NMFBLBF1vGpBDxfvX3bT23bfnsRo4s15uorwKaV7X3HasHsjQoW0eNqTYHiGBulek8S0+90Xknrv9THoJiqpJqkBeofpQiXqX5V618tXTFFsKRJ6phlpbQWf2cbMabajttNJ3B44KtoJSJow48koViUqq1GW3BavJLaIXKMSMHmg9oSjXlTiTYcEEZKa/kYEu4HzH+CTxYhmAZitafJJSGarLyIbemD6c9dKLK9Frtj68/dJRxA2JDgVe81LYeb/3xRsBom0r4YzT8A6hHZcszh4H3wvsJMywPaPsmmBX1tXvgqCTmKeNH7dyLyLi3kWUTw9ok4pV8mMbQVe+tyq+dAjkFZ19Gg1pa48jOuq3XNtyOUDkFwzf8ENVW6mMjhd6eh1Wngr55aY62gP2kA69TRUUa7xCg4pPwMd7kukU9I+311WRjxwqdx+K9z918Nh+Ehzce//3AN16rOPpfJiqCBsWoIGofgkkvOrhJXb7ZBSV8svzmyNFJAEwluR6iW6JSQF8aYcFWeQvuFotN33nkyOjukcXDEGZsNzH5UtAJyLrlT7/Or9ByIMARY/bLEe2ttw4LkzwPX0zVri6275Z+Tr+vS1tQvbizhQX+2d6jRwB57dWTT5wiNTTauC0iaRxAQAQpIiilb6edtE9uJDim04tl8b0GkMJvSCCVUwIKIl495jl1QK4bnCVwbXf+Nm9M8b2DoPU91RhXbRUH0oa9hiK/MMmM1pNPt8sIQPodxmby96ls9G7B9FZz54hyvdDRZXOoxueOW+qswnlAT8Pjzr7WYDEFWLqhVHl3YjAnYEyvqPyjLV10UlsnTu74OIH6TGCiFnRNdEUNrebnly9HRW/qPROmHDa6/S39zhxd/Wve8OTESmdoItuQITLhTn+hUnhZoQBVVqWJwAYFrayIms6xJZY8R31ZKxaxYGd9xNCp3P+7To8IS9yboFTqky2xkebLSLfn+HS7xe0MqZXcpzdCKfivdIbm1ebxh/61TCdDH2Wx1T0uqMlwy70jnT6dzzS860fOuXLUw+3uEIg/ohj+iqYOEEPHAIG/ADJxSwbTR4/RjVzy+yaWUiKWxLukEG89+389O2WLfiqMNBTDEZ4+iXaBOjZ2i8yTTW0xGChxJcCUGPmug6KyNPvoEDLiPot5cTWScQG04DSfIGUnVEqHKDxX3mS/pZDnfV2OkxwUfNtqXdYzFlWBWnI9TxnL3wxXTu3eI8SYHxflga+4BF6OXBwi8eu8DXYDarKNvnEn0JHi0Fh8VVcAoZmJeQkJUhcvnhyAKmJ0tD21XmK4/7ZcFZ8RuBkIEpDy"},{"id":"4d1d9a48-feab-42a0-815a-edf76dcaaf69","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"故障排除","description":"troubleshooting","prompt":"为 Luxsin 应用 API 项目创建故障排除文档。详细说明常见问题的诊断方法和解决方案。包含数据库连接问题、缓存失效、搜索异常和日志分析的排查步骤。提供错误代码对照表、日志分析技巧和性能诊断工具的使用方法。说明网络连接问题、配置错误和权限问题的解决策略。包含系统监控指标的解读和告警处理流程。提供生产环境问题的应急响应方案和回滚策略。涉及安全事件的处理和数据恢复的操作指南。确保运维和开发人员能够快速定位和解决系统问题。","order":9,"progress_status":"completed","dependent_files":"pkg/logger/logger.go,internal/response/response.go,internal/config/config.go","gmt_create":"2026-05-27T15:42:25.0326686+08:00","gmt_modified":"2026-05-27T15:51:51.4638338+08:00","raw_data":"WikiEncrypted:CaKOW8OSSWs4aEYk06Hu0hGGy7zXJE5t3XZJK+9x87Wqy/1Xzi+22LbOfczFZkieMj5WEpLZAHMOxW2WrQJBBBBLWDFSQSfMzyLUONYz2Nl7KEGwStUbBydq7XRqsFITwnt/V34PJe33lfOUHLZdte9ZHqIcBUofSz417l0pyB/LxfxiLi3iV7uxs4nc6n2EFO0hgr4tRmmgaEM1CEq4EgiztB5945G3QMRbLtVRjxhkZe9eWYo9vc2zRYWsyCp6nsjGToiqmfJff57lDOhyn0MhEnJamhFrscVK3DVyGf1SpxoYkDkFQ8OxuxWIHhAN31k2cpGQv9LmsRHcL8ratSFNuE0JPDtSTdY/ZWlXZReIKt/Phb2FMvUA2BI6cCF2Evsk8rpZnwjGsdOlJ+sGevLXEX+KO/9vz0AE6s+rE5u71DR5usC6vuuFgFV4FP7o+3Lcj81SBIu9V+wYU4GkJfPm9eZdFSFgsvHSuqFzrpdlcAeV0XMnU6wZcRaZy/8ZdaUJaIWp/K5jIqfGuxtPSOD1zDJ9Vw0jCLMjDlUTY0Wkzwykxog7i2SnG61vtu/eLORV6aTh8tjNhzdBwbROp3XlsxD0Jxg41JcDSyt4dpyQ35FAPBMPr7Mb3YeD4W1JWqrn8tR5Q1goBmPFlekKRd1XmyYQSZsK4FvBVOUBeCzX1UO7I505eXz/lN/ZG62xC3zhdCt+qCOxJogd4T1f1Nux404SmdsvewY4mg5PnyoinMtMIMX67YY+iFfZEedlNURipIOxssz0zcp+qeJXI9lwR58sgAvpu9JbTbVQJv4I7n1XM9CayA7Nhd0WXIh+yChGMyFdfq6BDje0NtSgi44k/h+mFUk3BqzfQWasqg7rPzAKjx23DY3Wf/8AvNN7IpP2CH4yRynuCGZim6B1AEqKfL6RCsXi3dpi6y6HmEO4DRk7XL8l9c+vWr+u/yI6A9OGZtzl8B7MoVhhEuuTvPbLCrwnHsU3VReA05fImoZPThjC0vYsQuP5jijDtjnjnShV/o1rLBat0xPAhTT0+Ba23IeZGODiU8yg7NtgprzmcJSS/wFzeapmPZYCB70qjxvW/HgkOhwl1TsfHNP/T6k6i1j6gSPIxgCbZzvcJrH9sumu84lcS6Yfg9Qvr7PpOAuDKDj7riCajk2RbdUVxrptqpZkD0kYIKictTHLnL48Uvp97xnspGQYkJA4BAv0grWVZFzqj7o0BlwD7oL/FLdBMSbXkNRCvjQjGnIZ2nq8MEZP3aofJTmW7e63/JTbcplJzE6wdft6ZBF4hroZE8TbT/pMlEMDkQDxYbgPETx9z/quiPJ+0p6dAD2TjJdiV2GfAFz6WEnJ3NljmFPBV2/5DJ4ugFlz6oBXJZArZyUzJlbmfIXasvwycIUFMx470AIl4o7bGCbGGL+tWgljzbkg7dly6G5lMTM+gWVGvWdUtXCOvYLq+oqCr5Uddgt0"}],"wiki_items":[{"catalog_id":"78b906f9-f81c-4bb2-b076-5c5609c7eb41","title":"项目概述","description":"project-overview","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"f30115a0-52c0-4f22-8486-ec2e6c334e6d","gmt_create":"2026-05-27T15:44:16.3635684+08:00","gmt_modified":"2026-05-27T15:44:16.367324+08:00"},{"catalog_id":"6de9a03e-f360-4daa-97ac-dc1cd1937916","title":"快速开始","description":"getting-started","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"61e1b102-9ad1-44f6-accb-0e27be48ceb7","gmt_create":"2026-05-27T15:45:02.5387528+08:00","gmt_modified":"2026-05-27T15:45:02.550849+08:00"},{"catalog_id":"0506348d-993b-48f2-936c-908972f149bc","title":"系统架构","description":"architecture-design","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"ab98c251-c5f7-40df-bba1-21b2edf5d220","gmt_create":"2026-05-27T15:45:15.0879497+08:00","gmt_modified":"2026-05-27T15:45:15.0922502+08:00"},{"catalog_id":"cc6acec0-b687-417f-9c93-00f59162cfed","title":"数据库设计","description":"database-design","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"120f3824-43f7-4a38-9680-43b5b2f59e05","gmt_create":"2026-05-27T15:47:52.3181698+08:00","gmt_modified":"2026-05-28T19:00:07.241746+08:00"},{"catalog_id":"8d7c257e-b299-4adb-adfe-bc0ddbf112b7","title":"核心模块","description":"core-modules","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"7563e383-3ea0-4630-baeb-e86efcaeefb8","gmt_create":"2026-05-27T15:48:30.8129369+08:00","gmt_modified":"2026-05-27T15:48:30.8195851+08:00"},{"catalog_id":"8085e1b7-3658-4490-8b52-9a61f3e79976","title":"API 接口文档","description":"api-documentation","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"6159e8a9-0f6e-43af-b097-bfcd16c8b223","gmt_create":"2026-05-27T15:49:27.8849802+08:00","gmt_modified":"2026-05-27T15:49:27.8891715+08:00"},{"catalog_id":"f4f8585d-1446-4f49-85b2-efc715bda6cf","title":"部署运维","description":"deployment-operations","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"1da760f2-e12f-4b50-bd2e-539ff08c2047","gmt_create":"2026-05-27T15:49:39.6657096+08:00","gmt_modified":"2026-05-27T15:49:39.6688705+08:00"},{"catalog_id":"0ba3accc-326a-4433-930c-5b951d4e5dcf","title":"基础设施","description":"infrastructure","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"cfbcaa79-26f5-402f-8746-9fe524993684","gmt_create":"2026-05-27T15:49:51.0000417+08:00","gmt_modified":"2026-05-27T15:49:51.0048099+08:00"},{"catalog_id":"29142a7a-fa93-4a61-8ad8-c35c1b047599","title":"开发指南","description":"development-guide","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"081f97c7-d774-43b7-aff8-4973d577a059","gmt_create":"2026-05-27T15:50:56.179658+08:00","gmt_modified":"2026-05-27T15:50:56.1833555+08:00"},{"catalog_id":"67d62b58-6970-45ca-a17f-f48cb2ea679a","title":"业务处理器","description":"business-handlers","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"d1a696b8-5a9e-4ad2-8777-04eecc0bb424","gmt_create":"2026-05-27T15:51:42.2402901+08:00","gmt_modified":"2026-05-28T18:57:39.9102608+08:00"},{"catalog_id":"4d1d9a48-feab-42a0-815a-edf76dcaaf69","title":"故障排除","description":"troubleshooting","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"3ce5cfd0-f4f6-439a-b60d-6fb4c36a26bd","gmt_create":"2026-05-27T15:51:51.4591126+08:00","gmt_modified":"2026-05-27T15:51:51.4638338+08:00"},{"catalog_id":"591ea147-ba05-4d86-a671-941af668ca2f","title":"品牌管理接口","description":"brand-management-api","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"6f1fe170-ae35-4660-91dc-ab89735274b7","gmt_create":"2026-05-27T15:52:20.2715607+08:00","gmt_modified":"2026-05-27T15:52:20.2747568+08:00"},{"catalog_id":"6e42204e-3d78-4997-a95a-3311c8fcaa43","title":"缓存系统","description":"cache-system","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"795a5202-49be-4c11-a2b4-44312eca8ae7","gmt_create":"2026-05-27T15:53:16.9891352+08:00","gmt_modified":"2026-05-28T18:58:12.5480638+08:00"},{"catalog_id":"fb8ae541-8bbc-4544-9133-e797be1433e0","title":"分层架构设计","description":"layered-architecture","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"523107ca-244f-43c5-a4fe-4649e36a88ad","gmt_create":"2026-05-27T15:53:50.4703345+08:00","gmt_modified":"2026-05-27T15:53:50.4735252+08:00"},{"catalog_id":"948e0792-2de7-47b1-b73b-e7b246e749ff","title":"数据访问层","description":"data-access-layer","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"599c0bda-3332-415c-a535-362503079473","gmt_create":"2026-05-27T15:54:10.7247654+08:00","gmt_modified":"2026-05-28T18:58:34.9036056+08:00"},{"catalog_id":"8b3ba473-1cf0-4471-a203-9a87732dc227","title":"型号管理接口","description":"model-management-api","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"6af33e3a-220d-4e68-87ed-bfb96bda4c3a","gmt_create":"2026-05-27T15:54:37.220316+08:00","gmt_modified":"2026-05-27T15:54:37.2236089+08:00"},{"catalog_id":"5b9847ff-f7b8-488b-821b-6fdfe2dbde40","title":"搜索引擎","description":"search-system","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"d0c2dea0-a71a-4f16-9889-b37e1e7996e3","gmt_create":"2026-05-27T15:55:50.6464041+08:00","gmt_modified":"2026-05-27T15:55:50.6500526+08:00"},{"catalog_id":"ccdbaf47-6cde-4ad7-95f8-5b92d33e2440","title":"路由系统","description":"routing-system","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"f4014d47-467e-4cfe-8549-1dfb69cbc325","gmt_create":"2026-05-27T15:56:02.5802842+08:00","gmt_modified":"2026-05-27T18:35:29.939743+08:00"},{"catalog_id":"e81027fa-c24e-4492-8100-f051facb89c9","title":"数据模型","description":"data-models","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"97c42095-5b4f-4cec-bbbb-1ba8bb9981d4","gmt_create":"2026-05-27T15:56:31.7739386+08:00","gmt_modified":"2026-05-28T19:00:48.7296891+08:00"},{"catalog_id":"8b7558c2-be32-47b8-99e2-1964009b4337","title":"设备管理接口","description":"device-management-api","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"e1ed4fc8-f1d6-4e8a-907b-9c39bbe13b92","gmt_create":"2026-05-27T15:57:09.1993166+08:00","gmt_modified":"2026-05-28T18:57:12.2561837+08:00"},{"catalog_id":"bc6825c8-9aa3-4f0e-96ca-ef4925af0570","title":"依赖注入模式","description":"dependency-injection","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"5910d326-0408-450d-b403-06a19f3da81b","gmt_create":"2026-05-27T15:57:20.0015238+08:00","gmt_modified":"2026-05-27T15:57:20.0074643+08:00"},{"catalog_id":"4b0e33d8-28d6-44dd-b90a-57af5c6cfaa9","title":"系统监控接口","description":"system-monitoring-api","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"0fc3d59c-d219-4f97-af10-473ee62f4de5","gmt_create":"2026-05-27T15:58:27.2590583+08:00","gmt_modified":"2026-05-27T15:58:27.261717+08:00"},{"catalog_id":"f5a7db4b-765d-46e4-9395-af7bbe8d8fd3","title":"日志系统","description":"logging-system","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"23a2ffc3-fa50-41ba-b7a6-55354d68a95a","gmt_create":"2026-05-27T15:58:35.6388373+08:00","gmt_modified":"2026-05-27T15:58:35.6424946+08:00"},{"catalog_id":"e2d8da89-04c9-4fee-8dfe-adfaff79c9c1","title":"统一响应","description":"unified-response","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"699a84c5-5140-4267-861e-62bffbffccb4","gmt_create":"2026-05-27T15:58:41.4359+08:00","gmt_modified":"2026-05-27T15:58:41.4408299+08:00"},{"catalog_id":"f351f338-eeb0-4243-921a-eed11d063072","title":"中间件模式","description":"middleware-pattern","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"e8e5fe7e-cc7c-4259-95d0-f6b46d888ed8","gmt_create":"2026-05-27T16:00:02.1459491+08:00","gmt_modified":"2026-05-27T16:00:02.1508768+08:00"},{"catalog_id":"c79882f1-420e-4d6c-a40c-dff8c7e8988f","title":"组件交互机制","description":"component-interaction","extend":"{}","progress_status":"completed","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","reference_count":0,"id":"5a04f737-b877-4908-a4fc-67a88614aafc","gmt_create":"2026-05-27T16:00:37.8802374+08:00","gmt_modified":"2026-05-27T16:00:37.8856299+08:00"}],"wiki_overview":{"content":"基于我对项目的深入分析,现在我可以生成一个全面的项目概述:\n\n\u003cblog\u003e\n\n# Luxsin 应用 API 项目架构分析\n\n## 1. 项目介绍\n\n### 目标与定位\nLuxsin 应用 API 是一个基于 Go 语言构建的音频设备(耳机)数据管理服务,主要为移动应用提供品牌、型号、设备信息等数据查询接口。该项目采用现代化的微服务架构设计,专注于音频设备数据的高效检索和管理。\n\n### 核心目标\n- 提供 RESTful API 接口,支持音频设备数据的查询和管理\n- 实现高性能的数据检索,结合 MySQL 和 Meilisearch 搜索引擎\n- 构建可扩展的缓存层,使用 Redis 提升系统性能\n- 确保生产环境的稳定性和可靠性\n\n### 目标用户\n- 移动应用开发者\n- 音频设备数据管理系统\n- 第三方集成商\n\n## 2. 技术架构\n\n### 整体架构设计\n\n```mermaid\ngraph TD\n A[客户端应用] --\u003e B[Gin Web框架]\n B --\u003e C[中间件层]\n C --\u003e D[路由层]\n D --\u003e E[处理器层]\n E --\u003e F[仓库层]\n F --\u003e G[数据库层]\n \n H[Meilisearch搜索] --\u003e E\n I[Redis缓存] --\u003e E\n \n C --\u003e J[CORS中间件]\n C --\u003e K[日志中间件]\n C --\u003e L[请求ID中间件]\n \n M[配置管理] --\u003e N[数据库连接]\n M --\u003e O[Redis连接]\n M --\u003e P[搜索客户端]\n```\n\n### 设计模式\n- **分层架构模式**:清晰的业务逻辑分层,便于维护和测试\n- **依赖注入模式**:通过构造函数注入依赖,提升代码可测试性\n- **工厂模式**:用于创建各种客户端和服务实例\n- **中间件模式**:统一处理跨域、日志、请求ID等功能\n\n### 系统关系图\n\n```mermaid\nflowchart TD\n Client[客户端请求] --\u003e Gin[Gin Engine]\n Gin --\u003e Middleware[中间件链]\n Middleware --\u003e Handler[业务处理器]\n Handler --\u003e Repository[数据仓库]\n Repository --\u003e DB[(MySQL数据库)]\n Handler --\u003e Search[Meilisearch]\n Handler --\u003e Cache[Redis缓存]\n \n subgraph \"核心组件\"\n Gin\n Middleware\n Handler\n Repository\n end\n \n subgraph \"外部服务\"\n DB\n Search\n Cache\n end\n```\n\n## 3. 关键实现\n\n### 主要入口点\n- **服务器启动**:`cmd/server/main.go` - 应用程序的主入口,负责初始化所有服务组件\n- **路由配置**:`internal/router/router.go` - 定义 API 路由和中间件配置\n- **配置管理**:`internal/config/config.go` - 统一的配置加载和验证机制\n\n### 核心模块\n\n#### 数据访问层\n- **数据库连接**:`internal/database/mysql.go` - MySQL 数据库连接管理\n- **品牌仓库**:`internal/repository/brand.go` - 品牌数据的 CRUD 操作\n- **型号仓库**:`internal/repository/model.go` - 型号数据的查询和管理\n\n#### 业务处理层\n- **品牌处理器**:`internal/handler/brand.go` - 品牌数据的业务逻辑处理\n- **型号处理器**:`internal/handler/model.go` - 型号数据的业务逻辑处理\n- **模型列表处理器**:`internal/handler/model_list.go` - 结合搜索功能的型号查询\n- **设备信息处理器**:`internal/handler/device.go` - 设备上报信息处理\n\n#### 缓存和搜索\n- **Redis客户端**:`internal/cache/redis.go` - Redis 连接和操作封装\n- **Meilisearch客户端**:`internal/search/meilisearch.go` - 搜索功能实现\n\n### 配置管理\n- **环境配置**:`internal/config/config.go` - 支持开发和生产环境的配置切换\n- **数据库配置**:`internal/config/database.go` - MySQL 连接参数配置\n- **Redis配置**:`internal/config/redis.go` - Redis 连接配置\n- **搜索配置**:`internal/config/meilisearch.go` - Meilisearch 搜索配置\n\n### 中间件系统\n- **CORS中间件**:`internal/middleware/cors.go` - 跨域资源共享处理\n- **日志中间件**:`internal/middleware/logger.go` - 请求日志记录\n- **请求ID中间件**:`internal/middleware/request_id.go` - 请求追踪标识\n\n### 日志系统\n- **日志配置**:`pkg/logger/logger.go` - 基于 Zap 的日志系统,支持开发和生产环境不同配置\n\n### 数据模型\n- **品牌模型**:`internal/model/brand.go` - 品牌数据结构定义\n- **型号模型**:`internal/model/model.go` - 型号数据结构定义\n\n### 响应处理\n- **统一响应格式**:`internal/response/response.go` - API 响应的标准格式化\n\n## 4. 核心特性\n\n### 功能架构图\n\n```mermaid\nstateDiagram-v2\n [*] --\u003e 接收请求\n 接收请求 --\u003e 验证参数\n 验证参数 --\u003e 处理业务逻辑\n 处理业务逻辑 --\u003e 查询数据库\n 查询数据库 --\u003e 返回结果\n 处理业务逻辑 --\u003e 使用缓存\n 使用缓存 --\u003e 返回结果\n 处理业务逻辑 --\u003e 执行搜索\n 执行搜索 --\u003e 返回结果\n \n 返回结果 --\u003e 记录日志\n 记录日志 --\u003e [*]\n \n 验证参数 --\u003e 错误处理\n 错误处理 --\u003e 返回错误\n 返回错误 --\u003e 记录日志\n```\n\n### 实现亮点\n\n#### 多数据源架构\n- **混合存储策略**:结合传统关系型数据库和现代搜索引擎\n- **缓存优化**:使用 Redis 缓存热点数据,提升响应速度\n- **异步处理**:支持设备信息上报的异步处理机制\n\n#### 高可用设计\n- **优雅关闭**:支持服务器优雅启动和关闭\n- **信号处理**:正确处理系统信号,确保资源正确释放\n- **连接池管理**:数据库和缓存连接的生命周期管理\n\n#### 开发体验优化\n- **环境隔离**:开发和生产环境的配置分离\n- **统一日志**:结构化的日志输出,便于问题排查\n- **错误处理**:完善的错误处理和返回机制\n\n### 性能考虑\n\n```mermaid\ngraph LR\n A[请求到达] --\u003e B[中间件处理]\n B --\u003e C[缓存检查]\n C --\u003e D{缓存命中?}\n D --\u003e|是| E[直接返回缓存]\n D --\u003e|否| F[查询数据库]\n F --\u003e G[更新缓存]\n G --\u003e H[返回响应]\n E --\u003e H\n H --\u003e I[记录日志]\n```\n\n## 5. 项目特色\n\n### 架构优势\n- **模块化设计**:清晰的职责分离,便于团队协作和维护\n- **可扩展性**:支持添加新的数据源和业务功能\n- **可观测性**:完整的日志记录和监控支持\n- **安全性**:中间件层提供统一的安全控制\n\n### 技术选型\n- **Go 1.24**:现代化的编程语言,提供优秀的性能和并发能力\n- **Gin 框架**:高性能 HTTP Web 框架,适合构建 RESTful API\n- **MySQL**:成熟的关系型数据库,适合结构化数据存储\n- **Meilisearch**:快速的全文搜索引擎,提供优秀的搜索体验\n- **Redis**:高性能的内存数据结构存储,用于缓存和会话管理\n\n### 开发最佳实践\n- **依赖注入**:通过构造函数注入依赖,提升代码可测试性\n- **错误处理**:统一的错误处理机制,避免错误传播\n- **配置管理**:环境变量驱动的配置管理,支持容器化部署\n- **日志标准化**:结构化日志输出,便于日志分析和监控\n\n## 6. 总结与建议\n\n### 项目特点总结\nLuxsin 应用 API 项目展现了现代 Go 语言 Web 服务的最佳实践,采用了清晰的分层架构、依赖注入和中间件模式。项目在性能、可维护性和可扩展性方面都表现出色,为音频设备数据管理提供了可靠的基础设施。\n\n### 架构优势\n- **清晰的层次结构**:从路由到数据访问的完整分层设计\n- **现代化技术栈**:选择合适的技术解决特定问题\n- **完善的基础设施**:包含缓存、搜索、日志等完整的系统组件\n- **良好的工程实践**:遵循 Go 语言的最佳实践和编码规范\n\n### 改进建议\n1. **增加单元测试**:为关键业务逻辑添加更多的单元测试覆盖\n2. **API 文档**:集成 Swagger 或类似工具生成 API 文档\n3. **监控指标**:添加 Prometheus 指标收集,完善运维监控\n4. **健康检查**:扩展健康检查端点,提供更详细的系统状态信息\n5. **配置热更新**:支持部分配置的动态更新,减少重启需求\n\n### 下一步发展方向\n- **微服务拆分**:根据业务领域进一步拆分服务\n- **消息队列**:引入消息队列处理异步任务\n- **容器化部署**:完善 Docker 和 Kubernetes 部署配置\n- **性能优化**:持续优化查询性能和缓存策略\n\n---\n\n**Sources:**\n- [main.go](cmd/server/main.go)\n- [go.mod](go.mod)\n- [config.go](internal/config/config.go)\n- [router.go](internal/router/router.go)\n- [brand.go](internal/handler/brand.go)\n- [brand_repository.go](internal/repository/brand.go)\n- [brand_model.go](internal/model/brand.go)\n- [meilisearch.go](internal/search/meilisearch.go)\n- [redis.go](internal/cache/redis.go)\n- [cors.go](internal/middleware/cors.go)\n- [logger.go](pkg/logger/logger.go)\n- [database_config.go](internal/config/database.go)\n- [model.sql](sql/model.sql)\n\n\u003c/blog\u003e","gmt_create":"2026-05-27T15:40:06.9577463+08:00","gmt_modified":"2026-05-27T15:40:06.9577463+08:00","id":"5a60eb9b-0b2d-4d2f-99c6-dd1e4cd34dd3","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc"},"wiki_readme":{"content":"No readme file","gmt_create":"2026-05-27T15:38:58.8115445+08:00","gmt_modified":"2026-05-27T15:38:58.8115445+08:00","id":"cf8cd5f4-1600-41c4-9afb-1db3a1464c48","repo_id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc"},"wiki_repo":{"id":"a6c92e0a-0eb8-4b81-8beb-0169c32d76bc","name":"app-api","progress_status":"completed","wiki_present_status":"COMPLETED","optimized_catalog":"\".\\n├── _tmp_desc\\\\\\n├── cmd\\\\server\\\\\\n│ └── main.go\\n├── internal\\\\\\n│ ├── cache\\\\\\n│ │ └── redis.go\\n│ ├── config\\\\\\n│ │ ├── config.go\\n│ │ ├── database.go\\n│ │ ├── meilisearch.go\\n│ │ └── redis.go\\n│ ├── database\\\\\\n│ │ └── mysql.go\\n│ ├── handler\\\\\\n│ │ ├── brand.go\\n│ │ ├── device.go\\n│ │ ├── health.go\\n│ │ ├── model.go\\n│ │ └── model_list.go\\n│ ├── middleware\\\\\\n│ │ ├── cors.go\\n│ │ ├── logger.go\\n│ │ └── request_id.go\\n│ ├── model\\\\\\n│ │ ├── brand.go\\n│ │ └── model.go\\n│ ├── repository\\\\\\n│ │ ├── brand.go\\n│ │ └── model.go\\n│ ├── response\\\\\\n│ │ └── response.go\\n│ ├── router\\\\\\n│ │ └── router.go\\n│ └── search\\\\\\n│ └── meilisearch.go\\n├── pkg\\\\\\n│ ├── encode\\\\\\n│ │ └── base64.go\\n│ └── logger\\\\\\n│ └── logger.go\\n├── sql\\\\\\n│ └── model.sql\\n├── .gitignore\\n├── Makefile\\n├── README.md\\n├── go.mod\\n└── go.sum\\n\"","current_document_structure":"WikiEncrypted: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","catalogue_think_content":"WikiEncrypted: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","recovery_checkpoint":"wiki_generation_completed","last_commit_id":"f3e3e82f5295183a2cc1bd572fba563e7e244771","last_commit_update":"2026-05-28T19:00:49.3644817+08:00","gmt_create":"2026-05-27T15:32:45.7755498+08:00","gmt_modified":"2026-05-28T19:00:49.3644817+08:00","extend_info":"{\"language\":\"zh\",\"active\":true,\"branch\":\"main\",\"shareStatus\":\"\",\"server_error_code\":\"\",\"cosy_version\":\"1.2.3\"}"}} \ No newline at end of file