zenstack-migrate-from-v2 について
ZenStack プロジェクトを V2 から V3 に移行する開発者向けのスキルです。パッケージ、スキーマ、アクセス制御、アダプター、クエリフックの変更を扱います。
主な機能
- 01パッケージと CLI コマンドの変更
- 02アクセス制御プラグインの設定
- 03ポリシー構文の移行
- 04抽象モデルの変換
- 05サーバーアダプターの更新
- 06TanStack Query フックの移行
活用シーン
- 01ZenStack V2 から V3 への移行計画
- 02ポリシーとクライアント初期化の更新
- 03V3 向けサーバーハンドラーの調整
- 04旧クエリフックの置き換え
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ zenstackhq/ skills --skill zenstack-migrate-from-v2インストール後、Claude Code で/zenstack-migrate-from-v2を入力して読み込まれたか確認します。
詳細
ZenStack V2 から V3 への移行
ZenStack V3 は大幅に書き換えられています。Prisma ORM エンジンは、Kysely を基盤とする ZenStack 独自のエンジンに置き換わりました。一方、ZModel スキーマはおおむね互換性を保ち、クエリ API は PrismaClient と互換性があります。対応データベース:PostgreSQL、MySQL、SQLite。
V2 は Prisma ベースだったため、移行は 2 段階になります。まず Prisma から ZenStack への一般的な変更を行い、次に以下の V2 固有の変更を適用します。一般的なセットアップや CLI については、zenstack-project-setup を参照してください。
ステップ 1 — まず Prisma の移行を行う
V2 は Prisma 上で動作していたため、まず zenstack-migrate-from-prisma スキルを使います(依存関係を入れ替え、スキーマを zenstack/schema.zmodel に移動し、クライアントを ZenStackClient に置き換え、generate/migrate スクリプトを更新します)。その後、以下の V2 固有の手順を適用してください。
ステップ 2 — ZenStack パッケージの名前を変更する
npm uninstall zenstack @zenstackhq/runtime
npm install @zenstackhq/schema @zenstackhq/orm
npm install --save-dev @zenstackhq/cli
| V2 | V3 |
|---|---|
zenstack(CLI) | @zenstackhq/cli |
@zenstackhq/runtime | @zenstackhq/orm |
| — | @zenstackhq/schema(新規) |
CLI コマンドは zenstack <cmd> から zen <cmd> に変わります(例:zen generate)。
ステップ 3 — アクセス制御がプラグインに変更
V2 では、アクセス制御はランタイムに組み込まれていました(enhance(prisma))。V3 では、オプトイン形式のプラグインになっています。
- インストールします:
npm install @zenstackhq/plugin-policy - スキーマで宣言します:
plugin policy { provider = '@zenstackhq/plugin-policy' } - クライアントをラップし、リクエストごとにユーザーをバインドします:
import { ZenStackClient } from '@zenstackhq/orm'; import { PolicyPlugin } from '@zenstackhq/plugin-policy'; export const db = new ZenStackClient(schema, { dialect }); export const authDb = db.$use(new PolicyPlugin()); // was: enhance(prisma, { user }) // per request: const userDb = authDb.$setAuth(user); // was: passing { user } to enhance()
ポリシー/ランタイムモデルの詳細については、zenstack-access-control を参照してください。
ステップ 4 — 更新後ポリシー:future() から post-update + before() へ
V2 では、update ルール内で future() を使って更新後の条件を表していました。V3 では専用の post-update 操作を使います。この操作では、フィールドをそのまま参照すると新しい値を表し、before() で古い値を読み取ります。
// V2
@@deny('update', future().ownerId != ownerId)
// V3
@@deny('post-update', ownerId != before().ownerId)
ステップ 5 — 抽象モデルから type + mixin へ
V2 の abstract model + extends は、with で適用する type に変わります(zenstack-schema-modeling を参照)。
// V2
abstract model Timestamped {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Post extends Timestamped { title String }
// V3
type Timestamped {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Post with Timestamped { title String }
(注:V3 にも extends はありますが、これは @@delegate によるポリモーフィズム用で、別の機能です。単純な mixin の代替として使わないでください。)
ステップ 6 — サーバーアダプター
V3 では、明示的な apiHandler(RPCApiHandler または RestApiHandler)を渡す必要があります。また、クライアントを提供するコールバックは getPrisma から getClient に名前が変わっています。
// V2
ZenStackMiddleware({ getPrisma: (req) => enhance(prisma, { user: getUser(req) }) });
// V3
ZenStackMiddleware({
apiHandler: new RPCApiHandler({ schema }),
getClient: (req) => authDb.$setAuth(getUser(req)),
});
すべてのフレームワークと両方の API スタイルについては、zenstack-crud-server を参照してください。
ステップ 7 — クライアント側フック(TanStack Query)
フラットなフック名は、ORM を反映したクライアントの下にまとめられたフックに置き換わります。
// V2
import { useFindManyUser } from '~/hooks';
const { data } = useFindManyUser({ where: { ... } });
// V3
import { useClientQueries } from '@zenstackhq/tanstack-query/react';
import { schema } from '~/zenstack/schema';
const client = useClientQueries(schema);
const { data } = client.user.useFindMany({ where: { ... } });
V3 ではSWR のサポートが終了しました。TanStack Query のセットアップ全般については、zenstack-crud-server を参照してください。
ステップ 8 — その他のプラグイン/ユーティリティの移行
- Zod:プラグインではなくユーティリティになりました(zod ユーティリティのドキュメントを参照)。
- OpenAPI:自動 CRUD API ハンドラーに統合されました。
apiHandler.generateSpec()で仕様を生成します(zenstack-crud-serverを参照)。 - カスタムプラグイン:V3 のプラグインシステムは改訂されています。最新のプラグインドキュメントを参照してください。
アップグレード後
zen generate を実行し、型チェックを行い、テストスイート/アプリを動かして確認してください。V2 の暗黙的な enhance() ではなく、明示的な $use(new PolicyPlugin()) + $setAuth() のフローになったことで、アクセス制御が想定どおりに動作することを確認してください。
参考ドキュメント
このトピックに関する ZenStack のドキュメント一式は、references/ に含まれています。
- migrate-v2.md — 公式の「ZenStack v2 からの移行」ガイド