chore add core rust project files and diesel migrations

Track required workspace crates, scripts, and historical diesel migrations so the repository contains the complete runnable backend baseline.

Made-with: Cursor
This commit is contained in:
2026-04-23 17:20:01 +08:00
parent c843fecbce
commit 44c320d8fa
392 changed files with 11786 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
# 联调与切流(htyts / htyproc
## 环境变量
### htyts(任务 API
`htyts::config` 一致,典型项包括:`TS_DATABASE_URL`、Redis`htycommons::redis_util` 所读变量)、`TS_PORT``task_server.zombie_min`(或等价)、JWT/密钥类变量与现有 `htyws`/`htykc` 对齐。课程调度:`TS_SUDOER_TOKEN``TS_DOMAIN``HTYKC_URL` 等。
### htyproc(执行器)
| 变量 | 说明 |
|------|------|
| `TS_URL` | 任务服务基址(含协议与端口),如 `http://127.0.0.1:8080` |
| `TS_DOMAIN` | `HtyHost` 语义,与现网域名一致 |
| `NGX_URL` | OpenResty/Nginx 基址,用于 `combine` / `convert` 等 |
| `PROC_SUDOER_TOKEN` | 调 TS 与 Ngx 的 sudoer JWT(与 Java proc 一致) |
| `PROC_PORT` | 控制面 HTTP 端口,默认 `8081` |
| `WAIT_SEC` / `task_server.wait_sec` | 轮询间隔秒数,默认 `5` |
| `MAX_PROCESSING_TASKS` | 并发执行上限,默认 `20` |
| Redis | 与 TS 相同实例;`htycommons::redis_util::get_redis_url()` |
## Nginx 示例
将原指向 Java `task_server` / `proc_server``location` 改为 Rust 进程 upstream(端口按部署调整):
```nginx
upstream htyts_backend {
server 127.0.0.1:8080;
}
upstream htyproc_backend {
server 127.0.0.1:8081;
}
location /api/v1/ts/ {
proxy_pass http://htyts_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /api/v1/proc/ {
proxy_pass http://htyproc_backend;
proxy_set_header Host $host;
}
```
切流前在**并行端口**上跑 `htyts`/`htyproc`,用 curl 或 `htymusic`/`htyadmin` 指向测试域名验证后再改 `proxy_pass`
## 联调要点(htymusic / htyadmin
- 创建/更新任务、`one_pending_task` 拉取、任务状态回写与 Redis payload 一致。
- 课程通知:`/api/v1/ts/kc/*` 启停与状态与运维脚本一致。
- proc`GET /api/v1/proc/start|stop|status` 行为与 Java 一致后再切换 upstream。`status` 载荷中的 `status` 字段与 Java `ProcessorHelper.Status` 一致:`PENDING` / `RUNNING` / `ABORT` / `ERROR`
## 监控与下线 Java 条件建议
- 指标:`one_zombie_task` 数量、任务 `FAILED` 比例、proc 日志中 `update_task` 失败率、Redis `TS_*` 键与 DB 行一致性抽检。
- 条件:在目标环境**至少一个完整业务周期**内无回归;TS/proc 错误率与 Java 基线可比或更好;回滚方案(保留 Java 二进制与旧 upstream 块)已验证。
## htyts 本地 E2EDocker + cargo test
- Compose`huiwing/docker-compose.ts-e2e.yml`Postgres 14、Redis 7;端口 `5436` / `6390`,避免与 AuthCore `docker-compose.test.yml``5433` / `6380` 冲突)。
- 建表:`huiwing/htyts_models/migrations/`,本地/CI 用 `diesel migration run`(与 `htyuc_models` 相同流程)。
- 一键脚本:`huiwing/scripts/run-ts-e2e.sh``up --wait`、清空 `dbtask` 与 Redis、`POOL_SIZE`/`JWT_KEY`/DB URL 等环境变量后执行 `cargo test -p htyts --test ts_e2e_http`
- `HtySudoerToken` 校验依赖 Redis 中 `HW_T_{token_id}` 与 JWT 一致;测试内会写入与 AuthCore `verify_jwt` 相同的约定。
+58
View File
@@ -0,0 +1,58 @@
# 阶段 A 契约清单(task_server / proc / task_commons → Rust
本文档与 `htyts_models``htyts` crate 一并落地,供后续阶段 B/C 实现与现网对齐时对照。
## PostgreSQL`DbTask` 表
Java 实体:仓库根目录下 [`task_commons/.../DbTask.java`](../../task_commons/src/main/java/cn/alchemystudio/taskcommons/db/DbTask.java)。
- **表名(已核对):** 正式机 `alchemy-studio.cn` 上任务库为 `htytask_alchemy``htytask_huiwings``moicen` 等环境库名可能为 `htytask_moicen`,以该机 `\l` 为准)。`public` 下表名为 **`dbtask`**(非 `db_task`),与 [`htyts/src/schema.rs`](../htyts/src/schema.rs) 一致。
- **核对命令(需本机可 `ssh weli@alchemy-studio.cn``sudo -u postgres` 免密):** `sudo -n -u postgres psql -d htytask_alchemy -c '\d+ public.dbtask'`。直连 `psql -U postgres` 可能要求密码,可改用上述 `sudo`
- **已记录的列类型(`htytask_alchemy.public.dbtask`):** `task_id varchar(255)` PK`task_type` / `task_status` / `created_by` / `updated_by` `varchar(255)``hty_id` / `meta` 可空;`meta varchar(65535)``duration` `double precision``created_at` / `updated_at` `timestamp(6) without time zone`
- **列(与 Java 字段一致):** `task_id` (PK), `hty_id`, `task_type`, `task_status`, `duration`, `created_by`, `created_at`, `updated_by`, `updated_at`, `meta`
- **枚举存字符串:** 与 Java `Enum.name()` 一致,如 `PENDING`, `UPLOAD_PICTURE`。Rust 侧解析见 `htyts_models::TaskStatus::from_str` / `TaskType::from_str`
参考 DDL**以现网为准**):
```sql
-- VERIFY table name and types against production before use.
CREATE TABLE IF NOT EXISTS dbtask (
task_id TEXT PRIMARY KEY,
hty_id TEXT,
task_type TEXT NOT NULL,
task_status TEXT NOT NULL,
duration DOUBLE PRECISION,
created_by TEXT NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_by TEXT NOT NULL,
updated_at TIMESTAMP NOT NULL,
meta TEXT
);
```
## Redis
- Java`task_commons` `BaseRedisService.TS_REDIS_PREFIX` = `"TS_"`;任务 payload 为 `TS_{task_id}` 的字符串值(JSON)。
- Rust`htyts_models::task_payload_redis_key` / `TS_REDIS_PREFIX`
- **Sudoer 缓存(与 AuthCore `HW_T_` 不同):** Java `task_server``CheckAuthFilter` 使用 `TS_SUDO_T_{token_id}``HtyToken` JSON(见 `RedisTokenCacheService`)。Rust `htyts``create_task` / `update_task` 已按该语义校验(可选走 `HTYUC_URL` + `/api/v1/uc/verify_jwt_token`,环境变量 `AUTH_CHECKING` / `TOKEN_VERIFY` / `EXP_DAYS` 与 Java 对应)。
-`htycommons::redis_util``HW_``T_` 等前缀**不要混用**到任务 payloadsudoer 校验路径以 `task_server` 为准。
## HTTP 契约(后续阶段实现)
- **Task service** 前缀:`/api/v1/ts`(见 Java `TaskApp` + `TaskService`)。
- **Proc 控制面:** `/api/v1/proc/start|stop|status`
- **Ts 客户端(proc → ts):** `TsProxy` 路径 `create_task`, `update_task`, `one_pending_task`, `one_zombie_task`
- **AI 客户端:** `AiProxy` `/api/v1/ai``compare`, `watermark`, `compress`, `get_task_result`
## 与 AuthCore 的复用(proc 侧)
以下类型在 Java 中来自 `task_commons`Rust 侧 **优先使用 AuthCore 已有定义**
- `ReqHtyResource``ReqRefResource` 等:在 **`htycommons::models`**(见 `htyuc_models``ReqHtyResource` 的引用与 `HtyResource::to_req`)。
- 实现 proc 前请在 `AuthCore``grep` 上述类型名,避免在 `htyts_models` 重复定义。
## JSON 字段名
- `ReqTasksWithPage` 使用 `totalPage`Java bean)。
- `AudioFileAndAiScorePayload` 使用 `aiScorePayload` / `audioPayload`(已在 `htyts_models` 标注 `serde(rename = ...)`)。
- 其它 payload 与 `CommonTaskResult` 若与现网抓包不一致,以 **实际响应** 为准并补 `serde` 别名。