# hyapp-admin-server

HYApp 管理后台 API，基于 Gin、GORM 和 MySQL。

当前后台后端位于 `hyapp-server/server/admin`，是 `hyapp-server/go.work` 内的独立 Go module。它只依赖 `hyapp.local/api` 这个 protobuf 契约 module，不直接依赖 app 后端服务实现包。

## Local Run

```bash
go mod tidy
go run ./cmd/server -config configs/config.yaml
```

从 `hyapp-server` 根目录可以用 Makefile 启动：

```bash
make admin-up
```

依赖已经启动时，可以只启动后台进程：

```bash
make admin
```

默认端口：`13100`。本地 MySQL 对齐 app 后端，使用 `127.0.0.1:23306`；`mysql_dsn` 指向后台库 `hyapp_admin`，`user_mysql_dsn` 只读访问用户库 `hyapp_user`。本地 bootstrap 由 `configs/config.yaml` 的 `bootstrap` 控制，首次启动如果没有用户，会创建配置里的管理员账号。

依赖：

- MySQL：`127.0.0.1:23306`
- Redis：`127.0.0.1:13379`
- user-service：`127.0.0.1:13005`

显式执行 bootstrap：

```bash
go run ./cmd/server -config configs/config.yaml -bootstrap
```

## Structure

后台后端按模块化单体组织。业务代码按模块收口，每个模块内按功能拆文件：

- `internal/modules/<module>/routes.go`：模块路由。
- `internal/modules/<module>/handler.go`：HTTP 参数和响应适配，不直接访问 repository。
- `internal/modules/<module>/service.go`：模块业务 Service。
- `internal/modules/<module>/request.go`：模块请求结构。
- `internal/modules/<module>/response.go`：模块响应 DTO 或展示转换。
- `internal/modules/shared`：跨模块的当前用户、分页参数、审计事件和少量通用 DTO。
- `internal/service`：只保留 JWT/AuthService 这类跨模块基础能力。
- `internal/platform`：后台服务自有基础设施适配，避免 import app 后端 `pkg`。
- `internal/response`：通用响应协议，按 body、codes、page、success、error 拆分。
- `internal/repository/*`：后台库读写，按 auth、rbac、menu、audit、job 等拆分。
- `internal/integration/*`：访问 app 后端服务的 client。
- `internal/migration`：版本化 SQL migration。
- `internal/cache`：Redis 健康检查和分布式锁。
- `internal/job`：DB 租约、Redis 锁、重试和导出产物任务执行器。
- `internal/security`：密码和 token 安全工具。

关键运行策略：

- `environment`、`jwt_secret`、`mysql_auto_migrate`、`bootstrap` 都只来自 `config.yaml`。
- 非 `local/dev` 环境禁止默认 JWT secret、默认 bootstrap 密码和 `mysql_auto_migrate`。
- 数据权限通过角色的 `data-scopes` 保存，并在后台用户列表/导出查询中执行。
- 任务产物默认写入 `storage/exports`，通过 `/api/v1/jobs/:id/artifact` 下载。

## System Message Push

菜单入口：APP配置 / 系统消息推送，菜单 code 为 `operation-full-server-notice`，页面路径为 `/app-config/system-message-push`。

接口：

```text
POST /api/v1/admin/operations/full-server-notices/fanout
```

参数只传后台需要的命令字段：`message_type` 为 `system` 或 `activity`，`target_scope` 支持 `all_registered_users`、`all_active_users`、`single_user`、`user_ids`、`region`、`country`，内容字段为 `title`、`summary`、`body`，跳转字段为 `action_type`、`action_param`，扩展字段为 `metadata_json`。`command_id` 是幂等键，不传时由 admin-server 按管理员和当前时间生成。

返回值包含 `job_id`、`status`、`created`、`command_id`、`message_type`、`target_scope`。接口只创建 activity-service 的 `message_fanout_jobs`，实际逐用户写入由 message fanout worker 分批完成。

权限：

- 查看菜单：`full-server-notice:view`
- 发送通知：`full-server-notice:send`

相关 IM：Flutter 消息页的系统/活动标签读取后端 inbox；当前客户端只展示标题、摘要/正文和时间。腾讯云 IM 单聊和房间群消息不走这个后台入口。

## Verify

```bash
go test ./...
```
