@ripla/godd-mcp 1.0.8-canary.2 → 1.0.8-canary.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -4
- package/dist/godd.cjs +354 -252
- package/dist/godd.js +1288 -237
- package/dist/index.js +238 -136
- package/notes/api/docker/Dockerfile +11 -2
- package/notes/api/docker/Dockerfile.test +6 -2
- package/package.json +1 -1
- package/templates/feedback/feedback-lambda/index.mjs +93 -26
- package/templates/feedback/frontend/FeedbackWidget.tsx +27 -0
- package/templates/feedback/frontend/api.ts +2 -1
- package/templates/feedback/frontend/types.ts +5 -0
- package/templates/notes-docs/005_architecture/api/README.md +17 -0
- package/templates/notes-docs/005_architecture/db/README.md +17 -0
- package/templates/notes-docs/005_architecture/features/README.md +18 -0
- package/templates/notes-docs/005_architecture/infra/README.md +19 -0
- package/templates/notes-docs/005_architecture/stacks/README.md +20 -0
- package/templates/notes-docs/007_guides/godd_tools.md +8 -3
- package/templates/notes-docs/007_guides/godd_usage.md +0 -2
- package/templates/notes-docs/007_guides/setup_godd.md +6 -0
- package/templates/notes-docs/README.md +30 -17
|
@@ -6,9 +6,18 @@ RUN apt-get update && apt-get install -y --no-install-recommends libpq-dev gcc &
|
|
|
6
6
|
|
|
7
7
|
RUN pip install uv
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
# Dependencies are installed from uv.lock, never re-resolved from pyproject.toml:
|
|
10
|
+
# resolving at build time installs whatever is newest that day, so the same
|
|
11
|
+
# source built on two days produced different images (#1384 — SQLAlchemy 2.1
|
|
12
|
+
# arrived unannounced and broke Alembic). --locked fails the build when uv.lock
|
|
13
|
+
# no longer matches pyproject.toml, rather than quietly resolving afresh.
|
|
14
|
+
COPY pyproject.toml uv.lock ./
|
|
15
|
+
RUN uv export --locked --no-dev --no-emit-project -o /tmp/requirements.txt \
|
|
16
|
+
&& uv pip install --system -r /tmp/requirements.txt
|
|
10
17
|
|
|
11
|
-
|
|
18
|
+
# The project itself, without letting it pull in anything the lock did not pin.
|
|
19
|
+
COPY . .
|
|
20
|
+
RUN uv pip install --system --no-deps .
|
|
12
21
|
|
|
13
22
|
EXPOSE 3100
|
|
14
23
|
CMD ["sh", "-c", "uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-3100}"]
|
|
@@ -8,8 +8,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends libpq-dev gcc &
|
|
|
8
8
|
|
|
9
9
|
RUN pip install --no-cache-dir uv
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
# Same lock as the production image (docker/Dockerfile), plus the dev extra, so
|
|
12
|
+
# tests run against the versions that ship (#1384). The source is used in place
|
|
13
|
+
# from /app, so the project itself is not installed.
|
|
14
|
+
COPY pyproject.toml uv.lock ./
|
|
15
|
+
RUN uv export --locked --extra dev --no-emit-project -o /tmp/requirements.txt \
|
|
16
|
+
&& uv pip install --system -r /tmp/requirements.txt
|
|
13
17
|
|
|
14
18
|
COPY . .
|
|
15
19
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ripla/godd-mcp",
|
|
3
|
-
"version": "1.0.8-canary.
|
|
3
|
+
"version": "1.0.8-canary.21",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "GoDD MCP Server - AI-powered development workflow tools via Model Context Protocol (slash commands support)",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
// Lambda Function URL handler — フィードバック受付 → GitHub Issue 起票
|
|
2
2
|
// 認証: GoDD Notes Bot (GitHub App) のインストールトークンを都度生成
|
|
3
|
+
// Slack への通知はここでは行わない。feedback ラベルの Issue を GoDD の registry が
|
|
4
|
+
// GitHub の Webhook で受けて投稿する(案件ごとに Slack の認証情報を持たないため)
|
|
3
5
|
|
|
4
6
|
import crypto from "node:crypto";
|
|
5
|
-
import {
|
|
6
|
-
SecretsManagerClient,
|
|
7
|
-
GetSecretValueCommand,
|
|
8
|
-
} from "@aws-sdk/client-secrets-manager";
|
|
9
7
|
|
|
10
8
|
const GITHUB_API = "https://api.github.com";
|
|
11
9
|
const TOKEN_BUFFER_SECONDS = 300;
|
|
@@ -13,15 +11,30 @@ const JWT_EXPIRY_SECONDS = 600;
|
|
|
13
11
|
// Function URL のリクエスト上限は 6MB。原画は送らない設計のため 3MB で十分
|
|
14
12
|
const MAX_IMAGE_BYTES = 3 * 1024 * 1024;
|
|
15
13
|
const PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const FEEDBACK_LABEL = "feedback";
|
|
15
|
+
// 「すぐ直してほしい」の希望。Slack の通知にスタンプが付いて Issue を移すときに引き継がれる
|
|
16
|
+
const FIX_REQUESTED_LABEL = "godd:fix-requested";
|
|
17
|
+
|
|
18
|
+
// SDK は Lambda ランタイムに同梱されている。読み込みを使う時まで遅らせ、
|
|
19
|
+
// SDK の無い環境(テスト)でも本文の組み立てを検証できるようにする
|
|
20
|
+
let sm = null;
|
|
21
|
+
|
|
22
|
+
async function secretsManager() {
|
|
23
|
+
if (sm) return sm;
|
|
24
|
+
const { SecretsManagerClient, GetSecretValueCommand } = await import(
|
|
25
|
+
"@aws-sdk/client-secrets-manager"
|
|
26
|
+
);
|
|
27
|
+
sm = { client: new SecretsManagerClient(), GetSecretValueCommand };
|
|
28
|
+
return sm;
|
|
29
|
+
}
|
|
18
30
|
|
|
19
31
|
// シークレットのキャッシュ(コールドスタートごとにリセット)
|
|
20
32
|
const secretCache = {};
|
|
21
33
|
|
|
22
34
|
async function getSecret(secretName) {
|
|
23
35
|
if (secretCache[secretName]) return secretCache[secretName];
|
|
24
|
-
const
|
|
36
|
+
const { client, GetSecretValueCommand } = await secretsManager();
|
|
37
|
+
const res = await client.send(
|
|
25
38
|
new GetSecretValueCommand({ SecretId: secretName }),
|
|
26
39
|
);
|
|
27
40
|
const value = res.SecretString;
|
|
@@ -153,20 +166,28 @@ async function ensureBranch(repo, branch, token) {
|
|
|
153
166
|
});
|
|
154
167
|
}
|
|
155
168
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
169
|
+
const LABELS = {
|
|
170
|
+
[FEEDBACK_LABEL]: {
|
|
171
|
+
color: "D93F0B",
|
|
172
|
+
description: "フィードバックウィジェットからの自動起票",
|
|
173
|
+
},
|
|
174
|
+
[FIX_REQUESTED_LABEL]: {
|
|
175
|
+
color: "FBCA04",
|
|
176
|
+
description: "GoDD Comment で「すぐ直してほしい」が選ばれた(承認前の希望)",
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
async function ensureLabel(repo, name, token) {
|
|
181
|
+
const label = await ghFetch(
|
|
182
|
+
`/repos/${repo}/labels/${encodeURIComponent(name)}`,
|
|
183
|
+
token,
|
|
184
|
+
).catch(() => null);
|
|
160
185
|
if (label) return;
|
|
161
186
|
|
|
162
187
|
// 既存ラベルは触らず、無い場合のみ作成する(同時作成の競合は無視して続行)
|
|
163
188
|
await ghFetch(`/repos/${repo}/labels`, token, {
|
|
164
189
|
method: "POST",
|
|
165
|
-
body: JSON.stringify({
|
|
166
|
-
name: "feedback",
|
|
167
|
-
color: "D93F0B",
|
|
168
|
-
description: "フィードバックウィジェットからの自動起票",
|
|
169
|
-
}),
|
|
190
|
+
body: JSON.stringify({ name, ...LABELS[name] }),
|
|
170
191
|
}).catch(() => {});
|
|
171
192
|
}
|
|
172
193
|
|
|
@@ -185,10 +206,22 @@ async function commitImage(repo, branch, filePath, imageBuffer, token) {
|
|
|
185
206
|
// Markdown テーブルのセルに利用者入力を埋め込むためのエスケープ。
|
|
186
207
|
// パイプ・改行を無害化しないと表の構造ごと壊せてしまう(偽の指示文の埋め込みも含む)
|
|
187
208
|
function cell(value) {
|
|
188
|
-
return String(value).replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
|
|
209
|
+
return inert(String(value)).replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
|
|
189
210
|
}
|
|
190
211
|
|
|
191
|
-
|
|
212
|
+
// 利用者入力に HTML コメントを開かせない。末尾の機械向けの印(metaLine)を
|
|
213
|
+
// 偽装されると、Slack 通知のリンクや「すぐ直す」の判定を書き換えられてしまう
|
|
214
|
+
function inert(text) {
|
|
215
|
+
return text.replace(/<!--/g, "<!--");
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 機械向けの印。registry の Slack 通知と、修正ワークフロー(スクショを
|
|
219
|
+
// git show で取り出す)がこの 1 行を読む。人が読む本文の書式とは独立させる
|
|
220
|
+
function metaLine({ branch, screenshotPath, fixRequested }) {
|
|
221
|
+
return `<!-- godd-comment: branch=${branch} screenshot=${screenshotPath} fix-requested=${fixRequested} -->`;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export function buildIssueBody(comment, imageUrl, page, meta, pin, extra = {}) {
|
|
192
225
|
const lines = [
|
|
193
226
|
"## フィードバック",
|
|
194
227
|
"",
|
|
@@ -197,8 +230,12 @@ function buildIssueBody(comment, imageUrl, page, meta, pin, extra = {}) {
|
|
|
197
230
|
...(extra.screenName ? ["### 画面名", "", cell(extra.screenName), ""] : []),
|
|
198
231
|
"### 指摘・要望コメント",
|
|
199
232
|
"",
|
|
200
|
-
`> ${comment.replace(/\n/g, "\n> ")}`,
|
|
233
|
+
`> ${inert(comment).replace(/\n/g, "\n> ")}`,
|
|
201
234
|
"",
|
|
235
|
+
// 希望の記録だけ。修正は Slack の通知にスタンプが付いてから始まる
|
|
236
|
+
...(extra.fixRequested
|
|
237
|
+
? ["### すぐ直してほしい", "", "希望あり(Slack の通知にスタンプが付いてから修正を始める)", ""]
|
|
238
|
+
: []),
|
|
202
239
|
"### スクリーンショット(指摘箇所)",
|
|
203
240
|
`[スクリーンショットを開く](${imageUrl})`,
|
|
204
241
|
"",
|
|
@@ -214,16 +251,30 @@ function buildIssueBody(comment, imageUrl, page, meta, pin, extra = {}) {
|
|
|
214
251
|
`| UA | ${cell(meta.userAgent)} |`,
|
|
215
252
|
`| 撮影日時 | ${cell(meta.capturedAt)} |`,
|
|
216
253
|
`| ピン位置 | (${pin.x.toFixed(1)}%, ${pin.y.toFixed(1)}%) |`,
|
|
254
|
+
"",
|
|
255
|
+
metaLine({
|
|
256
|
+
branch: extra.branch,
|
|
257
|
+
screenshotPath: extra.screenshotPath,
|
|
258
|
+
fixRequested: extra.fixRequested === true,
|
|
259
|
+
}),
|
|
217
260
|
];
|
|
218
261
|
return lines.join("\n");
|
|
219
262
|
}
|
|
220
263
|
|
|
221
264
|
// ペイロードの形状検証。未検証のまま参照すると TypeError → 500 になり、
|
|
222
265
|
// 内部エラーメッセージが送信者へ漏れるため、先に固定文言の 400 で弾く
|
|
223
|
-
function validatePayload(payload) {
|
|
266
|
+
export function validatePayload(payload) {
|
|
224
267
|
if (typeof payload !== "object" || payload === null) return "不正なペイロードです";
|
|
225
|
-
const {
|
|
226
|
-
|
|
268
|
+
const {
|
|
269
|
+
comment,
|
|
270
|
+
annotatedScreenshot,
|
|
271
|
+
pin,
|
|
272
|
+
page,
|
|
273
|
+
meta,
|
|
274
|
+
reporter,
|
|
275
|
+
screenName,
|
|
276
|
+
fixRequested,
|
|
277
|
+
} = payload;
|
|
227
278
|
if (typeof comment !== "string" || !comment.trim()) return "comment は必須です";
|
|
228
279
|
if (typeof annotatedScreenshot !== "string")
|
|
229
280
|
return "annotatedScreenshot は必須です";
|
|
@@ -248,6 +299,8 @@ function validatePayload(payload) {
|
|
|
248
299
|
return "reporter が不正です";
|
|
249
300
|
if (screenName !== undefined && typeof screenName !== "string")
|
|
250
301
|
return "screenName が不正です";
|
|
302
|
+
if (fixRequested !== undefined && typeof fixRequested !== "boolean")
|
|
303
|
+
return "fixRequested が不正です";
|
|
251
304
|
return null;
|
|
252
305
|
}
|
|
253
306
|
|
|
@@ -284,8 +337,16 @@ export async function handler(event) {
|
|
|
284
337
|
}
|
|
285
338
|
const validationError = validatePayload(payload);
|
|
286
339
|
if (validationError) return respond(400, { error: validationError });
|
|
287
|
-
const {
|
|
288
|
-
|
|
340
|
+
const {
|
|
341
|
+
comment,
|
|
342
|
+
annotatedScreenshot,
|
|
343
|
+
pin,
|
|
344
|
+
page,
|
|
345
|
+
meta,
|
|
346
|
+
reporter,
|
|
347
|
+
screenName,
|
|
348
|
+
fixRequested,
|
|
349
|
+
} = payload;
|
|
289
350
|
|
|
290
351
|
let imageBuffer;
|
|
291
352
|
try {
|
|
@@ -307,8 +368,11 @@ export async function handler(event) {
|
|
|
307
368
|
const rand = Math.random().toString(36).slice(2, 8);
|
|
308
369
|
const filePath = `feedback/${ts}_${rand}.png`;
|
|
309
370
|
|
|
371
|
+
const labels = fixRequested
|
|
372
|
+
? [FEEDBACK_LABEL, FIX_REQUESTED_LABEL]
|
|
373
|
+
: [FEEDBACK_LABEL];
|
|
310
374
|
await ensureBranch(repo, branch, token);
|
|
311
|
-
await ensureLabel(repo, token);
|
|
375
|
+
for (const label of labels) await ensureLabel(repo, label, token);
|
|
312
376
|
const imageUrl = await commitImage(
|
|
313
377
|
repo,
|
|
314
378
|
branch,
|
|
@@ -320,13 +384,16 @@ export async function handler(event) {
|
|
|
320
384
|
const issueBody = buildIssueBody(comment.trim(), imageUrl, page, meta, pin, {
|
|
321
385
|
reporter: reporter?.trim(),
|
|
322
386
|
screenName: screenName?.trim(),
|
|
387
|
+
fixRequested: fixRequested === true,
|
|
388
|
+
branch,
|
|
389
|
+
screenshotPath: filePath,
|
|
323
390
|
});
|
|
324
391
|
const issue = await ghFetch(`/repos/${repo}/issues`, token, {
|
|
325
392
|
method: "POST",
|
|
326
393
|
body: JSON.stringify({
|
|
327
394
|
title: `[フィードバック] ${comment.trim().replace(/\r?\n/g, " ").slice(0, 60)}`,
|
|
328
395
|
body: issueBody,
|
|
329
|
-
labels
|
|
396
|
+
labels,
|
|
330
397
|
}),
|
|
331
398
|
});
|
|
332
399
|
|
|
@@ -53,6 +53,7 @@ export function FeedbackWidget() {
|
|
|
53
53
|
const [comment, setComment] = useState("");
|
|
54
54
|
const [reporter, setReporter] = useState(loadSavedReporter);
|
|
55
55
|
const [screenName, setScreenName] = useState("");
|
|
56
|
+
const [fixRequested, setFixRequested] = useState(false);
|
|
56
57
|
const [error, setError] = useState<string | null>(null);
|
|
57
58
|
const [result, setResult] = useState<FeedbackResult | null>(null);
|
|
58
59
|
|
|
@@ -62,6 +63,7 @@ export function FeedbackWidget() {
|
|
|
62
63
|
setPin(null);
|
|
63
64
|
setComment("");
|
|
64
65
|
setScreenName("");
|
|
66
|
+
setFixRequested(false);
|
|
65
67
|
setError(null);
|
|
66
68
|
setResult(null);
|
|
67
69
|
}, []);
|
|
@@ -169,6 +171,7 @@ export function FeedbackWidget() {
|
|
|
169
171
|
comment: comment.trim(),
|
|
170
172
|
reporter: reporter.trim() || undefined,
|
|
171
173
|
screenName: screenName.trim() || undefined,
|
|
174
|
+
fixRequested,
|
|
172
175
|
annotatedScreenshot: annotated,
|
|
173
176
|
pin,
|
|
174
177
|
page: {
|
|
@@ -416,6 +419,30 @@ export function FeedbackWidget() {
|
|
|
416
419
|
background: "#fbf9f4",
|
|
417
420
|
}}
|
|
418
421
|
/>
|
|
422
|
+
<label
|
|
423
|
+
htmlFor="feedback-fix-requested"
|
|
424
|
+
style={{
|
|
425
|
+
display: "flex",
|
|
426
|
+
alignItems: "center",
|
|
427
|
+
gap: 6,
|
|
428
|
+
marginTop: 10,
|
|
429
|
+
fontSize: 13,
|
|
430
|
+
color: INK,
|
|
431
|
+
cursor: phase === "submitting" ? "default" : "pointer",
|
|
432
|
+
}}
|
|
433
|
+
>
|
|
434
|
+
<input
|
|
435
|
+
id="feedback-fix-requested"
|
|
436
|
+
type="checkbox"
|
|
437
|
+
checked={fixRequested}
|
|
438
|
+
onChange={(e) => setFixRequested(e.target.checked)}
|
|
439
|
+
disabled={phase === "submitting"}
|
|
440
|
+
/>
|
|
441
|
+
すぐ直してほしい
|
|
442
|
+
<span style={{ fontSize: 12, color: SUB }}>
|
|
443
|
+
(担当者が確認してから修正を始めます)
|
|
444
|
+
</span>
|
|
445
|
+
</label>
|
|
419
446
|
<div
|
|
420
447
|
style={{
|
|
421
448
|
display: "flex",
|
|
@@ -11,7 +11,8 @@ export interface FeedbackResult {
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* フィードバックをバックエンドへ送信する。
|
|
14
|
-
*
|
|
14
|
+
* バックエンド(feedback Lambda)がスクショのコミットと GitHub Issue の作成を行う。
|
|
15
|
+
* Slack への通知は、作られた Issue をもとに GoDD の registry が行う。
|
|
15
16
|
*/
|
|
16
17
|
export async function submitFeedback(
|
|
17
18
|
payload: FeedbackPayload,
|
|
@@ -32,6 +32,11 @@ export interface FeedbackPayload {
|
|
|
32
32
|
reporter?: string;
|
|
33
33
|
/** 画面名(任意・フリーテキスト) */
|
|
34
34
|
screenName?: string;
|
|
35
|
+
/**
|
|
36
|
+
* 「すぐ直してほしい」の希望。希望の記録だけで、これだけでは修正は始まらない
|
|
37
|
+
* (送信者をサーバー側で確認できないため、開発チームの Slack でのスタンプを挟む)
|
|
38
|
+
*/
|
|
39
|
+
fixRequested?: boolean;
|
|
35
40
|
/** ピン合成済みスクリーンショット(PNG の data URL)。原画はペイロードサイズ削減のため送らない */
|
|
36
41
|
annotatedScreenshot: string;
|
|
37
42
|
/** 指摘位置のピン */
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# 005_architecture/api — API 設計
|
|
2
|
+
|
|
3
|
+
> 本ドキュメントは `docs/005_architecture/api/README.md` の **テンプレート** です。
|
|
4
|
+
|
|
5
|
+
本ディレクトリは、**API のインターフェース設計**(エンドポイント・リクエスト/レスポンス・エラー)を整理する場所です。Swagger / OpenAPI の定義ファイルもここに置きます。
|
|
6
|
+
|
|
7
|
+
## 記述ルール
|
|
8
|
+
|
|
9
|
+
- エンドポイントを追加・変更したら、ここと関連する要件定義の両方を更新する
|
|
10
|
+
- エラーレスポンスの形式とステータスコードの使い分けを明記する(実装者が推測で決めないため)
|
|
11
|
+
- 認証・認可の前提を明記する
|
|
12
|
+
|
|
13
|
+
## エンドポイント一覧
|
|
14
|
+
|
|
15
|
+
| メソッド | パス | 概要 | 認証 |
|
|
16
|
+
|---|---|---|---|
|
|
17
|
+
| [GET] | [/api/v1/xxx] | [概要] | [要 / 不要] |
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# 005_architecture/db — DB 設計
|
|
2
|
+
|
|
3
|
+
> 本ドキュメントは `docs/005_architecture/db/README.md` の **テンプレート** です。
|
|
4
|
+
|
|
5
|
+
本ディレクトリは、**テーブル定義・ER 図・インデックス設計・マイグレーション方針**を整理する場所です。
|
|
6
|
+
|
|
7
|
+
## 記述ルール
|
|
8
|
+
|
|
9
|
+
- スキーマを変更したら、マイグレーションと同じ PR でここを更新する
|
|
10
|
+
- 論理削除・監査列・命名規約など、全テーブルに共通する規約を先に定める
|
|
11
|
+
- ER 図は Mermaid か drawio で置き、実装とずれたら差し替える
|
|
12
|
+
|
|
13
|
+
## テーブル一覧
|
|
14
|
+
|
|
15
|
+
| テーブル名 | 概要 | 主キー | 備考 |
|
|
16
|
+
|---|---|---|---|
|
|
17
|
+
| [table_name] | [概要] | [id] | [備考] |
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# 005_architecture/features — 機能設計書
|
|
2
|
+
|
|
3
|
+
> 本ドキュメントは `docs/005_architecture/features/README.md` の **テンプレート** です。
|
|
4
|
+
|
|
5
|
+
本ディレクトリは、**機能ごとの設計書**(どう作るか)を置く場所です。要件(`003_requirements/`)が「何を作るか」を定めるのに対し、ここは実装方針・データフロー・DB 設計を定めます。
|
|
6
|
+
|
|
7
|
+
## 記述ルール
|
|
8
|
+
|
|
9
|
+
- **1 機能 = 1 ファイル**(`<feature_name>.md`)で管理する
|
|
10
|
+
- ファイル名は `docs/001_project/features.csv` の機能名と対応させる
|
|
11
|
+
- 実装と設計が乖離したら、設計書側を必ず更新する(設計書は SSOT の一部)
|
|
12
|
+
- 雛形は `docs/003_requirements/【仕様書】フォーマット①(ビジネスサイド向け).md` を使う。技術的な記述が主になる機能ではフォーマット②を使ってよい
|
|
13
|
+
|
|
14
|
+
## 設計書一覧
|
|
15
|
+
|
|
16
|
+
| # | 機能 | ファイル | ステータス |
|
|
17
|
+
|---|---|---|---|
|
|
18
|
+
| 1 | [機能名] | [feature_name].md | [draft / fixed] |
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# 005_architecture/infra — インフラ設計
|
|
2
|
+
|
|
3
|
+
> 本ドキュメントは `docs/005_architecture/infra/README.md` の **テンプレート** です。
|
|
4
|
+
|
|
5
|
+
本ディレクトリは、**インフラのアーキテクチャ設計**(構成図・ネットワーク・環境ごとの差異・監視)を整理する場所です。
|
|
6
|
+
|
|
7
|
+
構築の**手順**は `docs/007_guides/infra/` に置きます。ここは「どうなっているか」、あちらは「どう作るか」です。
|
|
8
|
+
|
|
9
|
+
## 記述ルール
|
|
10
|
+
|
|
11
|
+
- 環境(本番 / ステージング / 開発)ごとの差異を明記する
|
|
12
|
+
- 構成を変更したら構成図も差し替える(図と文章がずれると、図のほうが信じられてしまう)
|
|
13
|
+
- コスト・可用性・セキュリティ上のトレードオフは ADR に残す
|
|
14
|
+
|
|
15
|
+
## 構成一覧
|
|
16
|
+
|
|
17
|
+
| 環境 | リージョン | 主要サービス | 備考 |
|
|
18
|
+
|---|---|---|---|
|
|
19
|
+
| [本番] | [ap-northeast-1] | [サービス名] | [備考] |
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 005_architecture/stacks — 技術スタック
|
|
2
|
+
|
|
3
|
+
> 本ドキュメントは `docs/005_architecture/stacks/README.md` の **テンプレート** です。
|
|
4
|
+
|
|
5
|
+
本ディレクトリは、**採用している言語・フレームワーク・ライブラリとそのバージョン**、および選定理由を整理する場所です。
|
|
6
|
+
|
|
7
|
+
## 記述ルール
|
|
8
|
+
|
|
9
|
+
- 依存を追加・更新したら、ここも併せて更新する(`godd-docs` の同期対象)
|
|
10
|
+
- 「なぜそれを選んだか」を残す。選定理由が無いと、後から入れ替えてよいのか判断できない
|
|
11
|
+
- 設計上の意思決定を伴う変更は ADR にも残す
|
|
12
|
+
|
|
13
|
+
## スタック一覧
|
|
14
|
+
|
|
15
|
+
| 層 | 技術 | バージョン | 選定理由 |
|
|
16
|
+
|---|---|---|---|
|
|
17
|
+
| フロントエンド | [技術名] | [x.y.z] | [理由] |
|
|
18
|
+
| バックエンド | [技術名] | [x.y.z] | [理由] |
|
|
19
|
+
| データベース | [技術名] | [x.y.z] | [理由] |
|
|
20
|
+
| インフラ | [技術名] | [x.y.z] | [理由] |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# GoDD ツール一覧(
|
|
1
|
+
# GoDD ツール一覧(39 件)
|
|
2
2
|
|
|
3
3
|
**「こういうことをしたいが、何と言えばいいか」を探すページ**です。上から読む必要はありません。
|
|
4
4
|
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
|---|---|---|
|
|
42
42
|
| 1 | `godd-dev` | **開発の入口。2つの使い方があります。** 受領資料(zip・議事録・文字起こし)やチャットの要望を渡すと**起票モード**(作業に分ける → 起票〔単一なら実装Issue 1件のみ / 複数なら親Issue + 子Issue〕→ 質問投稿 → 実ファイル受領時のみ資料保管 → Issue を番号昇順に1件ずつ実装)、`#<Issue番号>` を渡すと**実装モード**(回答記録 → ATDD 実装 → 品質ゲート → 責務別コミット) |
|
|
43
43
|
| 2 | `godd-check` | 提出する前のチェック。仕様書との食い違い・影響範囲・テスト・今動いているものを壊していないか・秘密情報の混入をまとめて調べる |
|
|
44
|
-
| 3 | `godd-review` | コードのレビュー。指摘を重大度(CRITICAL / MAJOR / MINOR / SUGGESTION
|
|
44
|
+
| 3 | `godd-review` | コードのレビュー。指摘を重大度(CRITICAL / MAJOR / MINOR / SUGGESTION)で分けて返す。コードは直さない。Codex CLI か Claude Code がログイン済みで入っていれば、実装したのとは別の会社の AI にも見てもらう |
|
|
45
45
|
| 4 | `godd-commit` | 変更を意味のまとまりごとに分けて記録し、説明文も作る |
|
|
46
46
|
| 20 | `godd-dev-workflow` | 開発ワークフロー全体(環境構築 → 実装 → テスト → コミット → PR) |
|
|
47
47
|
|
|
@@ -99,7 +99,12 @@
|
|
|
99
99
|
| 31 | `godd-config` | `config.godd` の表示・更新(`GODD_CONFIG` 環境変数でパス指定可)。**リポジトリガード対象外**の唯一のツール |
|
|
100
100
|
| 32 | `godd-comment` | フィードバック機構(画面のスクリーンショット + ピン + コメント → GitHub Issue を自動で起票)の導入。**GoDD Notes を導入済みのプロジェクト向け** |
|
|
101
101
|
| 33 | `godd-slack-question` | Issue の不明点を Slack のスレッドで PM に質問し、スレッドの URL を Issue に記録する |
|
|
102
|
-
| 34 | `godd-knowledge-save` |
|
|
102
|
+
| 34 | `godd-knowledge-save` | 作業中に得た知見を保存する。**自分から頼んだときだけ動きます**。保存先は自分に付与された project のどれか |
|
|
103
|
+
| 35 | `godd-knowledge-projects` | 知見の保存先にできる project(自分に付与されたもの)の一覧を見る。保存か検索が使えるなら自動で使えます |
|
|
104
|
+
| 36 | `godd-knowledge-search` | 蓄積された知見を検索する(意味の近さとキーワードの両方で探します)。頼んだときに加え、`godd-dev` が判断に迷う場面などで自分から引きます。探せるのは自分に付与された project の知見だけ |
|
|
105
|
+
| 37 | `godd-knowledge-attachment` | 検索結果に出た添付ファイルのダウンロード URL を取得する(**約 1 時間で使えなくなります**) |
|
|
106
|
+
| 38 | `godd-knowledge-search-general` | 他の案件の知見を、会社名・人名を外した形(一般層)で検索する。頼んだときに加え、`godd-dev` が判断に迷う場面などで自分から引きます。どの案件の知見かは分かりません |
|
|
107
|
+
| 39 | `godd-dev-actions` | GitHub Actions での無人実行用の `godd-dev`(GoDD Maintenance の修正 Actions が使う)。**人が手元で使うときは `godd-dev` を使います** |
|
|
103
108
|
|
|
104
109
|
---
|
|
105
110
|
|
|
@@ -65,8 +65,6 @@ GoDD は **2 系統のインターフェース** を提供します。
|
|
|
65
65
|
| `godd-sync` | `main` ブランチを最新化(コンフリクトは SSOT 準拠側を優先) |
|
|
66
66
|
|
|
67
67
|
> **残りは [godd_tools.md](./godd_tools.md) にまとめています。** 全ツールの網羅一覧はそちらが正で、本ガイドは使い方に絞ります。
|
|
68
|
-
| `godd-slack-question` | Issue の不明点(「# 質問内容」コメント)を Slack スレッドとして投稿し、スレッド URL を Issue に記録(事前レビュー済みの `config.godd.slack` を読み取り専用で参照) |
|
|
69
|
-
| `godd-comment` | フィードバック機構(画面スクショ + ピン + コメント → Issue 起票)の導入 |
|
|
70
68
|
|
|
71
69
|
---
|
|
72
70
|
|
|
@@ -158,6 +158,12 @@ Step 3 まで完了したら、利用する IDE に応じて MCP を登録しま
|
|
|
158
158
|
|
|
159
159
|
**初回承認(必須)**: プロジェクトスコープの `.mcp.json` は、ファイルがあるだけでは有効化されません。対象プロジェクトで `claude` を起動すると承認ダイアログが表示されるので、`godd` サーバーを**承認**してください。承認状態は `claude mcp list` で確認できます(承認前は `⏸ Pending approval`、承認後は接続済みになります)。
|
|
160
160
|
|
|
161
|
+
### Google 連携(ripla-google)
|
|
162
|
+
|
|
163
|
+
ライセンスに Google 連携の案件が割り当てられている場合だけ、`godd init` が `.cursor/mcp.json` / `.mcp.json` に `ripla-google` も自動で設定します(完了時に「ripla-google(Google 連携 MCP)を設定しました(割当案件 N 件、…)」と表示されます)。割り当てが無いライセンスでは何も追加されません。
|
|
164
|
+
|
|
165
|
+
設定されたら IDE / Claude Code を再起動し、`/mcp` で `ripla-google` が connected になっていることを確認してください。Claude Code では `godd` と同じく初回の承認が必要です。
|
|
166
|
+
|
|
161
167
|
以下の手動登録は、`.mcp.json` の自動生成を使わない場合(生成前のバージョン、またはプロジェクト外スコープで登録したい場合)のフォールバック手順です。
|
|
162
168
|
|
|
163
169
|
Claude Code では `claude mcp` コマンドで MCP サーバーを登録します。
|
|
@@ -9,9 +9,15 @@
|
|
|
9
9
|
|
|
10
10
|
| 用途 | 参照先 |
|
|
11
11
|
|---|---|
|
|
12
|
-
| 埋め方のサンプル |
|
|
12
|
+
| 埋め方のサンプル | `003_requirements/【仕様書サンプル】*.md`(ユーザー管理・権限管理機能 / 通知機能 / 受注・出荷一覧) |
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
## このファイルの役割(重要)
|
|
15
|
+
|
|
16
|
+
本ファイルの「ディレクトリ構成」は、**コピー先プロジェクトの `docs/README.md` になります**。そして `godd-docs` は実行のたびにコピー先の `docs/README.md` を読み、**そこに書かれた構造を正として実リポジトリと突き合わせ、不足しているドキュメントを作成します**。
|
|
17
|
+
|
|
18
|
+
したがって、ここに書かれていないものは作られません。構成を変えたときは、このツリーと実ファイルの両方を更新してください。
|
|
19
|
+
|
|
20
|
+
ツリー中の `<...>` は**可変部分のプレースホルダー**であり、ファイル名ではありません。`<feature_name>.md` という名前の実ファイルを作らないでください。
|
|
15
21
|
|
|
16
22
|
---
|
|
17
23
|
|
|
@@ -30,24 +36,30 @@ docs/
|
|
|
30
36
|
│ └── <business_flow_name>.drawio # 特定業務のビジネスフローを図示
|
|
31
37
|
├── 003_requirements/
|
|
32
38
|
│ ├── README.md ## フォルダの説明・requirements 一覧
|
|
39
|
+
│ ├── 【仕様書】フォーマット①(ビジネスサイド向け).md ## 仕様書の雛形(既定)
|
|
40
|
+
│ ├── 【仕様書】フォーマット②(エンジニア向け).md ## 仕様書の雛形(技術寄りの記述が必要な場合)
|
|
41
|
+
│ ├── 【仕様書サンプル】<機能名>.md ## 雛形の埋め方サンプル(3 本を同梱)
|
|
33
42
|
│ ├── spec/
|
|
34
43
|
│ │ └── README.md ## 仕様 SSOT(API 仕様・インフラ仕様等)の説明
|
|
35
44
|
│ └── <Product Name>/
|
|
36
|
-
│ └── <feature_name>.
|
|
45
|
+
│ └── <feature_name>.md # 機能別の要件定義(フォーマット①から作成)
|
|
37
46
|
├── 004_pages/
|
|
38
47
|
│ ├── README.md ## フォルダの説明
|
|
39
48
|
│ └── app/
|
|
40
|
-
│
|
|
41
|
-
│
|
|
42
|
-
│ │ └── <page_name>.template.md ## 画面ごとの画面要件を記載
|
|
43
|
-
│ └── users/
|
|
49
|
+
│ └── <url path>/ # 画面の URL パスをそのままフォルダ構造にする
|
|
50
|
+
│ └── requirements.md # 画面ごとの画面要件を記載
|
|
44
51
|
├── 005_architecture/
|
|
45
52
|
│ ├── README.md ## フォルダの説明
|
|
46
|
-
│ ├── stacks/
|
|
47
|
-
│
|
|
48
|
-
│ ├──
|
|
49
|
-
│
|
|
53
|
+
│ ├── stacks/
|
|
54
|
+
│ │ └── README.md ## 技術スタック(言語・FW・ライブラリとバージョン)
|
|
55
|
+
│ ├── api/
|
|
56
|
+
│ │ └── README.md ## API 設計(Swagger / OpenAPI 等)
|
|
57
|
+
│ ├── db/
|
|
58
|
+
│ │ └── README.md ## DB 設計(ER 図・テーブル定義)
|
|
59
|
+
│ ├── infra/
|
|
60
|
+
│ │ └── README.md ## インフラアーキテクチャの設計
|
|
50
61
|
│ └── features/
|
|
62
|
+
│ ├── README.md ## 機能設計書の置き場(1 機能 = 1 ファイル)
|
|
51
63
|
│ └── <feature_name>.md # 機能設計書(データフロー / DB 設計)
|
|
52
64
|
├── 006_development_workflow/
|
|
53
65
|
│ ├── README.md ## フォルダの入口・読む順
|
|
@@ -68,7 +80,7 @@ docs/
|
|
|
68
80
|
│ ├── setup_godd_notes.md ## GoDD Notes の構築手順
|
|
69
81
|
│ ├── setup_local_environment.template.md ## ローカル環境構築
|
|
70
82
|
│ ├── bot-token-setup.md ## GitHub App の設定
|
|
71
|
-
│ └── infra/
|
|
83
|
+
│ └── infra/ ## インフラ担当向け
|
|
72
84
|
│ ├── README.md ## 入口・読む順
|
|
73
85
|
│ ├── setup_infra.template.md ## インフラ CI/CD 構築
|
|
74
86
|
│ ├── setup_aws_accounts.md ## AWS アカウント構成
|
|
@@ -126,10 +138,11 @@ godd init # config.godd / .cursor/mcp.json を生成
|
|
|
126
138
|
|---|---|
|
|
127
139
|
| `001_project/README.md` | プロジェクト立ち上げ時に PM が記入 |
|
|
128
140
|
| `001_project/pages.csv` / `features.csv` | 立ち上げ〜キックオフまでに PM が記入。以降は変更を Issue で管理 |
|
|
129
|
-
| `003_requirements/<Product>/<
|
|
130
|
-
| `004_pages
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
141
|
+
| `003_requirements/<Product Name>/<feature_name>.md` | 機能追加時に PM が新規作成(雛形は `【仕様書】フォーマット①`) |
|
|
142
|
+
| `004_pages/app/<url path>/requirements.md` | 画面追加時に PM / デザイナーが新規作成 |
|
|
143
|
+
| `005_architecture/features/<feature_name>.md` | 機能の設計が決まった時点で作成・更新 |
|
|
144
|
+
| `006_development_workflow/` のテンプレート | プロジェクト立ち上げ時に **チーム方針に合わせて書き換え** |
|
|
145
|
+
| `007_guides/setup_local_environment.template.md` / `007_guides/infra/setup_infra.template.md` | ローカル環境・インフラの構成変更時に更新 |
|
|
133
146
|
|
|
134
147
|
---
|
|
135
148
|
|
|
@@ -172,7 +185,7 @@ flowchart LR
|
|
|
172
185
|
|
|
173
186
|
- 「特定プロジェクトの事情」ではなく、**他プロジェクトでも有用な汎用化された改善** を反映する(プロジェクト固有の内容は持ち込まない)
|
|
174
187
|
- 構成・章立てを変える場合は、既に godd init 済みのプロジェクトへの影響(差分の取り込み方法)も PR 本文に書く
|
|
175
|
-
-
|
|
188
|
+
- 変更は GoDD リポジトリ側のテンプレート群にまとめて反映する(配布元の SSOT。本ファイルのコピー先プロジェクトには存在しない)
|
|
176
189
|
|
|
177
190
|
---
|
|
178
191
|
|