with one click
with one click
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | Architecture Rules |
| description | システム間連携の標準パターン、アーキテクチャ要件、およびネットワーク構成のルール |
拡張機能からApp Basecamp側へ巨大なデータ(ページテキスト等)を渡す場合の標準パターンは以下の「ワンタイム・データリレー」方式とする。
sitecue_page_contents テーブルに直接巨大なデータを INSERT し、返却された context_id (UUID) を取得する。context_id を URLパラメータ (例: ?context_id=...) に付与して App Basecampの特定のページを開く。context_id を用いてデータを SELECT した後、直ちにそのレコードを DELETE し、DBに一時データを恒久的なゴミとして残さないようにする。ローカル環境におけるAPI (Wrangler/Hono) と App Basecamp (Next.js) 間の通信トラブルや IPv4/IPv6 のすれ違いを防ぐため、以下のネットワークルールを厳守すること。
localhost の使用は禁止する。必ず 127.0.0.1 を使用すること。8787 で固定する。Wranglerが自動で 8788 等にフォールバックして立ち上がるのを防ぐため、起動時は必ず 127.0.0.1:8787 (またはスマホ実機テスト時は 0.0.0.0:8787) で明示的にバインドさせること。next.config.ts において、通信警告を抑制するための allowedDevOrigins: ["127.0.0.1", "localhost"] を設定する場合は、experimental ブロックの中ではなく、必ずコンフィグのルートレベルに記述すること。localhost フォールバックの回避: 次のフレームワーク(Turbopack等)の内部プロキシ仕様において、request.url が意図せず localhost に書き換わり、Supabase Auth等のコールバックURL不一致エラーを引き起こす。ミドルウェアやAPIルートでのリダイレクト先構築時は、必ずヘッダーの x-forwarded-host または host からURLを構築し、念の為 hostname === "localhost" の場合は強制的に 127.0.0.1 に置換する二重の防御策を敷くこと。クライアント側の location.origin も同様に置換して防御する。middleware.ts がセッションをリフレッシュして最新のクッキーをセットしても、同リクエスト内で末端の Server Component(page.tsx 等)は古いクッキーしか読めず、user=null として独自の redirect("/login") を発火させるケース(仕様)がある。この際、せっかくミドルウェアが構築した ?next= パラメータが消失してログイン後の画面復帰ができなくなるため、Server Component側でログアウト・未認証リダイレクトを投げる際は、必ず searchParams プロパティを受け取って手動で元のフルパスを再構築し、redirect("/login?next=...") に渡すこと。当プロジェクトのNext.jsは、Cloudflare Pagesではなく Cloudflare Workers (Node.js互換) で稼働しています。AIエディタは過去の知識でコードを破壊しないよう、以下の掟を絶対厳守すること。
@opennextjs/cloudflare を使用しています。古い @cloudflare/next-on-pages の使用やインストール提案は 絶対禁止 です。export const runtime = "edge"; を記述してはいけません。OpenNextのNode.js標準動作が破壊されビルドが落ちます。wrangler pages deploy は禁止です。正しくは bun run deploy (裏側は wrangler deploy) です。.env を無視します。プレビュー用の変数は必ず .dev.vars に記述するようユーザーに案内してください(※.dev.vars は絶対にGitコミットしないこと)。NEXT_PUBLIC_)は、必ず wrangler.toml の [vars] セクションと .env.production の両方に記述してください。
next build)に静的ファイルへ変数をインライン化するために .env.production が必要であり、デプロイ後のWorkerランタイム時のために wrangler.toml が必要となるためです。wrangler.toml に書く提案は厳禁です。必ず bun x wrangler secret put <KEY_NAME> を使うよう案内してください。将来的なマーケティング用LP(ランディングページ)とWebアプリケーションのライフサイクルを分離するため、以下のサブドメイン分割構成をベストプラクティスとして維持すること。
app.sitecue.app 等のサブドメインを使用する。api.sitecue.app を使用し、App Basecamp側と明確に分離してCORSを厳格に管理する。sitecue.app は、将来的にSEOや高速表示に特化したLP(または別システム)をデプロイするために予約・隔離しておく。sitecueのApp Basecampは単なるメモ帳ではなく、情報を加工・発信する「活動拠点(Base Camp)」として機能する。今後の実装では以下の掟を絶対遵守すること。
Note と Draft の厳格な分離 (The Separation of Concerns)
sitecue_notes は拡張機能で収集する「素材(Read-Only寄り)」である。sitecue_drafts はApp Basecampで練り上げる「成果物(Read/Write)」である。Template 駆動設計 (Template-Driven UI/Logic)
sitecue_drafts はハードコードされた特定のプラットフォーム(x, zenn等)に依存せず、ユーザー定義の sitecue_templates に紐づく (template_id)。if 分岐するのではなく、紐づくテンプレートのデータ(max_length, boilerplate, weave_prompt 等)を基準としたデータ駆動(Data-Driven)で実装すること。template_id が null の場合は、いかなる制限も受けない「Blank Canvas(自由帳)」として扱うこと。責務の分離 (Routing)
/) に、執筆・錬成アトリエは /studio/ 配下に構築し、それぞれの責務を明確に分離すること。sitecue_notes 等)の読み書きは Hono API を経由せず、supabase-js を用いて直接通信すること(RLSによる保護を活用するため)。apps/api/) に専用エンドポイントを作り、JWT認証を経由してプロキシ(仲介)させること。fetch 等を用いて通信してよい。OAuthログインのBFCache(ブラウザバック)トラップ回避
App BasecampにおけるOAuthログイン(Google, GitHub等)のトリガーボタンに、クライアントサイドのステート(useState による isLoading など)を用いてローディング状態を管理することは絶対禁止とする。
外部ドメインへ遷移した後にユーザーがブラウザバックで戻ってきた際、BFCacheによって「ボタンが無効化された状態」が復元され、永久に操作不能になる致命的なバグを引き起こすため。
認証トリガーは必ずピュアな HTML <form> と Next.js の Server Actions ("use server") を用いて実装し、クライアントJSに依存しない堅牢なリダイレクト処理を構築すること。
認証・セッション境界ページのキャッシュ無効化
/login などの認証を司るページでは、Next.jsの Router Cache によって古い状態(ログイン済みなのにログイン画面が出る等)が引き起こされるのを防ぐため、必ずページコンポーネントの最上部に export const dynamic = "force-dynamic"; を記述し、静的キャッシュを無効化すること。
生成AIやコストのかかる外部APIを呼び出す機能を実装する際は、ランニングコストの流出を防ぐため、必ず以下の「3段構えのガード」をアーキテクチャに組み込むこと。
sitecue_profiles 等のテーブルで、ユーザーの月間利用回数 (usage_count) とリセット日時を厳密に管理する。apps/api/) 側で必ずDBの利用回数とプランの上限を確認し、上限到達時は外部APIを叩かずに即座に 403 Forbidden を返すこと。plan: "free")等を JSON レスポンスに含めて返却すること。apps/app/src/constants/limits.ts に定義された定数をインポートして使用すること。APIの肥大化を防ぎ、関心の分離とテスト容易性を保つため、apps/api/ 内の実装は以下の厳格なレイヤー構造に従うこと。単一の index.ts にロジックを集中させることは技術的負債となるため絶対禁止とする。
index.ts (Entry Point):
app.route()) のマウントのみを担当する「薄い層」に保つこと。routes/ (Routing Layer):
services/ へ委譲すること。services/ (Service / Business Logic Layer):
Context)に直接依存せず、純粋な関数として実装しテスト可能にすること。middlewares/:
types.ts:
Bindings (環境変数) や Variables (ユーザー情報等) を一元管理し、各レイヤーで安全に import して使用する。AIプロンプト構築のバックエンド集約と物理的分離 (Separation of Concerns)
weave_prompt)の動的な取得は、必ずバックエンド(apps/api/ の services/ レイヤー)の責務とする。フロントエンドから生のプロンプトを送信してはならない。services/ のロジック内にプロンプトの長文(英語の指示やルール等)を直接ハードコードしてはならない。プロンプトの組み立て(テンプレートリテラル等)は必ず apps/api/src/prompts/ ディレクトリ配下に純粋な関数として切り出し、ロジックとプロンプトコンテンツを物理的に分離すること。【🚨過去のバグ教訓】API層におけるSupabaseの厳格な型アサーション
apps/api/ 内で Supabase からデータを .single() 等で取得した際、型が推論できず暗黙の any となり、プロジェクトの絶対ルールである「Biomeの any 禁止令」に抵触。結果としてAIエディタが自己解決(Lintエラー修正)の無限ループに陥り、プロセスがフリーズする事故が発生した。const data = rawData as { weave_prompt: string | null };)を行い、暗黙の any を絶対に発生させないこと。UIの挙動やグローバルなイベント監視(スクロール検知、キーボードショートカット、クリック領域外の判定など)において、複数のコンポーネントやページに同様のロジックを散らばらせる「分散型実装」は絶対的なアンチパターンとする。
page.tsx や下層コンポーネントではなく、必ず最上位の AppShell.tsx(またはそれに準ずる Layout コンポーネント)に集約(Centralized)すること。onScroll をアタッチするのではなく、window.addEventListener('scroll', handler, true) (キャプチャリングフェーズ)等を用いて最上位で一括検知する設計を採用すること。モバイル対応などのレスポンシブなUIにおいて、不自然な空白や重なり(透け)を防ぐための原則。
<div className="h-14" /> のような透明なスペーサー要素をDOMに差し込む設計は、レイアウトの不整合を生むため原則禁止とする。absolute を用いて画面上に浮かせるアプローチは直下のコンテンツと自然に連動しないため避ける。通常のブロックレベル要素(Flow配置)として扱うことを基本とする。
-mt-14 等)を用いた要素の押し上げ・隠蔽アプローチは、iOSのスクロール慣性と激しく干渉しレイアウトシフトを引き起こす致命的なアンチパターンであることが判明したため、今後は使用を固く禁ずる。fixed bottom-0 や absolute bottom-4 などの絶対配置は画面サイズ差異による見切れの原因となるため使用禁止とする。必ず親コンテナを flex flex-col とし、コンテンツ領域を flex-1 overflow-y-auto min-w-0、フッター領域を shrink-0 pb-safe としてFlow配置で構成すること。sticky)とスクロールするリストアイテム等が重なる際、背景が透けるバグを防ぐため、コンポーネント単体で z-10 などを設定しない。システム全体の重なり順(Z-index階層)を意識し、固定ヘッダーは z-20 や z-50 など、明確に上位のレイヤーを確保すること。z-index 階層を AppShell のヘッダー (z-20) よりも高く設定(例: z-30)し、inert 属性で背後のインタラクションを完全に遮断すること。ナビゲーションやペインの表示状態において、URLとローカルステートが競合するバグを防ぐための絶対原則。
usePathname または useSearchParams を用いてURLから直接判定すること。ローカルやグローバルな状態(フラグ)を新たに作って制御してはならない。exact=all)を持ったまま新しいアクション(例: 新規作成 new=note)をトリガーする際、URL生成時に元のパラメータを勝手に削らないこと。不要なパラメータのパースやフォールバック処理は、必ず「URLを受け取って処理を実行する側(受信側)」の初期化ロジックで行うこと(多層防御の原則)。