summaryrefslogtreecommitdiff
path: root/src/FundLab.Api/Persistence.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-21 06:38:58 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-21 06:38:58 +0800
commit64a4ca5c0a523ffc51c861eac1291671b90a2f3a (patch)
tree12b846aa15ba8563dfbce29f53b966667c8d30a7 /src/FundLab.Api/Persistence.fs
parent03f89aea966dfe9edcd08695a79788a6be703b26 (diff)
downloadfund-lab-64a4ca5c0a523ffc51c861eac1291671b90a2f3a.tar.gz
fix(api,web): 下单/读取请求身份隔离与零手续费支持(3d-1 评审修正)
- Web: orderSeq 拆分为 orderCreateSeq/orderReadSeq,并发刷新不再丢弃在途下单结果;换基金/换 token 双序列失效并携带 fundId 双重守卫 - 零手续费:DB CHECK fee_amount >= 0(幂等迁移),校验改为拒绝负数,UI 提示与占位符同步 - 测试:API 增加零手续费回放与 DB 负手续费约束回归(43/43),浏览器新增 H 系列延迟 POST 并发刷新/失败恢复/换基金隔离(78/78)
Diffstat (limited to 'src/FundLab.Api/Persistence.fs')
-rw-r--r--src/FundLab.Api/Persistence.fs9
1 files changed, 6 insertions, 3 deletions
diff --git a/src/FundLab.Api/Persistence.fs b/src/FundLab.Api/Persistence.fs
index 88c0350..6c60bdd 100644
--- a/src/FundLab.Api/Persistence.fs
+++ b/src/FundLab.Api/Persistence.fs
@@ -131,13 +131,16 @@ type FundRepository(connectionString: string) =
fund_id uuid NOT NULL REFERENCES funds(id),
fund_code text NOT NULL,
amount numeric(20, 2) NOT NULL CHECK (amount > 0),
- fee_amount numeric(20, 2) NOT NULL CHECK (fee_amount > 0),
+ fee_amount numeric(20, 2) NOT NULL CHECK (fee_amount >= 0),
reserved_total numeric(20, 2) NOT NULL CHECK (reserved_total > 0),
status text NOT NULL,
is_synthetic boolean NOT NULL,
submitted_at timestamptz NOT NULL DEFAULT now()
);
+ ALTER TABLE subscription_orders DROP CONSTRAINT IF EXISTS subscription_orders_fee_amount_check;
+ ALTER TABLE subscription_orders ADD CONSTRAINT subscription_orders_fee_amount_check CHECK (fee_amount >= 0);
+
CREATE TABLE IF NOT EXISTS subscription_order_idempotencies (
idempotency_key text PRIMARY KEY,
request_hash text NOT NULL,
@@ -564,8 +567,8 @@ type FundRepository(connectionString: string) =
Error "fund code cannot be empty"
elif command.Amount <= 0m then
Error "amount must be positive"
- elif command.FeeAmount <= 0m then
- Error "fee amount must be positive"
+ elif command.FeeAmount < 0m then
+ Error "fee amount cannot be negative"
elif Decimal.Round(command.Amount, 2) <> command.Amount then
Error "amount exceeds cash precision"
elif Decimal.Round(command.FeeAmount, 2) <> command.FeeAmount then