feat(§T): 账户看板 + 场内模拟交易 9 端点(用户自助首版)
新增 §T 用户自助段(docs/05 §19 新号段 7 个 = A×40/C×7/K×4/M×4/O×3/R×4/T×9): - T001 GET /api/v1/users/me/account/dashboard — 账户/资金/持仓/盈亏汇总 - T002 POST /api/v1/users/me/orders — 委托提交(首版 market 立即全额成交) - T003 / T004 / T005 委托列表/详情/撤单 - T006 GET /api/v1/users/me/holdings — 持仓列表(含市值/盈亏/当日盈亏) - T007 / T008 成交记录列表/详情 - T009 GET /api/v1/users/me/cash-ledger — 资金账本 要点(与 docs/00 §6.6 一致): - 首版市价委托立即全额成交,不实现撮合队列/部分成交;T005 撤单首版对任何在场委托返回 ORDER_NOT_CANCELLABLE (409) - 价格来源复用 base FundQuoteService;service 层不二次封装(满足 AGENTS 第 2 条) - 首版风控 3 条硬性:产品可交易、客户适当性、持仓比例上限(fin_market_price 缺失或过期 → 拒绝买入) - 数据库零修改:10 张 fin_* 表全部 docs/00 既定,本批 PR 改列类型与可空性均 0;底座实际偏差(id 无 AUTO_INCREMENT、所谓'生成列'是普通 NOT NULL)由 service _next_id / 业务派生值补偿 注册 API:9 端点均注册进 app.main;user=9001(cust)'s id 写账 权限码(tools/seed_test_rbac.py 同步登记 + CUSTOMER 全量): 9047 account:read:self 9048 trade:order:create 9049 trade:order:read 9050 trade:order:cancel 9051 holding:read:self 9052 trade:txn:read 错误码(app/core/errors.py + docs/05 §3.6 + tests/unit/core/test_errors.py DOCUMENTED 三方同步): 404 ACCOUNT_NOT_FOUND / ORDER_NOT_FOUND 409 ORDER_NOT_CANCELLABLE 422 INSUFFICIENT_FUNDS / INSUFFICIENT_HOLDING / HOLDING_RATIO_EXCEEDED / SUITABILITY_MISMATCH / PRODUCT_NOT_TRADABLE 503 FUND_QUOTE_UNAVAILABLE(可重试) 新增:app/api/controllers/trading.py / app/api/schemas/trading.py / app/service/trade_service.py / tools/seed_sim_account_demo.py / tests/unit/service/test_trade_service.py(unit×8) / tests/contract/test_trading_endpoint_contract.py(contract×11) 修改:app/main.py(挂载 controller) / app/core/errors.py(10 新异常类) / tools/seed_test_rbac.py / docs/05-接口文档.md(§19 T001-T009 + §3.6 9 新码) / tests/unit/core/test_errors.py(DOCUMENTED 同步) 门禁:pytest tests/unit tests/contract 1313 passed (+19 新增) / ruff all clean / 三道守卫全过
This commit is contained in:
@@ -181,6 +181,15 @@ Run Query Service -> RunRepository/ConversationRepository -> JSON/SSE View
|
||||
| `DEPENDENCY_UNAVAILABLE` | 503 | 是 | 必需依赖不可用 |
|
||||
| `UPSTREAM_TIMEOUT` | 504 | 是 | 上游超过时间预算 |
|
||||
| `AGENT_INTERNAL_ERROR` | 500 | 视情况 | 未分类内部错误 |
|
||||
| `ACCOUNT_NOT_FOUND` | 404 | 否 | 账户不存在或状态非"正常" |
|
||||
| `INSUFFICIENT_FUNDS` | 422 | 否 | 账户可用资金不足以扣减本次买入金额+费用 |
|
||||
| `INSUFFICIENT_HOLDING` | 422 | 否 | 可用持仓不足以卖出本次数量 |
|
||||
| `PRODUCT_NOT_TRADABLE` | 422 | 否 | 产品未上市或不在交易时段 |
|
||||
| `FUND_QUOTE_UNAVAILABLE` | 503 | 是 | 行情快照缺失或过期(持仓比例上限校验依赖) |
|
||||
| `HOLDING_RATIO_EXCEEDED` | 422 | 否 | 买入后超过产品持仓比例上限 |
|
||||
| `SUITABILITY_MISMATCH` | 422 | 否 | 客户适当性等级与产品风险等级不兼容 |
|
||||
| `ORDER_NOT_CANCELLABLE` | 409 | 否 | 委托已进入不可撤单阶段(首版直接成交后不可撤) |
|
||||
| `ORDER_NOT_FOUND` | 404 | 否 | 委托不存在或不属于当前客户 |
|
||||
|
||||
### 3.7 数据格式
|
||||
|
||||
@@ -1144,6 +1153,29 @@ GET /internal/metrics
|
||||
| O001 | `GET /internal/health/live` | 内网 | 否 | `200` | 否 |
|
||||
| O002 | `GET /internal/health/ready` | 内网 | 否 | `200/503` | 否 |
|
||||
| O003 | `GET /internal/metrics` | 监控系统 | 否 | `200` | 否 |
|
||||
| T001 | `GET /api/v1/users/me/account/dashboard` | `account:read:self`(已登录) | 否 | `200` | 账户看板(汇总账户/资金/持仓/盈亏) |
|
||||
| T002 | `POST /api/v1/users/me/orders` | `trade:order:create`(已登录) | 必须 | `201` | 委托提交(市价立即全额成交) |
|
||||
| T003 | `GET /api/v1/users/me/orders` | `trade:order:read`(已登录) | 否 | `200` | 委托列表(按 id 倒序游标分页) |
|
||||
| T004 | `GET /api/v1/users/me/orders/{order_no}` | `trade:order:read`(资源所有者) | 否 | `200` | 委托详情 |
|
||||
| T005 | `POST /api/v1/users/me/orders/{order_no}/cancellations` | `trade:order:cancel`(资源所有者) | 必须 | `200` | 撤单(首版仅"已接受/已部分成交"可撤) |
|
||||
| T006 | `GET /api/v1/users/me/holdings` | `holding:read:self`(已登录) | 否 | `200` | 持仓列表(含市值/盈亏/当日盈亏) |
|
||||
| T007 | `GET /api/v1/users/me/transactions` | `trade:txn:read`(已登录) | 否 | `200` | 成交记录列表 |
|
||||
| T008 | `GET /api/v1/users/me/transactions/{txn_no}` | `trade:txn:read`(资源所有者) | 否 | `200` | 成交详情 |
|
||||
| T009 | `GET /api/v1/users/me/cash-ledger` | `account:read:self`(已登录) | 否 | `200` | 资金账本(按 id 倒序游标分页) |
|
||||
|
||||
> **T001 – T009 的四点说明**:
|
||||
>
|
||||
> - **首版只支持 `price_type="market"` 市价委托**(`docs/00` §6.6 定义),系统**立即全额成交**,
|
||||
> 委托状态直接落到 `已成交`;因此 T005 撤单首版对任何在场委托都返回
|
||||
> `ORDER_NOT_CANCELLABLE`(409),保留接口作为后续限价/部分成交开启的入口。
|
||||
> - **价格来源**仅复用底座 `FundQuoteService` 的公共行情快照
|
||||
> (`fin_market_price` 最新交易日,quote_source = `eastmoney_demo_seed`);
|
||||
> Service 层**不**做行情二次封装,从而满足 AGENTS.md 第 2 条 Agent/Service 不直接命中行情 API。
|
||||
> - **数据库零变更**:T 段所用的 10 张 `fin_*` 表均由 `docs/00` 定义;本批 PR **不**重命名/删除/修改列类型
|
||||
> 与可空性,与 AGENTS.md 第 1 条一致。
|
||||
> - **持仓比例上限**在 T002 买入路径强制校验
|
||||
> `(当前持仓 + 本次拟成交)/ total_fund_shares * 100 <= single_investor_max_holding_ratio`;
|
||||
> `fin_market_price` 缺失或过期则拒绝买入(docs/00 §6.6 红线)。
|
||||
|
||||
> **A034 – A038 的两点说明**:
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user