コンテンツへスキップ

V Groupの舞台裏:シニアソフトウェアエンジニアの仕事とは?

私はリディンです。VグループのシニアOdooおよびPythonフルスタック開発者です。ERPの世界の外にいる人々が「Odoo開発者」と聞くと、通常はフォームビューを調整したり、時折レポートを書いたりする人を思い浮かべます。しかし、私が関わっているプロジェクトの現実は、システムエンジニアリングに近いものです。マルチテナントインフラストラクチャ、病院レベルの統合、ライセンスおよび知的財産保護、そして実際の悪用に耐えなければならないアクセス制御モデルなどです。私は、その作業のいくつかを紹介したいと思います。ハイライトリールとしてではなく、私が日々実際に解決している問題の正直な視点として。

Illustration: a senior Odoo engineer working across infrastructure, hospital integration and security


ケーススタディ 1: V-Cloudの構築、内部Odoo.shの代替

私が関わった中で、建築的に興味深いプロジェクトの一つはV-Cloudです。これは、私たち自身の顧客のためにOdooインスタンスをホスティングおよび管理するための内部SaaSプラットフォームであり、概念的にはOdoo.shに似ていますが、社内で構築され運営されています。

核心的な課題は「OdooをDockerで実行できるか」ではなく、その部分は trivial です。実際の問題は、集中管理可能な顧客ごとの隔離でした。すべての顧客は、自分専用のデータベース、ファイルストア、およびコンテナスタックが必要であり、要求に応じて展開および削除できる必要がありました。それでも、単一のコントロールプレーン(顧客ポータルと内部ツール)から管理できる必要があり、1つのテナントの不正行為(暴走するcron、メモリリーク、悪いマイグレーション)が他の誰にも影響を与えないようにする必要がありました。

V-Cloud: one Docker container stack per customer, managed from a single control plane

それは、一連の決定を処理することを意味していました:

  • テンプレートから生成された、手動で維持されるのではなく、顧客ごとのDocker Composeベースのスタック。これにより、新しい顧客のオンボーディングはプロビジョニング操作となり、手動のサーバー構成作業ではなくなります。
  • 顧客のカスタムモジュールが変更されたときにビルド/デプロイをトリガーするためのGitHubウェブフック処理は、冪等性について慎重に考える必要がありました。ウェブフックは同じイベントに対して複数回発火する可能性があり、単純なハンドラーでは重複したデプロイを引き起こしたり、スタックを半分更新された状態に残したりすることがあります。
  • 顧客向けポータルで、基盤となるオーケストレーション層を露出させることなく、必要最低限の制御(再起動、ログの表示、バックアップの管理)を提供します。

最も考慮を要したトレードオフは、隔離の粒度と運用のオーバーヘッドの対立でした。顧客ごとに完全に隔離されたVMは「最も安全な」答えだったかもしれませんが、私たちの規模では運用上非常に重すぎました。完全に共有されたインフラストラクチャ(1つのOdooインスタンス、複数のデータベース)は運用コストが安いですが、特にリソースの競合やセキュリティの境界に関して、強力なテナントの隔離を保証することが非常に難しくなります。私たちは、顧客ごとのコンテナを適切な中間地点として選びました — 私たちの脅威モデルに対して十分な隔離を提供し、クライアントごとに専任の運用チームなしでプロビジョニングとスケーリングが可能な軽さを持っています。

V-Cloud: one Docker container stack per customer, managed from a single control plane


ケーススタディ 2: 病院クライアントのためのHIS API統合

ヘルスケアの統合は全く異なる難易度のカテゴリーであり、正確性はUXの贅沢ではありません。小売の文脈での在庫移動の重複は迷惑ですが、薬局の調剤APIにおける在庫移動の重複は、システムが実際には一度しか調剤されていない薬剤について在庫が二重に差し引かれたと信じることを意味します。これは実際の在庫に影響を及ぼし、間接的には患者ケアにも影響を与えます。

ある病院統合プロジェクトでは、私は時折重複したstock.move.lineレコードを生成し、静かに在庫を二重に差し引く調剤APIを引き継ぎました。この種のバグはテストで見つけるのが本当に難しいもので、失敗するわけではなく、ただ静かに間違った数字を生成し、それが在庫調整の際に数日後に現れるだけです。

Pharmacy dispensing API flow between the hospital HIS and Odoo inventory

デバッグプロセスは次のように見えました:

  1. まずは決定的に再現してください。コードに手を加える前に、断続的な病院のトラフィックを信頼するのではなく、再現を確実にトリガーする方法を構築しました。信頼できる再現なしに「修正」された非決定的なバグは、ほぼ常に戻ってきます。
  2. 実際の呼び出しパスを追跡し、仮定されたものではなく、実際のものを確認してください。APIエンドポイントは書面上では冪等に見えましたが、特定の同時リクエストのタイミングの下で、基盤となるピッキング/移動作成ロジックが二度呼び出されていました — 孤立した状態では正しいが同時実行下では間違っているコードの典型的なケースです。
  3. 適切なレイヤーで修正します。症状を修正するのではなく(事後に重複を排除するのではなく)、実際の作成パスを修正して、重複リクエストが検出され、在庫移動が生成される前にショートサーキットされるようにしました。

関連する、劇的ではないが同様に重要な修正は、同じ統合内で間違ったフィールド(バーコードではなく病院の内部のhis_location_code)を検索する位置検索ヘルパーでした。二つが偶然にも同一である限り問題なく機能しましたが、これはデータが適切に維持される日には生産インシデントになる「偶然正しい」コードの典型です。同時に、ピッキングタイプの解決を倉庫に対応させました。元のロジックは静かに単一の倉庫を前提としていましたが、これは病院が同じインスタンスに複数の病棟や調剤ポイントを持つと成り立たなくなります。

広い教訓:統合作業において、最も厄介なバグはエラーを投げるものではありません。静かに成功しながら間違ったことをしているものです。

Fix for duplicate stock.move.line records: duplicate requests detected before any stock move is created


ケーススタディ 3: Odooを壊さずにPyArmorでIPを保護する

クライアントが管理するサーバーにカスタムモジュールを出荷する際、私たちが管理するインフラストラクチャではなく、ソース保護について考える必要があります。クライアントがサーバーを所有していますが、モジュールのロジック(およびその背後にある努力)は私たちのものです。そこで、PyArmorのようなコード保護ツールが登場します。これは、Pythonソースを難読化し、パッケージ化することで、モジュールがOdooのアドオン読み込みメカニズム内で正しく動作し、可読なソースを出荷せずに済むようにします。

これはシンプルに聞こえますが、実際にOdooのようなフレームワークに対して試してみると、ロード時に多くのイントロスペクションを行うため、モジュールマニフェストを検査し、ORMモデル登録のためにクラス階層を歩き、場合によってはソースレベルのメタデータを読み取ることができる必要があります。単純な難読化は以下のようなものを壊します:

  • モデルクラスの発見、もし難読化ツールがOdooのレジストリがクラス定義を検査する方法に干渉する場合
  • 動的インポートと遅延読み込みされたサブモジュールは、オブフスケーターがより単純なインポートグラフを仮定すると誤って処理する可能性があります
  • ランタイムパフォーマンス、難読化されたバイトコードがすべてのインポートにオーバーヘッドを追加するため — これは、モジュールがすべてのワーカー再起動時にインポートされるときに重要です

PyArmor obfuscation applied to the business logic of a custom Odoo module

これを正しく行うためには、単に「スクリプトが実行される」と確認するのではなく、実際のOdooモジュールロードライフサイクルに対して難読化されたモジュールをテストする必要があり、何を保護するか、何を可読のままにするかを慎重に考える必要があります。マニフェストファイルや薄い統合グルーは一般的にプレーンなままである必要がありますが、実際のビジネスロジックがロックダウンされる部分です。これは、20%が暗号化関連のツールで、80%がフレームワークの内部を十分に理解してどこで壊れるかを正確に知ることができる問題の良い例です。


ケーススタディ 4: サブユーザーアクセス制御を正しく設定する

いくつかのクライアントプロジェクトで繰り返し寄せられるリクエストは、「メインポータルユーザーが自分のチームや顧客のために制限付きのサブアカウントを作成できるようにしたい」というバージョンです。小さな機能のように聞こえますが、実際にはそうではありません。

単純なアプローチ — 権限の少ない新しいセキュリティグループ — はすぐに崩壊します。なぜなら、これらのケースにおけるアクセス制御は通常「このユーザーはモデルXを見ることができるか」というだけではなく、関係に基づいているからです。サブユーザーは親アカウントに関連付けられたレコードのみを見るべきであり、会社全体のデータを見るべきではありません。そして、そのスコープはサブユーザーが触れるすべてのモデルに対して維持されなければならず、他のモジュールによって後で追加されたモデルも含まれます。

これは、グループメンバーシップだけでなく、安定したリレーショナルフィールド(例:parent_account_idやそれに相当するもの)に基づいたレコードルールに設計を推進し、create()/write()の所有権を慎重に管理することを意味します。これにより、サブユーザーがレコードの親を再割り当てして自分の可視性を高めることができなくなります。指摘すべきトレードオフは、レコードルールに基づくスコーピングは初期の作業が多く、新しいモデルがフローに追加されるたびに規律が必要ですが、監査に耐え、ビューでのアドホックなドメインフィルタリングのようにデータが静かに漏れ出すことはありません。ビューレベルのフィルタリングはUXの便利さであり、セキュリティの境界ではありません。それを境界として扱うのは、他のチームが痛い目に遭ったのを見た間違いです。

Portal sub-user access control with record rules scoped to the parent account


Vグループの働き方文化が際立っている理由

これについては率直に言いたいと思います。なぜなら、私がここで働くことを楽しむ主な理由の一つだからです:Vグループの職場文化は本当に良いです。

プロセスは簡単で整理されています。私たちのファンクショナルコンサルタントは、クライアントから直接要件を収集し、クライアントが実際に何を必要としているかを理解します。そして、そのタスクは明確な範囲と明確な締切を持って私に割り当てられます。そこから、私は技術的な実装を担当します — 問題を分析し、解決策を設計し、コードを書いてテストします — そして、準備が整ったら、完成した作業をクライアントにデモします。そのループ — 明確な要件、明確な所有権、実際の締切、そして最後のデモ — はプロジェクトごとに繰り返され、チェーン内のすべての人が自分の役割をうまく果たすため、うまく機能します。

具体的に何がそれを良くするのか:

  • 私は責任を持つことを信頼されています。タスクが私に割り当てられると、私は技術的な判断を下す者です — どのように解決するか、どのトレードオフをするか — すべてのステップで細かく管理されることはありません。
  • 締切は現実的ですが、合理的です。私は時間通りに納品することが求められており、実際にそうしていますが、締切を守るために壊れていると知っているものを出荷するように頼まれたことはありません。
  • デモ文化は皆を正直に保ちます。完成した作品をクライアントに直接提示することは、正しく仕上げるための自然で健全なプレッシャーを意味し、うまくいったときには実際に目に見える評価が得られます。
  • コンサルタントと開発者は別々のサイロではなく、一つのチームとして働きます。要件収集から開発、デモへの引き継ぎはスムーズで、機能面と技術面が実際にお互いに話し合うため、開始時と終了時だけでなく、常に連携しています。

その組み合わせ — 明確なプロセス、真のオーナーシップ、サポートするチーム、そして目に見える結果 — が、この投稿の中でのより難しい技術的な問題を単なるストレスではなく、やりがいのあるものに感じさせる要因です。


この種の仕事があなたに教えること

ホスティングインフラストラクチャ、ヘルスケア統合、ライセンス管理、アクセス制御を同じチームで行うことは、特定の種類のエンジニアリングの成熟を強いる:あなたは「Odooのやり方」を固定されたパターンのセットとして考えるのをやめ、フレームワークを実際に理解する必要がある内部を持つ基盤として考え始める — 同時実行時のORMの動作、モジュールのロードライフサイクル、セキュリティモデルの実際の境界と見かけの境界の違い。


Vグループに開発者として参加する際の期待事項

正直に言うと、曖昧さを期待してください。医療、物流、製造のクライアントからの要件は、完全に仕様が決まった状態で届くことはほとんどなく、コードを書く前に適切な確認質問をすることが仕事の重要な部分です。フルスタックでの作業を期待してください — ある日はDockerとデプロイメント、次の日はORMレベルのデバッグ、その次の日はセキュリティレビューです。そして、「テストでは動く」というのはレビューの始まりであり、終わりではないことを期待してください — 特にお金、在庫、または患者データに関わるものについては、静かな間違った答えは大きなエラーよりも悪いのです。


応募

Vグループコンサルティング&ソリューション 
- あなたの成功のため - 


V Groupの舞台裏:シニアソフトウェアエンジニアの仕事とは?
V Group Consulting & Solutions Co., Ltd., Ridhin 2026年8月27日
このポストを共有
アーカイブ
V Group、タイの健康・ウェルネス関連製造企業グループ向けERP導入プロジェクトを受注