目的
- 開発ポータルに登録された「あるべき仕様」と、Odoo 18 の実メタ/実テーブルを照合し、
**実装済/部分実装/未実装/不一致(ドリフト)**を自動判定。 - 差分の根拠(どのテーブルの何が違うか)を明示し、**修正指示(Fixヒント)**まで出す。
判定ステータス(例)
- Implemented(実装済):仕様=実態が一致
- Partially Implemented(部分実装):一部は一致、足りない項目あり(例:DB列はあるがビュー未配置)
- Drift(不一致):存在するが仕様と異なる(型違い/JSONBでない/選択肢差異 等)
- Not Implemented(未実装):該当要素が見つからない
- Conflict(競合):複数ビューやモジュール継承で相反条件(要人手確認)
照合観点(チェックリスト)
- モデル・フィールド定義
ir_modelにモデルがあるかir_model_fieldsにフィールドがあるか(name,ttype,relation,translateなど)- Odoo 18の多言語:
translate = trueのテキスト系は実テーブル列が JSONBか
- 物理テーブル(information_schema)
- 対象テーブル(例:
res_partner)に対象列(例:x_customer_rank)が存在 data_type = 'jsonb'か(多言語対象なら必須)
- 対象テーブル(例:
- 既定値
ir_defaultに既定値があるか(モデル×フィールド)
- Selection 候補
ir_model_fields_selectionに候補が揃っているか- コード定義の selection の場合は DBに現れないため不明/要手動確認として扱う
- ビュー反映(画面配置と UI 挙動)
ir_ui_view.arch_dbに<field name="x_customer_rank">が存在string(ラベル/翻訳はコード翻訳扱い)、widget、placeholder、help設定が仕様と一致attrsで 非表示/必須/読み取り専用/条件付き必須 が仕様どおりgroups属性で権限グループが設定済み
- 権限
ir_model_access(CRUD)・ir_rule(レコードルール)が想定と一致
- アクション/メニュー(必要な場合)
ir_actions_act_window/ir_ui_menuに所定の配置があるか
- 出自/コード出力可否(ポータル側メタ)
- 仕様の「AI生成/手動生成要/未実装」と判定結果を自動同期(逆引きで次アクション提示)
実装フロー(アーキテクチャ)
- Read-only 接続で Odoo に照会
- A) PostgreSQL 読取専用ユーザーで直接参照(高速・網羅的)
- B) Odoo JSON-RPCで取得(権限を尊重した形。必要に応じてA/B併用)
- Validation サービス(開発ポータル内の小さなジョブ)
- ポータル仕様(モデル、フィールド、型、translate、selection、UI条件、権限)をロード
- Odoo メタ&実列をクエリ
- 仕様 ↔ 実態 を比較してステータス+差分理由を生成
- Fixヒントを自動生成(例:欠けている XML 断片、
attrs条件、ir_default追加SQL など)
実行タイミング:オンデマンド([検証]ボタン)+デイリーの定期チェック(通知)。
※定期ジョブは後述の注意を守って構築(ここでは設計指針のみ記載)。
すぐ使える照合SQL(例)
例:モデル
res.partner(テーブルres_partner)、フィールドx_customer_rank(translate=True のテキスト系を想定)
A. モデルとフィールド定義
-- モデル存在
SELECT id, model, name FROM ir_model WHERE model = 'res.partner';
-- フィールド定義(型・翻訳フラグ・関連など)
SELECT
imf.id,
imf.name,
imf.field_description,
imf.ttype,
imf.relation,
imf.translate
FROM ir_model_fields imf
JOIN ir_model im ON imf.model_id = im.id
WHERE im.model = 'res.partner' AND imf.name = 'x_customer_rank';
B. 物理列(JSONB 確認)
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'res_partner'
AND column_name = 'x_customer_rank';
-- data_type が 'jsonb' なら多言語列としてOK
C. 既定値(ir_default)
SELECT d.id, d.json_value
FROM ir_default d
JOIN ir_model_fields f ON d.field_id = f.id
JOIN ir_model m ON f.model_id = m.id
WHERE m.model = 'res.partner' AND f.name = 'x_customer_rank';
D. Selection 候補(Studio定義のみDBに出る想定)
SELECT s.value AS key, s.name AS display_label
FROM ir_model_fields_selection s
JOIN ir_model_fields f ON s.field_id = f.id
JOIN ir_model m ON f.model_id = m.id
WHERE m.model = 'res.partner' AND f.name = 'x_customer_rank'
ORDER BY s.value;
-- 0行なら「コード定義の可能性→要手動確認」
E. ビュー配置(存在&属性の一部検査)
-- フォーム系ビューにフィールドが出ているか(簡易:文字列検索)
SELECT id, name, type
FROM ir_ui_view
WHERE model = 'res.partner'
AND arch_db LIKE '%<field name="x_customer_rank"%';
-- さらに attrs/goups/widget まで取るなら arch_db を取得してアプリ側でXMLパース・比較
SELECT id, name, type, arch_db
FROM ir_ui_view
WHERE model = 'res.partner';
F. モデル権限(アクセス/レコードルール)
-- モデル×グループのCRUD
SELECT a.id, g.name AS group_name, a.perm_read, a.perm_write, a.perm_create, a.perm_unlink
FROM ir_model_access a
JOIN ir_model m ON a.model_id = m.id
LEFT JOIN res_groups g ON g.id = a.group_id
WHERE m.model = 'res.partner';
-- レコードルール(ドメイン)
SELECT r.id, r.name, r.domain_force
FROM ir_rule r
JOIN ir_model m ON r.model_id = m.id
WHERE m.model = 'res.partner';
判定ロジック例(フィールド単位)
ir_modelにモデルがなければ Not Implementedir_model_fieldsにフィールドがなければ Not Implementedinformation_schemaで列なし → Not Implementedttype/relation/translateが仕様と相違 → Drifttranslate=trueかつdata_type <> 'jsonb'→ Drift(多言語列要件不一致)- 既定値(ir_default)が未設定 → Partially Implemented
- ビュー未配置 or
attrs/groups/widgetが不一致 → Partially Implemented / Drift - 権限が未設定 → Partially Implemented
併せてFixヒント:
- JSONB不一致 → 「フィールド再定義(translate=True)or データ型調整」
- ビュー未配置 → 対象ビューへの
<field …>XML スニペット提示- 必須条件不足 →
attrs="{'required':[('state','=','draft')]}"の差分例提示- 既定値なし →
ir_default挿入例提示
画面UI(ポータル)のイメージ
- フィールド一覧に 「実装判定」列(色付きバッジ)
- 行クリックで差分詳細(仕様値 vs 実値)+Fixヒント
- 一括チェック(モデル単位/モジュール単位)
- 判定履歴(いつ、誰が、結果)
例:x_customer_rank(あなたの仕様に沿って)
- 仕様:
ttype=char or selection,translate=true(JSONB),default='bronze',widget=radio,必須条件=state='draft',表示権限=Sales Manager,placeholder/help指定 - 期待チェック結果:
ir_model_fields:存在/translate=trueinformation_schema:data_type = 'jsonb'(char/text/html を translate=true にしている場合)ir_default:既定値に'bronze'ir_ui_view:<field name="x_customer_rank" widget="radio" …>、attrsに必須条件、groups設定ir_model_access/ir_rule:想定どおり
実装時の注意
- view 継承(
inherit_id)が多層になると、最終形は「合成結果」。最終XMLを取得して照合する仕組みに。 - **selection(コード定義)**は DBに現れない場合あり → 「候補差分チェックは参考扱い」。
- マルチ会社/言語:
lang/company_idコンテキストで表示差異が出る。判定時に検証コンテキストを固定。 - 読み取り専用 DB ユーザーを使い、安全に参照のみ行う(誤更新防止)。
この仕組みを入れると、仕様→実装の可視化と差分是正のスピードが一気に上がります。
必要なら、上記SQLをベースに**最小プロトタイプ(1モデル/1フィールドの照合→結果JSON)**の雛形も用意できます。
コメントを残す