Design Rule コレクション
概要
生成パイプラインが消費するデザインルールのリビジョンを保持するコレクション。rule_process ワーカーが書き込む: デザイナーが選択した Figma ガイドラインボード(1 回の rule_upload イベント)から、各ボードを Figma REST API でレンダリングし、ボードごとに 1 回のビジョン抽出を実行し、フラグメントを決定論的にマージして単一の機械検証可能な RuleSet にする(webhook なし、PG への作用なし)。このコレクションそのものがルールのリビジョン履歴である: (design_rule_id, マージ済み RuleSet の content_hash) ごとに 1 件の不変ドキュメントを持ち、version がその序数となる。各リビジョンは、マージ済みルール — generation-assemble がスペック違反を自動修正またはフラグ付けするために実行するバリデータプログラム — と、ソースボード(画像参照)の両方を保存する。ソースボードは、セクションごとの選択呼び出しすべてに選択 LLM のビジョン参照として添付される。
テーブル定義
| 論理名 | 物理名 | カラム名 | データ型 | 主キー | リレーション | ユニーク | NULL許可 | デフォルト値 | 備考 |
|---|---|---|---|---|---|---|---|---|---|
| Design Rule | design_rule | _id | string | ◯ | uuid。DocumentDB の _id(代理キー)として格納する |
||||
| organization_id | number | テナント所有者 | |||||||
| project_id | number | project:id | プロジェクトスコープ。すべての読み書きは organization_id + project_id でフィルタする |
||||||
| design_rule_id | string | プラットフォームの design_rule 行 id(値による参照であり、FK ではない)。このコレクションそのものがバージョン履歴である: (design_rule_id, content_hash) ごとに 1 件の不変ドキュメントを持ち、version = 序数。生成は再現性のため (design_rule_id, content_hash) を固定する。lineage.processed_at = 最終同期マーカー |
|||||||
| version | number | rule_process は version = (design_rule_id の現行最大値) + 1 を割り当てる。ユニーク (design_rule_id, content_hash) により冪等 — 内容が変わらない再実行は既存のドキュメント/バージョンに写像される。並行登録は単一の rule_upload イベントによって直列化される |
|||||||
| content_hash | string | ◯ | バージョン同一性 — マージ済み RuleSet の sha256(正規化 JSON、キーをソート)。ユニーク (design_rule_id, content_hash) — 同一の抽出結果は既存リビジョンに収束する。例: d4e5f6... |
||||||
| draft_source | string | ルール内容の出所 — human/llm_draft_adjusted/llm_extracted。ボード抽出は llm_extracted として登録され、デザイナーのレビュー待ちとなる。例: llm_extracted |
|||||||
| rules | object | バリデータが実行する機械検証可能なルール。形状: { spacing: {scale[], section_gap}, typography: [{style_token, max_lines, usage, size_px, size_min_px, size_max_px, line_height_pct, weight, applies_to[]}], colors: {entries[{token, value, usage}], allowed[]}, usage_rules: [], layout_patterns: [], rich_layouts: [], globals: {}, component_inventory: [], component_specs: [{component, variants[], states[], seen_on_screens[], slot_rules}], screen_group_policies: [{group, covers, screen_ids[], device, content_width_px, padding_x_px, padding_y_px, section_gap_px, element_gap_px, columns_min, columns_max, section_separator, full_bleed, source_text}] }。各ルールクラスは束縛先の spec フィールドを明示する。component_inventory は component_specs に置き換え済みで、旧リビジョン互換のため保持。slot_constraints は削除された — wf_role を許可された platform_design_id に束縛する設計だったが、これを生成する抽出パスは存在せず、フィールドは常に空でバインディングは一度も実行されなかった |
|||||||
| llm_usage | object | この取り込みのコスト(プロバイダ自身の報告値): { calls, requests, input_tokens, output_tokens, cached_input_tokens, stages: [{stage, calls, requests, input_tokens, output_tokens, cached_input_tokens}] } — ステージ別、入力トークンの多い順。再構成ではなく実測のため、リトライも可視化される |
|||||||
| boards | array | ルールの抽出元となったガイドラインボード。要素の形状: { node_id: string, title: string, image_url: string(S3 上のレンダリング格納先), content_hash: string(画像の sha256), mime: string }。assemble 時に S3 から読み込まれ、セクションごとの選択呼び出しすべてにビジョン参照として添付される。画像が欠けている場合、生成は fail-closed となる |
|||||||
| extraction_model_id | string | 抽出の来歴 — ボードからルールを抽出したビジョンモデル | |||||||
| extraction_prompt_version | string | 抽出の来歴 — ルール抽出プロンプトのバージョン。例: re@0.1 |
|||||||
| extracted_at | datetime | 抽出の来歴 — 抽出が実行された日時 | |||||||
| lineage | object | 全ドキュメント共通の lineage エンベロープ。形状: { source_url: string, source_hash: string, processor_version: string, index_schema_version: number, processed_at: datetime, job_id: string }。source_hash ≡ content_hash。job_id = 生成元の rule_process 実行 id |
リレーション
- project_id → project.id
design_rule_id→ プラットフォームのdesign_rule行 id(値による参照であり、FK ではない。レジストリ行はプラットフォーム API を通じてクライアントが作成するものであり、このワーカーが作成するのではない)。- DocumentDB 内ではリレーションは強制されない。論理リレーションであり、アプリケーションコードで検証する。
インデックス
- PRIMARY KEY (_id)
- UNIQUE INDEX (design_rule_id, content_hash) — 不変性/冪等性のフェンス。内容が変わらない再実行は既存のドキュメント/バージョンに写像され、新しい序数を発行しない。
- SECONDARY INDEX (organization_id, project_id, design_rule_id) — バージョン履歴の参照 + 次の序数のための
max(version)割り当て。
Type Codes
draft_source:
human: キュレーターが執筆/編集llm_draft_adjusted: 一度きりの初期 LLM ドラフトをキュレーターが調整llm_extracted: 選択されたガイドラインボードから、取り込み時のビジョン抽出によって抽出されたもの。デザイナーのレビュー待ちとして登録される — デザイナーは抽出されたルールを確認し、ガイドライン修正後に再登録する(同一のマージ済みルールは同じリビジョンに収束し、変更されたルールは次のバージョンを発行する)
注記
rule_processがこのコレクションへの書き込みを所有する。デザイナーが選択したガイドラインボードからルールを抽出する: Figma REST API でボードタイトルを解決し(ボードノードの欠落はハードエラー)、各ボードを PNG としてレンダリングして(サービスアカウント PAT)S3 に格納し、ボードごとに 1 回のビジョン抽出を実行し(LLM フェンスコール 4 — このワーカーはもはや LLM フリーではなく、PAT を必要とする)、フラグメントを決定論的にマージする(ボードはnode_idでソートして処理。許可値の和集合はソート。first-non-null/先出現優先)。webhook なしで PG への作用も持たないことは変わらない:design_ruleドキュメントそのものが記録である。generation-parse はプロジェクトの最新リビジョンを固定する(versionが最大のもの。同値はlineage.processed_atが最新のもの)。リビジョンが存在しない場合、ピンはNoneとなり、バリデータは no-op となってすべてのノードがrules_unvalidatedとフラグ付けされる(validator_report.status = no_rules)。従来のインライン厳密ファイルピン経路は削除された(parse メッセージはもはやdesign_rule_file_urlをモデル化しない)。generation-assemble は固定されたリビジョンを((design_rule_id, content_hash)をキーに)決定論的なルールバリデータとして読み取り、さらにそのboards[]の画像を S3 から読み込んで、セクションごとの選択呼び出しすべてに advisory なビジョン参照として添付する。固定ドキュメントの欠落またはボード画像の欠落は生成を fail-closed にする(ContractFailure)。- ドキュメントは不変である — 新しいルールリビジョンは新しいドキュメントであり、インプレース編集は決して行わない。
versionはdesign_rule_idごとの序数である。再現性はリビジョンの不変性に依拠する — 別途のセットハッシュは存在しない。 content_hash= マージ済み RuleSet の正規化 JSON(キーをソート)に対する sha256。これはバージョン同一性であると同時に冪等性キーでもある — 同一の抽出結果は既存リビジョンに収束し、変更されたルールは次のバージョンを発行する。- ドキュメント形状が変わったら(
lineageに含まれる)index_schema_versionを上げること。