コンテンツにスキップ

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 3001(localhost:3001)
テストtsx によるロジック単体テスト(WorkflowEngine・入金ステータス・三社間計算・粗利計算・ダッシュボード集計など領域ごとに個別スクリプト)

社内ユーザーの書込は「画面(Server Components)→ Route Handler(/api/*)→ ゲートウェイ層(オリジン検証・CSRF・レート制限・冪等キー導出)→ service_role でのRPC/直接書込」という経路をとる。読み取りは publishable key での直接クエリが中心。販売店発注フォームだけはこの経路の外側にあり、ブラウザから直接Supabaseへ書き込む。

flowchart TD
    subgraph client[クライアント]
        staff[社内ユーザー]
        dealer[販売店]
    end

    subgraph nextapp[Next.js App Router / localhost:3001]
        rsc[Server Components<br/>各画面の表示・読み取り]
        api[Route Handlers<br/>/api/case-registrations 等]
        gw[ゲートウェイ層<br/>origin検証・CSRF・レート制限・冪等キー導出]
        dealerform[app/dealer/orders/new<br/>saveDealerOrder]
    end

    subgraph supabase[Supabase]
        auth[Auth<br/>staff_profilesと突合]
        db[(Postgres<br/>主要39テーブル)]
        storage[Storage<br/>case-attachments非公開バケット]
    end

    staff -->|email+password| auth
    staff -->|publishable key・読み取り| rsc
    rsc --> db
    staff -->|案件登録等の書込| api
    api --> gw
    gw -->|service_role| db
    dealer -->|社内認証の外側| dealerform
    dealerform -->|publishable key・直接INSERT/DELETE| db
    rsc -->|署名URL| storage

この構成でのポイントは次のとおり。

  • 画面読み取りはSupabase Authのセッションに紐づく publishable key での直接クエリが中心であり、RLSではなくアプリ側のクエリ範囲で読み取りを制御している(確認できた範囲では case_settlements・order_items・三社間系テーブルはマイグレーションで明示的にRLSを無効化しており、一般テーブルに有効なRLSがあることは本ページの情報源からは確認できない)。
  • 社内の書込APIの一部(案件登録など)はRoute Handler経由でゲートウェイ層を通し、service_role でRPCを呼ぶ設計にしている。ゲートウェイ層の具体的な検査項目は権限を参照。
  • 販売店発注フォームはSupabase Authの外側で稼働し、ゲートウェイ層(オリジン検証・CSRF・レート制限)を経由せず cases/case_products/case_settlements へ直接INSERTする。

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

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

ValueOSは主要テーブル39本で構成する(詳細はデータモデルを参照)。中核は次の5本柱である。

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

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

エンティティ群主テーブル役割
明細case_products案件配下の商品・パッケージ明細。line_type・product_id・package_id・supplier_id・数量・仕入価格・販売価格・粗利をスナップショットで保持し、発注/請求の共通ソースとなる
パッケージcase_packages、case_package_items複数商品を束ねたパッケージ単位の明細構成
決済case_settlements決済区分(settlement_type。正式値は前金/売掛/3社間決済/カード。掛売・三社間決済は旧称で、2026-08-01のnormalizeで掛売→売掛、ローン/三社間決済→3社間決済に統一済み。「その他」は正式区分外だが保持可)・手数料率/額・頭金率/額・支払条件・カードブランド/ステータス・ローン会社/承認番号/ステータスを保持する
三社間three_party_money_requests、finance_receipts、dealer_settlements(+明細)、supplier_paymentsローン会社を介する三社間決済のリクエスト・入金・販売店精算・仕入先支払を個別テーブルで管理する
販売店発注―販売店フォーム(app/dealer/orders/new)の saveDealerOrder が cases/case_products/case_settlements へ直接INSERTする。case_registration_requests は経由せず、起票そのものに承認ゲートは無い(起票後の社内受理フローは画面・機能を参照)
社内案件登録case_registration_requests社内の案件登録画面(/cases/new)が POST /api/case-registrations 経由で create_case_registration RPC(service_role)を呼び案件化する。処理状態は PROCESSING/COMPLETED/FAILED で管理し、同期実行する
マスタproducts、packages、contractors(施工店)、company_settings、staff_profiles商品・パッケージ・施工店・自社設定・スタッフ権限の基礎マスタ
申請系(RPC)product_setup_requests、supplier_purchase_price_bulk_requests、dealer_sales_price_bulk_requests、package_bulk_setup_requests、case_line_append_requestsマスタ変更・価格一括更新・明細追加を申請〜承認の形で処理する
添付case_attachments案件に紐づくファイルをSupabase StorageへDirect-to-Storageで保存する

cases.status はテキスト列であり、DBレベルのenum制約は無い。正式な選択肢は画面側の定数(app/cases/caseStatus.ts)で管理する9値で、これ以外の値(旧表記・工事系・他画面の書込値)は表示時にエイリアス吸収する。DBの値を一括UPDATEして統一する運用はしていない。

区分値
正式9値(選択・新規書込対象)新規受付/受付済/発注済/納品済/請求済/入金済/完了/差戻し/キャンセル
主なエイリアス(読取時に正式値へ吸収。DB書込はしない)受付済み→受付済、差し戻し→差戻し、取消→キャンセル、発注待ち→受付済、納期回答待ち/納品待ち→発注済、請求待ち→納品済、入金待ち→請求済、工事日調整中/工事待ち/施工中→納品済、完工→完了

app/admin/orders(受注管理画面。後述)は受付・差し戻し操作で正式9値とは異なる語彙(受付済み・差し戻し)を直接書き込む設計であり(取消操作は正式値キャンセルを書き込む)、これらは上表のエイリアスとして正式値に吸収される。app/orders(仕入発注)側は未発注/発注済/納品済の3値の独立ステータスを持ち、getCaseStatusFromOrderStatus()で案件ステータスへの反映を試みるが、この関数が返す発注待ちは正式9値に含まれないテキストであり、表示側のエイリアス吸収に依存する。

以下は業務上想定される代表的な遷移を示す参考図であり、DBレベルの制約やアプリ側のステートマシンによる強制ではない(StatusSelectからの手動変更、受注管理の受付/差し戻し/取消、発注ステータス反映など複数の経路が同じ列を独立に更新する)。

stateDiagram-v2
    [*] --> 新規受付: 販売店発注 or 社内登録
    新規受付 --> 受付済: 受注管理で受付
    新規受付 --> 差戻し: 受注管理で差し戻し
    新規受付 --> キャンセル: 受注管理で取消
    差戻し --> 受付済: 再受付
    差戻し --> キャンセル: 取消
    受付済 --> 発注済: 発注登録
    発注済 --> 納品済: 全発注delivered_date登録
    納品済 --> 請求済: 請求発行
    請求済 --> 入金済: 入金確認
    入金済 --> 完了: 手動更新
    受付済 --> キャンセル
    発注済 --> キャンセル
    納品済 --> キャンセル
    完了 --> [*]
    キャンセル --> [*]
機能領域概要
案件管理案件の登録・編集・ステータス管理。cases を起点に明細・発注・請求・入金・決済・タスクを紐付ける。新規登録は/cases/newからPOST /api/case-registrationsのみで行い、publishable keyでの直接cases.insertは使わない
受注管理(app/admin/orders)販売店発注で起票された案件(新規受付等)を社内が確認し、受付/差し戻し/取消のいずれかを選ぶ画面。差し戻しは理由入力必須(memoへ追記保存)。受付済み到達後は取消のみ可能、完了・取消等の終端状態は操作不可(アクション0件で操作パネル自体を非表示)
発注管理仕入先別の発注登録・進捗管理。画面の選択ステータスは未発注/発注済/納品済の3値(PURCHASE_ORDER_STATUSES)。納期回答待ち・納期確定・一部納品等はDB既存値・集計側の導出表示として読取互換で扱う
請求管理請求書の発行・ステータス管理(未請求/請求書作成済/請求済/入金待ち。無効値は取消)。入金状況(未入金/一部入金/入金済/期限超過)はsummarizeInvoicePayments()による表示判定であり、請求ステータスとは別軸
入金管理入金の記録・消込。summarizeInvoicePayments() で請求に対する入金状況を集計する
決済区分管理案件ごとの決済区分(前金/売掛/3社間決済/カード等。掛売・三社間はレガシー別名)と、区分に応じた手数料・頭金・承認情報の管理
三社間精算ローン会社を介した三社間決済における請求・入金・販売店精算・仕入先支払の一連の処理
販売店発注受付(app/dealer/orders/new)販売店が直接入力する発注フォーム。saveDealerOrder が cases/case_products/case_settlements へ直接INSERTする。起票そのものに承認ゲートは無く、案件は常に新規受付固定で作成される。起票後の社内確認は上記「受注管理」で行う
経営ダッシュボード(/)表示期間内の売上(税抜)・実粗利・粗利率・(期間非連動の)未入金額の集計と、未発注/未請求/未入金/期限超過の業務アラート表示。詳細は次節「業務ルール/ワークフロー」を参照

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

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

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

WorkflowEngine の決済区分別条件・工程・三社間金銭フローの詳細は業務フローを正本とする。

主要フロー(起票〜入金)のシーケンス

Section titled “主要フロー(起票〜入金)のシーケンス”
sequenceDiagram
    actor Dealer as 販売店
    participant Form as app/dealer/orders/new
    participant DB as Supabase Postgres
    actor Staff as 社内担当(受注管理)
    participant WF as WorkflowEngine
    actor Kaikei as 発注担当/経理

    Dealer->>Form: 案件情報・商品・決済区分を入力
    Form->>DB: cases→case_products/case_packages→case_settlementsへ順にINSERT
    alt いずれかのINSERTが失敗
        Form->>DB: cleanupCaseが作成済み行を逆順DELETE
        Form-->>Dealer: 登録失敗を表示(中間状態を残さない)
    end
    Staff->>DB: 受注管理で案件を確認
    Staff->>DB: 受付/差し戻し/取消(cases.statusを更新)
    Kaikei->>WF: 決済区分をもとにcanOrderを評価
    WF-->>Kaikei: 判定結果・警告文
    Kaikei->>DB: 発注(orders/order_items)を登録
    Kaikei->>WF: 全発注納品後にcanInvoiceを再評価
    WF-->>Kaikei: 判定結果・請求締日/支払期日
    Kaikei->>DB: 請求(invoices/invoice_line_items)を発行
    Kaikei->>DB: 入金(payments)を記録
    DB-->>Kaikei: summarizeInvoicePayments()で消込状況を返す

経営ダッシュボード(/、app/page.tsx → loadDashboard())の集計関数名は aggregateDashboardV1 であり、税抜売上・確定粗利は請求日(invoices.invoice_date)基準で計算する。案件の受注日(cases.order_received_date)や case_products の価格スナップショットを直接合算する方式ではない。

指標集計基準
売上(税抜)期間内にinvoice_dateを持つ有効請求(取消除く、isActiveCaseStatusが真の案件のみ)の税抜金額(subtotal_ex_tax優先、無ければfloor(invoice_amount / 1.1))合計
実粗利案件単位の確定粗利(revenue − cost − fee)を、期間内請求の税抜金額比で案件のコスト・手数料に按分し、期間内分だけを合計した値。案件の全請求が期間内に収まる場合は案件単位の確定粗利と一致する
粗利率実粗利 ÷ 売上(税抜)× 100
未入金額有効請求ごとに、通常決済はsummarizeInvoicePayments().unpaidAmount、3社間決済は信販入金・販売店仕切精算からの回収残高(computeThreePartyRecoveryAmounts)を合算。期間非連動の全期間集計

案件単位の確定粗利は次の式で決まる(lib/profit/caseProfitCalc.ts)。

revenue = Σ(有効請求のsubtotal_ex_tax、無ければfloor(invoice_amount/1.1))
cost = Σ(有効発注のorder_amount。ステータスが「キャンセル」「取消」の発注は除外)
fee = fee_amount(税抜・優先)。無ければ floor(revenue × fee_rate / 100)
profit = revenue − cost − fee

案件が複数請求・複数期間にまたがる場合、期間内粗利は「期間内請求分の税抜金額 ÷ 案件全体の税抜売上」の比率でcostとfeeを按分する。端数は最後の請求行に寄せて(Math.floorの切り捨て残差を最終行が吸収)、按分合計が元のcost/feeと一致するようにしている。

業務ルール(税・端数): 消費税率は10%固定。明細ごとには課税せず、請求書単位で1回だけ計算する。消費税の1円未満は切り捨て(tax = Math.floor(subtotal_ex_tax * 0.10))。invoice_amount(税込)自体は変更しない。粗利・ダッシュボード売上はこの税抜額(subtotal_ex_tax)を使う。

フォールバック: subtotal_ex_tax/tax_amount列は2026-08-07のマイグレーションで追加されたスナップショット列でNULL許容。値が無い請求(追加前に発行された請求等)はfloor(invoice_amount / 1.1)で税抜を逆算する。このフォールバックは印刷表示・粗利集計・ダッシュボード集計で共通利用する。

表示期間: プリセットは「今月」(既定)/「先月」/「今年」/「過去12ヶ月」/「カスタム」。表示粒度は今月・先月が日次、今年・過去12ヶ月が月次、カスタムは62日以内なら日次・それ超は月次に自動切替する。

期限超過の定義: 支払期日(due_date)が当日より前、かつ未入金残高が残っている場合に期限超過。当日中は超過扱いにしない。3社間決済は顧客請求のdue_dateでは期限超過判定を行わない(isOverdueは常にfalse)。

KPIからの導線: 各KPIカードはbuildDashboardKpiHref()でクエリ付きのリンクを生成する。売上/粗利/粗利率は/cases?invoiceFrom=…&invoiceTo=…、未発注/未請求は/cases?alert=…、未入金額/未入金/期限超過は/payments?…へ遷移する。

旧集計との関係: lib/dashboard/salesMetrics.tsのsumSalesAndProfit()はcase_products.sales_price/gross_profitを単純合算する旧方式で、コード上はlib/dashboard/index.tsからexportされたまま残っている。現行の経営ダッシュボード(app/page.tsx → loadDashboard → aggregateDashboardV1)はこの関数を呼び出しておらず、確認できた範囲では他の呼び出し元も無い。詳細は確認事項を参照。

アラート条件
未発注canOrder = true かつ、その案件に紐づく有効発注が0件
未請求canInvoice = true かつ、その案件に紐づく有効請求が0件
未入金有効請求のうち、未入金または一部入金の状態にあるもの(通常決済はsummarizeInvoicePayments()、3社間決済は回収残高ベース)
期限超過有効請求のうち期限超過状態にあるもの(3社間決済は対象外。上記「期限超過の定義」参照)

canOrder・canInvoice が false の案件は未発注/未請求アラートの対象外とする。これら4種のアラート集計はWorkflowEngineの評価を案件ごとに行うloadWorkflowAlertCaseIds()(未発注・未請求)と、請求単位のsummarizeDashboardInvoiceUnpaid()(未入金・期限超過)という別系統のクエリで構成する。前者は案件一覧(cases)にconstruction_completed_date列を含めて取得を試み、環境側でこの列が未適用(スキーマキャッシュ未反映)の場合はエラーメッセージを検知してこの列を含まない再クエリへフォールバックする。

社内ユーザーの認証はSupabase Auth(email + password)が担う。ログイン成功後、staff_profilesテーブルでアカウントの有効性(is_active)と管理者権限(is_admin)を確認する。ログイン失敗・状態不整合は次のエラーコードで区別する。

エラーコード発生条件
UNAUTHORIZEDメールアドレス・パスワードの組み合わせが不正、または未入力
PROFILE_MISSINGSupabase Auth認証は成功したがstaff_profilesに対応行が無い(自動でサインアウトさせる)
INACTIVEstaff_profiles.is_activeがfalse(同じく自動サインアウト)
CONFIG_ERRORSupabase Auth用の環境変数(URL/publishable key)が未設定
AUTH_FAILED上記以外の予期しない例外

is_adminが確認できた権限差は次のとおり。それ以外の画面・APIが管理者限定かは本ページの情報源からは確認できない。

  • サーバー側で強制: スタッフ管理API(/api/staff)はis_adminがfalseのセッションからのリクエストを拒否する
  • UI側の表示制御: サイドバーの「設定」メニュー群、マスタ画面の削除ボタンはis_adminがtrueのときのみ表示する(クライアント側の表示制御であり、対象テーブル自体がDB側でも管理者限定に制御されているかは未確認)
  • is_admin列が未適用の環境(マイグレーション未反映)でもログイン経路自体は落とさず、is_admin: falseとして扱うフォールバックがある

レート制限(lib/gateway/rateLimit.ts): ログインはIP単位で10回/60秒、加えて全IP合計の失敗数が60回/60秒を超えると一律ブロックする(成功ログインはカウントしない)。案件登録(/api/case-registrations)はセッション+IP単位で30回/60秒。超過時はいずれもRATE_LIMITEDエラー(HTTP 429)を返す。

案件登録APIのゲートウェイ検査(/cases/new → POST /api/case-registrations): 同一オリジンチェック→セッションCookie必須→CSRFトークン検証→JSON Content-Type必須→レート制限→サーバー側で導出した冪等キー(クライアントが送るrequest_idは無視し、セッションのactor鍵とIdempotency-Keyヘッダーから再導出)を付与したうえでservice_roleによりcreate_case_registrationRPCを呼ぶ。

販売店発注フォーム(app/dealer/orders/new)は社内認証の外側にあり、上記のゲートウェイ検査(オリジン・CSRF・レート制限・セッション)を経由せずsaveDealerOrderがcases/case_products/case_settlementsへ直接INSERTする。case_registration_requestsは経由せず、起票そのものへの人による承認ステップも無い(起票後の社内受理は画面・機能の「受注管理」を参照)。三社間金銭アクション・その他の申請系RPCへの書込権限はservice_roleに限定し、当該テーブルはRLSを無効化したうえでGRANT/REVOKEによるACLでPUBLIC/anon/authenticatedから権限を剥奪する方式である(詳細はデータモデルを参照)。

ケース挙動
販売店発注の途中失敗cases→case_products/case_packages→case_settlementsのいずれかのINSERTが失敗すると、cleanupCaseが作成済み行を逆順DELETEし、中間状態の案件を残さない設計。DELETE自体が失敗した場合の扱いは未確認
決済区分が未解決settlement_typeが正式値・エイリアスいずれにも一致しない場合、WorkflowEngineはcanOrder/canInvoiceともfalseを返す。案件詳細で決済区分を手動修正するまでこの状態は解消しない
construction_completed_date列の未適用環境ダッシュボードの業務アラート集計はこの列を含めたcases取得を試み、スキーマキャッシュ未反映のエラーを検知した場合はこの列を含まない再クエリへフォールバックする
請求の税抜スナップショット欠落subtotal_ex_tax/tax_amountが未設定の請求(2026-08-07のマイグレーション以前に発行された請求等)は、floor(invoice_amount / 1.1)で税抜額を逆算するフォールバックを印刷表示・粗利集計・ダッシュボード集計で共通利用する
過入金summarizeInvoicePayments()は確認済み入金合計が請求額を超える場合overpaidAmountを算出し警告文を返す。入金の取消・金額修正は別途手動で行う
案件ステータスの表記ゆれ引用符付き文字列("'新規受付'"等)・工事系ステータス(工事日調整中/施工中等)・受注管理の書込値(受付済み/差し戻し)がDBに混在する。表示側はエイリアス吸収で対応するが、DB値の一括統一UPDATEは行っていない
期限超過判定の非対称性通常決済は請求のdue_dateで期限超過を判定するが、3社間決済は信販入金・仕切精算ベースの回収残高のみを見て、顧客請求のdue_dateによる期限超過判定は行わない
登録APIの流量超過案件登録は30回/60秒(セッション+IP単位)、ログインはIP単位10回/60秒(+全IP合計失敗60回/60秒)を超えるとRATE_LIMITED(HTTP 429)を返す
観点当方CRMValueOS
強い領域案件獲得〜見積〜催事(前段)受発注〜請求〜入金(後段)
案件の呼称WholesaleCasecases
卸金額の呼称WholesalePrice(dealer_sales_prices / supplier_purchase_prices)sales_prices / purchase_prices
決済区分の呼称WSettlement(前金/掛売/三社間/カード/その他)case_settlements.settlement_type(正式値: 前金/売掛/3社間決済/カード)
販売店発注の呼称DealerIntakeFormapp/dealer/orders/new(saveDealerOrder が直接INSERT・起票自体に承認ステップ無し。起票後の社内受理は「受注管理」で実施)
発注/請求/入金卸案件のフラグ集約(差)独立エンティティ(orders/invoices/payments)
決済区分別ワークフローwholesaleFlow で機械判定(上位)WorkflowEngine で機械判定
経営ダッシュボードの集計軸未整理(redesign/valueos-gap参照)請求日(invoice_date)基準の確定粗利集計(aggregateDashboardV1)

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

  • lib/dashboard/salesMetrics.tsのsumSalesAndProfit()(case_products.sales_price/gross_profitを単純合算する旧集計)はlib/dashboard/index.tsから現在もexportされているが、現行の経営ダッシュボード(app/page.tsx)はaggregateDashboardV1のみを使用しており、他の呼び出し元は確認できなかった。将来の再利用予定か削除漏れかの確認が要る
  • staff_profiles.is_adminが及ぼす権限差は、スタッフ管理APIのサーバー側拒否とUIの表示制御(設定メニュー・マスタ削除ボタン)のみ確認できた。マスタ本体の更新・削除がDB側(RLS等)でも管理者限定になっているかは本ページの情報源からは確認できない
  • 受注管理(app/admin/orders)の受付/差し戻し/取消操作はcases.statusのみを更新し、決済区分(case_settlements.settlement_type)の設定は対象外である。受付操作の時点で決済区分が未設定のままの案件を、どの画面・操作で確定させる想定かは未確認