コンテンツにスキップ

ValueOS 概要・アーキテクチャ

位置づけ: クライアントERP(ValueOS)

ValueOSは、住宅設備商社向けにクライアントが自社開発しているERPである。正本は github.com/stanaka-blip/valueos。Next.js(App Router)+ Supabase(Postgres / Auth / Storage)で構成し、開発環境は localhost:3001 で稼働する。

案件(cases)を単一の軸として、受注=発注(orders)・請求(invoices)・入金(payments)・タスクの5本柱で受発注〜請求〜入金の一気通貫を管理する。案件ごとの発注可否・請求可否は WorkflowEngine が決済区分(settlement_type)に基づいて機械判定し、各画面はその判定結果を表示するレイヤーに徹する。

当方CRMは案件獲得〜見積〜催事という前段に強く、ValueOSは受発注〜請求〜入金という後段に強い。両者は相補的な関係にあり、詳細な機能差分・項目突合は redesign/valueos-gap を正本とする。

本ページはValueOSそのものの構造(アーキテクチャ・データモデル・業務ロジック)を扱う。当方CRMとの機能差分・移行方針は対象外とし、以下を参照する。

論点参照先
当方CRMとの機能差分・項目突合redesign/valueos-gap
ValueOSのデータモデル詳細valueos/data-model
WorkflowEngineの判定ロジック詳細valueos/workflow
当方CRM側のスコープ・フェーズ計画redesign/scope-phasing
領域採用技術
フロントエンド/サーバーNext.js(App Router)、React
データベースSupabase Postgres
認証Supabase Auth(社内認証。staff_profiles でアカウント有効性・管理者権限を管理)
ストレージSupabase Storage(case_attachments はDirect-to-Storageでアップロード)
スタイリングTailwind CSS
開発環境next dev --port 3001localhost:3001
テストtsx によるロジック単体テスト(WorkflowEngine・入金ステータス・三社間計算・粗利計算・ダッシュボード集計など領域ごとに個別スクリプト)

データ(5本柱+周辺エンティティ)

Section titled “データ(5本柱+周辺エンティティ)”

ValueOSは主要テーブル28本で構成する。中核は次の5本柱である。

主テーブル役割
案件cases案件番号・販売店・顧客・現場住所・受注日・希望納期・工事日・ステータス・部門・担当・優先度を保持する起点エンティティ
受注=発注orders(+ order_items仕入先ごとの発注書番号・発注日・納期回答・納品日・発注金額・ステータスを個別に保持する
請求invoices(+ invoice_line_items請求書番号・請求日・支払期日・請求金額・税区分・ステータスを個別に保持する
入金payments入金日・入金額・確認ステータスを個別に保持する(管理用に拡張済み)
タスクタスクエンティティ(案件紐付)案件配下の対応事項をステータス・期日・担当・優先度で管理する

5本柱を支える主要エンティティは以下のとおりである。

エンティティ群主テーブル役割
明細case_products案件配下の商品・パッケージ明細。line_typeproduct_idpackage_idsupplier_id・数量・仕入価格・販売価格・粗利をスナップショットで保持し、発注/請求の共通ソースとなる
パッケージcase_packagescase_package_items複数商品を束ねたパッケージ単位の明細構成
決済case_settlements決済区分(settlement_type。正式値は前金/売掛/3社間決済/カード。掛売・三社間決済は旧称で、2026-08-01のnormalizeで掛売→売掛、ローン/三社間決済→3社間決済に統一済み。「その他」は正式区分外だが保持可)・手数料率/額・頭金率/額・支払条件・カードブランド/ステータス・ローン会社/承認番号/ステータスを保持する
三社間three_party_money_requestsfinance_receiptsdealer_settlements(+明細)、supplier_paymentsローン会社を介する三社間決済のリクエスト・入金・販売店精算・仕入先支払を個別テーブルで管理する
販売店発注販売店フォーム(app/dealer/orders/new)の saveDealerOrdercasescase_productscase_settlements へ直接INSERTする。case_registration_requests は経由せず、人による承認ステップも無い
社内案件登録case_registration_requests社内の案件登録画面(/cases/new)が申請〜RPCで案件化する。処理状態は PROCESSINGCOMPLETEDFAILED で管理し、同期実行する
マスタproductspackagescontractors(施工店)、company_settingsstaff_profiles商品・パッケージ・施工店・自社設定・スタッフ権限の基礎マスタ
申請系(RPC)product_setup_requestssupplier_purchase_price_bulk_requestsdealer_sales_price_bulk_requestspackage_bulk_setup_requestscase_line_append_requestsマスタ変更・価格一括更新・明細追加を申請〜承認の形で処理する
添付case_attachments案件に紐づくファイルをSupabase StorageへDirect-to-Storageで保存する
機能領域概要
案件管理案件の登録・編集・ステータス管理。cases を起点に明細・発注・請求・入金・決済・タスクを紐付ける
発注管理仕入先別の発注登録・進捗管理(発注済/納期回答待ち/納期確定/一部納品/納品済)
請求管理請求書の発行・ステータス管理(未請求/作成済/請求済/入金待ち/一部入金/入金済)
入金管理入金の記録・消込。summarizeInvoicePayments() で請求に対する入金状況を集計する
決済区分管理案件ごとの決済区分(前金/売掛/3社間決済/カード等。掛売・三社間はレガシー別名)と、区分に応じた手数料・頭金・承認情報の管理
三社間精算ローン会社を介した三社間決済における請求・入金・販売店精算・仕入先支払の一連の処理
販売店発注受付販売店が直接入力する発注フォーム(app/dealer/orders/new)の saveDealerOrdercasescase_productscase_settlements へ直接INSERTする(人による承認ステップは無い)
経営ダッシュボード期間内の売上・実粗利・粗利率・未入金額の集計と、未発注/未請求の業務アラート表示(詳細は次節)

WorkflowEnginelib/workflow/WorkflowEngine.ts)は、案件の決済区分(settlementType)から決済ルールを解決し、発注可否(canOrder)・請求可否(canInvoice)・現在の業務状態・次アクション・担当・警告メッセージを共通ロジックで判定する。画面はこの判定結果を表示するレイヤーであり、各フォームが独自にステータスを分岐させることはない。

判定の主なルールは次のとおりである。

判定内容
決済区分未確定ルールを解決できない場合、canOrdercanInvoice ともに false とし、担当を「経理」、次アクションを「決済条件を確定してください」とする
発注可否決済区分ごとの条件(例: 前金の入金確認、ローン承認、カード決済確定)を満たさない場合は canOrder = false とし、区分別の警告文を返す
請求可否(売掛)案件内の全発注が納品済(delivered_date 登録済)になって初めて canInvoice = true となる。納品日未登録または未納品の発注が残る場合は警告文を返す
与信日算出決済ルールの datePolicy.trigger が全発注納品済を起点とする場合、請求締日・支払期日を発注データから算出する

WorkflowEngine は詳細ページ valueos/workflow を参照する。

ダッシュボード集計基準(Ver1.0)

Section titled “ダッシュボード集計基準(Ver1.0)”
指標集計基準
売上期間内に cases.order_received_date(顧客が当社へ正式発注した日)を持つ有効案件の case_products.sales_price 合計
実粗利同条件での case_products.gross_profit 合計
粗利率実粗利 ÷ 売上
未入金額summarizeInvoicePayments().unpaidAmount(期間非連動の全期間集計)

受注日は cases.order_received_date を用い、orders.order_datecreated_at は用いない。キャンセル案件は lib/status/activeRecords.ts の有効判定により集計から除外する。

アラート条件
未発注canOrder = true かつ、その案件に紐づく有効発注が0件
未請求canInvoice = true かつ、その案件に紐づく有効請求が0件

canOrdercanInvoicefalse の案件はアラート集計の対象外とする。現時点の業務アラートは未発注/未請求の2種のみであり、未入金・期限超過(支払期日超過)を自動検知するアラートは含まない。未入金額自体はダッシュボード集計基準の指標として別途表示する(前節参照)。

社内ユーザーの認証はSupabase Authが担う。ログイン成功後、staff_profiles テーブルでアカウントの有効性(is_active)と管理者権限(is_admin)を確認する。プロフィール未登録・非アクティブ・認証失敗はそれぞれ個別のエラーコードで区別する。販売店発注フォーム(app/dealer/orders/new)は社内認証の外側にあり、saveDealerOrdercasescase_productscase_settlements へ直接INSERTする。case_registration_requests は経由せず、人による承認ステップも無い。

観点当方CRMValueOS
強い領域案件獲得〜見積〜催事(前段)受発注〜請求〜入金(後段)
案件の呼称WholesaleCasecases
卸金額の呼称WholesalePricedealer_sales_prices / supplier_purchase_pricessales_prices / purchase_prices
決済区分の呼称WSettlement(前金/掛売/三社間/カード/その他)case_settlements.settlement_type(正式値: 前金/売掛/3社間決済/カード)
販売店発注の呼称DealerIntakeFormapp/dealer/orders/newsaveDealerOrder が直接INSERT・承認ステップ無し)
発注/請求/入金卸案件のフラグ集約(差)独立エンティティ(ordersinvoicespayments
決済区分別ワークフローwholesaleFlow で機械判定(上位)WorkflowEngine で機械判定

両者の統合方針・段階的な機能差分の埋め方は redesign/valueos-gap を正本とする。