NestJS + Prisma + GraphQL(code-first)+ React + Apollo Client を使って実装した シンプルな Todo アプリケーションです。
バックエンド〜フロントエンドまでを一貫して TypeScript で実装し、GraphQL Code Generator による型安全な開発を目的としています。
このプロジェクトは、以下を目的とした Todo アプリです。
- NestJS + Prisma + GraphQL を使った API 設計/実装 の確認
- React + Apollo Client + GraphQL Code Generator を使った 型安全なフロント実装 の確認
- 小さめのモノレポ構成(backend / frontend / docs)の設計と、フェーズ分割による開発プロセスの練習
仕様の詳細は docs/requirements.md、設計の詳細は docs/architecture.md にまとめています。
2025-12-05.22.14.01.mov
- Node.js: 22.17.1 (LTS)
- TypeScript: 5.9.3
- Framework: NestJS 11
- GraphQL:
@nestjs/graphql@nestjs/apollo@apollo/server(Apollo Server)graphql16.12.0
- ORM: Prisma 6.19.0
- DB: SQLite(開発用)
- その他:
@as-integrations/express5(Apollo Server × Express 5 連携)
- React: 19.2.0
- Vite: 7.2.4
- TypeScript: 5.9.3
- GraphQL クライアント: Apollo Client 3 系
- GraphQL Code Generator:
@graphql-codegen/clitypescripttypescript-operationstypescript-react-apollo
Todo は以下の情報を持ちます。
id: 一意な IDtitle: タイトル(必須)description: 詳細(任意)completed: 完了フラグ(デフォルト: false)category: カテゴリ(INBOX/WORK/STUDY/PRIVATE/OTHER)priority: 優先度(HIGH/MEDIUM/LOW)createdAt: 作成日時updatedAt: 更新日時
GraphQL API(code-first)で以下を提供しています。
Querytodos: Todo 一覧取得todo(id: Int!): 単一 Todo 取得
MutationcreateTodo(input: CreateTodoInput!): Todo!updateTodo(input: UpdateTodoInput!): Todo!deleteTodo(id: Int!): Boolean!
Todo 一覧ページ (TodoPage)
- Todo 一覧表示
- ローディング中表示 / エラー表示 / 0件時メッセージ
- 最終更新日時(
updatedAt)の表示
Todo 新規作成フォーム (TodoForm)
- 入力項目:
- タイトル(必須)
- 詳細(任意)
- カテゴリ(セレクトボックス)
- 優先度(セレクトボックス)
- 送信時:
- GraphQL
CreateTodoを実行 - 成功後にフォームリセット
- 親コンポーネントの
refetch()を呼び出し一覧更新
- GraphQL
Todo 一覧コンポーネント (TodoList) / 1件表示 (TodoItem)
- 完了 / 未完了の切り替え
- タイトル / カテゴリ / 優先度のインライン編集
- 削除(confirm ダイアログ付き)
- 優先度バッジの表示(HIGH / MEDIUM / LOW)
- レイアウト崩れを防ぐための簡単なスタイル調整
カテゴリフィルタ(フロント側のフィルタ)
- 作成フォームの下部にカテゴリセレクトボックス(例: 「すべて / INBOX / WORK / STUDY / PRIVATE / OTHER」)
- 選択されたカテゴリに応じて、フロント側で一覧を絞り込み表示
null(「すべて」)のときは全件表示
検索フィルタ(フロント側のフィルタ)
- 作成フォームの下部にタスクの名前・詳細欄を参照して部分一致でフィルタをかける検索ボックス
詳細は docs/architecture.md を参照してください。ここでは要点のみまとめます。
- モノレポ構成
- 1つのリポジトリに
backend/・frontend/・docs/を配置
- 1つのリポジトリに
- バックエンド
- NestJS モジュール構成
AppModule(ルート)PrismaModule(PrismaServiceを提供)TodoModule(Resolver / Service / DTO / モデルを集約)
- code-first GraphQL:
@ObjectType,@Fieldで GraphQL の型定義を記述@InputTypeで入力用 DTO を定義
- NestJS モジュール構成
- フロントエンド
- Vite + React + Apollo Client
- GraphQL Code Generator で
useGetTodosQueryなどの Hooks を自動生成 - フロント側状態とサーバ状態をシンプルに分離
.
├── backend
│ ├── eslint.config.mjs
│ ├── nest-cli.json
│ ├── package-lock.json
│ ├── package.json
│ ├── prisma
│ │ ├── dev.db
│ │ ├── prisma.module.ts
│ │ ├── prisma.service.ts
│ │ └── schema.prisma
│ ├── prisma.config.ts
│ ├── README.md
│ ├── src
│ │ ├── app.controller.spec.ts
│ │ ├── app.controller.ts
│ │ ├── app.module.ts
│ │ ├── app.service.ts
│ │ ├── main.ts
│ │ ├── schema.gql
│ │ └── todo
│ │ ├── dto
│ │ │ ├── create-todo.input.ts
│ │ │ └── update-todo.input.ts
│ │ ├── models
│ │ │ └── todo.model.ts
│ │ ├── todo.module.ts
│ │ ├── todo.resolver.ts
│ │ └── todo.service.ts
│ ├── test
│ │ ├── app.e2e-spec.ts
│ │ └── jest-e2e.json
│ ├── tsconfig.build.json
│ └── tsconfig.json
├── docs
│ ├── architecture.md
│ └── requirements.md
├── frontend
│ ├── codegen.yml
│ ├── eslint.config.js
│ ├── index.html
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ └── vite.svg
│ ├── README.md
│ ├── src
│ │ ├── apollo
│ │ │ └── client.ts
│ │ ├── App.css
│ │ ├── App.tsx
│ │ ├── features
│ │ │ └── todos
│ │ │ ├── components
│ │ │ ├── constants
│ │ │ ├── pages
│ │ │ └── types.ts
│ │ ├── generated
│ │ │ └── graphql.tsx
│ │ ├── graphql
│ │ │ └── todos.graphql
│ │ ├── index.css
│ │ └── main.tsx
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ └── vite.config.ts
├── package-lock.json
├── package.json
└── README.md- Node.js 22.x(LTS)
- npm または pnpm / yarn
git clone git@github.com:AKARI-intern/intern-hw-saas-sw-dib-Jo042.git
cd intern-hw-saas-sw-dib-Jo042
cd backend
# パッケージインストール
npm install
# .env作成(SQLite の例)
cp .env.sample .env
# .env 内の DATABASE_URL を確認・調整
# 例: DATABASE_URL="file:./dev.db"
# Prisma マイグレーション(DB作成)
npx prisma migrate dev
# 開発サーバ起動
npm run start:dev
- 起動後、
http://localhost:3000/graphqlにアクセスすると GraphQL Playground が開きます。 todos/createTodoなどのクエリ・ミューテーションを試せます。
cd frontend
# パッケージインストール
npm install
# GraphQL Code Generator(必要に応じて)
npm run codegen
# 開発サーバ起動
npm run dev
- 起動後、
http://localhost:5173にアクセスすると Todo アプリが表示されます。 - バックエンドの GraphQL エンドポイント URL は
src/apollo/client.tsで設定しています。
- バックエンド を
npm run start:devで起動 - フロントエンド を
npm run devで起動 - ブラウザで
http://localhost:5173を開く
画面上でできること:
- 「新しい Todo を追加」フォームから
- タイトル
- カテゴリ
- 優先度
- 詳細
を入力して追加
- 追加済み Todo のカードで
- チェックボックス → 完了 / 未完了切り替え
- タイトル / カテゴリ / 優先度 → インライン編集
- 削除ボタン → Todo 削除
- 画面上部のカテゴリフィルタから
- 「すべて / INBOX / WORK / STUDY / PRIVATE / OTHER」を選択して表示を絞り込み
このプロジェクトでは、バックエンドで Prisma + SQLite を使用しています。
開発中に DB の中身を確認したい場合は、以下のいずれかの方法を利用できます。
ブラウザで DB の中身を確認できる公式ツールです。
実行手順:
cd backend
npx prisma studio
実行すると自動でブラウザが開き、
http://localhost:5555 から Todo テーブルを確認できます。
※ 開発中にレコードを閲覧・編集したい場合は、基本的に Prisma Studio を推奨します。
開発は以下のフェーズに分けて進めました(詳細は docs/requirements.md 参照)。
- Phase 0:要件定義・設計・docs 作成
- Phase 1:バックエンド土台(NestJS + GraphQL セットアップ)
- Phase 2:Prisma 導入 + Todo モデル + GraphQL CRUD
- Phase 3:フロントエンド土台(React + Apollo Client)
- Phase 4:GraphQL Codegen 導入 + フロントから CRUD を通す
- Phase 5:拡張機能(カテゴリフィルタなど)
- Phase 6:リファクタリング・ドキュメント整備
Git ブランチは、フェーズ/機能単位で feature/... ブランチを切り、main にマージする方針で運用しています。
Nice to have として要件に挙げているもののうち、今後対応したいもの:
- 並び替え(作成日時 / 更新日時 の昇順・降順)
- 優先度による色分けの強化 + 優先度フィルタ/ソート
- GraphQL API 側でのフィルタ・ソート引数の追加
- テスト(ユニットテスト / E2E テスト)の追加
(検討中 / 未設定)