產能模組 (Capacity Module) Functional Spec

來源:capacity-module 下游:OOA(草稿 2026-06-15,Step 1–3) 性質:單一 feature;為產能真相源頭,經轉接器(ACL)餵粗排等下游。本模組是 resource-selection consumed port ResourceCouplingQuery.allowedTargets§RS-OA-5)與 WorkCapability/eligible生產端。 狀態:已簽核(2026-06-15)— UC-AD 全定稿(§CAP-FS 112);驗證 script 決定不寫。


概述

產能模型從「以工作站為主體」翻轉成「以資源為主體」的彈性結構(§CAP-UR-9)。資源是多型的(機台、模治具、操作員、換模技師等,不限於此),每個各自帶工作能力(製程列表)、隸屬工作站、地理位置與資源間關聯,可用時間則用行事曆、班表、加班/休息來描述。模組產出的產能,本質鍵就是「資源 × 時間區段」(§CAP-UR-7),也就是粗排等下游的產能真相源頭。下游實際吃的「資源×日」讀模型,則由轉接器(ACL)投影而來(投影設計屬 Stage 3 OOA,本 FS 不展開)。


本次 Scope 決策(2026-06-15 拍板)

#項目決策
S1優先度關聯(§CAP-UR-10 之 #4:A/B 機台某些條件同時選中排單)明確不做本期——條件未定義、寫不出具體行為(見覆蓋對照)
S2限制關聯(§CAP-UR-6只定對外產出契約(單向、資源→受限資源集);維護方式(誰填/怎麼填)明確不做(對齊 resource-selection §RS-UR-10 風格)
S3跨日班日界(§CAP-UR-5產能歸起班日(週二晚班算週二),見 §CAP-FS-1
S4產能投影邊界(§CAP-UR-7/8)FS 只定對外觀察點(資源×時間區段);「→ 既有資源×日 AvailableCapacity/CapacitySlot」的投影由轉接器(ACL)/OOA 做,FS 不設計

結構觀察點(帶進 OOA/audit、本 FS 不拍板解法):① 資源型別多型(§CAP-UR-10)與 domain-model Resource flat→abstract+4 子類 delta(見 audit 未結 ❌)重疊;② 資源×時間區段 vs 既有資源×日(domain-model 2026-06-09 已下沉到資源×日,剩時間軸 delta);③ 配對特例(§CAP-UR-2)挑戰既有「節點=工作站-製程單一對」不變量。


Use Cases

Actor 多為呼叫方(產能查詢/轉接器/下游消費方),非人。

UC-A:解析資源可用時間區段 ✅ 已定稿

  • Actor:呼叫方(產能查詢/轉接器)
  • 觸發條件:給定一個資源 + 一段日期範圍,要求算出該資源在這段期間的可用時間區段
  • 行為
    1. 取該資源自帶的班表(班別代號在前端設定介面指定,此處已解析為 dayOfWeek + 起始時間 + 時長 + 多組休息時段)
    2. 行事曆(日曆天)把週期性班表展開到日期範圍的每一個日曆天,得各日班別區間
    3. 套用加班/休息表集合運算疊加:以班表區間為底,加班=聯集(∪)加區段、休息=差集(−)減區段
    4. 再扣除班表自帶的休息時段(差集 −)
    5. 跨日班:在日界切成兩段,兩段都標記產能歸屬日=起班日§CAP-UR-5§CAP-FS-1
  • 預期結果:該資源在日期範圍內的一組可用時間區段 [起, 迄),每段帶歸屬日(明確輸出欄位);已做集合運算、已扣休息、跨日班已切段並歸起班日
  • 例外路徑:見 §CAP-FS-1(跨日班歸屬)、§CAP-FS-2(集合運算順序與重疊衝突)、§CAP-FS-3(無班別日)
  • 設計前提:集合運算依固定順序。重疊衝突(例如休息砍到加班加出的時段)由模組外的 UI alert 處理,本模組不在這擋(資料正確性歸模組外負責,跟 resource-selection 同一套哲學)。至於歸屬日欄位與粗排「日投影」怎麼互動,是之後的議題(接 S4,留給 OOA/粗排對齊)。

UC-B:資源能力-工作站配對(對外能力契約) ✅ 已定稿

  • Actor:呼叫方(resource-selection 等消費方)
  • 觸發條件:給定 (製程, 工作站),要求該配對下的合格資源
  • 行為
    1. 對資源池每個資源,看其**工作能力**是否涵蓋該 (製程, 工作站)
    2. 主規則:先比製程、再比工作站,預設兩者皆需 match(exact pair;工作站資訊長在能力 pair 裡,沿用 domain-model WorkCapability = Map<製程, 工作站集合> 合一形狀)
    3. 回傳所有 match 的資源(合格資源集),供下游 eligible(processId, workCenterId) / 能力匹配消費
  • 預期結果:該 (製程,工作站) 的合格資源集(生產端契約;可能為空集)
  • 地理位置:純資訊欄位,不參與配對§CAP-UR-3§CAP-FS-7
  • 例外路徑:見 §CAP-FS-5(特例配對)、§CAP-FS-6(能力空集)
  • 設計前提
    • 特例(同製程異工作站、佔用時不論工作站,§CAP-UR-2)不在本模組的能力契約展開:eligible 維持 exact pair。這種特例其實是現場把資源「指派」到異工作站的 VSMNode,交由下游 resource-selection 的指派路徑(韌性放行 BR-1)處理(§CAP-FS-5)。本層 eligible 保持乾淨,「節點=工作站-製程單一對」不變量在這一層守住。
    • 能力空集就老實回 { },不 fail-fast。空集要不要當錯誤,是消費方的職責(resource-selection §RS-FS-5:能力路徑空集才 fail-fast),不是本模組(§CAP-FS-6)。這條職責切線跟「本模組不做產能/CO 計算」是對稱的。

UC-C:單向限制關聯對外查詢契約 ✅ 已定稿

  • Actor:呼叫方(resource-selection)
  • 觸發條件:查詢某 restrictive 資源(操作員/技師)的允許目標集
  • 行為
    1. 取該 restrictive 資源的單向限制關聯
    2. 回其允許目標集——操作員→可操作的機台集技師→可更換的模具集§CAP-UR-6
  • 預期結果Set<受限資源Id>,形狀對齊下游 consumed port allowedTargets(restrictive) → Set<ResourceId>§RS-OA-5
  • 例外路徑:見 §CAP-FS-8(方向)、§CAP-FS-9(未設定/設空)
  • 設計前提
    • 單向,不提供反向查詢。口述原話「機台只能給某些操作人員」在 requirement 已正規化為「操作員→機台」(資源→受限資源),方向由下游 OP1→{M1,M2} 釘住(§CAP-FS-8)。
    • 未設定或設空就回 { } 空集,不臆測成「全部」。本模組不必握有全集,「未設定」跟「設了但空」對它來說同義(§CAP-FS-9)。下游耦合過濾只在節點「有宣告」需要該限制型別時才查 allowedTargets,剔光則韌性放行(§RS-FS-4)。
    • 維護方式不在範圍(誰填/怎麼填,S2、對齊 §RS-UR-10 風格)。

UC-D:彙整資源×時間區段可用產能(產能真相源頭) ✅ 已定稿

  • Actor:呼叫方(轉接器)
  • 觸發條件:取得某範圍內「資源 × 時間區段」的可用產能真相
  • 行為
    1. 對資源池中每個資源(含機台/模治具/操作員/技師,皆為第一級資源)跑 UC-A,得各自的可用時間區段(帶歸屬日)
    2. 彙整成 {資源 → 可用時間區段清單} 的對外視角(產能本質鍵=資源×時間區段,§CAP-UR-7
  • 預期結果:資源×時間區段的**可用產能真相**;日粒度投影(→ 既有 AvailableCapacity/CapacitySlot 資源×日)由轉接器(ACL) 做,不在本模組(S4、§CAP-FS-12
  • 例外路徑:見 §CAP-FS-10(可用 vs 佔用邊界)、§CAP-FS-11(模治具/技師佔用量屬下游)
  • 設計前提
    • 只產 raw 可用時間區段,不扣任何佔用。FREEZE 已凍排程、COCT 佔用量都不在此,佔用全留給下游(轉接器投影+引擎 overlay,對齊既有 domain-model OccupationFREEZEIN_RUN)(§CAP-FS-10)。本模組只回答「本來有沒有空」,不回答「已被誰佔走」。
    • 模治具/換模技師的產能佔用量由 DataBox.changeOverTime 推算,那是下游拿本模組的可用產能去扣的事,不在本模組計算(§CAP-UR-1§CAP-FS-11)。

流程圖

UC-A — 解析資源可用時間區段

flowchart TD
    Start[呼叫方給 資源 + 日期範圍] --> Shift[取資源自帶班表\n班別已解析為 起始+時長+休息]
    Shift --> Expand[依行事曆展開到每個日曆天\n得各日班別區間]
    Expand --> HasShift{該日曆天有班別?}
    HasShift -- 無 --> Empty[該日回空區段 不報錯]
    HasShift -- 有 --> Merge[集合運算 加班∪ · 休息−]
    Merge --> Rest[再扣班表自帶休息時段 −]
    Rest --> Cross{含跨日班?}
    Cross -- 是 --> Split[於日界切兩段\n兩段皆標記歸屬日=起班日]
    Cross -- 否 --> Tag[標記歸屬日=當日]
    Split --> Out[輸出帶歸屬日的可用區段清單]
    Tag --> Out
    Empty --> Out

I/O 範例

日期慣例:06-16=週二、06-17=週三。

UC-A

正常值(早班 + 午休)

  • input:資源 M1;班表=週二早班 08:00 起 9h、休息 12:00–13:00;範圍 06-16
  • output:
    [ (06-16 08:00, 06-16 12:00, 歸屬日=06-16),
      (06-16 13:00, 06-16 17:00, 歸屬日=06-16) ]
    

邊界值(跨日晚班)

  • input:資源 M1;班表=週二晚班 22:00 起 9h、無休息;範圍 06-16 ~ 06-17
  • output:
    [ (06-16 22:00, 06-17 00:00, 歸屬日=06-16),
      (06-17 00:00, 06-17 07:00, 歸屬日=06-16) ]   # 切日界兩段、皆歸起班日
    

異常值(無班別日)

  • input:資源 M1;範圍含 06-21(週日,無對應班別)
  • output:06-21 → [ ](回空區段,不報錯,視為合法空輸出)

補充(加班/休息集合運算,含詭異重疊)

  • input:資源 M1;班表=週二早班 08:00 9h、休息 12:00–13:00;加班表 06-16 18:00–20:00;休息表 06-16 16:00–17:00
  • 運算:base 08–17 →(∪加班18–20、−休息16–17)→ 08–16,18–20 →(−班表午休12–13)→ 08–12,13–16,18–20
  • output:[ (08:00,12:00), (13:00,16:00), (18:00,20:00) ] 歸屬日=06-16

    若休息表砍到加班加出的時段(如休息 18:30–19:00),模組仍依序運算(得 18:00–18:30, 19:00–20:00);此重疊衝突由模組外 UI alert,非本模組職責(§CAP-FS-2)。

UC-B

樣本資源池:M1: {P1→[W1,W2]}M2: {P1→[W1]}M3: {P2→[W1]}

正常值(主規則:兩者皆 match)

  • input:eligible(製程=P1, 工作站=W1)
  • output:{M1, M2}(M3 製程不符)

邊界值(製程 match、工作站不符 → 主規則排除)

  • input:eligible(製程=P1, 工作站=W3)
  • output:{ } 空集

    M1/M2 能力涵蓋 P1,但工作站只到 W1/W2、不含 W3。特例(同製程異工作站)不在此回——由下游指派路徑處理(§CAP-FS-5)。

異常值(能力空集)

  • input:eligible(製程=P9, 工作站=W1)(無任何資源能力含 P9)
  • output:{ } 空集(不報錯;fail-fast 屬下游 §CAP-FS-6

UC-C

樣本限制關聯:OP1→{M1,M2}(操作員 OP1 可操作 M1、M2)、MOP1→{MOLD1}(技師 MOP1 可換 MOLD1)。

正常值(操作員→機台)

  • input:allowedTargets(restrictive=OP1)
  • output:{M1, M2}

邊界值(技師→模具,另一型別方向)

  • input:allowedTargets(restrictive=MOP1)
  • output:{MOLD1}

異常值(未設定限制關聯)

  • input:allowedTargets(restrictive=OP9)(OP9 未設任何限制關聯)
  • output:{ } 空集(未設定與設空同回空,不臆測全部;§CAP-FS-9

UC-D

樣本資源池(混型別):M1(機台)、MOLD1(模具)、OP1(操作員)、MOP1(技師),各帶班表;範圍 06-16

正常值(多型別彙整)

  • input:資源池 {M1, MOLD1, OP1, MOP1},皆週二早班 08:00 9h、休息 12:00–13:00
  • output:
    { M1   → [(08:00,12:00),(13:00,17:00)] 歸06-16,
      MOLD1 → [(08:00,12:00),(13:00,17:00)] 歸06-16,
      OP1   → [(08:00,12:00),(13:00,17:00)] 歸06-16,
      MOP1  → [(08:00,12:00),(13:00,17:00)] 歸06-16 }
    

    模治具/技師同走時間區段機制;未扣任何佔用(raw 可用,§CAP-FS-10)。

邊界值(某資源跨日班)

  • input:OP1 改週二晚班 22:00 9h,其餘同上;範圍 06-16 ~ 06-17
  • output:OP1 → [(06-16 22:00, 06-17 00:00),(06-17 00:00, 06-17 07:00)] 皆歸06-16(繼承 UC-A 跨日切段,§CAP-FS-1

異常值(資源池空 / 該日無班別)

  • input:資源池為空,或某資源該日曆天無對應班別
  • output:{ }(空池回空);無班別資源回空清單、不報錯§CAP-FS-3

邊界條件 / 異常情境

「編號」欄即全域碼 §CAP-FS-{N}CAPspec-codes.md。append-only,不重編。UC-A 衍生 13;UC-B 衍生 47;UC-C 衍生 8~9;UC-D 定稿後 append。

  • §CAP-FS-1
    • 條件:班別跨日界(如週二晚班 22:00→週三 07:00)
    • 結果:於日界切兩段輸出;兩段產能皆歸起班日(週二)(§CAP-UR-5)。歸屬日為明確輸出欄位
  • §CAP-FS-2
    • 條件:同一日曆天有班表+加班+休息
    • 結果:集合運算固定順序:班表為底 →(加班 ∪、加班/休息表 −)→(扣班表自帶休息 −)。重疊衝突(休息砍到加班加出的時段)模組依序運算、不擋,由模組外 UI alert
  • §CAP-FS-3
    • 條件:該日曆天無對應班別
    • 結果:回空區段、不報錯(合法空輸出)
  • §CAP-FS-4
    • 條件:eligible(製程, 工作站) 主規則
    • 結果:exact pair:製程在資源能力、且工作站在該製程的工作站集,兩者皆 match 才合格(§CAP-UR-2 主規則)
  • §CAP-FS-5
    • 條件:特例:同製程、異工作站(現場上機到別工作站的資源)
    • 結果:不在本模組能力契約展開eligible 維持 exact、不放寬工作站。特例由下游 resource-selection 指派路徑(韌性放行 BR-1)處理(§CAP-UR-2 特例)
  • §CAP-FS-6
    • 條件:能力空集(無資源涵蓋該 (製程,工作站))
    • 結果:eligible{ }不報錯/不 fail-fast;空集的 fail-fast 處置屬下游 resource-selection §RS-FS-5
  • §CAP-FS-7
    • 條件:地理位置
    • 結果:純資訊欄位,不參與配對/能力/時間運算(§CAP-UR-3
  • §CAP-FS-8
    • 條件:限制關聯方向
    • 結果:單向:操作員→可操作機台集、技師→可更換模具集;不提供反向查詢§CAP-UR-6,對齊下游 allowedTargets
  • §CAP-FS-9
    • 條件:restrictive 資源未設定或設空限制關聯
    • 結果:allowedTargets{ } 空集、不臆測「全部」;下游耦合過濾剔光則韌性放行(§RS-FS-4
  • §CAP-FS-10
    • 條件:可用 vs 佔用
    • 結果:UC-D 只產 raw 可用時間區段、不扣任何佔用FREEZE/CO/CT 都不在此);佔用留下游投影 + 引擎 overlay(對齊 domain-model Occupation/FREEZE/IN_RUN
  • §CAP-FS-11
    • 條件:模治具/換模技師
    • 結果:第一級獨立資源,同走時間區段機制;其產能佔用量由 DataBox.changeOverTime 推算屬下游、不在本模組計算(§CAP-UR-1
  • §CAP-FS-12
    • 條件:日粒度投影(資源×時間區段 → 資源×日)
    • 結果:由轉接器(ACL) 做、不在本 FS(S4,投影設計屬 Stage 3 OOA)

requirement 覆蓋對照

  • §CAP-UR-9 建模主體翻轉(工作站→資源)
    • 對應:概述
    • 狀態:已涵蓋(結構觀察點,留 OOA)
  • §CAP-UR-12 時間三件套(行事曆/班表/加班休息)
    • 對應:UC-A
    • 狀態:已涵蓋
  • §CAP-UR-13 工廠術語→時間區間(含跨日班)
    • 對應:UC-A(資源自帶班別、前端設定)
    • 狀態:已涵蓋
  • §CAP-FS-1
    • requirement 需求點:§CAP-UR-5 跨日班歸起班日
    • 狀態:已涵蓋
  • §CAP-UR-7 產能本質鍵=資源×時間區段
    • 對應:UC-A(區段)/UC-D(彙整)
    • 狀態:已涵蓋
  • §CAP-UR-11 資源帶能力/工作站/地理
    • 對應:UC-B(能力/工作站合一 pair)
    • 狀態:已涵蓋
  • §CAP-UR-2 配對主規則+特例
    • 對應:UC-B、§CAP-FS-4/5
    • 狀態:已涵蓋(主規則本模組;特例走下游指派路徑)
  • §CAP-UR-3 地理位置純資訊欄位
  • §CAP-UR-10 資源多型
    • 對應:UC-D(各型別同進)、§CAP-FS-11
    • 狀態:已涵蓋(型別階層屬 OOA,FS 不畫)
  • §CAP-UR-1 模治具/技師獨立資源、佔用量屬下游
  • §CAP-UR-6 限制關聯單向
    • 對應:UC-C、§CAP-FS-8/9
    • 狀態:已涵蓋(對外契約);維護方式明確不做(S2)
  • §CAP-UR-8 架構意圖(轉接器餵下游)
    • 對應:概述/S4/§CAP-FS-12
    • 狀態:投影設計留 OOA(明確不在 FS)
  • §CAP-UR-10(#4)優先度關聯
    • 對應:—
    • 狀態:明確不做(下一期)(S1,條件未定義)

待裁定 / 未解問題

  • Q1(UC-A future,OOA/粗排對齊):歸屬日輸出欄位與粗排「日投影」的互動——跨日班歸起班日後,下游日粒度怎麼吃,待粗排/轉接器對齊時再議(接 S4)。
  • Q2(OOA 收結構解法):UC-B 配對特例(同製程異工作站)走下游指派路徑(§CAP-FS-5),與既有「節點=工作站-製程單一對」不變量的衝擊由 OOA 結構面處理。
  • Q3(OOA delta):資源型別多型(機台/模具/操作員/技師)與 domain-model Resource flat→abstract+4 子類 delta(audit 未結 ❌)對齊,屬 OOA。
  • 下一步:UC-A~D 全定稿。待 ① 寫驗證 script(UC-A 時間區段解析)② 簽核。

驗證 Script(可選)

決定不寫(2026-06-15):UC-A~D 的 I/O 範例已足以人工檢核自洽;時間區段解析雖含演算法成分,邏輯直觀、無多步交互風險,省下 script。日後若時間運算長出複雜分支再回補。


簽核

  • 編輯者:Alan / 日期:2026-06-15
  • Reviewer:Alan / 日期:2026-06-15
  • 狀態:已簽核。Stage 2 Exit Gate 通過 → 交棒 /object-oriented-analysis-partner 做 Stage 3 OOA。