@event/session-card を配線する。engine は元実装と挙動差分ゼロを実証済み。
1. 依存と機能
package.json に "@event/session-card": "*"、next.config.ts の transpilePackages に追加。 event.config.ts で sessionCard: true(cms が自動で要求される)。
2. 保存アクション(overlay 永続化)
src/app/admin/card/_actions.ts:
"use server";
import { cookies } from "next/headers";
import { createContentOverlayStore, type CardOverlay } from "@event/session-card/persist";
import { adminAuth } from "@/lib/adminAuth";
import { store } from "@/lib/cms";
const overlayStore = createContentOverlayStore({ store }); // content/sessions.json に single-record PATCH
export async function saveCardOverlayAction(sessionId: string, overlay: CardOverlay) {
const c = (await cookies()).get(adminAuth.cookieName)?.value;
if (!adminAuth.isAuthedFromValue(c)) return { ok: false, error: "unauthorized" };
const r = await overlayStore.patch(sessionId, overlay);
return r.ok ? { ok: true } : { ok: false, error: r.error };
}
3. ページ
src/app/admin/card/page.tsx—listSessionsFromEventの公開セッション一覧、各行 →/admin/card/[id]src/app/admin/card/[id]/page.tsx—resolveCardModel(session, speakers)で CardModel を作り<CardStudio>へsrc/app/admin/card/[id]/CardStudio.tsx("use client")—<SessionCardDesigner model onChange onSave>。
onSave で CardModel → CardOverlay に写像して saveCardOverlayAction を呼ぶ
(starter に完成形があるので apps/starter/src/app/admin/card/** をコピーして app 名を直すのが最短。 route gate は if (!features.isEnabled("sessionCard")) notFound(); を各ページ冒頭に。)
4. 確認
/admin/card にセッション一覧、行クリックで Designer。 並び替え・タイトル改行上書き・scale スライダーを動かして「保存」→ content/sessions.json に overlay が入る。 Designer の auto-prefill(隠し auto カードの onResolved で実際の改行位置を textarea に初期表示)が効いていること。
テーマ差し替え
SessionCard / SessionCardDesigner に themes={{ mytheme: { name, vars: { "--card-bg": ..., "--card-accent": ... } } }} を渡し、CardModel.theme をそのキーにする。DEFAULT_THEME(中立ダーク)が既定。