本文へ移動

自分だけの業務システムを作る

SetFNワークスペースでは、自社専用のグループウェアやERPのようなシステムを自分で作ることができます。 データベース構造の設計と画面の制作はAIに任せ、その成果物をファイルにしてワークスペースにアップロードするだけです。 作成するファイルは2つ。行う作業は、アップロードと「配布する」ボタンのクリックです。 ここでは、「製造現場の在庫管理プログラム」を例に作成します。

AIプロンプトを使わずに、完成済みのファイルをすぐに試したい場合は、サンプル一式のZIPをダウンロードから、スキーマ、index.html、mock-db-upload.html、READMEをまとめて入手できます。


1. データベースを作成するための.sfnファイルを作る

SetFNワークスペースでは、.sfnというファイルでDBを作成できます。Claude、GPT、GeminiなどのAIに.sfnファイルの例をコピーして渡し、「部品と製品の在庫を管理したい」のように要件を説明すると、AIがファイルを作成します。

次の内容をコピーし、下の部分の要件を書き換えてAIに渡してみてください。

あなたは、SetFNというノーコードのバックエンドプラットフォームのスキーマファイル(.sfn)を設計するエンジニアです。
.sfnは、次の構造を持つJSONファイルです。

{
  "content-type": "application/setfn-schema",
  "dbType": "sqlite3",
  "apiBuild": {
    "dbName": "英小文字_アンダースコア_DB名",
    "dbEngine": "sqlite",
    "includeClient": false,
    "features": {
      "realtime": { "enabled": false },
      "upload": { "enabled": false },
      "ai-chat": { "enabled": false }
    }
  },
  "data": [
    {
      "table": { "name": "テーブル名", "cmt": "このテーブルの説明" },
      "columns": [
        { "name": "id", "type": "serial4", "primary": true, "default": "auto_increment" },
        { "name": "カラム名", "type": "text", "notnull": true, "cmt": "カラムの説明" },
        { "name": "数値カラム", "type": "int4", "notnull": true, "default": "0" },
        { "name": "_created_at", "type": "timestamp", "default": "now()" }
      ],
      "permissions": {
        "security": { "login": true },
        "ops": {
          "list": { "login": true },
          "view": { "login": true },
          "create": { "login": true },
          "update": { "login": true },
          "delete": { "login": true, "roles": ["admin"] }
        }
      }
    }
  ]
}

カラムのtypeは、serial4(自動増分のPK)/ text / int4(整数)/ timestampだけを使用してください。
カラムには、notnull、default、unique、index、cmtを必要に応じて付けてください。

では、この形式で、製造業の会社が使う「在庫管理システム」のDBを設計してください。要件は次のとおりです。

- 部品を登録し、部品ごとの現在の在庫数量を管理する。
- 製品を登録し、製品ごとの現在の在庫数量を管理する。
- 1つの製品は、複数の部品を組み立てて作られる。どの製品にどの部品がいくつ必要か(BOM、部品表)を管理する。
- 部品/製品の入庫・出庫の履歴を残す。特に「部品を組み立てて製品を生産する」イベントが発生したときは、その時点で使用された部品と生産された製品の数量を、1つの出来事としてまとめて追跡できなければならない(後から「この製品を作るのに部品がどれだけ使われたか」を照会できる必要がある)。

DB名(dbName)は "inventory_management" にしてください。
テーブルは4つ以内で、実務ですぐに使えるくらい実用的に設計してください。
ほかの説明は付けず、完成した.sfnのJSONコードだけを出力してください。

次は、このようにして作成されたAIの応答の例です。実際の結果は、AIによって、また実行するたびに少しずつ異なる場合があります。この内容と完全に同じである必要はなく、似た構造になっていれば問題ありません。ただし、ほかの説明がなく、{で始まり}で終わる形式でなければ、出力された結果をそのままエディタに貼り付けることができません。

{
  "content-type": "application/setfn-schema",
  "dbType": "sqlite3",
  "apiBuild": {
    "dbName": "inventory_management",
    "dbEngine": "sqlite",
    "includeClient": false,
    "features": {
      "realtime": { "enabled": false },
      "upload": { "enabled": false },
      "ai-chat": { "enabled": false }
    }
  },
  "data": [
    {
      "table": { "name": "parts", "cmt": "部品マスター。照会/登録/変更はメンバーなら誰でも可能、削除は管理者のみ" },
      "columns": [
        { "name": "id", "type": "serial4", "primary": true, "default": "auto_increment" },
        { "name": "part_code", "type": "text", "notnull": true, "unique": true, "cmt": "部品コード" },
        { "name": "name", "type": "text", "notnull": true, "cmt": "部品名" },
        { "name": "spec", "type": "text", "cmt": "規格(例:M2、220V/50Hz)。同じ名前でも規格が異なる場合は、別のpart_codeで登録" },
        { "name": "category", "type": "text", "cmt": "部品の分類(電子部品/機構部品/梱包材など)" },
        { "name": "unit", "type": "text", "notnull": true, "default": "EA", "cmt": "単位" },
        { "name": "unit_cost", "type": "int4", "notnull": true, "default": "0", "cmt": "単価" },
        { "name": "current_stock", "type": "int4", "notnull": true, "default": "0", "cmt": "現在庫" },
        { "name": "safety_stock", "type": "int4", "notnull": true, "default": "0", "cmt": "安全在庫(再発注点)" },
        { "name": "supplier", "type": "text", "cmt": "仕入先" },
        { "name": "_user_id", "type": "int4", "notnull": true, "index": true },
        { "name": "_nick", "type": "text", "cmt": "最後に登録/変更したメンバーの表示名" },
        { "name": "_created_at", "type": "timestamp", "default": "now()" }
      ],
      "permissions": {
        "security": { "login": true, "ownerColumn": "_user_id" },
        "ops": {
          "list": { "login": true },
          "view": { "login": true },
          "create": { "login": true },
          "update": { "login": true },
          "delete": { "login": true, "roles": ["admin"] }
        }
      }
    },
    {
      "table": { "name": "products", "cmt": "製品マスター。照会/登録/変更はメンバーなら誰でも可能、削除は管理者のみ" },
      "columns": [
        { "name": "id", "type": "serial4", "primary": true, "default": "auto_increment" },
        { "name": "product_code", "type": "text", "notnull": true, "unique": true, "cmt": "製品コード" },
        { "name": "name", "type": "text", "notnull": true, "cmt": "製品名" },
        { "name": "category", "type": "text", "cmt": "製品の分類" },
        { "name": "unit", "type": "text", "notnull": true, "default": "EA", "cmt": "単位" },
        { "name": "price", "type": "int4", "notnull": true, "default": "0", "cmt": "販売価格" },
        { "name": "current_stock", "type": "int4", "notnull": true, "default": "0", "cmt": "現在庫" },
        { "name": "_user_id", "type": "int4", "notnull": true, "index": true },
        { "name": "_nick", "type": "text", "cmt": "最後に登録/変更したメンバーの表示名" },
        { "name": "_created_at", "type": "timestamp", "default": "now()" }
      ],
      "permissions": {
        "security": { "login": true, "ownerColumn": "_user_id" },
        "ops": {
          "list": { "login": true },
          "view": { "login": true },
          "create": { "login": true },
          "update": { "login": true },
          "delete": { "login": true, "roles": ["admin"] }
        }
      }
    },
    {
      "table": { "name": "bom", "cmt": "製品ごとの部品構成表(単一階層)。bom_key(product_id:part_id)にunique制約を設定し、同じ製品に同じ部品が重複して登録されないようにする" },
      "columns": [
        { "name": "id", "type": "serial4", "primary": true, "default": "auto_increment" },
        { "name": "product_id", "type": "int4", "notnull": true, "index": true },
        { "name": "part_id", "type": "int4", "notnull": true, "index": true },
        { "name": "qty_per_unit", "type": "int4", "notnull": true, "default": "1", "cmt": "製品1個を作るのに必要な部品の数量" },
        { "name": "bom_key", "type": "text", "notnull": true, "unique": true, "cmt": "product_id:part_idの組み合わせ。重複登録の防止用" },
        { "name": "_user_id", "type": "int4", "notnull": true, "index": true },
        { "name": "_nick", "type": "text", "cmt": "登録したメンバーの表示名" },
        { "name": "_created_at", "type": "timestamp", "default": "now()" }
      ],
      "permissions": {
        "security": { "login": true, "ownerColumn": "_user_id" },
        "ops": {
          "list": { "login": true },
          "view": { "login": true },
          "create": { "login": true },
          "update": { "login": true },
          "delete": { "login": true, "roles": ["admin"] }
        }
      }
    },
    {
      "table": { "name": "stock_transactions", "cmt": "入出庫/組立の統合履歴。item_type=part|product、tx_type=입고|출고|조립사용|조립생산(入庫|出庫|組立使用|組立生産)。1つの組立生産イベントは、同じbatch_idを共有する複数件の組立使用(部品の消費)と1件の組立生産(製品の増加)で構成され、製品にどの部品がどれだけ使われたかを追跡できる" },
      "columns": [
        { "name": "id", "type": "serial4", "primary": true, "default": "auto_increment" },
        { "name": "item_type", "type": "text", "notnull": true, "cmt": "part | product" },
        { "name": "item_id", "type": "int4", "notnull": true, "index": true, "cmt": "parts.id または products.id" },
        { "name": "item_name", "type": "text", "notnull": true, "cmt": "登録時点の品目名のスナップショット" },
        { "name": "tx_type", "type": "text", "notnull": true, "cmt": "입고(入庫) | 출고(出庫) | 조립사용(組立使用) | 조립생산(組立生産)" },
        { "name": "reason", "type": "text", "cmt": "入出庫の理由。組立使用/組立生産はtx_type自体が理由であるため空欄にする" },
        { "name": "qty", "type": "int4", "notnull": true, "cmt": "常に正の数。方向はtx_typeで判断" },
        { "name": "batch_id", "type": "text", "index": true, "cmt": "組立生産イベントをまとめるid。単純な入出庫の場合は空" },
        { "name": "note", "type": "text", "cmt": "メモ" },
        { "name": "_user_id", "type": "int4", "notnull": true, "index": true },
        { "name": "_nick", "type": "text", "cmt": "登録したメンバーの表示名" },
        { "name": "_created_at", "type": "timestamp", "default": "now()" }
      ],
      "permissions": {
        "security": { "login": true, "ownerColumn": "_user_id" },
        "ops": {
          "list": { "login": true },
          "view": { "login": true },
          "create": { "login": true },
          "update": { "login": true, "roles": ["admin"] },
          "delete": { "login": true, "roles": ["admin"] }
        }
      }
    }
  ]
}

この結果をコピーし、ワークスペースで作成 → テンプレートファイル → 新しいスキーマ(DB)から、空のスキーマファイルを作成します。

作成 > テンプレートファイル > 新しいスキーマ(DB)の選択画面

ファイル名を入力して保存すると、空のスキーマファイルが作成されます。

新しく作成した空のスキーマファイル

右上のエディタタブを押し、先ほどのAIの応答をそのまま貼り付けます。

スキーマエディタ画面

保存してから上部のAPIビルドタブに移動すると、テーブルごとに自動生成されたAPIの一覧を確認できます。

APIビルド画面

配布するを押して設定を展開し、データベース識別子を確認してから、配布するをもう一度押します。数秒待つと、「配布完了!」のメッセージが表示されます。最後に、上部のフロッピーディスクのボタンを押して保存します。ここまでで、DBの構成は完了です。 部品/製品/構成表/入出庫履歴の4つのテーブルと、それらのテーブルを操作するREST APIが実際に作成され、すぐに使用できる状態になります。次は、このDBと接続する画面を作成します。

2. 画面を構成するための.htmlファイルを作る

今回もAIに依頼します。作りたいものを企画して整理し、AIに伝えます。このとき、先ほど作成した.sfnファイルの内容も、参考資料として一緒に渡します。

  • 部品・製品を登録する入力フォーム
  • 入庫・出庫を登録するフォーム
  • 「この製品をいくつ生産した」と登録すると、必要な部品の数量を自動的に計算して在庫に反映
  • 現在の在庫状況を表で表示し、表の上で直接値を修正して保存

次の内容を、続けてAIチャットに貼り付けます。(先頭に、手順1で作成した結果もあわせて貼り付けます。)

[ここに手順1の結果を貼り付ける]

上のスキーマは、すでにデプロイされています。このスキーマを使用するWeb画面(index.html)を1つ作成してください。

画面でデータを読み込んだり保存したりするときは、次のルールでサーバーにリクエストしてください。

1. ログインしたユーザーのAPIトークンを取得するには:
   POST /api/auth/bootstrap  (credentials: "include")
   応答: { data: { access_token, user: { id, nick } } }

2. 以降のすべてのリクエストには、このヘッダーを付ける: Authorization: Bearer <access_token>

3. テーブルのCRUD:
   照会   GET  /api/web/{dbName}/{table}/list?カラム=値   → 応答 { rows: [...] } (rowsは結果がない場合nullになることがあるため、常に rows || [] で処理する)
   作成   POST /api/web/{dbName}/{table}/create          → body: JSON, 応答 { lastInsertId }
   変更   PUT  /api/web/{dbName}/{table}/update/{id}     → body: JSON (変更したカラムだけを送ってもよい)
   削除   DELETE /api/web/{dbName}/{table}/delete/{id}

画面に必要な機能は次のとおりです。

- 部品と製品を新規登録できる入力フォーム
- 部品/製品の入庫・出庫を登録できるフォーム(登録すると現在の在庫数量もあわせて更新)
- 「この製品をいくつ生産した」と登録すると、登録済みの構成表に従って必要な部品の数量を自動的に計算し、部品の在庫を減らして製品の在庫を増やす機能。部品の在庫が足りない場合は、登録を止めて知らせてください。
- 現在の部品/製品の在庫状況を表で表示する画面。表のセルをクリックすると、その場で値を修正して保存できるようにしてください。
- 入庫/出庫/組立の履歴を時系列で表示する一覧。

HTML/CSS/JSを1つのファイルにすべてまとめてください。すっきりした白い背景に、カード型のレイアウトで作成してください。
ほかの説明は付けず、完成したindex.htmlのコードだけを出力してください。

次は、このようにして作成されたhtmlファイルの例です。実際の結果は、AIによって少しずつ異なる場合があります。

index.html

このファイルをワークスペースにアップロードすると、実際にチームメンバーが使える画面が完成します。

3. テストデータを投入する

実際に動作する様子を目で確認するには、データが必要です。ボタン1つでサンプルデータを投入する画面も、AIにすぐに作成を依頼できます。

[ここに手順1の結果を貼り付ける]

上のスキーマはすでにデプロイされており、このスキーマを使用するindex.htmlもすでに作成されています。
ボタンを1つ押すと、テスト用のデータを自動的に投入する画面(mock-db-upload.html)を作成してください。

データは、手順2の画面と同じ方式(POST /api/auth/bootstrap でトークンを取得し、POST /api/web/{dbName}/{table}/create で作成)で、実際のサーバーに登録してください。

- 部品10〜15個、製品3〜5個、各製品の部品構成、入出庫の履歴数件を、実際に作成して登録してください。
- 部品/製品の名前と数量は、製造業の現場で実際に使われそうな値にしてください。
- すでに同じコードのデータがある場合は、その項目だけを飛ばして処理を続けてください。
- 進行状況を画面に1行ずつログとして表示し、終わったら「完了」と表示してください。
ほかの説明は付けず、完成したmock-db-upload.htmlのコードだけを出力してください。

次は、このようにして作成されたhtmlファイルの例です。実際の結果は、AIによって少しずつ異なる場合があります。この画面はデプロイせず、デモの準備が必要なときだけ開いて使用します。

mock-db-upload.html

実際にデータを投入して使ってみると、次のように動作します。

部品状況 — セルをダブルクリックすると、その場で修正・保存される

BOM登録 — 右側の部品カードを左側にドラッグ&ドロップすると、構成に追加される

組立生産の登録 — 製品と生産数量を決めると、必要な部品の数量と現在庫が自動的に表示される

取引履歴 — バッチ番号ごとに、組立生産・組立使用の内容がまとめて記録される

4. 繰り返し修正する

一度で完成させる必要はありません。画面を使っているうちに、足りない機能や直したい部分が出てきたら、続けてAIに依頼します。ただし、何を修正するかによって、その後に行う作業が異なります。

  • DBの構造(テーブル・カラム)が変わる修正(例:新しいカラムの追加、新しいテーブルの追加)は、修正された.sfnをあらためて受け取ってエディタに貼り付け、APIビルドでもう一度デプロイする必要があります。
  • DBの構造はそのままで、画面だけを直す修正(例:デザイン、文言、ボタンの位置)は、index.htmlだけをあらためて受け取り、既存のファイルを上書きします。APIをもう一度デプロイする必要はありません。
  • すでにデータが入っているテーブルの構造を変更するときは、デプロイ設定の既存データを上書きを確認します。上書きを有効にすると既存データは完全に削除されます。

この4つのステップだけで、データベースの設計、実際の画面、テストデータ、そしてその後の修正まで、すべてAIが作成します。その後は、画面のデザインや細かい項目を、必要に応じて調整していきます。