コンテンツにスキップ

Schema specifications and constraints

Data Engineの各APIは、同じスキーマを扱っていても対応範囲が異なります。あるAPIが受け付けるスキーマを、別のコンパイラ・AIツール・UI仕様がそのまま扱えるとは限りません。このガイドは現在の実装に基づく利用条件を説明します。個々のAPIのシグネチャとオプションはソースのJSDocを参照してください。

操作 行うこと 保証しないこと
createSchema TypeScriptの型情報を持たせて渡されたスキーマを返す スキーマの実行時検証、複製、凍結、入力データの検証
createAjvValidator JSON Schemaに対するデータ検証 認可、保存、すべての独自拡張の業務的な意味の実行
generateZodSchema 実装済みの変換範囲でZodオブジェクトを生成 任意のJSON Schemaと等価な検証
zodToJSONSchema 対応するZodの形を変換 情報を失わない往復変換、すべてのrefinement・transformの保持
auditSchema オプションに応じて$id・x-plugin・x-db等の規約を検査 JSON Schemaのメタスキーマ検証、業務データの検証
generateSqlFromJSONSchema 選択したテーブルのPostgreSQL向けSQL文字列を生成 SQL実行、マイグレーション完了、全JSON Schema制約のDBへの転記

保存・交換するスキーマ仕様はJSON Schemaを正本とし、その適合判定にはAJVを使います。Zodはアプリケーションとの連携に利用できますが、変換成功だけで全制約が引き継がれたと判断しないでください。

AJVアダプターは$schema省略時にdraft-07を使います。標準のdraft-07と2020-12のURIを認識し、HTTP・HTTPSと末尾の#に対応します。未対応のURIは例外になります。明示したdraftオプションと$schemaの不一致も例外です。ひとつのスキーマ内でdialectを混ぜたり、このアダプター経由でdraft-04・2019-09が使えると仮定したりしないでください。

dereferenceSchemaはファイル・HTTPリゾルバーを無効にしています。参照先は渡した文書内に置きます。URL形式の参照が外部取得を許可するわけではありません。参照解決後も循環が残る場合があるため、有限JSONを要求するAPIへ渡す際は、そのAPIの条件も満たす必要があります。

厳格なCSPや動的関数生成を制限する実行環境では、AJVのコンパイル方式を確認してください。AJVにはビルド時に検証関数を生成する仕組みがありますが、現在のcreateAjvValidatorは実行時にコンパイルします。利用先のホストで動くことを検証してください。

required・null・default・未知のキー

Section titled “required・null・default・未知のキー”
  • propertiesに書くだけでは必須になりません。必須キーは、そのオブジェクトのrequiredに列挙します。
  • キーの欠落とnullは別です。値としてnullを受け付ける場合は、許可する型へ明示的に含めます。
  • 未知のキーを拒否したいオブジェクトごとにadditionalProperties: falseを指定します。省略時は、通常のJSON Schemaでは追加キーを許可します。合成スキーマを閉じる場合はdialectごとの規則も確認します。
  • defaultは、利用側が明示的に適用しなければ注釈です。既定の検証処理は値を補充しません。generateJSONSchemaDefaultsは別の操作です。
  • 配列にはminItems・maxItems、数値には数値境界、文字列にはminLength・maxLengthを指定します。これらはエンジン全体のペイロード上限とは別です。

一般向けAJVアダプターの現在の既定値はcoerceTypes: false・allErrors: true・strict: falseです。通常は文字列"3"を数値3へ変換しません。ただし、ajvOptionsで型変換・既定値挿入・未知のキー削除を有効にすると、入力が変更される場合があります。フォームの文字列正規化は独立した処理にし、正規化後の値を検証してください。凍結されたAIツール入力には変更を伴う設定を使わないでください。

データを受け入れる前に検証する

Section titled “データを受け入れる前に検証する”
import { createSchema, createAjvValidator } from '@alneas/data-engine/schema';
const schema = createSchema({
$schema: 'https://json-schema.org/draft/2020-12/schema',
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
quantity: { type: 'integer', minimum: 1 },
tags: { type: 'array', items: { type: 'string' }, minItems: 1, maxItems: 5 },
note: { type: ['string', 'null'] },
},
required: ['name', 'quantity', 'tags'],
additionalProperties: false,
});
const validate = createAjvValidator({
draft: '2020-12',
ajvOptions: { coerceTypes: false, useDefaults: false, removeAdditional: false },
});
const result = validate(schema, { name: 'Notebook', quantity: 2, tags: ['office'], note: null });
if (!result.valid) throw new Error(result.errors.join('; '));
// 暗黙変換は行わず、配列の最低要素数も検証するため、両方とも失敗します。
console.assert(!validate(schema, { name: 'Notebook', quantity: '2', tags: ['office'] }).valid);
console.assert(!validate(schema, { name: 'Notebook', quantity: 2, tags: [] }).valid);

不正なスキーマ・未解決参照・未対応dialectはコンパイル時に例外になる場合があります。入力データの不適合を示す{ valid: false }と、設定の誤りを区別してください。信頼したスキーマを初期化時にコンパイルし、同じバリデーターとスキーマオブジェクトを再利用します。コンパイル後のスキーマは変更せず、仕様変更時には新しいオブジェクトを渡します。一般向け検証関数は、攻撃者が任意に指定するスキーマ・正規表現を隔離実行するサンドボックスではありません。ホスト側でスキーマ登録と入力サイズを管理します。

正式なJSON Schema入力検証はAJVで行います。同期APIは両dialectで$asyncスキーマを実行前に拒否します。generateZodSchemaはpropertiesを省略できるobjectルート用のUI変換で、JSON Schema全体の評価器ではありません。

キーワード runtime・生成コードの動作
properties / required root・入れ子の必須キーを検証。propertiesにないキーも対象で、additionalPropertiesも適用。任意は欠落可能という意味でnull許可とは別
null / type配列 null単独・nullable・複数の単純型に対応
enum root・入れ子の双方で他の実装済み制約と合わせて検証。JSON構造の同値で比較。TypeScriptのenum値型はscalarのみ
additionalProperties falseはproperties省略時も追加キー拒否。schema指定は追加値を検証。省略/trueはparse結果でも追加値を保持
minimum / maximum / 正のmultipleOf 0の境界値を含めて検証
minLength / maxLength / pattern 0を含めて検証。JavaScript正規表現・Zodの文字列長の仕様に従う
minItems / maxItems / 単一itemsスキーマ 同種配列の要素と件数を検証
排他的境界・合成・参照・uniqueItems・tuple・contains 未実装。AJVで検証する
format UI用の一部だけ。dateは文字列型のみで暦上の妥当性は検証しない。AJVの全formatと同等ではない
x-zod ここで実装するのは数値coerceだけ。非coerceのAJVとは意図的に異なる

multipleOf: 2に対する{ n: 3 }は両方で失敗します。未対応キーワードがある場合に変換ZodでAJVを置き換えないでください。許可した追加キーは削除せず保持します。coerceを指定した場合の変換結果、Unicode文字列長・formatの判定は業務のfixtureで比較してください。

generateZodSchemaCodeは@alneas/data-engine/schema/compilerのimportと、安全にJSON化したスキーマ、識別子へ変換したexport名を生成し、同じruntime変換器を呼びます。識別子に使えない文字はunderscoreにし、数字始まりにはunderscoreを追加します。生成物にもpackage依存と上記制約があります。引用符・ハイフンキー・空白付きtitle・slashを含むpatternで、生成コードの実行を回帰検証します。

x-ui・x-db・x-plugin・x-codelist・x-rules・x-zodは、標準の検証キーワードではありません。利用するAPIごとに実装範囲が異なります。一般向けAJVのstrict: falseは未知のキーワードを無視できる設定であり、業務上の意味を自動実行する設定ではありません。strictなツール入力検証では、未知の拡張キーワードが拒否される場合があります。DDL・UI用メタデータとAIツール入力のスキーマは分けてください。

DDL生成には、空でないpropertiesを持つ単一テーブルを選んで渡します。$defsだけのbundleは拒否されます。generateSqlFromJSONSchemaはPostgreSQL向けであり、ほかの生成関数はそれぞれ対象・制限が異なります。DBのNULL許可は次の優先順位です。

  1. 主キーは常にNULL不可。
  2. それ以外は明示的なx-db.nullableを優先。
  3. 未指定時は、requiredに含まれない列、またはnullを許可する型をNULL許可にする。

この互換性のためのDB対応付けは、JSON Schemaの「欠落」と「null」の区別とは別です。配列の要素数制限など、すべてのJSON Schema制約がSQL CHECKへ変換されるわけではありません。生成SQLは対象DBで確認し、アプリケーション側の入力検証も維持してください。

x-db.type・x-db.default・x-db.checkはSQL式に関わる値を含められます。スキーマを編集できる主体は信頼する管理者に限定し、リクエストで受け取ったスキーマをそのままSQL実行へつなげないでください。スキーマ検証・識別子の引用・移行SQL生成だけでは、DB認可や安全な移行手順は保証されません。

AIツール・Generative UIの入力境界

Section titled “AIツール・Generative UIの入力境界”

Actionツールの入力スキーマはルートがtype: 'object'で、同期検証できる必要があります。AJVはstrictでunion型を許可し、型変換・既定値挿入・キー削除を無効にしています。defineActionToolではJSDocにある明示的なparser・handler・出力projectionが必要です。同期parserで入力を絞り込み、ホスト側で認可してから副作用を実行します。ツールの説明文は実行権限にはなりません。

Generative UIのコンポーネントdataSchemaは、さらに限定されたinline・同期・draft-07・objectルートのスキーマです。登録するコンポーネント型は最大32個です。実装はコンポーネントスキーマ内のどの位置でも$schema・$id・$ref・$anchor・$dynamicRef・$dynamicAnchor・$recursiveRef・$recursiveAnchor・$asyncを拒否します。一般向けの2020-12スキーマをそのまま渡すことはできません。生成する応答はversion 1、空白だけではない文書ID、最大32個の平坦なblockで構成し、block IDは重複不可です。文書・block IDは最大128文字です。

ツールとGenerative UIのsnapshot境界で許可する値は、plain object・穴のない配列・文字列・真偽値・有限数値・nullです。循環・getter/setter・Symbolキー・非列挙プロパティ・疎配列・クラスインスタンス・undefined・BigInt・関数・NaN・Infinityは拒否します。Date・File・Blob・Bufferを直接渡さず、アプリケーションが許可するJSON表現へ変換してください。

各snapshotは独立に、訪問する値が最大10,000個、深さが最大64(ルートは0)です。JSON文字列化した結果のJavaScriptの.lengthは1,000,000以下である必要があります。これはUTF-16コード単位数であり、UTF-8で1MBという意味ではありません。JSON解析前のHTTP本文・stream上限は別途必要です。検証結果は元データから切り離して再帰的に凍結されるため、返された値を使用し、変更しないでください。

スキーマ自体が持ち運べても、すべてのアダプターがすべてのホストで動くわけではありません。LocalStorageAdapterにはNode互換のファイルシステムが必要です。DB SDK連携には、別途利用側がSDK・接続設定・資格情報を用意します。SQL文字列の生成は接続処理ではありません。ソースファイルの存在だけで公開importパスが保証されるわけでもないため、実際のexportsを確認してください。

S3/R2/OCI uploadはBufferなしでstring・Blob・Uint8Array・ReadableStreamを受け取り、downloadはUint8Arrayを返します。文字列化はTextDecoderを使います。LocalStorageAdapterは@alneas/universal-storage/serverから、ブラウザでは/portableまたはbrowser解決のrootを使います。長期cloud資格情報は信頼するホストに置き、ブラウザへは短期署名URLを渡します。

データ検証だけでは、ユーザー認可・テナント分離・DB制約・法令への適合・AI出力への信頼は成立しません。ホストアプリケーションでこれらを実装し、実際の操作全体を確認します。TSAクライアントには信頼する検証backendが必要です。データモデルのimportや請求書生成だけで、導入環境の法令適合が認証されることはありません。

Zod変換ではroot・nested双方のrequiredを、propertiesに宣言されていないキーにも適用します。additionalProperties:falseなら未宣言キーを追加しても受理せず、同時に要求されるキーが存在できないschemaは不適合となります。追加キーの型付き制約も維持します。enumはroot・nested双方へ他の制約と合わせて適用します。現行TypeScript型のenum値はscalarのみですが、実行時のJSON値比較は構造的等価です。任意のJSON Schema全体との同等性を保証するものではなく、最終判定はAJVで行います。

ContentのJSON/Markdown保存キーは設定した内部indexキーと同一にできません。既定JSON形式ではslug _indexが予約され、独自indexFileなら対応するslugが予約されます。get/save/deleteは衝突を内容の読み書き・index変更前に拒否します。衝突する既存文書はindexを上書きせず、内容を確認して別slugへ移行してください。instance内直列化は複数process間のtransactionを保証しません。

Zod内部が__proto__キーを除外するため、そのキーをproperties/requiredに持つschemaは変換時に例外で拒否します。この種のJSON SchemaにはAJVを使用してください。root enumや追加の必須キー検査でrefinementを持つオブジェクトの拡張はZod 4の.safeExtend()を使用します。通常の宣言済み必須フィールドには不要なrefinementを追加しません。Contentのslug/indexFileは空でない相対segmentとし、空segment・.・..・backslashを禁止します。ストレージごとのパス解釈で内部indexの別名を作らないための制約です。

汎用validatorはdata-engineがAJVを直接使う実装で、スキーマ検証にai-coreの導入は不要です。AIツール用validatorはai-coreが所有し、より厳密な境界制約を維持します。