Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
"stylelint.vscode-stylelint",
"prisma.prisma",
"eamodio.gitlens",
"oderwat.indent-rainbow"
"oderwat.indent-rainbow",
"github.copilot",
"github.copilot-chat"
]
}
}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ jobs:
version: 9
- name: Install dependencies
run: pnpm install
- name: Generate Prisma schema
run: npx prisma generate
- name: TypeScript Compile Check
run: pnpm tsc --noEmit
- name: Run ESLint
Expand Down
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@

芝浦工業大学デジクリのサークル内SNS「digichat」

## 環境設定の手順
## ドキュメント

| | |
| ------------------ | -------------------------------------------- |
| 環境構築 | [README.md](README.md) |
| 開発ルール | [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) |
| 認証のセットアップ | [docs/AUTH_SETUP.md](docs/AUTH_SETUP.md) |
| ADR | [docs/ADR.md](docs/ADR.md) |
| Prismaの操作方法 | [prisma/README.md](prisma/README.md) |
| データベース設計 | [prisma/ERD.md](prisma/ERD.md) |

## 環境構築の手順

### .envの用意

Expand All @@ -17,7 +28,7 @@ cp .env.sample .env
画面左下の青いところをクリック。
![](docs/images/readme-1.png)

その後、`コンテナーで開く`を選択。しばらく待つとDevContainerが自動で立ち上がる。
その後、`コンテナーで開く`を選択。しばらく待つとDevContainerが自動で立ち上がる。以降、コマンドはDevContainer内で実行すること。

### 依存関係のインストール

Expand All @@ -34,6 +45,7 @@ pnpm install
```bash
pnpm prisma migrate dev
```

### seedデータの適用

マイグレーションが終わったらseedデータを適用する。
Expand Down
138 changes: 138 additions & 0 deletions docs/ADR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Architecture Decision Record (ADR)

## 目次

- [ADR-010: emoji-mart](#adr-010)
- [ADR-009: tiptap](#adr-009)
- [ADR-008: unified](#adr-008)
- [ADR-007: Jest](#adr-007)
- [ADR-006: ESLint, Prettier, Stylelint](#adr-006)
- [ADR-005: CSS Modules](#adr-005)
- [ADR-004: Mantine](#adr-004)
- [ADR-003: PostgreSQL, Prisma, Auth.js](#adr-003)
- [ADR-002: DevContainer, Docker](#adr-002)
- [ADR-001: Next.js App Router, TypeScript, pnpm](#adr-001)

<h2 id="adr-010">ADR-010: emoji-mart</h2>

### Date

2025-02-23

### Context

emoji-martは、React用の絵文字ピッカーコンポーネントであり、ユーザーが絵文字を簡単に選択できるようにするためのライブラリである。
Mattermostがemoji-martを採用しているため、同じライブラリを選定した。

<h2 id="adr-009">ADR-009: tiptap</h2>

### Date

2025-02-23

### Context

tiptapは、React用のWYSIWYGエディタであり、リッチテキストエディタを簡単に実装するためのライブラリである。
tiptapは、カスタマイズ性が高く、プラグインを使用して機能を拡張することができる。

<h2 id="adr-008">ADR-008: unified</h2>

### Date

2025-02-23

### Context

unifiedは、MarkdownやHTMLなどの異なるフォーマットを統一的に扱うためのライブラリである。

本プロジェクトでは単純なテキストをMarkdownだけでなくTeXやReactコンポーネントに変換する必要があり、高度なカスタム変換が必要になるため、拡張性の高いunifiedやremark, rehypeを採用することにした。

<h2 id="adr-007">ADR-007: Jest</h2>

### Date

2025-12-14

### Context

Jestは、JavaScriptのテストフレームワークであり、ユニットテストや統合テストを簡単に実行することができる。

よりモダンなライブラリであるVitestを検討したが、メンバーにJestの経験者がいることや、Prismaのモックライブラリが存在することからJestを採用することにした。

<h2 id="adr-006">ADR-006: ESLint, Prettier, Stylelint</h2>

### Date

2024-12-14

### Context

ESLintは、JavaScriptの静的コード解析ツールであり、コードの品質を向上させるために使用される。
Prettierは、コードフォーマッターであり、コードのスタイルを統一するために使用される。
Stylelintは、CSSの静的コード解析ツールであり、CSSの品質を向上させるために使用される。

代替としてBiomeを検討したが、カスタムルールの作成に対応していないことや、まだ採用実績が少ないことから見送った。

<h2 id="adr-005">ADR-005: CSS Modules</h2>

### Date

2024-12-14

### Context

CSS Modulesは、CSSのスコープをコンポーネント単位で管理するための技術であり、スタイルの衝突を防ぐことができる。
Tailwind CSSの導入も検討したが、複雑なUIを構築する場合、Tailwind CSSのユーティリティクラスが多くなり、可読性が低下する可能性があるため、CSS Modulesを採用することにした。

<h2 id="adr-004">ADR-004: Mantine</h2>

### Date

2024-12-14

### Context

MantineはReactのUIコンポーネントライブラリであり、デザインシステムを構築するためのコンポーネントやスタイルを提供している。
コンポーネントやhooksの多さ、リリース頻度、React Server Componentへの対応などを考慮し、開発スピード向上とデザインの統一感を得るために採用することにした。

<h2 id="adr-003">ADR-003: PostgreSQL, Prisma, Auth.js</h2>

### Date

2024-12-14

### Context

既存の部内システムではMySQLを使用することが多かったが、拡張性の観点からPostgreSQLを採用することにした。

ORMとしてPrismaを採用することで、データベースの操作を簡素化することができる。Prismaはマイグレーション機能が充実しており、データベースのスキーマ変更を簡単に行うことができる。Prisma以外のORMも検討したが、エコシステムの充実度や採用実績を考慮し、Prismaを選択した。

Auth.jsは認証ライブラリであり、Google認証をはじめとするOAuth認証を簡単に実装することができる。

<h2 id="adr-002">ADR-002: DevContainer, Docker</h2>

### Date

2024-12-14

### Context

開発環境をDevContainerで提供することにした。これにより、開発環境の構築が容易になり、メンバー間での環境差異を減らすことができる。
また、Dockerを使用することで、開発環境を簡単に再現できるため、新しいメンバーが参加した際の学習コストを削減できる。
さらに、Dockerを使用することで、開発環境を本番環境に近づけることができるため、デプロイ時のトラブルを減らすことができる。

<h2 id="adr-001">ADR-001: Next.js App Router, TypeScript, pnpm</h2>

### Date

2024-12-14

### Context

Next.jsはReactのフレームワークであり、サーバーサイドレンダリングやファイルベースのルーティングなどの機能を提供している。

現段階においてサークル内にWebアプリケーションの開発経験があるメンバーが少ない。バックエンドにGoを採用することも検討したが、今後のメンバーの学習コストを考慮し、なるべく少ない技術領域で実装できるようフロント・バックともNext.jsで完結させることにした。

また、TypeScriptを採用することで、型安全性を確保し、開発効率を向上させることができる。

pnpmはNode.jsのパッケージマネージャーである。npmよりパッケージのインストール速度が速く、yarnのようにバージョンごとの破壊的変更がないため、pnpmを採用することにした。Bunの採用も検討したが、数は少ないながらも対応しているライブラリがあり、大規模プロジェクトにおける採用には不安が残るため見送った。
56 changes: 56 additions & 0 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Contributing

## 貢献方法

1. 機能追加やバグ修正を行った場合は、プルリクエストを作成してください。
2. プルリクエストは、`main`ブランチに対して作成してください。
3. 作業ブランチには`feat/`や`fix/`などのプレフィックスをつけることを推奨します。例: `feat/add-new-feature`や`fix/bug-fix`
4. マージを行う前に、必ず1人以上のレビュアーにレビューを依頼してください。レビュアーは、プロジェクトメンバーの中から選択してください。GitHubでアサインしたうえで、Mattermostの`~system-development`チャンネルでメンションしてください。
5. プロジェクトメンバーから1人以上の承認を得たら、プルリクエストをマージしてください。
6. プルリクエストをマージしたら、作業ブランチは削除してください。
7. 大きな機能を追加する場合や、検討が必要な点がある場合は、事前にIssueを作成するか、Mattermostの`~system-development`チャンネルで相談してください。

## ディレクトリ構成

```
.
├── .devcontainer
├── .github
├── .vscode
├── app
│ ├── _components
│ ├── api
│ ├── channels
│ ├── layout.tsx
│ └── page.tsx
├── components
├── libs
├── types
├── prisma
├── repositories
├── docs
└── public
```

## コーディング規則

規則は厳密な遵守を求めるものではなく、あくまで慣習をドキュメント化したものです。ただし、リンタやフォーマッタで指定されているものは遵守してください(大抵はスクリプトを実行することで自動修正されます)。

### TypeScript

- 原則としてinterfaceを使用せず、typeを使用してください。
- `any`は使用しないでください。型がわからない場合は`unknown`を使用してください。
- 関数にはできる限りJSDocを記述してください。
- インポート時はファイルパスにエイリアスを使用してください。例: `#/components/MyComponent`。
- ただし、同階層や`_components`ディレクトリのファイルをインポートする場合は相対パスを使用しても構いません。

### React

- コンポーネントは関数コンポーネントを使用してください。クラスコンポーネントは使用しないでください。
- 1ファイルにつき1コンポーネントを原則とします。
- コンポーネント名はアッパーパスカルケース(先頭大文字)で記述してください。例: `MyComponent`。

### CSS

- 原則としてCSS Modulesを使用してください。ファイル名は`[対応するReactコンポーネント名].module.css`としてください。
- クラス名はケバブケース(ハイフンでつなげる)で記述してください。例: `my-component`。
79 changes: 45 additions & 34 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,31 @@
"seed": "npx prisma migrate reset --force & npx tsx ./prisma/seed/init.ts"
},
"dependencies": {
"@auth/prisma-adapter": "^2.7.4",
"@auth/prisma-adapter": "^2.8.0",
"@emoji-mart/data": "^1.2.1",
"@emoji-mart/react": "^1.1.1",
"@mantine/code-highlight": "^7.15.1",
"@mantine/core": "^7.15.1",
"@mantine/hooks": "^7.15.1",
"@mantine/modals": "^7.15.1",
"@mantine/spotlight": "^7.15.1",
"@mantine/tiptap": "^7.15.1",
"@prisma/client": "^6.2.1",
"@tabler/icons-react": "^3.24.0",
"@tiptap/extension-image": "^2.11.5",
"@tiptap/extension-link": "^2.10.3",
"@tiptap/pm": "^2.10.3",
"@tiptap/react": "^2.10.3",
"@tiptap/starter-kit": "^2.10.3",
"@mantine/code-highlight": "^7.17.3",
"@mantine/core": "^7.17.3",
"@mantine/hooks": "^7.17.3",
"@mantine/modals": "^7.17.3",
"@mantine/spotlight": "^7.17.3",
"@mantine/tiptap": "^7.17.3",
"@prisma/client": "^6.5.0",
"@tabler/icons-react": "^3.31.0",
"@tiptap/extension-image": "^2.11.7",
"@tiptap/extension-link": "^2.11.7",
"@tiptap/pm": "^2.11.7",
"@tiptap/react": "^2.11.7",
"@tiptap/starter-kit": "^2.11.7",
"aws-sdk": "^2.1692.0",
"clsx": "^2.1.1",
"dayjs": "^1.11.13",
"dayjs-plugin-utc": "^0.1.2",
"emoji-mart": "^5.6.0",
"next": "15.1.0",
"next": "15.2.4",
"next-auth": "5.0.0-beta.25",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"rehype-katex": "^7.0.1",
"rehype-parse": "^9.0.1",
"rehype-raw": "^7.0.0",
Expand All @@ -46,29 +46,40 @@
"remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"remark-parse": "^11.0.0",
"remark-rehype": "^11.1.1",
"sharp": "^0.33.5",
"remark-rehype": "^11.1.2",
"sharp": "^0.34.0",
"unified": "^11.0.5",
"uuid": "^11.0.5"
"uuid": "^11.1.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@eslint/eslintrc": "^3.3.1",
"@next/eslint-plugin-next": "^15.2.4",
"@types/node": "^20.17.11",
"@types/react": "^19",
"@types/react-dom": "^19",
"@types/node": "^22.14.0",
"@types/react": "^19.1.0",
"@types/react-dom": "^19.1.1",
"@types/uuid": "^10.0.0",
"eslint": "^9.16.0",
"eslint-config-next": "15.1.0",
"eslint-config-prettier": "^9.1.0",
"eslint": "^9.24.0",
"eslint-config-next": "15.2.4",
"eslint-config-prettier": "^10.1.1",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-react-hooks": "^5.2.0",
"prettier": "^3.4.2",
"prisma": "^6.2.1",
"stylelint": "^16.11.0",
"stylelint-config-recess-order": "^5.1.1",
"stylelint-config-standard": "^36.0.1",
"typescript": "^5",
"typescript-eslint": "^8.19.0"
"prettier": "^3.5.3",
"prisma": "^6.5.0",
"prisma-markdown": "^1.0.9",
"stylelint": "^16.17.0",
"stylelint-config-recess-order": "^6.0.0",
"stylelint-config-standard": "^37.0.0",
"typescript": "^5.8.3",
"typescript-eslint": "^8.29.0"
},
"pnpm": {
"onlyBuiltDependencies": [
"@prisma/client",
"@prisma/engines",
"aws-sdk",
"esbuild",
"prisma",
"sharp"
]
}
}
Loading