S-ORD 委託回報查詢 Feature Spec

Feature 前綴:S-ORD | Feature 目錄orderReportsRoute/order-reportsBackend ControllerOrderReportsController資料來源OrderDetail(委託明細)+ MatchDetail(成交回報)

本頁摘要 Feature Spec;完整內容見 spec.md。feature-map 對應列:FSTS 功能對應表 §完整對應表

需求摘要

「委託回報查詢」是唯讀查詢功能模組,供交易員查閱委託送出後的執行回報紀錄(含委託狀態、成交結果)。1

業務背景:複委託流程中,交易員透過 COBOL 主機系統送出委託(Order)後,外部清算系統(如 CBL)回傳成交回報(Match/Trade Confirmation);資料透過 FD 檔案轉入 OrderDetailMatchDetail 資料表。此模組提供統一查詢介面,交易員無需直接存取資料庫。1

使用者故事:交易員希望查詢系統中所有客戶的委託回報紀錄,以追蹤委託執行狀態、核對成交結果、並在客戶詢問時快速定位委託資訊。1

Scope

In Scope

2 本 Feature 涵蓋:

  • 委託回報列表查詢(讀取 OrderDetail
  • 多維篩選:客戶帳號、股票代號、委託狀態(ProcessFlag)、買賣別(BSCode)、委託日期區間(OrderDate)、券商代號、上手券商代號
  • 列表分頁(預設 20,上限 500)
  • 單筆明細查詢(JOIN MatchDetail 取得成交回報清單)
  • 前端列表頁 /order-reports 篩選列、分頁表格、查看詳情按鈕
  • 權限 OrderReports.View(Admin / User 角色預設皆擁有)
  • 文件同步:feature-map.mdscenarios.mddomain.mddb-schema.md

Out of Scope

2 留給後續:

  • 委託建立/修改/刪除、下單、撤單(本功能為純查詢)
  • 成交回報手動輸入或修改
  • 匯出(CSV/Excel)、即時推播(WebSocket/SignalR)
  • 跨客戶成本分析或盈虧計算
  • MatchDetail 獨立列表頁(作為委託明細的子資料呈現)

資料模型

3 兩張表均由 COBOL FD 轉檔寫入(FSIO FD / FHIO-F FD),本功能不寫入

OrderDetail(委託明細,唯讀)

複合主鍵OrderDate + BrokerNo + OrderNo

主要欄位:OrderDate(char8 YYYYMMDD)、BrokerNo(券商代號)、OrderNo(委託書號 TERM+DSEQ 如 X0001)、AccountNoStockSymbolExchangeCodeCurrencyOrderShare / CancelShare / MatchShareOrderPriceBSCode(B/S)、OrderType(0 現股 / 1 融資 / 2 融券)、TradingType(1 價格限制 / 2 時間限制 / 3 交易指示)、ReservedAmount(圈存金額)、OrderFlag(1 下單 / 2 刪單)、ProcessFlag(空白/0/1/S/E/P/R)、RejectReasonOrderSource(0 一般 / 1 網路)、UpstreamBrokerNoExchangeRate

MatchDetail(成交回報,唯讀)

複合主鍵MatchDate + OrderNo + ExecAllocSeqNo

關聯:MatchDetail.OrderNo = OrderDetail.OrderNo AND MatchDetail.BrokerNo = OrderDetail.BrokerNo;一筆委託可對多筆成交(部分成交)。

欄位分 3 組:

  1. 基本資訊:MatchDate、ExecAllocSeqNo(分單號)、ExecutingBrokerNo、MatchTime(HHMMSS00)、MatchAmount、NetAmount、ReservedAmount、MarginSettlementDate、EquitySettlementDate、ExchangeRate。
  2. 客戶費用(FEE OCCURS 1~8):手續費、處理費、交易所費、結算費、匯款手續費、交易稅、印花稅、PTP 交易稅。
  3. 上手費用(UPFEE OCCURS 1~12):上手版本的手續費/處理費/交易所費/結算費/匯款手續費/交易稅/印花稅/股票服務費/營業稅/保管費/營業成本/交割費用。

COBOL → SQL 欄位對應(TMMDD→OrderDate、SHEET→OrderNo、CSEQ→AccountNo 等)於 spec §Data Model 完整列出。

API 設計

4 兩條端點

方法路徑說明
GET/api/v1/order-reports分頁查詢列表
GET/api/v1/order-reports/{orderDate}/{brokerNo}/{orderNo}單筆明細(含成交清單)

GET /api/v1/order-reports

4 Query 參數:pagepageSizebrokerNoaccountNostockSymbolprocessFlagbsCodeorderDateFromorderDateToupstreamBrokerNo

Response:PagedResponse<OrderReportResponse>,含 page / pageSize / totalCount / totalPages / items[],每筆帶中英欄位 label(如 bsCodeLabelprocessFlagLabeltradingTypeLabel)、計算欄位 remainSharematchCount

計算欄位remainShare = OrderShare - CancelShare - MatchShare(非 DB 欄位,DTO 層以 Math.Max(0, ...) 保護,負數截為 0)。4

FluentValidationpageSize 介於 1~500;orderDateFrom/To 須合法 YYYY-MM-DD;orderDateFrom <= orderDateTobsCode 僅允許 B 或 S;processFlag 僅允許(空白/0/1/S/E/P/R)。4

GET /api/v1/order-reports/{orderDate}/{brokerNo}/{orderNo}

5 Path 參數:orderDate(YYYYMMDD)、brokerNoorderNo

Response:OrderReportDetailResponse,含完整委託欄位 + matchDetails[](無成交為空陣列,不可為 null);每筆成交含基本資訊 + 客戶費用(FEE 18)+ 上手費用(UPFEE 112)。

User Scenarios

主流程 S-ORD-001 ~ 010

6 全為 Full Suite(情境編號 001 起始;S-ORD 為新模組):

  • 001 預設查詢:進入 /order-reports,依 OrderDate 降序、每頁 20 筆
  • 002 依券商代號篩選(如 9699)
  • 003 依客戶帳號篩選(如 100001)
  • 004 依股票代號篩選(如 AAPL,不分大小寫
  • 005 依委託狀態篩選(如「已完成」→ ProcessFlag='S'
  • 006 依買賣別篩選(買進 → BSCode='B'
  • 007 依委託日期區間(如 2026-01-01 ~ 2026-03-31)
  • 008 組合篩選:券商 + 買賣別 + 日期區間
  • 009 展開單筆成交明細(matchCount > 0
  • 010 查看無成交紀錄的委託(matchCount = 0 → 顯示「尚無成交紀錄」)

異常流程

7

情境觸發條件預期結果
S-ORD-ERR-001無符合紀錄200 + items: [] + Empty State
S-ORD-ERR-002pageSize=501400 ProblemDetails「分頁大小不得超過 500」
S-ORD-ERR-003非法日期字串(如 2026-13-01400 ProblemDetails 日期格式錯誤
S-ORD-ERR-004單筆查詢 PK 不存在404 ProblemDetails「委託回報不存在」
S-ORD-ERR-005查詢 API 逾時前端 Error Toast「查詢逾時,請稍後再試」
S-ORD-ERR-006OrderReports.View 權限前端 PermissionGuard;API 回 403

UI 驗證情境

8

  • S-ORD-VAL-001 起始日期晚於結束日期 → inline 錯誤「起始日期不得晚於結束日期」,查詢鍵停用
  • S-ORD-VAL-002 bsCode 非 B/S → 後端 FluentValidation 回 400

Acceptance Criteria

後端 API(AC-01 ~ 13)

9

  • AC-01 無篩選回 200,items 含基本欄位
  • AC-02 ~ 06 各單一篩選正確生效,包含 stockSymbol=aapl 須比對到 AAPL
  • AC-07 pageSize=501 → 400 RFC 7807
  • AC-08 ~ 09 單筆查詢存在回 200 含 matchDetails;不存在回 404
  • AC-10 無權限 JWT → 403
  • AC-11 回應為 PagedResponse<OrderReportResponse>page/pageSize/totalCount/totalPages
  • AC-12 remainShare = max(0, OrderShare - CancelShare - MatchShare)不得為負
  • AC-13 matchDetails 為陣列,無成交時為 []不可為 null

前端(AC-14 ~ 22)

10 篩選列 + 表格;套用篩選分頁重置;查無資料顯 Empty State;「查看詳情」按鈕導向 /order-reports/{orderDate}/{brokerNo}/{orderNo};詳情頁顯示委託基本資訊 Card + 成交明細 Card;無成交顯「尚無成交紀錄」;orderDateFrom > orderDateTo inline 錯誤不送 API;ProcessFlag Badge 配色(S 綠 / E R 紅 / 1 藍 / 0 空白灰 / P 黃);BSCode Badge(B 藍買進 / S 橘賣出);詳情頁「← 返回列表」按鈕導回列表。

UI 設計

11 UI 設計狀態:✅ 已完成,設計稿 pencil-new.pen(共用畫布),四個 Frame:列表頁、Empty State、篩選驗證錯誤、詳情頁。

列表頁:篩選列欄位(券商 Input、客戶帳號 Number、股票代號、委託狀態 Dropdown 多選、買賣別 Dropdown 單選、委託日期起迄 DatePicker、上手券商 Input)+ 資料表格(含展開/查看詳情按鈕)+ 分頁列。12

詳情頁:委託基本資訊 Card(5 欄 Grid,右上角顯示 ProcessFlag Badge)+ 成交明細 Card(成交清單表格 + 每筆成交的「分單號 N — 費用明細」區塊,客戶費用與上手費用分兩子區;上手費用以 4 欄 Grid 排列 UPFEE 12 欄)。13

ProcessFlag Badge 對應:空白/0=灰(未處理)、1=藍(已傳出)、S=綠(已完成)、E=紅(錯誤)、P=黃(人工)、R=紅(拒絕)。12

Edge Cases

14 重點處理:

  • OrderShare - CancelShare - MatchShare 負值 → remainShare 強制為 0(DTO 層 Math.Max(0, …)
  • ProcessFlag 空白等同 ‘0’(未處理),查詢時兩者視為同義(WHERE ProcessFlag IN ('', '0')
  • OrderDate 儲存為 char(8) YYYYMMDD;篩選傳入 YYYY-MM-DD 須在 Repository 層轉換比對
  • MatchTimechar(8) HHMMSS00,前端截前 6 碼顯示為 HH:MM:SS
  • 孤兒 MatchDetail(無對應 OrderDetail)不會出現在列表(以 OrderDetail 為主表)
  • 分頁超過最後一頁回 200 + 空陣列
  • stockSymbol 不分大小寫比對(UPPER()EF.Functions.Like
  • 日期區間跨度大(如 10 年)→ 依賴 OrderDate 索引(Risks 追蹤)

Tasks

Backend 層(T-01 ~ 12)

15 主要檔案:

  • Application:GetOrderReportsQuery / GetOrderReportDetailQuery(含 FluentValidation;Detail Handler 查不到時拋 NotFoundException → 404)
  • DTO:OrderReportResponse(含 remainShare 計算)、OrderReportDetailResponse(含 matchDetails)、MatchDetailResponse(基本資訊 + FEE 18 + UPFEE 112 全欄位)
  • Repository:IOrderReportRepository / OrderReportRepositoryGetPagedAsync 動態條件 + stockSymbol 不分大小寫 + 日期格式轉換;GetDetailAsync JOIN + matchCount
  • Controller:OrderReportsController 兩條路由掛 [RequirePermission("OrderReports", "View")]
  • 資源定義:ResourceDefinitions.OrderReports.View
  • SQL:015_add_order_reports_permissions.sql(Admin / User 角色 RolePermission seed)
  • Unit Test:GetOrderReportsQueryHandler(8 情境 + remainShare 負值保護)、GetOrderReportDetailQueryHandler(有/無成交 / 404)

Frontend 層(T-13 ~ 26)

16 主要檔案(src/features/orderReports/):

  • Types:orderReportsTypes.tsOrderReport, OrderReportDetail, MatchDetailItem, OrderReportsQueryParams, ProcessFlagValue, BSCodeValue
  • API:src/services/api/orderReportsApi.ts + api/orderReportsQueryKeys.ts
  • Hook:useOrderReportsQuery(列表)、useOrderReportDetailQuerylazy,展開時才觸發)
  • UI:OrderReportsFilterBar.tsxOrderReportsTable.tsxProcessFlagBadge.tsxBSCodeBadge.tsxListPage.tsxDetailPage.tsx
  • 路由:src/app/(dashboard)/order-reports/page.tsx[orderDate]/[brokerNo]/[orderNo]/page.tsx(均 PermissionGuard 包裝)
  • Sidebar:src/shared/constants/appConstants.ts 新增 /order-reports entry

文件同步(T-26 ~ 29)

17 需更新:docs/domain/feature-map.md(新增 S-ORD 列)、docs/domain/scenarios.md(S-ORD 情境編號與 Robot Framework Keyword 欄位)、docs/domain/domain.md(術語「委託回報 Order Report」、「成交回報 Match Detail」;BR-011 商業規則;OrderReports.View 權限列)、docs/domain/db-schema.mdOrderDetail / MatchDetail 標注 S-ORD 使用)。

Risks

18

風險等級緩解
OrderDetail 資料量龐大,全表掃描慢🔴 高確認 OrderDate/BrokerNo/StockSymbol 索引;必要時以 DB Script 補(不得改 FD 轉入資料)
OrderDate(char8 YYYYMMDD)轉換邏輯邊界錯誤🟠 中Repository 單元測試覆蓋跨月/年底
MatchDetail JOIN 與 matchCount 效能🟠 中列表只查 matchCount(COUNT 子查詢),展開時才 lazy load;確認 OrderNo + BrokerNo 索引
remainShare 負值(資料異常)🟡 低DTO 層 Math.Max(0, …)
ProcessFlag 空白 vs ‘0’ 語意🟡 低查詢條件 WHERE ProcessFlag IN ('', '0')
依賴 COBOL FD 轉檔正確性🟠 中本功能僅查詢;Empty State 提示「資料來源為轉檔結果」
EF Core Migration 歷史衝突(SQL Script 序號)🟡 低開發前確認最新序號;此次為 015

相關頁面

補充資訊

(未來 ingest 新來源會在此追加段落)


參考資料

Footnotes

  1. spec.md §Requirement Summary 2 3

  2. spec.md §Scope 2

  3. spec.md §Data Model

  4. GET list 2 3 4

  5. GET detail

  6. 主流程

  7. 異常流程

  8. UI 驗證情境

  9. 後端 API

  10. 前端

  11. spec.md §UI Design Reference

  12. 列表頁 2

  13. 詳情頁

  14. spec.md §Edge Cases

  15. Backend 層

  16. Frontend 層

  17. 文件同步

  18. spec.md §Risks