5177/Bundleデータは 「業務として何が必要か」 は表現できていますが、5176で設計判断として扱うには、まだ次が弱いです。
1. NFF は標準機能のどの追加利用・設定・ビューなのか
2. CusField はどのモデルに、どの型で、どんな条件で必要なのか
3. ロジックは何をトリガーに、どの条件で、何を更新するのか
4. 標準機能で代替できるなら、どこまで代替するのか
5. コード生成できる条件まで落ちているか
なので、BusinessStream解決ベースには、NFF / CusField / LogicCandidate を自然文ではなく、半構造化して持つべきです。
追加すべきデータ層
今の考え方に、次の3種類を追加するのが良いです。
BusinessStream Resolution Base
├─ confirmed_business_context
├─ field_standard_overlay_slots
├─ nff_slots
├─ custom_field_slots
├─ logic_slots
├─ gap_resolution_slots
└─ implementation_readiness
ポイントは、NFF・CusField・Logicを同じ「実装候補」扱いにしないことです。
それぞれ性質が違います。
| 種別 | 意味 | 実装の姿 |
|---|---|---|
| Standard Field | 標準フィールドを使う | Odoo標準項目を参照 |
| NFF | 標準機能を使うために必要な標準設定・標準ビュー・標準連携・標準機能上の見せ方 | 設定、保存フィルタ、ビュー拡張、標準モデル利用 |
| CusField | 標準にない業務状態・理由・分類を持つ | x_ field、selection、boolean、many2oneなど |
| Logic | 条件判定・自動更新・警告・状態遷移 | computed field、onchange、constraint、server action、scheduled action、button actionなど |
NFFの定義を明確にした方がいいです
NFFは「New Feature Field」ではなく、今回の文脈ではこう定義した方が自然です。
NFF = 標準機能を使う場合に追加で設計・設定・表示すべき機能要素
つまり、CusFieldとは違います。
例:
nff_slots:
- nff_key: nff::sales.delivery_allocation::delivery_allocation_view
type: standard_view_or_filter
label: 出荷・引当・納期回答一覧
base_model: sale.order.line
uses_standard_models:
- sale.order.line
- stock.move
- stock.picking
uses_standard_fields:
- sale.order.line.product_id
- sale.order.line.product_uom_qty
- sale.order.line.qty_delivered
- stock.picking.scheduled_date
- stock.picking.state
purpose: >
標準の受注明細・出荷情報を組み合わせて、出荷予定・引当・納期回答の確認画面を作る。
implementation_type: saved_filter_or_view_extension
standard_dependency:
- Sales Order
- Inventory Delivery
- Stock Reservation
decision_status: pending
これは「標準フィールドを使うが、業務画面・一覧・確認導線としては新しく作る」ものです。
つまり、コード生成対象になる可能性はあるが、カスタム業務ロジックではない。
CusFieldは「なぜ標準では不足するか」まで必須
CusFieldは、必ず次を持たせた方がいいです。
custom_field_slots:
- field_key: cusfield::sale.order.line::x_delivery_answer_status
model: sale.order.line
field_name: x_delivery_answer_status
label_ja: 納期回答状態
field_type: selection
selection_values:
- value: not_answered
label_ja: 未回答
- value: answered
label_ja: 回答済み
- value: need_reanswer
label_ja: 再回答必要
business_meaning: >
顧客に対する納期回答の状態を明細単位で管理する。
why_standard_is_not_enough: >
Odoo標準の scheduled_date や commitment_date は予定日を表すが、
顧客へ回答済みか、再回答が必要かという業務状態は表せない。
standard_alternatives_checked:
- model: sale.order
field: commitment_date
result: insufficient
reason: 受注単位であり、明細単位の回答状態ではない
- model: stock.picking
field: scheduled_date
result: insufficient
reason: 出荷予定日であり、顧客回答状態ではない
required_by:
- business_stream_id: BS-SALES-001
- gap_key: gap::delivery_answer_status
decision_status: pending
implementation_readiness: needs_selection_values
ここまで書かせると、無駄なCusFieldをかなり抑制できます。
重要なのは、CusFieldを作る条件です。
CusFieldを作ってよい条件:
- 標準フィールドでは意味が違う
- 標準フィールドでは粒度が違う
- 標準フィールドでは履歴・理由・判断状態を保持できない
- 標準機能の状態と混ぜると矛盾する
Logicは自然文ではなく「条件・トリガー・結果」で持つ
ここが一番重要です。
ロジックは自然文のままだと、あとで実装できません。
最低限、こう分解した方がいいです。
logic_slots:
- logic_key: logic::sales.delivery_allocation::delivery_answer_status_update
label: 納期回答状態の更新
logic_type: state_update
implementation_candidate:
- onchange
- server_action
- button_action
trigger:
type: user_action
event: delivery_answer_confirmed
source_model: sale.order.line
conditions:
all:
- field: sale.order.line.x_delivery_answer_status
operator: in
value:
- not_answered
- need_reanswer
- field: stock.picking.scheduled_date
operator: is_not_null
actions:
- type: update_field
model: sale.order.line
field: x_delivery_answer_status
value: answered
- type: write_log
model: sale.order.line
message: 納期回答済みに更新
exceptions:
- condition:
field: stock.picking.scheduled_date
operator: is_null
handling: block_or_warn
message: 出荷予定日が未設定のため、納期回答済みにできません。
affected_models:
- sale.order.line
- stock.picking
required_fields:
- sale.order.line.x_delivery_answer_status
- stock.picking.scheduled_date
decision_status: pending
implementation_level: level_2
codegen_readiness: needs_trigger_confirmation
この形にすると、あとで実装タイプを判定できます。
Logicの種類をenum化した方がいいです
ロジックは最初から分類しておくと良いです。
logic_type:
- computed_value
- state_update
- validation_constraint
- warning
- auto_assignment
- synchronization
- aggregation
- scheduled_check
- button_action
- report_filter
これにより、Odooでどの実装になるかが見えます。
| logic_type | Odoo実装候補 |
|---|---|
| computed_value | compute field |
| state_update | button / server action |
| validation_constraint | Python constraint |
| warning | onchange / constraint / activity |
| auto_assignment | automated action / server action |
| synchronization | write override / server action |
| aggregation | computed field / SQL view / report model |
| scheduled_check | cron |
| button_action | model method + button |
| report_filter | saved filter / search view |
BusinessStream単位の最終構造
BusinessStreamごとに、こういう構造にするとよいです。
business_stream_resolution_base:
business_stream_id: BS-SALES-001
label: 指定出荷日・在庫引当・納期回答・出荷調整をつなげる
confirmed_business_context:
purpose: ...
input_summary: []
process_summary: []
output_summary: []
main_model_candidates: []
related_model_candidates: []
gaps: []
questions: []
standard_field_overlay_slots:
description: フィールドデータで人間が採用した標準フィールドを差し込む場所
adopted_standard_fields: []
rejected_standard_fields: []
nff_slots:
- nff_key: ...
type: standard_view_or_filter
base_model: ...
uses_standard_models: []
uses_standard_fields: []
purpose: ...
decision_status: pending
custom_field_slots:
- field_key: ...
model: ...
field_name: ...
field_type: ...
business_meaning: ...
why_standard_is_not_enough: ...
decision_status: pending
logic_slots:
- logic_key: ...
logic_type: ...
trigger: {}
conditions: {}
actions: []
exceptions: []
required_fields: []
implementation_candidate: []
codegen_readiness: ...
resolution_effect:
resolves_gaps: []
creates_domain_guide_patch: []
creates_ontology_delta: []
affects_5176_nodes: []
これなら、自然文の「標準でいけそう」「追加が必要そう」ではなく、設計判断として扱えるデータになります。
Cypherに入れるならノードも分ける
5176で見るなら、グラフ側もこう分けた方がよいです。
(:BusinessStream)
(:BusinessBundle)
(:ConfirmedBusinessContext)
(:StandardFieldOverlaySlot)
(:NFFSlot)
(:CustomFieldSlot)
(:LogicSlot)
(:LogicCondition)
(:LogicAction)
(:Gap)
(:OpenQuestion)
(:ResolutionEffect)
関係はこうです。
(BusinessStream)-[:HAS_NFF_SLOT]->(NFFSlot)
(BusinessStream)-[:HAS_CUSTOM_FIELD_SLOT]->(CustomFieldSlot)
(BusinessStream)-[:HAS_LOGIC_SLOT]->(LogicSlot)
(NFFSlot)-[:USES_STANDARD_MODEL]->(OdooModel)
(NFFSlot)-[:USES_STANDARD_FIELD]->(OdooField)
(CustomFieldSlot)-[:EXTENDS_MODEL]->(OdooModel)
(CustomFieldSlot)-[:REQUIRES_BECAUSE_OF]->(Gap)
(LogicSlot)-[:HAS_CONDITION]->(LogicCondition)
(LogicSlot)-[:HAS_ACTION]->(LogicAction)
(LogicSlot)-[:REQUIRES_FIELD]->(CustomFieldSlot)
(LogicSlot)-[:USES_STANDARD_FIELD]->(OdooField)
(ResolutionEffect)-[:RESOLVES_GAP]->(Gap)
(ResolutionEffect)-[:AFFECTS_5176_NODE]->(...)
これで、5176上では、
このBusinessStreamを解決するには、
標準フィールド採用だけでなく、
NFFが2つ、CusFieldが1つ、Logicが1つ必要
という見え方にできます。
DomainGuide / Ontology Deltaへの分け方
ここも整理できます。
DomainGuideに入れるもの
DomainGuideは、標準やカスタムをどう業務で使うかです。
domain_guide_patch:
business_stream_id: BS-SALES-001
standard_usage:
- stock.picking.scheduled_date は出荷予定日として使う
- sale.order.line.qty_delivered は納品済数量として使う
nff_usage:
- 出荷・引当・納期回答一覧は sale.order.line を基点に作る
logic_usage:
- 納期回答済みの判断は x_delivery_answer_status で管理し、出荷予定日が未設定なら回答済みにしない
Ontology Deltaに入れるもの
Ontology Deltaは、標準にない追加だけです。
ontology_delta:
business_stream_id: BS-SALES-001
custom_fields:
- model: sale.order.line
field: x_delivery_answer_status
type: selection
meaning: 顧客への納期回答状態
custom_logic:
- logic_key: logic::sales.delivery_allocation::delivery_answer_status_update
type: state_update
required_fields:
- sale.order.line.x_delivery_answer_status
Cypherに入れるもの
Cypherはレビュー・同期・可視化用なので、全部入れてよいです。
BusinessStream
NFFSlot
CustomFieldSlot
LogicSlot
Gap
ResolutionEffect
実装条件の見える化
「実際にどう実装されるのか」を見るためには、各候補に implementation_condition を持たせるのが良いです。
implementation_condition:
required_when:
- 顧客への納期回答状態を明細単位で管理する
- 回答済み/再回答必要を検索・一覧表示したい
not_required_when:
- 出荷予定日のみで運用できる
- 納期回答履歴を管理しない
requires_customer_decision:
- 納期回答状態の選択肢
- 再回答必要になる条件
implementation_blocker:
- 状態遷移条件が未確定
これを入れると、コンサル/オフショアが自然文で曖昧に書いたものを、実装可能な単位にできます。
人間編集テンプレも変えるべきです
人間が編集するテンプレは、こうするのがよいです。
business_stream_id: BS-SALES-001
standard_field_overlay:
adopted_standard_fields:
- stock.picking.scheduled_date
- stock.picking.state
- sale.order.line.qty_delivered
nff_decisions:
- nff_key: nff::sales.delivery_allocation::delivery_allocation_view
decision: accepted
implementation_type: view_extension
notes: 受注明細を基点に一覧化する
custom_field_decisions:
- field_key: cusfield::sale.order.line::x_delivery_answer_status
decision: accepted
field_type: selection
selection_values:
- not_answered
- answered
- need_reanswer
reason_standard_is_not_enough: 標準日付項目では回答状態を持てないため
logic_decisions:
- logic_key: logic::sales.delivery_allocation::delivery_answer_status_update
decision: needs_review
implementation_type: button_action
trigger_confirmed: false
missing_decisions:
- 再回答必要になる条件
- 回答済みにする操作タイミング
これなら、入力は少ないまま、実装条件まで残せます。
次の抽出フェーズの目的を修正するなら
次フェーズは、単なるBusinessStream Resolution Baseではなく、こうした方がよいです。
P5-5177-to-5176 BusinessStream Resolution & Implementation Slots
目的:
Bundle / BusinessStreamデータから、前段階で確定している業務文脈を抽出し、
フィールドデータで人間が採用した標準フィールドを差し込めるようにし、
さらに NFF / CusField / Logic を実装候補スロットとして構造化する。
成果物はこうです。
business_stream_resolution_implementation_slots/
json/
01_business_stream_base.json
02_standard_field_overlay_slots.json
03_nff_slots.json
04_custom_field_slots.json
05_logic_slots.json
06_gap_resolution_slots.json
07_5176_sync_map.json
08_human_edit_template.json
09_implementation_readiness_report.json
cypher/
01_business_stream_resolution_graph.cypher
02_nff_custom_logic_slots.cypher
03_5176_resolution_links.cypher
domainguide/
01_domain_guide_patch_template.json
ontology_delta/
01_ontology_delta_candidate_slots.json
結論
はい。
NFF、CusField、Logicも必ず反映した方がいいです。
今の自然文だけだと、5176で「解決済み」と言えても、実装に進むとまた曖昧になります。
なので次は、BusinessStreamごとに、
標準フィールド採用
NFF
CusField
Logic
Gap解決
実装条件
を分けて持つべきです。
特にロジックは、
trigger
conditions
actions
exceptions
required_fields
implementation_type
codegen_readiness
まで持たせる。
この形にすれば、5176で「何が解決したか」だけでなく、その解決が実装可能なレベルまで落ちているかも判断できるようになります。
コメントを残す