コンテンツにスキップ

Storefront 実装ガイド(移行完了)(目次)

このセクションでは、Storefront の実装方針、GraphQL連携、UI/UX要件の反映方法をまとめます。

Storefront 正本は apps/storefront (Vite / ritsubi-storefront) へ移行済みです。 旧 storefront 実装は 2026-05 に削除済みです。

バックエンド連携の設計は /docs/02-design/、インフラ展開は /docs/03-implementation/infrastructure/ を参照してください。

切替完了(2026-05)

  • Storefront 正本は apps/storefront (Vite / ritsubi-storefront) へ移行済み。
  • 旧 storefront 実装は 2026-05 に削除済み。
  • 切替に伴い以下を一括実施した。
  • apps/storefront-vite (Vite) → apps/storefront
  • Nx project / package 名の ritsubi-storefront を Vite 側へ移譲

仮ID初回ログイン(顧客向け)

  • 画面: /auth/temporary-login
  • 仮IDと仮パスワードを入力
  • 仮IDに @ritsubi-platform.com を付与して通常ログインを流用
  • 初回設定: /auth/temporary-setup
  • 正式メールアドレスの設定とパスワード変更を行う
  • 管理者向けの特別フローは設けない

チェックアウト実装(2026-03 追加)

  • /checkout は route loader 側でチャネルの checkoutNoticeHtml を取得し、
    注文内容確認画面上部に表示します。
  • 配送希望日は ShippingMethod の deliveryDateLeadDays / deliveryDateSelectionStartOffsetDays / deliveryDateSelectionEndOffsetDays に、 都道府県別 leadDaysOffsetdefaultCutoffTime 超過判定 (+1 日) を合算した effectiveLeadDays を基準に候補日を生成し、default チャネルの 営業日カレンダー(休業曜日・祝日除外・個別休業日)で除外を行います。
  • 配送希望日の未保存時初期値は「最短日出荷」です。これは日付指定ではないため deliveryDate を保存せず、specialInstructions最短日出荷 を付与して後続連携へ渡します。 日付候補を選択した場合だけ deliveryDate を保存します。
  • 配送希望時間帯の未保存時初期値は「指定なし」です。配送方法側の deliveryTimeSlots に「指定なし」が含まれない場合も、Storefront では先頭候補として補完します。
  • defaultCutoffTime は SMILE Export Settings (smile.exportSettings) を正本とし、未保存時は共有定数 DEFAULT_CUTOFF_TIME ("14:00") にフォールバックします。SMILE 設定保存有無で配送日 selector が消えないようにするためです。
  • 営業日カレンダーが設定されている場合、checkout の配送セクションで定休日・祝日除外・個別休業日を顧客向けに表示します。
  • ご要望事項は Channel 設定の定型文候補と自由入力補足を組み合わせ、specialInstructions として Order.customFields に保存されます。再開時の下書き注文でも保存済み内容を復元します。
  • 注文確定直前に保存処理を行い、保存結果を確認してから支払い情報へ進みます。
  • ヘッダーでは customer.customFields.customerCode(お客様番号)を常時表示し、
    顧客識別を補助します。

認証導線(現行)

  • ログイン: /auth/login
  • 仮 ID ログイン: /auth/temporary-login
  • 初回設定: /auth/temporary-setup
  • パスワード再設定要求: /auth/password-reset
  • パスワード再設定実施: /auth/reset-password?token=<email_reset_token>
  • ログアウト: /auth/logout
  • パスワード変更(ログイン後): /account/password

パスワード再設定の受け入れ確認

  • /auth/password-reset はメールアドレスを受け付け、送信成功時に「送信完了画面」を表示する。
  • 受信メールのリンク先は /auth/reset-password?token=<token> であること。
  • /auth/reset-passwordtoken が有効な場合のみフォームを表示し、無効・欠落時は「無効なリンク」エラーを表示する。
  • フォーム送信成功後はログイン済み状態へ遷移し、一般導線(通常は /account)へ戻る。

ガード構成(実装準拠)

  • ルート認証ガード: apps/storefront/src/runtime/auth-guard.ts
  • apps/storefront/src/router.tsxbeforeLoad から適用する
  • 未認証時は /auth/login?redirect=... へリダイレクト
  • STOREFRONT_AUTH_BYPASS は開発用にのみガードをスキップ
  • メンテナンス導線: apps/storefront/src/routes/maintenance.tsx / apps/storefront/src/lib/maintenance-route.ts
  • /maintenance 画面と bypass query/cookie の扱いをここで正本化する
  • maintenance 状態の保管先は Cloudflare KV を正本とする
  • クライアント側ガード: apps/storefront/src/components/auth/auth-gate.tsx
  • server guard の補助として、サーバー判定待ちや一部例外経路の UX を支える
  • 画面側での個別リダイレクト分岐は原則追加しない

Storefront lane / provider 方針(2026-05 追加)

  • Storefront は会員制 catalog を正本とするため、公開 Web 向けの静的最適化だけでなく、認証済み route の request-time cost を抑える設計を採用する。
  • route は storefront lane / app lane / content lane に分けて扱う。
  • storefront lane: /products、商品詳細、カート、チェックアウト
  • app lane: /account/*/quick-order
  • content lane: 記事、お知らせ、サポート、signed token 付きの商品プレビュー
  • provider は root に集約し続けず、lane ごとに必要なものだけへ再配置する。
  • 記事・お知らせ・サポートでも B2B chrome の顧客バーを維持し、desktop の匿名右上カート fallback は置かない。
  • content lane の商品プレビューでは通常の商品詳細構成を保つが、購入 CTA は ConsentProvider 非依存の disabled 表示にし、購入・同意確認・閲覧履歴記録などの副作用を発生させない。
  • 詳細な方針と移行順は Storefront lane / provider 再設計方針 を参照する。

監査向け確認ポイント

  • 未ログインで /account へアクセスした際、/auth/login?redirect=%2Faccount へ遷移すること。
  • ログイン後は AuthGate 内を通じて保護ページが表示され、/auth/logout 遷移時に session/vendure-session が初期化されること。
  • /auth/reset-password で無効トークンを開いた時に、再設定フォームではなく案内エラーが表示されること。

ルーティングとスクロール復元

  • Storefront のスクロール復元は apps/storefront/src/router.tsx の TanStack Router scrollRestoration を正本とする。
  • RootLayout やページコンポーネントで route resolved / deferred data 後着に反応して window.scrollTo(0, 0) を直接呼ばない。
  • 画面遷移時のアクセシビリティ通知は main#main-content への focus({ preventScroll: true }) に限定し、スクロール位置の決定は router に任せる。
  • /products のように Suspense / deferred data / site shell 後着がある route では、同一 pathname + search の再解決でスクロール位置が変わらないことを E2E で固定する。