https://if-tech.notion.site/177285b35dff806faa95f2d08e32f195
※プロジェクトによって、リードエンジニアが書き換えてください。
- Production 環境: https://template-nextjs-swart.vercel.app/
- Development 環境:https://template-nextjs-git-main-if-app.vercel.app/
- Local 環境: http://localhost:3000
- Nextjs → Vercel
- DB → Supabase Postgres(Prisma)
- Auth → Supabase Auth
- Storage → Supabase Storage
- CI/CD → GitHub Actions
| 項目 | ルール | 例 |
|---|---|---|
| ブランチ名 | <Notion_Task_ID>-<ブランチの内容> | - #1-implement-score-management - #TSK-207-create-avatar-screen - #TSK-208-develop-questionnaire-function |
| commit メッセージ | <種類>: <変更内容> (#<Notion_Task_ID>) | - feat: スコア管理機能を実装 (#TSK-207) - fix: アバター画面のレイアウトを修正 (#TSK-208) - docs: アンケート機能の仕様書を更新 (#TSK-209) |
- 先頭に関連する NotionID を付ける
- Notion Task ID の後にハイフン(-)を入れる
- ブランチの内容を簡潔に表す英語の単語やフレーズを使用する
- 単語間はハイフン(-)で区切る
コミットメッセージは、プロジェクトの変更履歴を理解しやすくするために重要です。以下のルールにしたがってメッセージを記述してください。
| タイプ | 説明 | 例 |
|---|---|---|
feat |
新機能の追加 | feat: ユーザー認証機能を追加 |
fix |
バグの修正 | fix: ログイン時のエラーを修正 |
docs |
ドキュメントの変更 | docs: READMEを更新 |
style |
コードのフォーマット変更(機能に影響なし) | style: コードのインデントを修正 |
refactor |
コードのリファクタリング(機能改善なし) | refactor: 関数名をよりわかりやすく変更 |
perf |
パフォーマンスの改善 | perf: データ取得処理を最適化 |
test |
テストの追加や修正 | test: ユーザー認証機能の単体テストを追加 |
chore |
ビルドプロセスやツールの変更、その他雑多な作業 | chore: 依存パッケージを最新バージョンに更新 |
- 種類(タイプ): 上記のタイプから適切なものを選び、先頭に記述します。
- 変更内容(サマリー): 簡潔に変更点を説明します。
- タスク ID(オプション): 関連するタスクや Issue があれば、括弧内に記載します。
フォーマット:
<タイプ>: <変更内容> (#<タスク ID>)
例:
feat: 新しいダッシュボードを追加 (#TSK-101)fix: プロファイル画像のアップロードバグを修正 (#BUG-202)
- 簡潔に: 50 文字以内で変更点をまとめる。
- 命令形を使用: メッセージは命令形で書く(例:
Add,Fix)。 - 具体的に: 何を、なぜ変更したのかを明確に記述する。
- 関連タスクのリンク: 作業が特定のタスクや Issue に関連する場合は、リンクを追加する。
このルールに従うことで、プロジェクトの履歴が整理され、他の開発者とのコミュニケーションがスムーズになります。
- リポジトリクローン → VS Code で開く
# リポジトリクローン
git clone ~~~
cd ~~~
# リモートリポジトリ追加して、最新ブランチを取得
git remote add upstream https://github.com/if-tech-system/template-nextjs-native.git
git pull upstream main
# VS codeで開く
code .
# Nativeアプリが不要なら削除
rm -r ./native- Bun のインストール
# protoをインストール
curl -fsSL https://moonrepo.dev/install/proto.sh | bash
# .prototoolsファイルにpinされているバージョンのbunをインストール
proto install bun --pin- Vercel CLI のインストール
npm install -g vercel参考:https://vercel.com/docs/cli
初期設定のためのコマンドを実行する。 main ブランチを pull した場合もこれを実行するとリセットできる。
# 一気にセットアップする。
bun run setup
# 👆は以下のコマンドの集約
# 既存のnode_modulesがあれば消す
rimraf node_modules;
# Bunを最新にインストールする
bun upgrade
# .envファイルを作成
cp .env.example .env
# データベース作成&マイグレーション
bun run db:up && bun run db:migrate
# データベースに初期データを入れる
bun run db:seed
※コマンドは、package.json の scripts にて定義
bun dev
ローカル環境:http://localhost:3000
- Vercel へデプロイする際は、CORS_PROD_URL、CORS_PREV_URL を Vercel の環境変数を設定する
# VERCEL_ENV=productionの際に使用する「https://ドメイン」を設定
CORS_PROD_URL=https://production-domain.com
# VERCEL_ENV=previewの際に使用する「https://ドメイン」を設定
CORS_PREV_URL=https://preview-domain.com
# VERCEL_ENV=developmentの際に使用する「https://ドメイン」を設定
CORS_DEV_URL=https://development-domain.com
# ローカル環境の「http://ドメイン:ポート番号」を設定
CORS_LOCAL_URL=http://localhost:3000- src/const/config.ts の以下の項目を必ず設定する
// ログイン済みチェックURLリスト
export function isLoginedCheckUrl(url: string): boolean {
return (
url.startsWith("/my-page") ||
url.startsWith("/users") ||
url.startsWith("/posts")
);
}
// ログイン済みチェックで失敗した際のリダイレクト先
export const LOGINED_CHECK_FAILED_REDIRECT_URL: string = "/";# 開発環境へのデプロイ
bun dev-deploy
# 本番環境へのデプロイ
bun prod-deploy- dev 環境と prod 環境で Supabase プロジェクトを分けて作成する
- Authentication でメール認証や Google 認証を有効にする
- URL と KEY を、dev は
.envファイルにコピペ、prod は Vercel の環境変数に設定する
- Vercel にログイン
- if-tech-customer にてプロジェクト作成
- リポジトリを選択
- 設定
Vercel>Settings>Environment Variablesにて.env をコピーVercel>Settings>Gitにて GitHub 連携Vercel>Settings>Functions>Function Regionにて Tokyo,Japan(Northeast)-hnd1 に設定- ローカルで試しにデプロイ
bun run dev-deploy- 該当プロジェクトの Storage へ移動
- Vercel のプロジェクトページに移動 https://vercel.com/if-tech-customer
- 該当プロジェクト > Storage を選択
- Create Database からデータベース作成
- シンガポールを選択(現状日本リージョンはない) 作成が完了するとプロジェクトの Environment Variables に env ファイルの内容が自動で設定される。
GitHub Actions を利用して CI/CD を行う。
- Type:
bun run typecheck - Lint:
bun run biome:check - Format:
bun run biome:check - Build:
bun run build - 単体テスト:
bun run test
- main ブランチプッシュは dev へデプロイ
- release ブランチプッシュで prod へデプロイ
- 手動デプロイ設定
bun run dev-deploy.vercelディレクトリが作成される。
- 自動デプロイ設定 Project > Settings > Git
- GitHub 連携を行う
- リポジトリを選択
- Production Branch:
releaseに設定する。(事前に作らないとエラーになる)
https://vercel.com/if-app/template-nextjs/settings/git
もしくは、GitHub Actions から自動デプロイ設定を行う。 GitHub > リポジトリ > Settings > Actions secrets and variables にて Vercel トークンの設定する。
- ORG_ID:
team_X0xeBgqRASts3wkAxQQAhTJe(.vercel/project.json参照) - PROJECTID: prj~~~~~~~~~(
.vercel/project.json参照) - VERCEL_TOKEN: https://vercel.com/account/tokensでリポジトリ名-github作成
- web フロント:
/src - api:
/server - db:
/prisma
.github:GitHub Actions の設定.vercel:Vercel の設定.vscode:VS Code の設定/public:静的ファイル/@types:d.ts ファイル、nextjs-routes.d.ts は、ページが増えたり、API を追加した際などに自動で変更が反映されるため、自分の修正で変更が発生する場合は、必ず commit に含めること/prisma:Prisma のスキーマファイルschema.prisma:データベースのテーブルのモデルを定義したスキーマファイル。bun run db:migrateでデータベースのマイグレーションbun run db:generateで Prisma の型ファイルを生成seed.ts:データベースの初期データを投入するためのコードをまとめたファイル。bun run db:seedで実行
/lib:ライブラリ:初期化・設定して export して利用できるようにする。/supabase: Supabase のフロント、サーバークライアント設定/trpc: tRPC の Web、Native、サーバークライアント設定
/util:便利な変数、関数env.ts:環境変数index.ts:便利な関数
/src:Web アプリのソースコード/app: Nextjs App Router のディレクトリ/api:API 関連:trpc を使うので、基本使わない。trpc/[trpc].ts:trpc のエンドポイント
page.tsx:ページ(サーバーコンポーネントのみ)layout.tsx:レイアウト*/_components:ページのみ使うコンポーネント(クライアントコンポーネントあり)- trpc のコードを使うことでがシンプルになるため、集約したほうが見やすい。
- そのため、無理に hooks に分けなくて良い。
*/hooks:ページのみ使うカスタムフック(ロジックがでかい場合分離する)
/components:複数ページで使うコンポーネント/const:定数。アッパースネークケースで定義config.ts:設定key.ts:cookie や localStorage のキー
/hooks:複数ページで使うカスタムフック/test:テストコードを集約
/types:フロント、バックエンドの型定義/schemas:フロント、バックエンドのバリデーションスキーマの定義/server:API サーバー/router:trpc のルーティング設定/[ドメインオブジェクト名].ts:2 階層目でルーティング設定- 2 階層以上細かく分けられるので、
- あまりファットコントローラー気にせずに、ここにロジックを入れて良い。
- ロジックが複雑な場合は、service 層に分ける
/repository:データベース操作オブジェクト[table名].ts:テーブルごとにリポジトリを作成
/middleware:tRPC のミドルウェアauth.ts:認証・認可ミドルウェア
- VS Code: エディタ
- Bun: ランタイム・プロジェクト管理・テストツール
- TypeScript: 型付け
- React: フロントエンドライブラリ
- Next.js: React フレームワーク
- trpc: API クライアント・サーバー
- Prisma: ORM
- PostgreSQL: データベース
- Vercel: ホスティング
- GitHub Actions: CI/CD
- Docker: コンテナ
- Biome: フォーマット・Lint
- Zod: バリデーション
- simple-git-hooks: git フック。Commit Push 時に Lint・Format・テスト実行
- nextjs-routes: Next.js のルーティング型安全
- trpc&React Query:API クライアント
- Supabase Auth: 認証
- react-hook-form: フォーム
- mantine: UI ライブラリ
- dayjs: 日時操作
- dotenv: 環境変数
プロジェクト内での型定義とスキーマ定義に関する統一ルールを以下に示します。これにより、フロントエンドとバックエンド間での一貫性を保ち、メンテナンス性を向上させます。
-
ディレクトリ構成
- 型定義は
/typesディレクトリ内に配置します。 - ドメインごとにサブディレクトリを作成し、関連する型を整理します。
- index.ts に集約し、~types で呼び出せるように設定してください。
- 型定義は
-
命名規則
- 型名は
PascalCaseを使用します。 - 意味のある具体的な名前を付け、
User,Product,Orderなどとします。
- 型名は
-
API から取得するデータの型
- API から取得するデータの型については、基本的に Repository のメソッドの戻り値の型を設定して、フロントエンドでも利用してください。 【サンプル】
export type FindEngagedSubcontractorsReturnType = Awaited< ReturnType<typeof userRepository.findEngagedSubcontractors> >; export const userRepository = { async findEngagedSubcontractors(projectId: string) { try { return await prisma.user.findFirst({ where: { role: "SUBCONTRACTOR", subcontractorEntries: { some: { projectId: projectId, status: "ACCEPTED", }, }, }, }); } catch (error) { console.error( `プロジェクトID ${projectId} の担当下請け業者取得中にエラーが発生しました:`, error ); throw new Error("担当下請け業者の取得に失敗しました"); } }, };
使用ライブラリ
-
バリデーションスキーマは
Zodを使用します。 -
ディレクトリ構成
- スキーマ定義は
/schemasに配置し、フロントエンドとバックエンドで共有します。
- スキーマ定義は
-
命名規則
- スキーマ名は
<Entity>Schemaとし、たとえばUserSchema,ProductSchemaとします。
- スキーマ名は
-
型の推論
Zodのinferを使用して TypeScript 型を生成し、型とスキーマの整合性を保ちます。
-
共有
- フロントエンドではフォームバリデーションに、バックエンドでは API リクエストのバリデーションに同一スキーマを使用します。
-
拡張性
- 必要に応じて、スキーマにカスタムバリデーションやトランスフォーメーションを追加します。
- 一貫性の維持
- 型定義とスキーマ定義は常に最新の状態に保ち、変更があった際はフロントエンドとバックエンド双方に反映させます。
- コミット前の確認
- 型やスキーマを変更する際は、関連する部分が正しく動作するか必ずテストを実施してください。
- ドキュメントの更新
- 新しい型やスキーマを追加した際は、README や関連ドキュメントも更新し、チーム全体で共有します。
- Code Spell Checker: スペルチェック
- Biome: フォーマット・Lint
- Todo Tree: TODO コメントを表示
// TODO: explainで表示 - GitLens: Git の情報表示
- DotENV: .env ファイルのシンタックスハイライト
- prisma: prisma.schema のシンタックスハイライト
- Auto Rename Tag: 閉じタグを変更すると開始タグも変更される
- Docker: Dockerfile のシンタックスハイライトと補完。Docker パネル追加。
- GitHub Copilot: AI コード補完
- GitHub Actions: GitHub Actions のシンタックスハイライト
- Change Case: キャメルケース、スネークケース、パスカルケースなどの変換
Cmd + Shift + PでコマンドパレットからChange Caseと打って変換 - color-highlight: カラーコードをプレビュー
-
自由なカスタマイズの許容
使用していく中で、開発チームや個々のプロジェクトの状況に合わせて、独自にルールをカスタマイズして構いません。ただし、カスタマイズ内容はできるだけチーム全体で共有し、一貫性のある運用を心がけましょう。 -
改善提案の共有
使っていくうちに「もっとこうしたほうがいい」といった提案や改善点が出てきた場合は、積極的に共有してください。提案はルールのアップデートに反映し、プロジェクト全体の品質向上を目指します。 -
参考サイト
Project Rules に関する参考情報として、以下のサイトもご参照ください。
- API 設定:
/server/router.tsにルーターとリクエスト/レスポンスの型を設定する。 - クライアント設定:
/lib/trpcにてクライアント設定
- クライアントコンポーネントから叩く場合には
clientApiを使う。 - Native アプリから叩く場合には
nativeApiを使う。 - サーバーコンポーネントから叩く場合には
serverApiを使う。- ※認証が必要なメソッドは getIsLoggedIn を使って認証を確認しないとページごとレンダリングエラーになる
サーバーサイドで認証するため、Supabase 認証サービスで認証し、SessionCookie を使ってサーバー側で認証する。
- Supabase 認証サービスにて認証してサーバーへ送信
/src/hooks/supabaseAuth.ts signin() - サーバーミドルウェアにて検証後、SessionCookie を発行
/src/middleware.ts - クライアントを使って API を叩くときはセッション Cookie を使ってサーバー認証
/server/middleware/supabaseAuth.ts - Supabase ログアウト時にページリロードしてセッション Cookie を更新(削除)
/src/hooks/supabaseAuth.ts signout()→/src/middleware.ts
- Supabase 認証サービスにて新規登録
- Supabase 認証サービスの sessionCookie でサーバーサイド認証
- Supabase 認証サービスの accessToken をデコードして、sub を取得し、userId としてユーザー情報を登録
- Supabase 認証サービスにて新規登録
- Supabase 認証サービスの sessionCookie でサーバーサイド認証
- リダイレクト(/new-user)でセッションからユーザー情報を取得し、DB にユーザーを登録 ※このタイミング DB の USER の ID に supabase の userID を登録する
- Supabase 認証サービスにて手動で新規登録(auto confirm を使用)
- DB に接続し、User テーブルに登録した email アドレスと id と任意の名前と権限を登録する(そのほかアプリにおいて管理者に必要な情報があれば、追加する)
- id については、supabase の user 情報で確認(id)を活用する ※middleware で取得する userId が supabase の userId のため、DB にも supabase の userId を設定しておく ※ローカル環境については、seed データで投入されるように設定されているため修正する
| 権限 | id | password | |
|---|---|---|---|
| 管理者 | "9bf5aed7-ad62-4ce4-96fd-208b639fcd0f" | [email protected] | admintest |
| コンテンツ管理者 | "73787a60-d2f0-407b-8f10-f5e5e4887ff0" | [email protected] | contentstest |
- クライアントがサーバーにリクエストを送信(SessionCookie を含む)
- サーバーは SessionCookie を使って認証
- SessionCookie からユーザー情報を取得して認可
| tRPC の Procedure | 認証 | 説明 |
|---|---|---|
| publicProcedure | No | 認証不要 |
| userProcedure | Yes | 自分自身の認可 |
| adminProcedure | Yes | 管理ユーザーの認可 |
prisma を使用しているため、DB への日時の保存が UTC となるため、基本的に UTC での登録を行う。 また、正確の日時の反映のため、JST への変換処理は、フロントエンドで行う
このプロジェクトではレスポンシブデザインを実現するために、Mantine UI が提供するデフォルトのブレークポイントを採用する。
SP に適したスタイルは、xs ブレークポイント(576px)を基準に設定する。
仕様に関する質問については、該当する Issue のコメント、または、Notion のタスクに記載し、Slack にも連絡するようにする。 slack のメンションについては、質問をしたい人につける。
デザインについて、質問がある場合、Figma にコメントを残した上で、Slack にて、質問を記載する slack のメンションについては、質問をしたい人につける。