SCALE — Build Lab
開発パターン · SQL SCHEMA

D1 スキーマ設計(実例)

CATEGORY開発パターン TYPESQL Schema EFFORT30〜60分 DIFFICULTY
PRIMARY CODE
tsx · scale-crm:schema.sql
-- SCALE CRM D1 Schema
-- Cloudflare D1 (SQLite互換)
-- 適用: npx wrangler d1 execute scale-lead-prod --file=schema.sql --remote

-- 1. メインデータテーブル(Supabase app_data 互換)
CREATE TABLE IF NOT EXISTS app_data (
  key TEXT PRIMARY KEY,
  value TEXT NOT NULL,
  updated_at TEXT NOT NULL DEFAULT (datetime('now')),
  updated_by TEXT
);

CREATE INDEX IF NOT EXISTS idx_app_data_updated_at ON app_data(updated_at);
CREATE INDEX IF NOT EXISTS idx_app_data_key_prefix ON app_data(key);

-- 2. スナップショット(30分毎自動 + 手動)
CREATE TABLE IF NOT EXISTS snapshots (
  id TEXT PRIMARY KEY,
  taken_at TEXT NOT NULL DEFAULT (datetime('now')),
  taken_by TEXT,
  reason TEXT,
  payload TEXT NOT NULL
);

CREATE INDEX IF NOT EXISTS idx_snapshots_taken_at ON snapshots(taken_at DESC);

-- 3. エラーログ(クライアント自動収集)
CREATE TABLE IF NOT EXISTS error_log (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  occurred_at TEXT NOT NULL DEFAULT (datetime('now')),
  user TEXT,
  url TEXT,
  message TEXT NOT NULL,
  stack TEXT,
  ua TEXT
);

CREATE INDEX IF NOT EXISTS idx_error_log_occurred_at ON error_log(occurred_at DESC);

-- 4. 監査ログ(誰が・いつ・何を変えたか)
CREATE TABLE IF NOT EXISTS audit_log (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  occurred_at TEXT NOT NULL DEFAULT (datetime('now')),
  user TEXT,
  key TEXT NOT NULL,
  action TEXT NOT NULL CHECK(action IN ('upsert','delete')),
  before_value TEXT,
  after_value TEXT
);

CREATE INDEX IF NOT EXISTS idx_audit_log_occurred_at ON audit_log(occurred_at DESC);
CREATE INDEX IF NOT EXISTS idx_audit_log_key ON audit_log(key);

-- 5. ヘルスチェック用(ping用の軽量テーブル)
CREATE TABLE IF NOT EXISTS health_check (
  id INTEGER PRIMARY KEY,
  last_ping TEXT NOT NULL DEFAULT (datetime('now'))
);

INSERT OR IGNORE INTO health_check (id, last_ping) VALUES (1, datetime('now'));

前提条件
Tailwind CSS v4TypeScript 5
USE CASES
  • 新規 D1 プロジェクトの雛形

D1 スキーマ設計(実例)

:LiTarget: 用途

SCALE CRM 実運用 D1 のスキーマ。Key-Value 風データテーブル + 監査ログ + スナップショット。

:LiSparkle: 特徴

  • 実運用スキーマ
  • インデックス設計
  • 論理削除対応
  • D1/SQLite 互換

:LiCode: 実コード(SCALE Base より自動抽出)

:LiInfo: scale-crm:schema.sql の中身そのもの。コピペ即可。

-- SCALE CRM D1 Schema
-- Cloudflare D1 (SQLite互換)
-- 適用: npx wrangler d1 execute scale-lead-prod --file=schema.sql --remote

-- 1. メインデータテーブル(Supabase app_data 互換)
CREATE TABLE IF NOT EXISTS app_data (
  key TEXT PRIMARY KEY,
  value TEXT NOT NULL,
  updated_at TEXT NOT NULL DEFAULT (datetime('now')),
  updated_by TEXT
);

CREATE INDEX IF NOT EXISTS idx_app_data_updated_at ON app_data(updated_at);
CREATE INDEX IF NOT EXISTS idx_app_data_key_prefix ON app_data(key);

-- 2. スナップショット(30分毎自動 + 手動)
CREATE TABLE IF NOT EXISTS snapshots (
  id TEXT PRIMARY KEY,
  taken_at TEXT NOT NULL DEFAULT (datetime('now')),
  taken_by TEXT,
  reason TEXT,
  payload TEXT NOT NULL
);

CREATE INDEX IF NOT EXISTS idx_snapshots_taken_at ON snapshots(taken_at DESC);

-- 3. エラーログ(クライアント自動収集)
CREATE TABLE IF NOT EXISTS error_log (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  occurred_at TEXT NOT NULL DEFAULT (datetime('now')),
  user TEXT,
  url TEXT,
  message TEXT NOT NULL,
  stack TEXT,
  ua TEXT
);

CREATE INDEX IF NOT EXISTS idx_error_log_occurred_at ON error_log(occurred_at DESC);

-- 4. 監査ログ(誰が・いつ・何を変えたか)
CREATE TABLE IF NOT EXISTS audit_log (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  occurred_at TEXT NOT NULL DEFAULT (datetime('now')),
  user TEXT,
  key TEXT NOT NULL,
  action TEXT NOT NULL CHECK(action IN ('upsert','delete')),
  before_value TEXT,
  after_value TEXT
);

CREATE INDEX IF NOT EXISTS idx_audit_log_occurred_at ON audit_log(occurred_at DESC);
CREATE INDEX IF NOT EXISTS idx_audit_log_key ON audit_log(key);

-- 5. ヘルスチェック用(ping用の軽量テーブル)
CREATE TABLE IF NOT EXISTS health_check (
  id INTEGER PRIMARY KEY,
  last_ping TEXT NOT NULL DEFAULT (datetime('now'))
);

INSERT OR IGNORE INTO health_check (id, last_ping) VALUES (1, datetime('now'));

:LiFolder: ソースファイルのパス

/Users/oogushiyuuki/株式会社SCALE/scale-lead/schema.sql

:LiHandPointer: 使い方

対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。

:LiAlertCircle: 注意事項

  • 依存パッケージを忘れず追加