Skip to content

Commit 54440fc

Browse files
authored
Merge pull request #8 from LevelCapTech/feature/3-sync-agile-pmbok-assist
chore: 上流タスクとPRの構造化テンプレートを導入
2 parents 7874b78 + 0847e84 commit 54440fc

56 files changed

Lines changed: 3805 additions & 133 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/CODE_OF_CONDUCT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@
5151

5252
## 属性
5353

54-
この行動規範は[Contributor Covenant](https://www.contributor-covenant.org)、バージョン 2.0、(https://www.contributor-covenant.org/version/2/0/code_of_conduct.html)から適応されました。
54+
この行動規範は[Contributor Covenant](https://www.contributor-covenant.org)、バージョン 2.0、(<https://www.contributor-covenant.org/version/2/0/code_of_conduct.html>)から適応されました。
Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
---
2+
name: NextJS画面設計イシューテンプレート(Upstream Demo用)
3+
about: NextJS画面設計向けのイシューテンプレートです
4+
title: "[DESIGN] Upstream Demo: ★ここに画面名★"
5+
---
6+
7+
<!--
8+
置換手順:
9+
1. ★ここに画面名★: 対象画面名に置換する(例: 進捗ダッシュボード)。
10+
2. <issue-number>: GitHub Issue番号に置換する(例: 75)。
11+
3. <slug>: ルート/ファイル名用のkebab-caseに置換する(例: progress-dashboard)。
12+
4. <mock-path>: 対象画面に対応するモックファイルパスに置換する(例: mock/v1/web/src/app/progress-dashboard/page.jsx)。
13+
5. <PageName>: Reactコンポーネント名のPascalCaseに置換する(例: ProgressDashboard)。
14+
6. <部品名>: 画面に必要な部品名へ置換する(必要な個数に増減してよい)。
15+
16+
プレースホルダー種類: 6種類(★ここに画面名★ / <issue-number> / <slug> / <mock-path> / <PageName> / <部品名>)
17+
-->
18+
19+
# [DESIGN] Upstream Demo: ★ここに画面名★画面
20+
21+
## 目的
22+
23+
Upstream(public) デモアプリの画面設計を作成する。
24+
本プロジェクトは Dependency Inversion Principle に基づき、 Composition Root(AppProvider)で依存を解決する Plugin 型アーキテクチャを採用する。
25+
このIssueの目的は「設計内容を製造Agentへ漏れなく引き継ぐこと」であり、実装そのものは行わない。
26+
27+
以下を SSOT として固定する。
28+
29+
* Plugin型(DIP): 依存解決は Composition Root(AppProvider)のみ
30+
* ページ設計は contracts(契約)/ public UI / AppContext の責務分離で構成する
31+
32+
## 成果物
33+
- `.github/copilot/80-templates/implementation-plan.md` に準拠した plan ドキュメントを`.github/copilot/plans/<issue-number>-page-<slug>.md`として作成する。
34+
- ファイル追加は、`.github/copilot/plans/<issue-number>-page-<slug>.md`のみとする。
35+
- コード修正・他のファイルの追加・編集を禁止する!
36+
37+
## 前提 / スコープ
38+
39+
* Upstream(public) のみ(private の存在/実装は一切書かない)
40+
* ルーティングは App Router(**app/** 方式)のみを採用する
41+
* モックデータは可(実装Issueで publicデモとして動く完成実装にする)
42+
43+
### モック画面
44+
45+
モック画面 `<mock-path>` を参考に対象画面を設計する。
46+
47+
対象画面は下記の部品を持つ。
48+
49+
* `<部品名>`
50+
* `<部品名>`
51+
* `<部品名>`
52+
* `<部品名>`
53+
* `<部品名>`
54+
* `<部品名>`
55+
56+
## ゴール(このIssueで達成)
57+
58+
1. 「ページを追加する手順」が **SSOT化**されている
59+
2. contracts と UI と DI が **規約通りに分離**されている
60+
3. `.github/copilot/plans/<issue-number>-page-<slug>.md` の機能設計書を新規作成している
61+
62+
## 非ゴール
63+
64+
* private 実装、DB接続、認証、社内API等の導入
65+
66+
## SSOT規範(必須)
67+
68+
### Dependency Injection Rule
69+
70+
* 依存性注入(依存解決)は `AppProvider.tsx` のみ
71+
* `app/*/page.tsx`**`packages/contracts/*``packages/ui/*` と AppContext** を参照可能とする
72+
* `packages/contracts/*` は interface/type のみ(実装、URL、認証、fetchなどの具体語禁止)
73+
* `packages/ui/*` は public UI(会社固有前提なし)
74+
75+
### CSSフレームワーク
76+
77+
* MUI は Emotion エンジンを前提に運用する(推奨)
78+
* styled は @emotion/styled を標準とする(MUIと同一基盤)
79+
* Tailwind はユーティリティ(レイアウト/微調整/状態/レスポンシブ)用途に限定する
80+
* スタイル注入順を固定し、Tailwind による上書きを容易にする
81+
82+
#### CSS必須ルール
83+
84+
- **スタイル注入順を固定する**:MUIのスタイルは先に注入し、Tailwind等で上書き可能にする(`StyledEngineProvider injectFirst`
85+
- **同一要素で同じプロパティを多重指定しない**(例:padding/color/fontをTailwindとMUIとstyledで混ぜない)
86+
87+
#### CSS原則
88+
89+
- MUIを `styled-components` エンジンへ切替(`@mui/styled-engine-sc`)は原則しない(SSR差分/依存/事故率が上がるため)
90+
91+
## フォルダ構造(Upstream)
92+
93+
* Next.js アプリのルートは repo 直下で固定。だけど UI/Contracts は同一repo内のローカルパッケージとして `packages/` に切る。
94+
* 本repoは「`apps/` 配下にアプリを置く monorepo 形」は採用しない(=アプリは repo 直下)。ただし `packages/` にローカルパッケージ(`ui` / `contracts` / `plugins`)を同居させる。
95+
* `src/providers` はアプリ全体(Root layout 相当)の Provider 群、`app/**/providers.tsx` は画面スコープの Provider とする(Composition Root としての依存解決は `AppProvider.tsx` のみ)。
96+
* UI はアトミックデザインを採用する。
97+
98+
* Hooks は Organisms 以上(または Container)で許可。
99+
* Atoms/Molecules は基本ダム。状態は持っても「見た目に閉じる」。
100+
* 画面スコープの状態共有は Page/Template 配下の Context を第一選択。
101+
* Props drilling が 3 階層を超えたら Context or Container を検討。
102+
* ルーティングは App Router(`app/` 方式)とする。
103+
104+
* `next/router` は使わず `next/navigation` を使う。
105+
* Server Components がデフォルトで、クライアントが必要なコンポーネントだけ "use client" を付ける。
106+
107+
[見本]
108+
109+
```
110+
app/
111+
layout.tsx # Root layout(Server)
112+
page.tsx # /(Server)
113+
<slug>/
114+
page.tsx # /<slug>(Server)
115+
layout.tsx # /<slug> 配下のレイアウト
116+
providers.tsx # (use client) 画面スコープContext Provider(依存解決はしない)
117+
_components/ # ルート専用の薄い部品
118+
DashboardShell.tsx # (use client) state/compose only
119+
120+
public/
121+
122+
src/
123+
providers/
124+
AppProvider.tsx # (use client) アプリ全体のProvider
125+
AppContext.tsx
126+
composition/
127+
createClientContainer.ts
128+
createServerContainer.ts
129+
registerPlugins.ts
130+
pluginRegistry.ts
131+
lib/
132+
createClientDeps.ts # Public deps factory(※containerを使うなら薄くする/廃止も可)
133+
createServerDeps.ts # Server deps factory(※containerを使うなら薄くする/廃止も可)
134+
135+
packages/
136+
contracts/
137+
src/
138+
index.ts # packages/contracts の公開API(barrel)
139+
domain/ # ドメインモデル(Entity/ValueObject など、UIやI/Oに依存しない)
140+
Project.ts # ドメイン型: Project
141+
Session.ts # ドメイン型: Session
142+
ports/ # 抽象(DIPの境界)。plugins がここを実装する
143+
ProjectRepository.ts # Project 永続化/取得の抽象
144+
SessionRepository.ts # Session 永続化/取得の抽象
145+
Telemetry.ts # ログ/計測の抽象
146+
Auth.ts # 認証/認可の抽象(例: 現在ユーザー取得、権限判定)
147+
usecases/ # ユースケース契約(アプリの操作単位)。container から呼ばれる
148+
SearchProjects.ts # ユースケース: Project 検索
149+
GetProject.ts # ユースケース: Project 取得
150+
GetSession.ts # ユースケース: Session 取得
151+
dto/ # 表示/転送向けのDTO(ドメインと分離したい場合)
152+
ProjectDto.ts # DTO: Project 表示/転送用
153+
pages/
154+
<slug>.ts # ページ単位の契約(Route単位)
155+
156+
ui/
157+
src/
158+
pages/ # 見た目のページ(App Routerのpage.tsxとは別)/画面スコープのContext(フィルタ状態や選択状態など)を提供
159+
<PageName>Page/
160+
<PageName>Page.tsx
161+
atoms/ # state を持つ場合も UI状態(hover, open等)のみとする/ドメイン状態・データ取得・副作用は禁止
162+
ProjectName/
163+
ProjectName.tsx
164+
templates/ # レイアウト構造(Header/Footer/サイドバー配置など)/画面共通のContextはtemplatesで提供
165+
StandardLayout/
166+
StandardLayout.tsx
167+
molecules/ # 簡単な UI state は可、ただし外部I/Oやグローバル状態は避ける
168+
ProjectCard/
169+
ProjectCard.tsx
170+
organisms/ # hooks を許可(フォーム、リスト、フィルタ状態など)/ただし「ドメインの取得・永続化」は、可能なら usecase 呼び出し(container経由)に寄せる
171+
Header/
172+
Header.tsx
173+
ProjectCardList/
174+
ProjectCardList.tsx
175+
Footer/
176+
Footer.tsx
177+
178+
plugins/
179+
src/
180+
index.ts
181+
http/
182+
projectRepository.ts
183+
sessionRepository.ts
184+
storage/
185+
cookieSessionStore.ts
186+
telemetry/
187+
consoleTelemetry.ts
188+
auth/
189+
noopAuth.ts
190+
```
191+
192+
※上記のフォルダ構造例は「リポジトリルート」直下を前提としており、`app/` ディレクトリはリポジトリ直下に配置される。
193+
### ディレクトリの責務
194+
195+
#### `app/`(ルーティング:薄く)
196+
197+
* URL の入口(`page.tsx` / `layout.tsx`)だけを持つ。
198+
* **実装詳細(HTTP/DB/Storage)を直に `new` しない。**
199+
* ルートは「container(DIコンテナ)から usecase を呼ぶ」くらいに留める。
200+
201+
例:
202+
203+
* `app/<slug>/page.tsx``<PageName>Page`(UI)に props を渡す or サーバでデータ取得して渡す。
204+
205+
#### `src/composition/`(依存生成の中心)
206+
207+
* 依存(ports の実装)を組み立て、usecase を生成し、必要なら plugin を登録する(ここで生成した依存を `AppProvider.tsx` から利用する)。
208+
* App Router の Server/Client の違いに合わせて入口を分ける。
209+
210+
推奨ファイル:
211+
212+
* `createClientContainer.ts`:ブラウザ実行("use client" 側)で使う依存を束ねる。
213+
* `createServerContainer.ts`:サーバ実行で使う依存を束ねる(秘密情報・サーバ専用 OK)。
214+
* `registerPlugins.ts`:どの plugin 実装を採用するか(差し替え点)。
215+
* `pluginRegistry.ts`:plugin の登録/参照の器。
216+
217+
#### `src/providers/AppProvider.tsx`(Client Composition Root)
218+
219+
* React Context などで container をアプリに流す。
220+
* ここが「Provider としての Composition Root(AppProvider)」の本体。
221+
222+
分業の明確化:
223+
224+
* `src/composition`**container 生成(依存生成)**
225+
* `src/providers`**container を React ツリーへ注入(Provider)**
226+
227+
### plugins パッケージ(実装の差し替え:必須)
228+
229+
#### `packages/plugins/`
230+
231+
* `contracts/ports` を満たす実装群。
232+
* 例:HTTP 版 repo、cookie 版 session、console telemetry など。
233+
* upstream ではデフォ実装をここに置き、downstream で差し替える方針とも相性が良い。
234+
235+
`packages/plugins/` は必須とする。実装の差し替え点は原則ここに集約し、採用と切替は `src/composition/registerPlugins.ts` で確定する。
236+
237+
238+
### Atomic Design(ui)
239+
240+
#### `packages/ui/`
241+
242+
* Atoms/Molecules:基本ダム(状態は「見た目に閉じる」)。
243+
* Organisms 以上(or Container)で hooks / 状態 / Context 利用。
244+
* Templates:レイアウト構造。
245+
* Pages:画面の見た目のまとまり(App Router の `page.tsx` とは別)。
246+
247+
**呼び出し責務の固定**
248+
249+
* usecase を呼ぶのは原則 `app/` or `src/*`(container 側)
250+
* `packages/ui` は props を受けて描画に専念(Atoms/Molecules の原則と整合)
251+
252+
253+
### contracts の方針(ドメイン/ユースケース単位が一次)
254+
255+
#### `packages/contracts/src/domain/`
256+
257+
* ドメインモデル(Entity/ValueObject 的な型)。
258+
* 例:`Project`, `Session`
259+
260+
#### `packages/contracts/src/ports/`
261+
262+
* DIP の「抽象(依存の向きの逆転)」。
263+
* 例:`ProjectRepository`, `SessionRepository`, `Telemetry`
264+
265+
#### `packages/contracts/src/usecases/`
266+
267+
* ユースケース単位の契約(再利用の核)。
268+
* 例:`SearchProjects`, `GetProject`, `GetSession`
269+
* UI(アプリ側の container)はこの usecase 契約を呼ぶ(または adapter 経由)。
270+
271+
#### `packages/contracts/src/dto/`(任意)
272+
273+
* 表示用/転送用の DTO(ドメインと分離したい場合)。
274+
275+
> ページ単位の contracts は「必須」ではなく、必要が出たら **composition** として追加する位置づけが安全。
276+
> 例:`contracts/src/pages/<slug>.ts` は、`SearchProjects` 等を束ねるだけの薄い合成契約にする。
277+
278+
279+
## 型定義(SSOTとして固定)
280+
281+
各ページは実装時に次の 4 点セットを基本とする(本Issueでは追加せず、planに定義する)。
282+
283+
1. docs: `.github/copilot/plans/<issue-number>-page-<slug>.md`(ページ仕様)
284+
2. contracts: `packages/contracts/src/pages/<slug>.ts`(interface/typeのみ)
285+
3. ui: `packages/ui/src/pages/<slug>/<PageName>Page.tsx`(public UI)
286+
4. app page: `app/<slug>/page.tsx`(Contextからdeps取得してUIへ渡すだけ)
287+
288+
## deps(依存束)の設計(Upstream内で完結)
289+
290+
* `AppContext``deps` を型付きで提供する
291+
* `createClientDeps` は “public完成実装”として、各ページ用の DataSource を返す(モックOK)
292+
293+
## 品質ゲート
294+
295+
* plan に lint/typecheck/build/test/security の実行計画が明記されている
296+
* plan に `app/<slug>/page.tsx` の依存制約を検証できる受け入れ条件が明記されている
297+
* plan に `contracts` に実装コードが入らないことを検証できる受け入れ条件が明記されている
298+
* plan に DI が AppProvider に固定されることを検証できる受け入れ条件が明記されている
299+
300+
## テスト設計(Design Issueで必須記載)
301+
302+
plan には必ず次を明記する。
303+
304+
* 対象: どのページ/コンポーネント/ユースケースをテストするか(一覧)
305+
* 方式: Unit(UI) / Unit(Domain, Usecase) / Integration(Route Handler) / Integration(MSW or nock or undici mock) / E2E(Playwright) のどれで守るか
306+
* ケース: 成功/失敗/空/遅延(最低ライン) + 必要箇所はリトライ
307+
* モック方針: Next依存のモック、APIモック(MSW or nock or undici mock)の置き場、共通ヘルパ
308+
* 実行コマンド: リポジトリルート起点(watch/ci/coverage を含む)
309+
* Storybook: 対象UI部品の Story 作成方針(どの状態を Story 化するか)
310+
* バックエンド統合: Route Handler 直接呼び出し時のテストDBまたはトランザクション方針
311+
* カバレッジ境界: `packages/` / `src/` / `app/` の対象方針(Server Component の扱いを明記)
312+
313+
## Done
314+
315+
* 対象画面で「docs→contracts→ui→page→AppProvider」の設計フローが確定している
316+
* 契約のプロパティが明確である
317+
* ルーティングが明確である

0 commit comments

Comments
 (0)