| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
| |
(3d-30 A)
|
| |
|
|
| |
point-in-time valuation (3d-29)
|
| | |
|
| |
|
|
| |
(3d-25)
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
| |
Expose a deterministic source key on booked dividend records and surface a read-only dividend history panel with empty state, backed by API tests and browser QA assertions.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
First vertical slice for portfolio rebalancing. Domain gains
RebalancePolicy: target-allocation validation (non-empty, per-code
shares positive two-decimal, sum exactly 100); diff computation over
the union of target and held codes (held without target = full exit)
producing BUY amount diffs and SELL unit diffs priced at the current
valuation NAV, clamped to available units, with no orders when a
weight already balances; and the deterministic idempotency key set
(rebalance:{plan}:{date}:{code} plus confirm/redeem counterparts).
Rebalance plans persist as rebalance_plans + rebalance_targets with
rebalance_idempotencies under the shared replay/conflict contract.
ExecuteRebalancePlan snapshots cash plus holdings valued at each
position's latest valuation NAV, then walks the diffs SELL-first
through the same Create/Confirm pipeline used by manual orders,
redemptions and SIP (nothing bypasses confirmation; a held code
without a valuation is skipped with an explicit marker; insufficient
cash/units fail the period visibly instead of silently trimming).
API exposes POST/GET /funds/{id}/rebalance/plans and POST
.../plans/{id}/execute. The frontend adds an 08/REBALANCE panel with
target editing (two codes, sum must equal 100), a plan list with a
manual execute button and post-run outcome rows; executing refreshes
orders/positions so the new orders are immediately visible. Domain
tests cover split validation, diff orders, exit/clamp logic, key
determinism; API tests cover create/execute end-to-end; Web tests
cover decoding and stale-execution protection.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Advance executes due periods as real subscription orders: each due
trade date claims a sip_executions row (PRIMARY KEY plan_id+trade_date
makes same-plan same-day runs atomic), places the order through
CreateSubscriptionOrder with a deterministic idempotency key
(sip:{plan}:{date}) and the period's trade date, then confirms through
the shared ConfirmSubscriptionOrder pipeline with key
sip-confirm:{plan}:{date} — identical freeze/fee/units math as manual
orders, nothing bypasses confirmation. Outcomes: succeeded,
pending_nav (cash stays frozen; later drives retry the confirmation
once the NAV lands), insufficient_cash (no order placed, period fails
visibly, reruns keep the marker), failed. Plans roll their
next_trade_date past the processed window and repeats of the same
endDate replay recorded executions instead of re-debiting.
Domain adds SipPolicy.advancePlan (due-date enumeration; weekends-only
trading-calendar approximation, noted in code). POST
/funds/{id}/sip/advance {endDate?, limit?} drives execution on demand
(no daemon). Plan responses/rows now carry last execution status/date;
front-end shows 已执行/待净值/现金不足 per plan. Optional
tradeDateOverride/anchorOverride keep manual flows untouched.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Introduce scheduled-investment plans as a schedule-only slice with no
cash, position or NAV side effects. Domain gains SipPolicy: amount
validation (positive, two-decimal, overflow-checked), frequency
parsing/round-trip (weekly/biweekly/monthly), nextTradeDate generating
the next due trade date off the plan anchor with month-end clamping
and weekend roll-forward, plus the isDue/executionNetAmount contract
the future executor will implement (execution itself stays
unimplemented and is marked as such; nothing debits cash in this
slice).
Persistence stores plans in sip_plans with anchor/next trade dates and
sip_plan_idempotencies under the shared replay/conflict contract; the
API exposes POST/GET /funds/{id}/sip/plans behind the bearer token.
The frontend adds a 07/SIP panel (code, amount, frequency select,
plan list with next debit date) and Web tests cover decoding,
validation, in-flight guards and stale completions. Choice note:
first debit is scheduled strictly after the anchor date (creating a
plan today never debits today).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Deposits credit a fund's available cash directly: Domain gains
CapitalPolicy (positive, two-decimal, overflow-checked amounts plus a
settle function that never touches units, NAV or realized P&L).
Persistence records deposits in fund_capital_deposits with a
fund_capital_idempotencies table, crediting cash and the deposit row
atomically under the same replay/conflict semantics as orders. The
API exposes POST /funds/{id}/capital/deposit and GET
/funds/{id}/capital/deposits behind the bearer token and idempotency
keys. The frontend adds an '追加资金' entry on the fund cash card with
in-place balance refresh, and repeats of the same amount reuse the
idempotency key so double submits credit cash exactly once. Browser
QA extends the J-series (J12-J18): invalid-amount rejection without
POST, single credited deposit with a 32-hex key, instant balance
refresh, unchanged units/cost proving no realized-income impact, and
same-key replay crediting only once.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Redeem confirmed holdings end to end with exact decimal semantics:
submission freezes position units (reserved_units) after an
available-units check without touching cash, confirmation settles at
the trade-date NAV with evidence and deferral rules identical to
subscriptions, credits the fund with proceeds net of the stated fee,
and writes off position cost pro rata (full redemption removes the
position row). Cash conservation holds at every step: frozen shares
and receivable cash never appear as available cash before settlement.
Domain gains RedemptionPolicy (request validation plus proceeds/fee/
cost-release computation) with unit tests. Persistence adds
redemption_orders, idempotency tables, reserved_units on positions
and Create/Confirm repository members; the API exposes
POST/GET /funds/{id}/redemptions and POST .../confirm. The frontend
adds a 06/REDEEM panel (submit, confirm, pending reasons, confirmed
proceeds/cost display), frozen-share display on the holdings panel,
and refresh wiring. Browser QA gains a K-series covering freeze,
settlement, cash accounting, replay and over-redemption rejection.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Wire the subscription confirmation and positions endpoints into the
frontend: order rows show per-order trade date and confirmed outcome
(NAV, units, NAV date, invested cash, residual) or pending_nav reason,
each confirmable order gets a confirm action posting to the existing
confirm endpoint with an idempotency key and request-sequence guard,
and a new holdings panel renders available/reserved cash plus per-code
positions (units, cost, latest valuation NAV with date, or an explicit
'估值待更新' when no valuation exists).
Orders list/create responses now return the full detail shape so
pending reasons and confirmation results survive refresh. The optional
text decoder accepts the current plain-value/null wire format alongside
the legacy case/fields envelope, restoring fund type and daily return
display. Browser QA gains a J-series covering the real confirm flow,
holdings rendering and cash accounting; Web tests cover decoders,
confirm guard, stale-response protection and token invalidation.
|
| |
|
|
|
|
|
|
| |
评审修正)
- Web: orderSeq 拆分为 orderCreateSeq/orderReadSeq,并发刷新不再丢弃在途下单结果;换基金/换 token 双序列失效并携带 fundId 双重守卫
- 零手续费:DB CHECK fee_amount >= 0(幂等迁移),校验改为拒绝负数,UI 提示与占位符同步
- 测试:API 增加零手续费回放与 DB 负手续费约束回归(43/43),浏览器新增 H 系列延迟 POST 并发刷新/失败恢复/换基金隔离(78/78)
|
| |
|
|
|
|
|
|
|
|
| |
- API: POST/GET /api/funds/{fundId}/orders,advisory lock + 行级锁事务预留现金,
幂等键重放/冲突/校验/目录缺失错误码齐全,基金响应新增 reservedCash
- Persistence: subscription_orders 与幂等表 + 保留现金列迁移
- Web: 认购表单与待确认订单列表(已提交·待确认),失败重试复用幂等键,
token 轮换隔离延迟响应
- 测试: API 41(含并发不足/回滚/真实宿主重启回归)、Web 17、Domain 19;
浏览器 QA 58 项全过
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
[变更性质]
- 本提交完成 3c-1 切片:Web 端基金建档(创建/重读)表单接入既有幂等 API,并提供仓库内可复现的端到端 QA 入口与生命周期回归。
[新增功能]
- 前端新增 03 / CREATE 面板:名称与初始现金(decimal 字符串)输入、创建/重新读取按钮、服务端返回的基金档案行(份额诚实显示 0、来源标注真实建档/合成标记);移动端单列布局。
- 创建请求携带 32 位十六进制 Idempotency-Key;网络失败重试复用同一 key,输入变更或成功后换新 key;token 变更清空档案并按序列号拒绝过期响应。
[实现方案]
- 金额全程 decimal 字符串,不经 JS float;update 层 fundSeq 守卫 FundCreate/FundRead 完成消息;BoundaryTests 新增 FundBoundaryTests 9 项(幂等键长度/复用、token 失效、stale 读取拒绝等)。
- qa/run.sh 一次性拉起非默认端口 Postgres/API/Vite(桩行情,_synthetic 标记),清理仅限本次创建的容器(ID+名称归属校验);临时目录 mktemp 隔离;qa/lifecycle-test.sh 验证拒绝路径不破坏既有资源。
[影响范围]
- Web 测试增至 17 项,全套 56 项通过;浏览器 QA 30/30 通过;README 更新阶段描述。本提交不包含 docs/overnight-progress.md 的现有修改。
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
[变更性质]
- 本提交完成 3b 行情闭环:真实 AKShare 搜索与净值采集、PostgreSQL 持久化、鉴权 API 与 Fable 前端净值曲线展示。
[新增功能]
- API 新增 /api/instruments/search、/api/instruments/{code}/nav 与 nav/refresh 接口,经 Bearer 鉴权调用 AKShare Python 采集器并幂等落库。
- 前端提供基金搜索、精确代码选择、历史净值刷新/重读与 SVG 折线图,token 变更即清空私有结果并失效在途请求。
[实现方案]
- MarketData 以 requiredProperty 校验采集器 payload,净值观测按 (code, nav_date) 幂等 upsert 并保留来源与哈希。
- 前端以 requestId 序列守卫 SearchCompleted/SearchFailed/NavCompleted/NavFailed,TokenChanged 同时递增 searchSeq/navSeq 拒绝过期响应;边界解码兼容 F# option 的 {"case":"Some"} 线格式。
[影响范围]
- 新增 FundLab.Web.Tests(边界解码、序列失效、图表纯函数共 8 项),扩展 API 测试至 20 项;vite dev 代理 /api 至本地 API。
- 真实 AKShare 端到端依赖本机 akshare 环境,由负责人另行验收;本提交不包含 docs/overnight-progress.md 的现有修改。
|
|
|
[变更性质]
- 本提交冻结当前可构建、可测试的应用基线,不包含 PostgreSQL 持久化。
[新增功能]
- 建立 F# Domain、API、Worker、Web 及测试项目。
- 增加 Bearer 认证、健康检查、账本领域模型和中文空状态页面。
[实现方案]
- 使用环境变量模板注入认证配置,并排除数据、凭证和构建产物。
- 保留 19 个 Domain 测试和 5 个 API 测试作为后续变更基准。
[影响范围]
- 为后续 3a PostgreSQL FOF 创建/读取切片提供可回滚基线。
- 当前仍不接入真实基金数据、真实交易或数据库。
|