142 lines
9.0 KiB
Markdown
142 lines
9.0 KiB
Markdown
# AGENTS.md
|
||
|
||
本仓库是 [youlai-boot](https://gitee.com/youlaiorg/youlai-boot) 的 TTSTD 定制分支,用于**老年平板设备管理**:设备端(sn)、家属端(client)、运营后台(device / app)。
|
||
|
||
## 1. 与 Gitee 上游的关系(最高优先级)
|
||
|
||
远程仓库:
|
||
|
||
| remote | 地址 | 用途 |
|
||
| --- | --- | --- |
|
||
| `gitee` | `git@gitee.com:youlaiorg/youlai-boot.git` | **上游只读**(push 已禁用),只用于比对/同步 |
|
||
| `origin` | `ssh://git@gitea.ttstd.com:2222/tt/youlai-boot.git` | 我方仓库 |
|
||
|
||
**只有以下目录是我方新增的业务代码,可自由新增/修改:**
|
||
|
||
| 目录 | 职责 |
|
||
| --- | --- |
|
||
| `src/main/java/com/youlai/boot/app/` | 客户端应用管理:应用分类、应用包(APK/XAPK/APKM 解析、上传、Mongo 存储) |
|
||
| `src/main/java/com/youlai/boot/client/` | 家属端:App 用户、通讯录、设备操作、文件 |
|
||
| `src/main/java/com/youlai/boot/device/` | 设备管理:sn 设备、截图、壁纸、策略、告警、APK 安装、硬件/网络/安全/系统信息 |
|
||
| `src/main/java/com/youlai/boot/open/` | 家属端开放认证:短信登录、密码登录、注册、重置密码 |
|
||
| `src/main/java/com/youlai/boot/common/config/` | `FilePath`(本地存储路径)、`WebMvcConfig`(静态资源映射) |
|
||
|
||
**其余所有目录(`auth/`、`system/`、`framework/`、`support/`、`config/`、`module/`、`codegen/` 等)都来自上游,尽量保持不动。**
|
||
|
||
### 修改前必做检查
|
||
|
||
```bash
|
||
git fetch gitee
|
||
git ls-tree -r --name-only gitee/master -- src/main/java/com/youlai/boot/xxx # 上游是否存在该文件
|
||
git log --oneline gitee/master -- src/main/java/com/youlai/boot/xxx # 上游是否有近期改动
|
||
```
|
||
|
||
- **上游存在该文件 → 尽量不改**。优先在五个自有目录内新增类/扩展点(继承、实现接口、新增 Controller)来满足需求。
|
||
- **确实必须改上游文件时**:只做最小必要改动,不做格式化/重命名/顺带重构,提交信息注明原因,例如
|
||
`chore(upstream): 安全配置放行 /api/v1/xxx 以支持新模块`。
|
||
- **上游不存在该文件 → 可新增**,但应落在上述五个目录内。
|
||
|
||
### 已登记的例外清单
|
||
|
||
以下改动位于上游目录,属结构性必要或历史遗留。**请勿删除、重构或格式化**,修改前先确认调用方。
|
||
|
||
#### A. 上游目录中新增的文件(上游不存在,因框架结构必须留在原包)
|
||
|
||
| 位置 | 说明 |
|
||
| --- | --- |
|
||
| `common/constant/ClientTypeConstants.java` | 端标识(admin / client) |
|
||
| `common/util/{HashUtils, FileUtils, RedisSafeOps, CodeGeneratorUtil}.java` | 校验值、文件、Redis 安全操作、编码生成工具 |
|
||
| `config/{DataSourceConfig, RedissonConfig, MqttConfig, RedisHealthConfig}.java`、`config/property/MqttProperties.java` | 多数据源、分布式锁、MQTT、Redis 健康检查 |
|
||
| `framework/security/filter/{MobileApiSignatureFilter, CachedBodyRequestWrapper}.java` | 设备端 ECDSA 验签过滤器与请求体缓存 |
|
||
| `framework/security/signature/DeviceSignatureVerifier.java` | 设备签名校验 |
|
||
| `framework/security/authorization/ClientAccessAuthorizationManager.java` | 家属端令牌隔离 |
|
||
| `support/mqtt/{MqttController, MqttMessageHandler, MqttProducer}.java` | MQTT 上报/推送 |
|
||
| `support/webrtc/**` | WebRTC 信令(`/ws/signal`) |
|
||
| `support/sms/SmsResult.java` | 短信发送结果 |
|
||
| `resources/mapper/system/DeviceMapper.xml` | 设备分页查询 |
|
||
| `test/java/com/youlai/boot/app/packages/component/ApkMetaParserTest.java` | 安装包解析测试 |
|
||
|
||
#### B. 被修改的上游文件(只允许最小增补,不做重构/格式化)
|
||
|
||
| 文件 | 允许的改动范围 |
|
||
| --- | --- |
|
||
| `config/SecurityConfig.java` | 放行 `/api/v1/sn/**`、`/api/v1/open/**`、`/ws/signal`;`/api/v1/client/**` 走 `ClientAccessAuthorizationManager` |
|
||
| `config/JacksonConfig.java` | **保持上游原样**(不得添加未使用的 import / 注释代码) |
|
||
| `config/RedisConfig.java` | 仅 `@Lazy` 延迟初始化;序列化方式必须与上游一致 |
|
||
| `framework/security/config/SecurityProperties.java` | client 端令牌 TTL 两个字段 |
|
||
| `framework/security/model/{SecurityUser, SecurityUserDetails}.java` | `clientType` 字段 |
|
||
| `framework/security/token/JwtTokenManager.java` | client 端 TTL 解析、`clientType` claim、校验失败日志 |
|
||
| `common/constant/JwtClaimConstants.java`、`common/constant/RedisConstants.java` | `clientType` claim、设备在线 key、短信验证码 key |
|
||
| `common/enums/{ActionTypeEnum, LogModuleEnum}.java`、`common/result/ResultCode.java` | 仅追加新枚举值/错误码 |
|
||
| `framework/web/advice/GlobalExceptionHandler.java` | Redis 相关异常、SSE 超时、静态资源 404 |
|
||
| `framework/web/log/OperationLogAspect.java` | 设备无登录会话时的操作人兜底;`error_msg` 上限 2000 |
|
||
| `system/service/impl/ConfigServiceImpl.java` | 缓存预热失败不阻断启动 |
|
||
| `support/file/model/FileInfo.java`、`support/file/service/impl/LocalFileServiceImpl.java` | md5/sha1/sha256 校验值 |
|
||
| `support/sms/{SmsTypeEnum, service/SmsService, service/impl/AliyunSmsServiceImpl}.java` | `sendWithResult`,按响应码判定成败 |
|
||
| `support/sse/{SseService, SseSessionManager, constant/SseEventConstants}.java` | 设备事件主题 |
|
||
| `pom.xml` | 新增依赖(websocket、mongodb、mqtt、apk-parser、apkanalyzer、redisson 等) |
|
||
| `.gitignore` | 目前仅新增 `/uploadFile/` |
|
||
| `resources/application-dev.yml`、`resources/application-prod.yml` | 数据源(mysql/tdengine)、redis、mongodb、oss、sms、mqtt、安全白名单、令牌 TTL |
|
||
| `sql/youlai-admin.sql` | `sys_log.error_msg` 由 1000 调整为 2000 |
|
||
|
||
#### C. 数据与运维脚本(非 Java 代码,允许新增)
|
||
|
||
`sql/*.sql`、`docs/sql/*.sql`、`docker/*`。
|
||
|
||
#### D. 禁止事项
|
||
|
||
- 上游文件里做格式化、重命名、import 重排、注释掉代码等无关改动。
|
||
- 配置文件提交真实凭证:密码/AccessKey 一律用环境变量或本地 profile 覆盖,不写入版本库。
|
||
- 在上游目录新增 Java 类(应放到自有目录,例如 `ByteArrayMultipartFile` 放在 `app/packages/component/`)。
|
||
|
||
## 2. 技术栈
|
||
|
||
Java 17 · Spring Boot 4.0.5 · Spring Security · MyBatis-Plus 3.5.15 · MySQL · Redis + Redisson · MongoDB(`spring-boot-starter-data-mongodb`) · WebSocket · knife4j/springdoc · MapStruct + Lombok · Hutool · apk-parser / apkanalyzer
|
||
|
||
## 3. 构建与运行
|
||
|
||
```bash
|
||
mvn -DskipTests clean package # 打包,产物 target/youlai-boot-4.12.0.jar
|
||
mvn test # 测试
|
||
java -jar target/youlai-boot-4.12.0.jar --spring.profiles.active=dev
|
||
```
|
||
|
||
- 默认 profile 为 `dev`(`application.yml`),配置见 `application-dev.yml` / `application-prod.yml`;代码生成配置在 `codegen.yml`。
|
||
- 数据库连接请使用本地 `/ 环境变量` 覆盖,**不要提交真实账号密码**。
|
||
- Windows 上 shell 为 PowerShell,勿使用 `head`/`tail`/`cd /d` 等 cmd/Unix 语法。
|
||
|
||
## 4. 代码约定
|
||
|
||
包结构(自有模块统一遵循):
|
||
|
||
```
|
||
xxx/
|
||
├── controller/ # @RestController,路径 /api/v1/...
|
||
├── service/ # 接口
|
||
│ └── impl/ # 实现,继承 MyBatis-Plus ServiceImpl<Mapper, Entity>
|
||
├── converter/ # MapStruct 转换器
|
||
├── mapper/ # MyBatis-Plus Mapper(自有模块一般不写 XML)
|
||
├── repository/ # Mongo 仓储(接口 + impl,用 MongoTemplate)
|
||
└── model/
|
||
├── entity/ # MySQL 实体(设备相关以 Sn 前缀命名,如 SnDeviceInfo)
|
||
├── document/ # Mongo 文档(如 AppPackageDocument)
|
||
├── form/ req/ query/ # 入参
|
||
└── vo/ dto/ # 出参
|
||
```
|
||
|
||
- 统一返回 `Result<T>` / `PageResult<T>`,分页参数用 `PageQuery`,分页结果用 `IPage`。
|
||
- 构造器注入:类加 `@RequiredArgsConstructor`,字段 `private final`。
|
||
- 接口文档:`@Tag(name = "序号.名称")` + `@Operation(summary = ...)`。
|
||
- 操作日志:`@Log(module = LogModuleEnum.X, value = ActionTypeEnum.Y)`。
|
||
- 鉴权分区:
|
||
- `/api/v1/sn/**`:设备端,`MobileApiSignatureFilter` 做 ECDSA 设备签名校验(非 JWT)
|
||
- `/api/v1/client/**`:家属端,仅接受 `clientType=client` 的令牌
|
||
- `/api/v1/open/**`:免登录(登录/注册/找回密码)
|
||
- 后台接口(`/api/v1/device`、`/api/v1/app/**`、`/api/v1/developers` 等):走 Spring Security,按需 `@PreAuthorize`
|
||
- 文件落盘统一走 `FilePath`(根目录为 `user.dir` 下的 `uploadFile/tablet/{screenshot,packages,category_icon,wallpaper}`),HTTP 访问走 `/static/{子目录}/**`,由 `WebMvcConfig` 映射;截图/壁纸用 `noCache`,安装包/分类图标用长缓存。
|
||
- 新增后台菜单/表结构请补充 `sql/` 脚本,保持与代码同步。
|
||
|
||
## 5. 提交约定
|
||
|
||
采用 Conventional Commits(`feat(device): ...`、`fix(client): ...`、`refactor(config): ...`、`chore: ...`)。涉及上游文件的改动需在正文说明原因。
|