Skip to content

feat: BFF GraphQL ゲートウェイ導入 + PureScript クライアント移行 + 旧 REST 層削除 - #2

Merged
turtton merged 17 commits into
mainfrom
feat/bff-graphql
Jul 20, 2026
Merged

feat: BFF GraphQL ゲートウェイ導入 + PureScript クライアント移行 + 旧 REST 層削除#2
turtton merged 17 commits into
mainfrom
feat/bff-graphql

Conversation

@turtton

@turtton turtton commented Jul 20, 2026

Copy link
Copy Markdown
Member

概要

フロントエンドと BFF 間のデータ通信を GraphQL に一本化。BFF (index.ts + bff/) に graphql-yoga による /graphql エンドポイントを新設し、PureScript クライアントはスキーマから自動生成した型で型安全にクエリする構成へ移行しました。旧 REST プロキシ・モック REST API・OpenAPI codegen は削除しています。Emumet バックエンド本体には手を付けていません。

主な変更

  • BFF GraphQL 層 (新設 bff/): schema.graphql (SDL、唯一の真実源) / schema.ts / session.ts (SessionAdapter DI、seal/unseal・refresh) / context.ts (認証コンテキスト) / emumet/{client,real,mock}.ts (バッチ契約クライアント + Real REST 実装 + ステートフル Mock) / loaders.ts (DataLoader、リクエスト単位メモ化) / resolvers.ts / server.ts (yoga ハンドラ、WeakMap + onResponse で Set-Cookie)
  • PureScript クライアント: src/App/Api/GraphQL.purs (graphql-client クエリ層 7 関数) + GraphQL/Types.purs (アプリ所有の安定 DTO + Tristate) + src/Generated/ (SDL からの型自動生成、bun scripts/sync-graphql.ts で再生成)
  • Update.purs 移行: アカウント詳細の 3 並列フェッチ → 1 クエリ化。保存後の再フェッチを廃止し mutation 戻り値で即時反映。stale 機構 (RefreshFailed/stale フラグ/staleBanner) を完全削除
  • 認証は変更なし: /auth/* は REST のまま (login/session/logout/OAuth 回帰確認済み)。/graphql は認証済みセッションのみ EmumetClient を注入、未認証は extensions.code: UNAUTHENTICATED
  • 削除: src/App/Api/Emumet//api/* プロキシ、handleMockApiscripts/{fetch-openapi,generate-api,sync-api}.tsopenapi/ (-2653 行)
  • テスト: bun test 51 件 (リゾルバ/Tristate/セッション/DataLoader 契約/Real REST 契約)
  • ドキュメント: README.md / AGENTS.md を GraphQL BFF 構成に更新

検証

  • spago build exit 0 / bun test 51 pass / bunx tsc --noEmit exit 0 / browser・server バンドル exit 0
  • E2E (mock モード) S1–S8 全 PASS: ログイン → 一覧 → 詳細 (GraphQL 1 リクエスト) → プロフィール編集即時反映 → メタデータ CRUD → ログアウト後リダイレクト → SSR 回帰 → /api/* 廃止確認 → 新規アカウント初回プロフィール保存 (upsert POST 経路)
  • Final Verification Wave (plan compliance / code quality / manual QA / scope fidelity) すべて APPROVE

備考

  • graphql は v16 に固定 (v17 の exports map が @urql/core のサブパス import と非互換でブラウザバンドルが壊れるため)
  • 依存: graphql-yoga, @graphql-tools/schema, dataloader (runtime) + purescript-graphql-client (dev)。@graphql-tools/mock 等は意図的に不採用 (ステートフル要件のため手書き Mock)

turtton and others added 17 commits July 20, 2026 15:19
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…ypes

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…lient bundle

graphql v17's exports map appends .mjs to subpaths like graphql/language/visitor.mjs, producing visitor.mjs.mjs which esbuild cannot resolve. @urql/core (transitive dep of purescript-graphql-client) imports these subpaths, breaking the browser bundle. v16 has real .mjs files at the expected paths.

This unblocks spago bundle --platform browser, the dev server, and all frontend development.

- graphql: ^17.0.2 → ^16 (resolves v16.14.2)
- No other dependencies changed
- Generated graphql types (src/Generated/) are identical under v16 introspection
- T8's DIRECTIVE_DEFINITION filter in sync-graphql.ts is a harmless no-op under v16
Format src/App/Api/GraphQL.purs and src/Generated/Schema/Gql/Enum/ModerationType.purs with purs-tidy 0.11.1.

Add a post-generation purs-tidy format-in-place step to sync-graphql.ts
so every regeneration of src/Generated/ produces tidy files.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@turtton
turtton merged commit 65b39c6 into main Jul 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant