Newer
Older
client_dwatch / docs / handoff / 指示書BA_編集モードの3画面の見た目と文言を揃える_20261019.md

指示書BA — 編集モードのある3画面(エラー一覧・アラート・D-Sec アラート)の見た目と文言を揃える

日付: 2026-10-19 / 担当: Cursor / 基点: develop 657c6ff(作業ツリーは空) 前提: D-165(編集モード)/D-161(プルダウン)/D-162(固定幅・解消日時 12px)/D-171(控えめなカード)/D-180(D-Sec アラート。特に 7b)/指示書AX・AZ/ CLAUDE.md §0-3(日本語フォント)・§6・§7・§9.6(モックが画面の正・JP/EN の器を壊さない)

★行番号はすべて 2026-10-19 に develop 657c6ff で確かめたもの★。同じファイルを上から直すと後ろの行はずれるので、★2つ目以降の場所は引用した文言・クラス名で探し直すこと★。

★本書は「書いてあることを全部やる」前提で、直す場所を1つずつ挙げてある★。「ほかにも同じものがあれば直す」とは書かない — ★見つけたら §2 のルールで直し、作業報告に書く★。

★git add -A・git add . は禁止★(CLAUDE.md §7)。★ファイルパスを1つずつ書く★。★push しない★(§11)。


0. 何をするか

# やること 種類 段階
1 ★解消日時が、下書きで「未解消」「対応中」に戻した行にも出たまま★(エラー一覧・D-Sec)。アラートと同じく下書きも見る。★判定を純粋関数1本にしてテストする★ 不具合 段階1
2 アラートの「読み込み中…」と取得失敗の文言が t() を通っていない(EN で日本語のまま) 不具合 段階1
3 対応状況の列の幅がモードの切り替えで変わる → ★3画面ともバッジ・プルダウンを 120px 固定★(アラートの形) 見た目 段階2
4 D-Sec の編集モードで、備考の入力欄が右の列に移る → ★左の本文(備考の行の位置)に出す★ 見た目 段階2
5 変えた行の目印が3画面でばらばら → カードの2画面は D-Sec の形(背景 --sf-h+上・右・下の枠 --ac)、エラー一覧(表)は今の形のまま 見た目 段階2
6 アラートの「編集」ボタンだけ絞り込みの行の右端・塗りの見た目 → ★見出しの右・エラー一覧 / D-Sec と同じボタン★ 見た目 段階2
7 解消日時の寄せが D-Sec だけ右 → ★3画面とも左寄せ★ 見た目 段階2
8 編集中の絞り込みの薄くし方が3画面でばらばら(エラー一覧は「~」「指定なし(全期間)」が濃いまま) → ★絞り込み全体を 0.5・中の部品すべて禁止カーソル★ 見た目 段階2
9 「編集中は絞り込みとページ送りを使えません」の余白と、失敗件数の置き方がアラートだけ違う → ★D-Sec の .editNotice の形(失敗件数は同じ行)★ 見た目 段階2
10 アラートの出発失敗の行のバッジだけ幅が固定されていない(「解消 (日時)」を1つのバッジに入れる作り) → ★事前チェックの行と同じ 120px のバッジ+下に解消日時★ 見た目 段階2
11 ★D-Sec の状態ボタンと数値カードの文言をアラート画面に揃える★(ユーザー決定 2026-10-19) 文言 段階3
12 ★決定 D-181 を追記★し、docs/code-map.md・docs/spec.md・docs/fixtures.md を追従させる 資料 段階4

★変えないもの★: API・データ層・型(app/api/**・lib/db/**・lib/types/**・d-watch-api.yaml)/取得・保存・下書きの ★ロジック★(saveDrafts() 等)/ 3画面の対応状況のバッジとプルダウンの文言「未解消 / 対応中 / 解消」(3画面の STATUS_OPTIONS / RESOLUTION_STATUS_OPTIONS)/D-Sec の数値カードの枚数(3枚)と下の小さい文字(即時対応 / 進行中 / 完了)/ D-Sec の種別のセレクト・副題(D-180 7b)/エラー一覧の列幅(--col-status: 150px ほか。表の最小幅 1130px のまま)/d-watch-mock.jsx。


1. 背景

  • 指示書AZ(AX のレビュー指摘)の後、2026-10-19 に監督が3画面の編集モードを並べて見比べた(監督の画面確認・fixtures)。その前のコミット 657c6ff で、エラー一覧の編集中のページ送りのカーソルだけを先に揃えた。
  • ★見比べで、上の #1〜#10 が出た★(#1・#2 は不具合寄り、#3〜#10 は見た目)。#11 はユーザー決定(2026-10-19「11はアラートの方にD-SECを揃えるようにしてください」)。
  • ★テストの件数(657c6ff)★: ★130ファイル / 3,077件 全件通過★(2026-10-19 監督が npx vitest run で実測)。本書の段階1 で6件増える見込み(3,083件)。
  • ★画面の部品のテスト(.test.tsx)はこのリポジトリに無い★(2026-10-19 find で確認)。★画面の文言(「未解消・対応中」「解消」)を固定しているテストも無い★(grep で確認。§7-4)。見た目は ★段階5 の画面確認★ で確かめる。

2. ★共通ルール(本書だけでなく、今後のすべての指示書に当てはまる)★

# ルール 本書での当てはめ
G1 ★API の挙動が変わったら、d-watch-api.yaml の ★影響を受けるパス・スキーマを全部★ 直す★(指示書に挙がっているものだけでなく)。読み・書き・件数(meta.total)・404 の条件・値の例と説明を、grep で関係する語を探して確かめる ★本書は API を変えない★(画面の見た目と文言だけ)。/ds-alerts の status の説明「open=未解消・対応中 / resolved=解消」(d-watch-api.yaml:1487)は ★値の意味の説明なので変えない★(ボタンの文言ではない)。YAML に差分が出たら止まって報告
G2 ★古い挙動を書いた docstring・コメントを残さない★。挙動を変えた関数だけでなく、★その関数・部品を説明している別の場所(ファイル冒頭の説明・CSS のコメント・docs/code-map.md)★も直す 本書の表の「コメントも直す」を全部やる。特に lib/prechecks/edit-drafts.ts:5(「両画面」→ 3画面)・CSS の「幅は列いっぱい」「右列は固定幅 240」「背景の色だけ」・docs/code-map.md の「一覧の上の『編集』」
G3 ★テストは「守る挙動が壊れたら落ちる」ように書く★。空同士の比較や、別の理由でも同じ結果になる比較は検査にならない。★書いたら一度わざと壊して赤になるのを確かめ、戻す★(壊した変更はコミットしない) 段階1 の showsResolvedTime() の表 H1〜H6。★2通りに壊して赤を確かめる★(1-3)
G4 ★決定の記録(docs/decisions.md の「実装の記録」)に、コミット・テスト件数の前後・画面確認の結果(出所つき。CLAUDE.md §6-6)・指示書と違う判断を書く★ 段階4 の D-181 の「実装の記録」

3. 落とし穴

# 罠 どう避けるか
3-1 ★git add -A・git add .★ 禁止。ファイルパスを1つずつ書く。各コミットの前に git diff --cached --name-status で中身を目で確かめる
3-2 ★他のセッションの変更を巻き込む★ ★着手前と各コミットの前に git status --short を見る★。§9 に無いファイルに変更があれば ★他のセッションのもの★。触らない・含めない。★docs/decisions.md は段階4 で末尾に追記するので、追記の前に git diff -- docs/decisions.md が空であることを確かめ、他人の差分があれば止まって報告★
3-3 ★CSS の不透明度が二重にかかる★(0.5 × 0.5 = 0.25) 項8 で新しい規則を足すときは、★古い規則(部品ごとの opacity: 0.5)を必ず消す★(表に「消す」と書いた行)
3-4 ★background の一括指定で ▼ が消える★ .statusSelect の ▼ は background-image。★状態の色は background-color のまま★(既存の注意書き。触らない)
3-5 ★font-family を宣言する★ ★宣言しない★(CLAUDE.md §0-3)。ボタンをアラートに写すときも、D-Sec の .editButton 一式には font-family が無いのでそのまま写す
3-6 ★新しい色を作る★ ★既存の CSS 変数(--sf-h・--ac・--bd 等)だけ★
3-7 ★画面の文言を「その他」っぽく直す・EN を勝手に作る★ 足す訳は §段階3 の2つだけ(モック d-watch-mock.jsx:140 の対訳)
3-8 ★ロジックまで直してしまう★ 取得・保存・下書き・canStartEdit などの条件は変えない。★本書で変える実行行は表に挙げたものだけ★
3-9 ★push する★ ★監督のレビューが終わるまで push しない★

段階0 — 着手前

  1. ★develop の本体で作業する★(.claude/worktrees/ の中ではない)。git log --oneline -1 が 657c6ff(またはその後の docs だけのコミット)であること。
  2. git status --short を控える。本書が未追跡で1行あるのはよい(★本書はコミットに含めない★。監督がコミットする)。 ★2026-10-19 の本書作成時点で、他のセッションの docs/handoff/pdf/README.md(変更)・docs/handoff/pdf/*_qa13_pdf.py(未追跡2本)があった★ — ★触らない・含めない★(3-2)。それ以外の見知らぬ行があれば誰のものか確かめてから進む。
  3. npx tsc --noEmit -p . → npm run lint → npm test。★テストのファイル数と件数を控える★(期待: 130ファイル / 3,077件)。
  4. ★見出しの下の余白を測っておく★(項6 で使う。§段階2 の 2-6c)。§段階5 の手順で :3100 を立てたあと、/alerts・/errors・/ds-alerts で次を実行し、値を控える:
    // 副題の下端 → 次の要素(数値カード、エラー一覧はカード)の上端
    const sub = document.querySelector('[class*="__subtitle"]').getBoundingClientRect().bottom;
    const next = document.querySelector('[class*="__statGrid"], [class*="__card"]').getBoundingClientRect().top;
    next - sub;
    ★監督の読み(未確認)★: アラートは ★16★(.header の 4px と .subtitle の 16px は、CSS のマージンの相殺で 16px になる)/エラー一覧は 16/D-Sec は 20。 ★アプリ内ブラウザが使えなければ、この測定は飛ばし、2-6c は 16px にする★(作業報告にそう書く)。

段階1 — 不具合(項1・項2)

1-1. 解消日時を出すかどうかを純粋関数にする — lib/prechecks/edit-drafts.ts

★今の挙動★: エラー一覧(components/features/errors/ErrorsScreen.tsx:611)と D-Sec(components/features/ds-alerts/DsAlertsScreen.tsx:570)は ★保存済みの値(item.resolution_status === "resolved")だけ★を見ている。 解消の行を編集モードで「未解消」「対応中」に変えても、★プルダウンの下に解消日時が出たまま★になる(保存すると解消日時はサーバーが消す — lib/prechecks/status-update.ts:71-75 の「戻すと消す」)。 アラート(components/features/alerts/AlertsScreen.tsx:649)は status === "resolved" && item.resolution_status === "resolved" で下書きも見ている(正しい)。

  1. draftNote()(:35-38)の直後に足す:
/**
 * 解消日時を出すか(対応状況のバッジ・プルダウンの下)。★保存済みの値が解消で、かつ画面に出す対応状況(下書き優先)も解消のときだけ★
 * (指示書BA 項1。D-181)。3画面(エラー一覧・アラート・D-Sec アラート)がこの1本を使う。
 * ・★下書きで解消にしただけの行には出さない★(解消日時は保存したときにサーバーが決める)
 * ・★保存済みが解消でも、下書きで未解消・対応中に変えた行には出さない★(保存すると解消日時は消える — `status-update.ts` の「戻すと消す」)
 */
export function showsResolvedTime(row: EditableRow, draft: ResolutionDraft | undefined): boolean {
  return row.resolution_status === "resolved" && draftStatus(row, draft) === "resolved";
}
  1. ★冒頭の docstring(:5)を直す(G2)★:
    • 今: 対象はエラー一覧(/errors)とアラート(/alerts)の両画面 — ★両画面がこのモジュールを使う★。
    • 直す: 対象はエラー一覧(/errors)・アラート(/alerts)・D-Sec アラート(/ds-alerts)の3画面 — ★3画面がこのモジュールを使う★(D-Sec は指示書AX から)。
    • 同じ docstring の :7 の (P1〜P8 / D1〜D5 / S1〜S3) → (P1〜P8 / D1〜D5 / S1〜S3 / H1〜H6)
  2. :18 の /** 下書きの対象の行。★\ErrorReportItem` も同じ3つを持つので両画面で使える★ /→/** 下書きの対象の行。★`ErrorReportItem`・`DsAlert` も同じ3つを持つので3画面で使える★ /`

1-2. テスト — lib/prechecks/__tests__/edit-drafts.test.ts(★期待値表を先に★)

# 行 下書き 期待 守るもの
H1 T(解消) なし ★出す★ 通常の解消の行
H2 T(解消) { status: "unresolved" } ★出さない★ ★項1 の不具合★
H3 T(解消) { status: "in_progress" } ★出さない★ ★項1 の不具合★
H4 T(解消) { note: "x" }(備考だけ) ★出す★ 備考だけ変えた解消の行
H5 R(未解消) { status: "resolved" } ★出さない★ 下書きで解消にしただけ(日時がまだ無い)
H6 S(対応中) なし ★出さない★ 解消でない行

(R / S / T はファイル冒頭 :23-25 の既存の行。新しい行は作らない)

  1. import(:10-20)に showsResolvedTime, を足す(setDraftStatus, の次。アルファベット順の並びは崩してよい — 既存も順不同)
  2. ★ファイル冒頭の docstring(:4)の (P1〜P8 / D1〜D5 / S1〜S3) → (P1〜P8 / D1〜D5 / S1〜S3 / H1〜H6)★
  3. describe("setDraftStatus / setDraftNote / draftNote(D1〜D5)", …)(:52-95)の閉じ }); の直後(describe("saveDrafts(S1〜S3)" の前)に足す:
describe("showsResolvedTime(H1〜H6。指示書BA 項1・D-181)", () => {
  const cases: [string, EditableRow, ResolutionDraft | undefined, boolean][] = [
    ["H1 T(解消)・下書きなし → 出す", T, undefined, true],
    ["H2 T(解消)・下書きで未解消 → 出さない", T, { status: "unresolved" }, false],
    ["H3 T(解消)・下書きで対応中 → 出さない", T, { status: "in_progress" }, false],
    ["H4 T(解消)・備考だけ変えた → 出す", T, { note: "x" }, true],
    ["H5 R(未解消)・下書きで解消 → 出さない(日時はまだ無い)", R, { status: "resolved" }, false],
    ["H6 S(対応中)・下書きなし → 出さない", S, undefined, false],
  ];
  it.each(cases)("%s", (_label, row, draft, expected) => {
    expect(showsResolvedTime(row, draft)).toBe(expected);
  });
});

1-3. ★壊して確かめる(G3)★ — 2回。壊した変更はコミットしない

  1. showsResolvedTime() の中身を一時的に return row.resolution_status === "resolved";(=今のエラー一覧・D-Sec の判定)にする → ★H2・H3 が赤★ → 戻す
  2. 一時的に return draftStatus(row, draft) === "resolved"; にする → ★H5 が赤★ → 戻す

1-4. 3画面で使う

# ファイル:行(今) 今 直す
1-4a components/features/errors/ErrorsScreen.tsx:22-29(import) draftNote, draftStatus, saveDrafts, setDraftNote, setDraftStatus, type ResolutionDrafts, setDraftStatus, の次の行に showsResolvedTime, を足す(1行増える)
1-4b components/features/errors/ErrorsScreen.tsx:609-611 コメント {/* 解消のときだけ解消日時を下に出す。★保存済みの値(\item`)で判定する★ —/下書きで「解消」を選んだだけではまだ解消日時が無い */}と{item.resolution_status === "resolved" && (` コメント(2行)を次の2行に:
{/* 解消のときだけ解消日時を下に出す(\showsResolvedTime()`。3画面で同じ)。★下書きで「解消」にしただけの行と、<br> 下書きで未解消・対応中に変えた行には出さない★(指示書BA 項1。D-181) */}<br>条件を{showsResolvedTime(item, draft) && (` に
1-4c components/features/ds-alerts/DsAlertsScreen.tsx:20-27(import) 同上 setDraftStatus, の次の行に showsResolvedTime, を足す
1-4d components/features/ds-alerts/DsAlertsScreen.tsx:568-570 1-4b と同じコメントと {item.resolution_status === "resolved" && ( 1-4b と同じに直す。★この行は段階2 の 2-4 で動かすので、段階2 では直した後の形のまま動かす★
1-4e components/features/alerts/AlertsScreen.tsx:20-27(import) 同上 setDraftStatus, の次の行に showsResolvedTime, を足す
1-4f components/features/alerts/AlertsScreen.tsx:647-649 コメント {/* 解消日時は解消のときだけ下に出す(未解消・対応中では何も出さない)。 / ★下書きで解消にしただけの行には出さない★(日時は保存したときにサーバーが決める) */} と {status === "resolved" && item.resolution_status === "resolved" && ( 条件を {showsResolvedTime(item, draft) && ( に(★意味は同じ★。status は draftStatus(item, draft)(:546))。コメントの末尾に (\showsResolvedTime()`。3画面で同じ。D-181)` を足す。★この箇所は段階2 の 2-10 で書き直すので、そこで最終形にする★

1-5. アラートの「読み込み中…」と取得失敗の文言を t() に通す(項2)

# ファイル:行(今) 今 直す
1-5a components/features/alerts/AlertsScreen.tsx:534 {loading && <div className={styles.loading}>読み込み中…</div>} {loading && <div className={styles.loading}>{t("読み込み中…")}</div>}
1-5b components/features/alerts/AlertsScreen.tsx:535 {!loading && error && <div className={styles.error}>{error}</div>} 直前の行に {/* サーバーの文言は辞書に無ければ原文のまま */} を足し、{!loading && error && <div className={styles.error}>{t(error)}</div>} にする(エラー一覧 ErrorsScreen.tsx:530-531・D-Sec DsAlertsScreen.tsx:499-500 と同じ)
  • 読み込み中…(lib/i18n.ts:75)・データの取得に失敗しました(:381)は辞書にある。★足す訳は無い★

1-6. 確かめてコミット

  • npx tsc --noEmit -p .・npm run lint・npm test(期待: 130ファイル / 3,083件。件数を控える)
  • コミット(5ファイル):
    git add -- lib/prechecks/edit-drafts.ts lib/prechecks/__tests__/edit-drafts.test.ts \
      components/features/errors/ErrorsScreen.tsx components/features/ds-alerts/DsAlertsScreen.tsx \
      components/features/alerts/AlertsScreen.tsx
    git diff --cached --name-status   # この5行だけ
    メッセージの例: fix: 解消の行を下書きで未解消・対応中に戻したら解消日時を隠し、アラートの読み込み中・取得失敗の文言も訳す(指示書BA 項1・2・D-181)

段階2 — 見た目(項3〜10)

★色は既存の CSS 変数だけ・font-family を宣言しない★(3-5・3-6)。★.tsx は表に挙げた箇所だけ★変える。

2-3. 対応状況の幅を 120px に揃える(項3)

★基準はアラート★(AlertsScreen.module.css:273-282 の .statusBadgeFixed と :290-309 の .statusSelect。どちらも 120px・同じ高さ)。

# ファイル:行(今) 今 直す
2-3a components/features/errors/ErrorsScreen.module.css:387-395(.statusBadge) display: inline-block; font-size: 12px; padding: 4px 14px; border-radius: 6px; font-weight: 600; white-space: nowrap;(幅なし) ★display: block; box-sizing: border-box; width: 120px; padding: 4px 8px; border: 1px solid transparent; text-align: center; font-size: 12px; border-radius: 6px; font-weight: 600; white-space: nowrap;★。コメント :387 を /* ★通常モードの対応状況(表示だけ。D-165)★ — ★編集モードのプルダウン(.statusSelect)と同じ 120px・同じ高さ★(モードを切り替えても形が変わらない。アラート・D-Sec と同じ。D-181) */ に
2-3b components/features/errors/ErrorsScreen.module.css:347(.statusSelect の width: 100%;) width: 100%; width: 120px;。コメント :342 の ★幅は列いっぱいの固定幅★(「対応中」と "In progress" で幅が変わらないように。指示書AW 4-17)。 → ★幅は 120px 固定★(「対応中」と "In progress" で幅が変わらないように。バッジと同じ幅。アラート・D-Sec と同じ。D-181)。
2-3c components/features/errors/ErrorsScreen.module.css:247-248(表のコメントの「対応状況 150」) 対応状況 150 : 見出し EN「STATUS」≒76 / 中身は通常モードがバッジ("In progress" ≒100)、編集モードがプルダウン / (下の \.statusSelect`。列幅いっぱいの固定幅。"In progress" + ▼ ≒110)。★どちらも収まる幅★(D-165)` 対応状況 150 : 見出し EN「STATUS」≒76 / 中身はバッジ・プルダウンとも 120px 固定(下の \.statusBadge` / `.statusSelect`。D-181)+ 左右の padding 24/("In progress" + ▼ ≒110 が収まる)。★列の幅(150)は変えない★(D-165)
2-3d components/features/ds-alerts/DsAlertsScreen.module.css:316-328(.statusBadge) display: inline-block;・min-width: 110px;・padding: 4px 14px; ほか(コメント :319 の「≒103px」) ★2-3a と同じ宣言にする★(display: block; box-sizing: border-box; width: 120px; padding: 4px 8px; border: 1px solid transparent; text-align: center; font-size: 12px; border-radius: 6px; font-weight: 600; white-space: nowrap;)。コメントは /* ★通常モードの対応状況(表示だけ。押しても何も起きない)★ — ★編集モードのプルダウンと同じ 120px・同じ高さ★(\AlertsScreen.module.css` の .statusBadge + .statusBadgeFixed と同じ。D-181。旧: min-width 110px・右寄せ — 指示書AZ 4b) */。★:319` の「≒103px」の行は消す★
2-3e components/features/ds-alerts/DsAlertsScreen.module.css:276(.statusSelect の width: 100%;) width: 100%; width: 120px;。コメント :271 の ★幅は列いっぱいの固定幅★。 → ★幅は 120px 固定★(バッジと同じ。D-181)。
2-3f components/features/ds-alerts/DsAlertsScreen.module.css:251-267(.statusColumn と .statusColumnEditing、それぞれのコメント) .statusColumn { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; } と .statusColumnEditing { width: 240px; align-items: stretch; gap: 6px; } ★2つをまとめて次の1つにする(.statusColumnEditing は消す)★:
/*
* カード右の対応状況(通常モードはバッジ、編集モードはプルダウン。解消のときは下に解消日時)。
* ★両モードで幅 120px 固定★ — 切り替えで左の本文の幅が変わり、文字の折り返しが動かないように(アラート画面と同じ。D-181)。
* ★備考の入力欄はここに出さない★(左の本文の \.noteInput`。指示書BA 項4)<br> */<br>.statusColumn {<br> flex-shrink: 0;<br> width: 120px;<br>}`
2-3g components/features/ds-alerts/DsAlertsScreen.tsx:537-543 <div className={ editing ? \${styles.statusColumn} ${styles.statusColumnEditing}` : styles.statusColumn }>`(7行) <div className={styles.statusColumn}>(1行)
2-3h components/features/alerts/AlertsScreen.module.css:340-342(.statusColumn) flex-shrink: 0; flex-shrink: 0; の次に width: 120px; を足し、前にコメント /* カード右の対応状況。★両モードで幅 120px 固定★(中のバッジ・プルダウンと同じ幅。エラー一覧・D-Sec と同じ。D-181) */
2-3i components/features/alerts/AlertsScreen.module.css:273-274(.statusBadgeFixed のコメント) /* ★通常モードの事前チェックの行のバッジ(D-165)★ — 編集モードのプルダウン(.statusSelect)と同じ幅・高さにして、 /* ★通常モードのバッジ(事前チェックの行・出発失敗の行とも。D-165 / D-181)★ — 編集モードのプルダウン(.statusSelect)と同じ幅・高さにして、
  • ★エラー一覧の列幅(--col-status: 150px・表の最小幅 1130px)は変えない★。バッジ・プルダウンは列の中で左に寄り、右に 6px 余る(意図どおり)

2-4. D-Sec の備考の入力欄を左の本文に出す(項4)

★モック(d-watch-mock.jsx:953)も備考はカードの左の本文★(検知の行の下)。アラートも入力欄は左の本文(AlertsScreen.tsx:575-592)。

  1. components/features/ds-alerts/DsAlertsScreen.tsx:534-535 を次に置き換える:
                    {/* 備考。★編集モードの入力欄もここ(左の本文の、備考の行の位置)に出す★ — 対応状況の列には入れない
                        (アラート・エラー一覧と同じく、切り替えで右の列の幅が変わらないように。指示書BA 項4・D-181)。
                        通常モードは ★空なら出さない★。
                        ★入力欄は固定の大きさ★(2行ぶん・`resize: none`・幅は本文いっぱい)。
                        上限超過(422)を画面側で先に防ぐ。上限値の正は lib/config(YAML の maxLength と同じ) */}
                    {editing ? (
                      <textarea
                        className={styles.noteInput}
                        aria-label={t("備考")}
                        value={draftNote(item, draft)}
                        rows={2}
                        maxLength={PRECHECK_NOTE_MAX_LENGTH}
                        placeholder={t("備考を入力")}
                        disabled={saving}
                        onChange={(e) => changeDraftNote(item, e.target.value)}
                      />
                    ) : (
                      item.note && <div className={styles.noteLine}>{item.note}</div>
                    )}
  1. ★右の列の {editing && ( … <textarea … /> )}(今の :575-588)は消す★(上に移したので)。
  2. components/features/ds-alerts/DsAlertsScreen.module.css:358-375(.noteInput)の width: 100%; の次に margin-top: 6px; を足し、コメント /* 通常モードの備考の行(.noteLine)と同じ位置から始める */ を付ける。:370 のコメント ★大きさは固定★ — 2行ぶんの高さ。 → ★大きさは固定★ — 2行ぶんの高さ・幅は左の本文いっぱい。

段階2 の後の D-Sec の右の列は次の形になる(2-3g・1-4d・2-4 の結果。★これと違えば直す★):

                  <div className={styles.statusColumn}>
                    {editing ? (
                      <select …(今の :547-559 のまま)… />
                    ) : (
                      <span className={`${styles.statusBadge} ${statusBadgeClass(item.resolution_status)}`}>…</span>
                    )}
                    {/* 解消のときだけ解消日時を下に出す(`showsResolvedTime()`)。… */}
                    {showsResolvedTime(item, draft) && (
                      <div className={styles.statusTime}>
                        {item.resolved_at ? formatDateTime(item.resolved_at) : "-"}
                      </div>
                    )}
                  </div>

2-5. 変えた行の目印(項5)

# ファイル:行(今) 今 直す
2-5a components/features/alerts/AlertsScreen.module.css:180-184(.itemCardChanged) background: color-mix(in srgb, var(--pr) 8%, var(--sf));/コメント「背景をうっすら色付けする。★左の帯(border-left)は分類の色なので変えない★」 ★D-Sec(DsAlertsScreen.module.css:187-194)と同じ★: background: var(--sf-h); border-top-color: var(--ac); border-right-color: var(--ac); border-bottom-color: var(--ac);。コメントは /* ★変えた行(下書きがある行)の目印(D-165)★ — 背景(\--sf-h`)と上・右・下の枠(`--ac`)。★左の帯(border-left)は分類の色なので変えない★(D-Sec アラートと同じ形。エラー一覧の表は背景+左端の帯。D-181) */`
2-5b components/features/alerts/AlertsScreen.tsx:552-553(カードの class のコメント) /* ★変えた行の目印は背景の色(\.itemCardChanged`)★ — 左の帯は分類の色なので変えない(D-165)。` /* ★変えた行の目印は背景と上・右・下の枠(\.itemCardChanged`。D-Sec と同じ。D-181)★ — 左の帯は分類の色なので変えない(D-165)。`
2-5c components/features/ds-alerts/DsAlertsScreen.module.css:187-188(.itemCardChanged のコメント) /* ★編集モードで変えたカードの目印★(\ErrorsScreen.module.css` の .rowChanged と同じ色)。` /* ★編集モードで変えたカードの目印★(背景は \ErrorsScreen.module.css` の .rowChanged と同じ色。アラートも同じ形。D-181)。`(中身は変えない)
  • ★エラー一覧(ErrorsScreen.module.css:312-320 の .rowChanged)は変えない★ — 背景は既に var(--sf-h)。表の行なので「背景+左端の帯(box-shadow)」のまま(カードの枠の形を表の行に当てはめない)

2-6. アラートの「編集」ボタンを見出しの右に移す(項6)

★モックとの関係(2026-10-19 確認)★: モックのアラート画面(d-watch-mock.jsx:583-584)は見出しと副題だけで、★「編集」ボタン自体が無い★(D-165 で足したもの)。 D-165 の決定は「一覧の上の『編集』で編集モードに入る」で、見出しの右も絞り込みの行の右も「一覧の上」に当たる。モックでも見出しの右にボタンを置く画面がある(レポート :647-650)。★モックと食い違わない★と判断した(§10 Q1)。

2-6a. components/features/alerts/AlertsScreen.tsx

  1. 見出し(:360-363)を次に置き換える(D-Sec DsAlertsScreen.tsx:314-358 と同じ形):
      <div className={styles.header}>
        <div>
          <h1 className={styles.title}>{t("アラート(事前チェック)")}</h1>
          <div className={styles.subtitle}>{t("スケジュール開始前のエラー検知と出発失敗")}</div>
        </div>
        <div className={styles.headerRight}>
          {/* ★編集 / 保存({n}件)/ キャンセル(D-165)★ — 見出しの右(エラー一覧・D-Sec と同じ位置・同じ見た目。D-181)。
              ★ボタンは固定幅★(JP/EN や件数で位置が動かないように) */}
          {editing ? (
            <>
              <button
                type="button"
                className={`${styles.editButton} ${styles.saveButton}`}
                disabled={saving}
                onClick={() => void saveEdits()}
              >
                {saving
                  ? t("保存中…")
                  : drafts.size > 0
                    ? t("保存({n}件)").replace("{n}", String(drafts.size))
                    : t("保存")}
              </button>
              <button
                type="button"
                className={`${styles.editButton} ${styles.cancelButton}`}
                disabled={saving}
                onClick={cancelEditMode}
              >
                {t("キャンセル")}
              </button>
            </>
          ) : (
            <button
              type="button"
              className={`${styles.editButton} ${styles.startButton}`}
              /* 編集できる行(事前チェック)が無いときは押せない(押しても何も変えられない) */
              disabled={loading || editableCount === 0}
              onClick={startEditMode}
            >
              {t("編集")}
            </button>
          )}
        </div>
      </div>
  1. ★絞り込みの行の右端の {/* ★編集 / 保存({n}件)/ キャンセル(D-165)★ — 絞り込みの行の右端。…*/} と <div className={styles.editActions}> … </div>(今の :483-520)は消す★。.toolbar の <div> と中の <fieldset className={styles.filterSet}> は残す。
  2. ★押せる条件(loading || editableCount === 0)・saveEdits / cancelEditMode / startEditMode は変えない★(3-8)

2-6b. components/features/alerts/AlertsScreen.module.css

# 場所(今) 今 直す
1 :5-7(.header) margin-bottom: 4px; display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: <段階0-4 で測ったアラートの値>px; gap: 12px; flex-wrap: wrap;。コメント /* 見出し(左: タイトルと副題・右: 編集のボタン)。★余白は直す前の見た目(段階0-4 で測った値)に合わせる★(指示書BA 項6) */。★測れなかったら 16px★
2 :15-19(.subtitle) margin-bottom: 16px; を含む ★margin-bottom: 16px; の行を消す★(余白は .header が持つ。D-Sec :28-31 と同じ)
3 :70-104(.editActions・.editButton・.editButtonPrimary・.editButton:disabled とそのコメント) 絞り込みの行の右端・min-width 96 / 112・塗りの主ボタン ★消して、DsAlertsScreen.module.css:33-87(/* 見出しの右: 編集モードのボタン */ の .headerRight から .saveButton:disabled, .cancelButton:disabled { cursor: progress; } まで)をそのまま写す★。写したコメントの「ErrorsScreen.module.css の .editButton 等と同じ」は残す
  • 写した後のボタン: 「編集」= .startButton(幅 88px・枠線あり・背景なし)/「保存(N件)」= .saveButton(幅 120px・背景 --pr-d・文字 --pr)/「キャンセル」= .cancelButton(幅 100px・枠線あり・背景なし)。★3画面で同じ★

2-6c. 見出しの下の余白

  • ★アラートは段階0-4 で測った値を保つ★(2-6b 1)。★D-Sec(20px。指示書AZ 4d)とエラー一覧(16px)は変えない★。3画面で値が違えば作業報告に書く(§10 Q3。監督が決める)

2-7. 解消日時を3画面とも左寄せにする(項7)

# ファイル:行(今) 今 直す
2-7a components/features/ds-alerts/DsAlertsScreen.module.css:330-335(.statusTime) font-size: 12px; color: var(--tx-m); white-space: nowrap; 先頭に margin-top: 2px; を足す(アラート :333 と同じ。列の gap を消したため)。コメント :330 を /* 解消のときだけバッジ・プルダウンの下に出す解消日時。★左寄せ(3画面とも。D-181)★ */ に
2-7b components/features/ds-alerts/DsAlertsScreen.module.css:337-340(.statusColumnEditing .statusTime { text-align: right; } とそのコメント) 右寄せ ★消す★(.statusColumnEditing は 2-3f で無くなった)
2-7c components/features/errors/ErrorsScreen.module.css:397(.statusTime のコメント) /* 解消のときだけバッジ・プルダウンの下に出す解消日時 */ /* 解消のときだけバッジ・プルダウンの下に出す解消日時。★左寄せ(3画面とも。D-181)★ */(中身は変えない)
2-7d components/features/alerts/AlertsScreen.module.css:331(.statusTime のコメント) /* 解消のときだけプルダウンの下に出す解消日時(旧ボタンの「解消 (日時)」の日時部分) */ /* 解消のときだけバッジ・プルダウンの下に出す解消日時(旧ボタンの「解消 (日時)」の日時部分)。★左寄せ(3画面とも。D-181)★ */(中身は変えない)

2-8. 編集中の絞り込みの薄くし方とカーソル(項8)

★基準はアラート★(AlertsScreen.module.css:49-60: 絞り込み全体を opacity: 0.5・中の部品すべて cursor: not-allowed)。★アラートは変えない★。

# ファイル:行(今) 今 直す
2-8a components/features/errors/ErrorsScreen.module.css:178-185 .toolbar:disabled .dateInput, .toolbar:disabled .select, .toolbar:disabled .searchInput, .toolbar:disabled .checkLabel { opacity: 0.5; cursor: not-allowed; }(「~」と「指定なし(全期間)」(.dateSep)が濃いまま) ★消して(3-3)、次の2つにする★:
/* 編集中(\.toolbar` の fieldset が disabled)は絞り込みを薄くして押せない見た目にする(D-165)。<br> ★子要素ごと(`> `)に薄くする★ — fieldset 自体に opacity をかけると、カードの区切り線(`.toolbar` の border-bottom)まで薄くなるため。<br> 「~」「指定なし(全期間)」も含めて全部薄くする(アラート・D-Sec と同じ見た目。D-181) /<br>.toolbar:disabled > {<br> opacity: 0.5;<br>}<br><br>/ 中の部品すべてを禁止カーソルにする(`.dateInput` / `.checkLabel` の `cursor: pointer` より詳細度が高い。アラート・D-Sec と同じ) /<br>.toolbar:disabled {<br> cursor: not-allowed;<br>}`
2-8b components/features/ds-alerts/DsAlertsScreen.module.css:131-135 .toolbar:disabled .select, .toolbar:disabled .statusButtons { opacity: 0.5; } ★.toolbar:disabled { opacity: 0.5; } にする★(中の部品を個別に挙げない。アラートの .filterSet:disabled と同じ)。コメント :131 は /* 編集中(\.toolbar` の fieldset が disabled)は絞り込み全体を薄くする(アラートと同じ。D-181) */`
  • D-Sec の .toolbar:disabled *(:140)とページ送りの規則(:141-144)・エラー一覧のページ送りの規則(:211-221)は ★変えない★(657c6ff で揃え済み)
  • ★> * の不透明度と、ページ送り・ボタンの :disabled の不透明度は重ならない★(別の要素)

2-9. 「編集中は絞り込みとページ送りを使えません」の形(項9)

★基準は D-Sec★(DsAlertsScreen.module.css:146-159: 横並び(display: flex)・失敗件数は同じ行・下に 12px)。

# ファイル:行(今) 今 直す
2-9a components/features/alerts/AlertsScreen.module.css:106-117(.editNotice・.editFailed) margin: -8px 0 12px;・.editFailed { margin-top: 4px; … }(失敗件数は次の行) ★消して、DsAlertsScreen.module.css:146-159(.editNotice と .editNoticeError。コメントごと)をそのまま写す★
2-9b components/features/alerts/AlertsScreen.tsx:523-532 <div className={styles.editNotice}><div>{t("編集中は…")}</div>{failedCount > 0 && (<div className={styles.editFailed}>…</div>)}</div> ★D-Sec(DsAlertsScreen.tsx:486-496)と同じ形★: 外側は <div className={styles.editNotice}> のまま、文言を <span>{t("編集中は絞り込みとページ送りを使えません")}</span>、失敗件数を {failedCount > 0 && (<span className={styles.editNoticeError}>{t("{n}件を保存できませんでした").replace("{n}", String(failedCount))}</span>)}。直前のコメント {/* 編集モードの案内と、保存に失敗した件数(D-165) */} を足す。★failedCount はそのまま使う★(rowErrors.size に変えない — 3-8)
  • ★エラー一覧(ErrorsScreen.module.css:187-201・ErrorsScreen.tsx:517-527)は変えない★ — 失敗件数は既に同じ行(display: flex)・文字の大きさと色も D-Sec と同じ。★絞り込みが白いカードの中にある表の画面なので、案内もカードの中(左右 20px の余白・下に区切り線)のまま★(項5 で表の行の目印を残すのと同じ考え方。§10 Q2)

2-10. アラートの出発失敗の行のバッジ(項10)

★今★: 出発失敗の行(severity が launch_failed。編集できない行)は .statusBadge だけ(幅なし)で、解消のときは「解消 (日時)」を1つのバッジに入れる(StatusBadgeText :85-100・:655-659)。事前チェックの行は 120px のバッジ+下に解消日時。

  1. components/features/alerts/AlertsScreen.tsx:620-660(<div className={styles.statusColumn}> から閉じ </div> まで)を次に置き換える:
                  <div className={styles.statusColumn}>
                    {/* ★編集モードの事前チェックの行だけプルダウン★(未解消 / 対応中 / 解消 から選ぶ。D-161 の見た目)。
                        それ以外(通常モード・出発失敗の行)は色付きのバッジ(表示だけ。D-165)。
                        ★出発失敗の行はどちらのモードでもバッジのまま★(書き込み先が無い。D-105)。
                        ★バッジもプルダウンも 120px 固定・解消日時は下★(行の種類によらず同じ形。エラー一覧・D-Sec と同じ。D-181) */}
                    {editable && editing ? (
                      <select
                        className={`${styles.statusSelect} ${statusBadgeClass(status)}`}
                        aria-label={t("対応状況")}
                        value={status}
                        disabled={saving}
                        onChange={(e) => changeDraftStatus(item, e.target.value)}
                      >
                        {RESOLUTION_STATUS_OPTIONS.map((o) => (
                          <option key={o.value} value={o.value}>
                            {t(o.label)}
                          </option>
                        ))}
                      </select>
                    ) : (
                      <span
                        className={`${styles.statusBadge} ${styles.statusBadgeFixed} ${statusBadgeClass(status)}`}
                      >
                        {t(resolutionStatusLabel(status))}
                      </span>
                    )}
                    {/* 解消日時は解消のときだけ下に出す(`showsResolvedTime()`。3画面で同じ。D-181)。
                        ★下書きで解消にしただけの行・下書きで未解消/対応中に変えた行には出さない★ */}
                    {showsResolvedTime(item, draft) && (
                      <div className={styles.statusTime}>
                        {item.resolved_at ? formatDateTime(item.resolved_at) : "-"}
                      </div>
                    )}
                  </div>
  • ★意味は今と同じ★: 出発失敗の行は draft が undefined(:545)なので status(:546)は item.resolution_status、showsResolvedTime(item, undefined) は「保存済みが解消か」。事前チェックの行は今と同じ式
    1. ★StatusBadgeText(:85-100。コメント /** 対応状況バッジの文言(解消は「解消 (日時)」)。… */ ごと)を消す★(使われなくなる。lint の未使用で落ちる)
    2. ★.statusBadge(AlertsScreen.module.css:265-271)は消さない★(.itemCardSubdued .statusBadge :195 が使う。全部のバッジに .statusBadge と .statusBadgeFixed の両方が付く)

2-11. 確かめてコミット

  • npx tsc --noEmit -p .・npm run lint・npm test(件数は段階1 と同じ)
  • 次の grep が0件であること:
    grep -n "statusColumnEditing\|editActions\|editButtonPrimary\|editFailed\|StatusBadgeText\|min-width: 110px" components/features/alerts components/features/errors components/features/ds-alerts -r
  • コミット(5ファイル):
    git add -- components/features/alerts/AlertsScreen.tsx components/features/alerts/AlertsScreen.module.css \
      components/features/errors/ErrorsScreen.module.css \
      components/features/ds-alerts/DsAlertsScreen.tsx components/features/ds-alerts/DsAlertsScreen.module.css
    git diff --cached --name-status   # この5行(ErrorsScreen.tsx は段階2 では変わらない)
    メッセージの例: style: 編集モードの3画面で、対応状況の幅(120px)・備考の入力欄の位置・変えた行の目印・編集ボタン・解消日時の寄せ・編集中の絞り込みの見た目・案内の形を揃える(指示書BA 項3〜10・D-181) (★2つに分けてもよい★: アラートの見出し・ボタン(2-6)とそれ以外。分けたら作業報告に書く)

段階3 — D-Sec の文言をアラート画面に揃える(項11。ユーザー決定)

★ユーザー決定(2026-10-19)★: 「11はアラートの方にD-SECを揃えるようにしてください」。

場所 今 直す アラートの同じ場所
状態ボタン1(components/features/ds-alerts/DsAlertsScreen.tsx:461) {t("未解消・対応中")} {t("未解消のみ")} AlertsScreen.tsx:459
状態ボタン2(:471) {t("全件")} ★変えない★ :469
状態ボタン3(:481) {t("解消")} {t("解消済み")} :479
数値カード3枚目のラベル(:363) label={t("解消")} label={t("解消済み")} :367
  • ★変えないもの★: 数値カードは3枚のまま(未解消 / 対応中 / 解消済み)・下の小さい文字(即時対応 / 進行中 / 完了)・バッジとプルダウンの「未解消 / 対応中 / 解消」(STATUS_OPTIONS :83-87。3画面で同じ)・ボタンの色(c.ng / c.txD / c.ok)・statusFilter の値(open / all / resolved)
  • ★承知のうえのこと(ユーザー了承)★: ★2画面とも「未解消のみ」は対応中も含む★(status=open = 解消でないもの。アラート lib/prechecks/query.ts:144-145・D-Sec lib/ds-alerts/query.ts:95-102)。文言は「未解消のみ」のまま
  • 状態ボタンの並び(:452)の直前にコメントを足す: {/* ★状態ボタンの文言はアラート画面に揃える(未解消のみ / 全件 / 解消済み。ユーザー決定 2026-10-19。D-181)★ —
    ★「未解消のみ」は対応中も含む★(status=open。アラートも同じ。ユーザー了承)。バッジ・プルダウンは「未解消 / 対応中 / 解消」のまま */}

3-1. lib/i18n.ts — ★「未解消のみ」「解消済み」は辞書に無い★(2026-10-19 grep で確認)

★今のアラート画面は、EN にしてもこの2つ(ボタン・数値カード)が日本語のまま出ている★。訳は ★モックの対訳(d-watch-mock.jsx:140 の "未解消のみ": "Unresolved", "解消済み": "Resolved")★を使う。

lib/i18n.ts:449-451 を次に置き換える:

  // ---- アラート・D-Sec アラート: 状態ボタンと数値カード(D-181。D-Sec はアラートの文言に揃えた)----
  // ★EN はモック(d-watch-mock.jsx:140)の対訳★。★`未解消` / `対応中` / `解消` は上に既にあるため再掲しない★。
  // ★足すとアラート画面のボタン・数値カードも EN になる(いままで日本語のまま出ていた)★
  未解消のみ: "Unresolved",
  解消済み: "Resolved",
  • ★"未解消・対応中" のキーは消す★(使う場所が無くなる。grep -rn "未解消・対応中" components lib --include=*.tsx --include=*.ts で、コメント以外に残っていないことを確かめる — コメントの「未解消・対応中」(lib/error-reports/query.ts:24 等)は別の話なので残す)
  • ★解消済みも表示(:436)とは別のキー★(重複キーにならない)

3-2. 確かめてコミット

  • npx tsc --noEmit -p .・npm run lint(★重複キーで落ちないこと★)・npm test
  • コミット(2ファイル):
    git add -- components/features/ds-alerts/DsAlertsScreen.tsx lib/i18n.ts
    git diff --cached --name-status
    メッセージの例: feat: D-Sec アラートの状態ボタンと数値カードの文言をアラート画面に揃え(未解消のみ/全件/解消済み)、その訳を辞書に足す(指示書BA 項11・D-181)

段階4 — 資料(D-181・code-map・spec・fixtures)

★追記の前に 3-2 の確認(git diff -- docs/decisions.md docs/code-map.md docs/spec.md docs/fixtures.md が空)★。

4-1. docs/decisions.md の末尾に D-181 を追記する

  • ★D-181 が空いていることを確かめる★(grep -n "^### D-181" docs/decisions.md が0件。2026-10-19 時点は空き。末尾は D-180 :13041〜:13077)。★埋まっていたら次の空き番号を使い、本書の「D-181」をすべてその番号に読み替え、作業報告に書く★
  • ★D-180 の本文・「実装の記録」は変えない★(D-180 7b は経緯として残す。上書きの関係は D-181 に書く)
  • :13077(D-180 の最後の行)の後に、空行・---・空行を置いてから次を足す(D-179 と D-180 の間と同じ区切り。★実物の区切りを見て合わせる★):
### D-181 `[決定]` 編集モードのある3画面(エラー一覧・アラート・D-Sec アラート)の見た目を揃え、D-Sec の状態ボタンと数値カードの文言をアラート画面に揃える

**日付**: 2026-10-19 / 実装: Cursor(指示書BA)

★根拠★: 監督の見比べ(2026-10-19。指示書AZ の後)/ユーザー決定 2026-10-19「11はアラートの方にD-SECを揃えるようにしてください」(項1)。

1. ★D-Sec アラートの状態ボタンを「未解消のみ / 全件 / 解消済み」、数値カードの3枚目のラベルを「解消済み」にする★(アラート画面と同じ文言)。
   ★D-180 7b のうち、状態ボタンと数値カードのラベルだけを上書きする★。★バッジと編集のプルダウンは「未解消 / 対応中 / 解消」のまま★(3画面で同じ)。
   数値カードは3枚(未解消 / 対応中 / 解消済み)と下の小さい文字(即時対応 / 進行中 / 完了)のまま。
   ★2画面とも「未解消のみ」は対応中も含む★(`status=open`。ユーザー了承)。
   ★「未解消のみ」「解消済み」の EN はモック(`d-watch-mock.jsx:140`)の対訳(Unresolved / Resolved)★ — 辞書に無く、アラート画面でも EN で日本語のまま出ていた
2. ★解消日時は「保存済みが解消で、画面の対応状況(下書き優先)も解消」のときだけ出す★(`showsResolvedTime()` `lib/prechecks/edit-drafts.ts`。3画面で1本)。
   旧: エラー一覧と D-Sec は保存済みの値だけを見ており、解消の行を下書きで未解消・対応中に戻しても解消日時が出たままだった
3. ★対応状況のバッジとプルダウンは3画面とも 120px 固定★(アラートの形)。★D-Sec の対応状況の列は両モードで 120px★(切り替えで左の本文が折り返し直さない)。
   エラー一覧の列幅(150px・表の最小幅 1130px)は変えない。旧: エラー一覧はバッジ幅なし・プルダウンは列いっぱい/D-Sec はバッジ min-width 110px(指示書AZ 4b)・編集中の右列 240px
4. ★D-Sec の備考の入力欄は、左の本文(通常モードの備考の行の位置)に出す★(アラート・モックと同じ)。旧: 編集モードで右の列に移っていた
5. ★変えた行の目印★: カードの2画面(アラート・D-Sec)は ★背景 `--sf-h`+上・右・下の枠 `--ac`★(左の帯は分類・種別の色なので変えない)。
   エラー一覧(表)は ★背景 `--sf-h`+左端の帯★のまま(表の行に枠の形を当てはめない)。旧: アラートは `--pr` 8% の背景だけ
6. ★「編集」「保存(N件)」「キャンセル」は3画面とも見出しの右・同じボタン★(幅 88 / 120 / 100px。「保存」だけ背景 `--pr-d`)。
   旧: アラートだけ絞り込みの行の右端・塗りの主ボタン(min-width 112 / 96px)。★モックのアラート画面に「編集」は無く(D-165 で追加)、D-165 の「一覧の上」にも当たるので、モックとは食い違わない★
7. ★解消日時は3画面とも左寄せ★(バッジ・プルダウンの左端に揃う)。旧: D-Sec だけ右寄せ(指示書AZ 4c)
8. ★編集中の絞り込みは、全体を不透明度 0.5・中の部品すべて禁止カーソル★(アラートの形)。エラー一覧は ★子要素ごと(`> *`)に薄くする★(カードの区切り線を薄くしないため)。
   旧: エラー一覧は部品ごとに薄くしていて「~」「指定なし(全期間)」が濃いままだった
9. ★「編集中は絞り込みとページ送りを使えません」は D-Sec の形(横並び・失敗件数は同じ行・下に 12px)★。アラートをこれに合わせた。
   エラー一覧は ★白いカードの中(絞り込みと表の間・左右 20px・下に区切り線)★のまま(絞り込みがカードの中にある表の画面のため。項5 と同じ考え方)
10. ★アラートの出発失敗の行のバッジも 120px・解消日時はバッジの下★(事前チェックの行と同じ形)。旧: 「解消 (日時)」を幅なしの1つのバッジに入れていた
11. (記録)見出しの下の余白は、エラー一覧 16px・D-Sec 20px(指示書AZ 4d)・アラートは直す前の値を保った(実装の記録に測った値を書く)。揃えるかは未決

#### 実装の記録

- ★2026-10-19 指示書BA(Cursor)★:
  - ★コミット★: <段階1 の hash>(項1・2)/<段階2 の hash(2つに分けたなら両方)>(項3〜10)/<段階3 の hash>(項11)
  - ★テスト★: BA 前 130ファイル / 3,077件(監督の実測 2026-10-19・`657c6ff`)→ BA 後 <段階5 で測った数>(全件通過。H1〜H6 の6件増)。H1〜H6 は2通りに壊して赤を確かめた(指示書BA 1-3)
  - ★見出しの下の余白(段階0-4)★: アラート <値>px・エラー一覧 <値>px・D-Sec <値>px(当方の fixtures 由来。測れなかったならそう書く)
  - ★画面確認★: <段階5 の結果と出所(誰が・どこで・いつ。当方の fixtures 由来)。監督に任せたならそう書く>
  - ★指示書と違う判断★: <あれば。無ければ「無し」>
  • ★<…> は実際の値に置き換える★。この記録を書くコミット自体の hash は書かない(書けない)

4-2. docs/code-map.md

★冒頭の改訂の履歴(:26 の「第4版改訂5」の行の次)に1項目足す★: - ★**第4版改訂6: 2026-10-19**(**D-181** / 指示書BA の実装 <段階3 のコミット> まで)★ — 編集モードのある3画面の見た目と D-Sec の文言を揃えた分だけ直しました(解消日時の判定 \showsResolvedTime()`・対応状況 120px・D-Sec の備考の入力欄の位置・変えた行の目印・アラートの「編集」の位置・D-Sec の状態ボタン「未解消のみ / 全件 / 解消済み」)。★直した箇所の行番号は <段階3 のコミット> で確かめました★。それ以外は上のとおりです`

# 場所(今) 今(要旨) 直す
4-2a :610(3.5 アラート「変えた行は背景の色(.itemCardChanged)で分かります」) 背景の色だけ 変えた行は背景の色と上・右・下の枠(\.itemCardChanged`。D-Sec と同じ。D-181)で分かります`
4-2b :609(3.5「一覧の上の「編集」(:485 以降。…)」) 一覧の上・:485 見出しの右の「編集」(\:<新しい行>`。編集できる行が0件なら押せない。3画面とも同じ位置・同じボタン。D-181)`
4-2c :618(3.5「★解消日時(プルダウン・バッジの下)は 12px★」) — 末尾に 。★出すのは保存済みが解消で、画面の対応状況(下書き優先)も解消のときだけ★(\showsResolvedTime()` `lib/prechecks/edit-drafts.ts`。3画面で1本。D-181)。★出発失敗の行もバッジ(120px)の下に出す★` を足す
4-2d :640(3.5b エラー一覧「通常は表示だけ → ツールバーの「編集」(…)」) ★今でも誤り★(ボタンは件数の右) ツールバーの「編集」 → 見出しの右(件数の右)の「編集」。同じ行の「解消のときは下に解消日時」の後に (下書きで未解消・対応中に戻すと隠れる。D-181)
4-2e :643(3.5b「対応状況 150」) — 対応状況 150 の後に (中のバッジ・プルダウンは 120px 固定。D-181) を足す
4-2f :765(3.10 D-Sec「★編集モードあり★(…)」) — 末尾に ★備考の入力欄はカードの左の本文(通常モードの備考の行の位置)・対応状況の列は両モードで 120px・解消日時は左寄せ(D-181)★。★状態ボタンは「未解消のみ(対応中も含む)/ 全件 / 解消済み」、数値カードは「未解消 / 対応中 / 解消済み」(アラート画面に揃えた。D-181)★ を足す
4-2g :2011(5B-10 の表の1行目「未解消 / 対応中 / 解消」) 表示名 未解消 / 対応中 / 解消済み(★3枚目のラベルはアラート画面に揃えた。D-181★)。根拠の欄 D-180 → D-180 / D-181

★行番号の追従(G2)★ — 次の行は本書で動くファイルの行番号を引いている。★本書のコミットの後の HEAD で関数名・クラス名・文言を grep し、引き直す★(★下(行番号の大きいほう)から直す★):

code-map の行 引いている場所 探す語
:592 AlertsScreen.tsx の行数(684行・f2b91fc) wc -l → 行数と <段階3 のコミット> に
:594 AlertsScreen.tsx の :225(/api/prechecks)・:132(sendPrecheckPatch()) api/prechecks?・function sendPrecheckPatch
:603 :43-49(severityColor) function severityColor
:604 :109-121(itemCardClass())・:570(「本清掃は成功」の Pill) function itemCardClass・本清掃は成功
:605〜:617 :123-126(isEditable())・:191-203(編集モードのコメント)・:587(maxLength)・:299(saveEdits)・:375 / :674(fieldset)・:257-267(beforeunload)・:284(cancelEditMode)・:601(.noteText) 各関数名・<fieldset・beforeunload・maxLength={PRECHECK_NOTE_MAX_LENGTH}・styles.noteText
:629 ErrorsScreen.tsx の行数(670行・f2b91fc) wc -l
:631 :238(/api/errors)・:105(sendErrorUpdate()) api/errors?・function sendErrorUpdate
:640 :285(canStartEdit)・:311(saveEdit)・:288(filtersDisabled)・:176-183(beforeunload)・:296(cancelEdit) 各名前
:641 :634(.noteText) styles.noteText
:643 :544-551(<colgroup>)・CSS .table(:246-261。★今でもずれている — 今は :254-270★) <colgroup>・^.table {
:760・:761 DsAlertsScreen.tsx の行数(613行・d282e07)・:200(/api/ds-alerts)・:96(sendDsAlertUpdate) wc -l・api/ds-alerts?・api/errors/
:767・:850 DsAlertsScreen.module.css:119(.masterSelect) ^.masterSelect
:845・:846 AlertsScreen.module.css:151(★今でもずれている — 今は :154★)・ErrorsScreen.module.css:152(.masterSelect) ^.masterSelect
:857 AlertsScreen.tsx:381 :393・ErrorsScreen.tsx:420 :434(openDatePicker) onClick={openDatePicker}
:866 ErrorsScreen.module.css:246(.table。★今でもずれている★) ^.table {
:922・:927・:928・:936・:937 API の表の画面側の行(DsAlertsScreen.tsx:200・AlertsScreen.tsx:225 :136・ErrorsScreen.tsx:238 :109) apiFetch の行
:1857 AlertsScreen.tsx:109-121 / :570 function itemCardClass・本清掃は成功
:2155 AlertsScreen.tsx:120(入力欄の maxLength。★今でもずれている★) maxLength={PRECHECK_NOTE_MAX_LENGTH}
  • ★最後に grep -n "未解消・対応中」\|\"未解消・対応中\"\|statusColumnEditing\|editActions" docs/code-map.md が0件★(コメントの「未解消・対応中」= status=open の意味の説明は残してよい。ボタンの文言として書いた箇所が無いこと)

4-3. docs/spec.md(F-07 D-Secアラート)

# 場所(今) 今 直す
4-3a :111 - サマリーカウント(未解消 / 対応中 / 解消。エラー一覧と同じ文言。D-180 項7b) - サマリーカウント(未解消 / 対応中 / 解消済み。★アラート画面と同じラベル。D-181★)
4-3b :111 の次 (状態ボタンの記述が無い) - 状態の絞り込み: 未解消のみ(★対応中も含む★)/ 全件 / 解消済み(★アラート画面と同じ文言。D-181★) を1行足す
4-3c :113 - 対応状況の遷移: 未解消 → 対応中 → 解消(編集モードでまとめて保存。D-161 / D-165) ★変えない★(バッジ・プルダウンの文言は「解消」のまま)

4-4. docs/fixtures.md

# 場所(今) 今 直す
4-4a :545(FX-ERR-14 の右端) D-Sec は「全件」「解消」で出る D-Sec は「全件」「解消済み」で出る
4-4b :546(FX-ERR-15 の右端) 同上 同上

4-5. 確かめてコミット

  • git diff --stat で4ファイルだけ(docs/decisions.md・docs/code-map.md・docs/spec.md・docs/fixtures.md)
  • git diff -- docs/decisions.md が D-181 の追記だけ(D-180 以前の行が変わっていたら止まって報告)
  • ★D-181 の「実装の記録」の画面確認・テスト件数は段階5 の後に埋める★ — 段階4 では <…> のまま一度コミットしてもよいし、段階5 の後にまとめて1つでもよい(どちらにしたか作業報告に書く)
  • メッセージの例: docs: D-181(編集モードの3画面の見た目と D-Sec の文言を揃えた)を追記し、code-map・spec・fixtures を追従させる(指示書BA)

段階5 — 全体の確認

  1. npx tsc --noEmit -p . — 0件
  2. npm run lint — 0件(★eslint-disable を足していない★)
  3. npm test — ★全件通過★。件数を控える(期待: 130ファイル / 3,083件)
  4. ★USE_FIXTURES=true で npm run build★(PowerShell: $env:USE_FIXTURES='true'; npm run build)— 成功(★本体で★。ワークツリーではない)
  5. ★画面の確認★ — ★アプリ内ブラウザ(mcp__Claude_Browser__*)を使う。Edge(ヘッドレス・CDP を含む)は使わない★(ユーザー指示 2026-10-16)。★ユーザーの :3000 は止めない★。 手順は指示書AX 段階10-1 の 1〜3(:3100 で next start・テスト用のトークンはその場で生成し、★文書・コミット・報告に書かない★)。★幅 1440px★(resize_window で 1440×900。終わったら preset: "desktop" に戻す)。★JP と EN の両方★。 ★アプリ内ブラウザが使えないときは、画面の確認をせずに「監督に任せる」と作業報告に書く★(ほかの手段で代わりにしない)。| 項 | 画面 | 操作 | 期待 | |---|---|---|---| | 1 | /errors | 「解消済みも表示」を入れる → 編集 → 解消の行(FX-ERR-03)を「未解消」に | その行の [class*="__statusTime"] が ★消える★。「解消」に戻すと ★また出る★ | | 1 | /ds-alerts | 「全件」→ 編集 → 解消のカード(FX-ERR-14)を「対応中」に | 同上 | | 1 | /alerts | 「全件」→ 編集 → 解消の事前チェックの行(あれば)を「未解消」に | 同上(今までと同じ) | | 2 | /alerts | EN で再読み込み | 読み込み中に "Loading…"(一瞬なので見えなければコードの差分で確かめた、と書く) | | 3 | 3画面 | 通常モード・編集モード × JP・EN | ★[class*="__statusBadge"] と [class*="__statusSelect"] の getBoundingClientRect().width がすべて 120★ | | 3 | /ds-alerts | 同じカードで通常 → 編集 | ★[class*="__itemMain"] の幅が変わらない★([class*="__statusColumn"] は両モードで 120) | | 4 | /ds-alerts | 編集 | textarea の closest('[class*="__itemMain"]') が null でない(左の本文の中)。[class*="__statusColumn"] textarea は0件 | | 5 | /alerts・/ds-alerts | 編集 → 1枚の状態を変える | そのカードの getComputedStyle(card).backgroundColor が --sf-h の値、borderTopColor が --ac の値、borderLeftColor は分類・種別の色のまま。2画面で同じ見た目 | | 5 | /errors | 同上(1行) | 行の背景 --sf-h・左端の帯(今までと同じ) | | 6 | /alerts | 通常 → 編集 | 「編集」「保存(N件)」「キャンセル」が ★[class*="__headerRight"] の中★、幅 88 / 120 / 100(JP・EN で同じ)。★絞り込みの行にボタンが無い★。★見出しの下の余白が段階0-4 で測った値と同じ★ | | 7 | 3画面 | 解消の行・カード | [class*="__statusTime"] の getComputedStyle().textAlign が start または left、getBoundingClientRect().left がバッジ(プルダウン)の left と同じ | | 8 | 3画面 | 編集 | 絞り込みの部品(エラー一覧は [class*="__dateSep"] の「~」「指定なし(全期間)」も)が薄い(★エラー一覧は [class*="__toolbar"] > * の opacity が 0.5・D-Sec は [class*="__toolbar"] が 0.5・アラートは [class*="__filterSet"] が 0.5★)。中の部品・ボタンの cursor が not-allowed。★エラー一覧のカードの区切り線は薄くならない★ | | 9 | /alerts | 編集 | [class*="__editNotice"] の display が flex、marginTop が 0px、marginBottom が 12px(D-Sec と同じ) | | 10 | /alerts | 「全件」→ 出発失敗のカード | バッジの幅 120(事前チェックのカードと同じ。★出発失敗のカードは fixtures では未解消だけなので、解消日時の表示はコードで確かめた、と書いてよい★) | | 11 | /ds-alerts | JP / EN | ボタン「未解消のみ」「全件」「解消済み」/ "Unresolved" "All" "Resolved"。3枚目のカード「解消済み」/ "Resolved"。★バッジとプルダウンは「解消」/ "Resolved"★ | | 11 | /alerts | EN | ボタン "Unresolved" "All" "Resolved"・2枚目のカード "Resolved"(★今まで日本語だった★) |
    • ★スクリーンショットを撮る★: 3画面 × 通常・編集 × JP(6枚)+ D-Sec と アラートの EN(2枚)
    • 終わったら自分で起動した :3100 の listen プロセスを止める
  6. 最後の grep(★結果を作業報告に貼る★):
    grep -rn "未解消・対応中" components lib/i18n.ts
    grep -rn "statusColumnEditing\|editActions\|editButtonPrimary\|editFailed\|StatusBadgeText" components
    grep -n "showsResolvedTime" components/features/errors/ErrorsScreen.tsx components/features/alerts/AlertsScreen.tsx components/features/ds-alerts/DsAlertsScreen.tsx lib/prechecks/edit-drafts.ts
    git diff 657c6ff --stat -- d-watch-api.yaml app lib/db lib/types
    • 1行目: 0件(components の中のコメントにも残っていないこと。★lib/error-reports/query.ts:24 等は対象外のディレクトリ★)
    • 2行目: 0件
    • 3行目: 3画面で1か所ずつ+定義1か所(import の行も出る)
    • 4行目: 何も出ない(API・データ層・型を変えていない)
  7. D-181 の「実装の記録」を埋める(G4)。

7. 記録だけ(★直さない★。作業報告に「確認した・直していない」と書く)

# 内容 場所 なぜ直さないか
7-1 EN の訳が無い: 「要対応」「対応完了」「合計」「全アラート」(アラートの数値カード)・「即時対応」「進行中」「完了」(D-Sec の数値カード) lib/i18n.ts ★EN はあとで一括(方針。指示書AZ R3)★。本書で足すのは状態ボタン・カードのラベルの2つだけ
7-2 期間の区切りの記号が違う: エラー一覧は「~」(U+FF5E)、アラートとモックは「〜」(U+301C) ErrorsScreen.tsx:429・AlertsScreen.tsx:388 本書の範囲外(文言の統一はユーザー判断)
7-3 D-Sec の状態ボタン1の色: モック(d-watch-mock.jsx:932)は c.wn、コードは c.ng(アラートと同じ) DsAlertsScreen.tsx:455 本書の範囲外。アラートに揃っているので変えない
7-4 ★画面の文言を固定しているテストは無い★(.test.tsx が無い・grep で「未解消・対応中」「解消」を固定するテスト0件。2026-10-19) — 画面の部品のテストを作るのは本書の範囲外。段階5 の画面確認で代える
7-5 見出しの下の余白が3画面で 16 / 16 / 20px(予想)。D-Sec の 20px は指示書AZ 4d の「AX 前は 4px+16px=20px」という読みによるが、CSS のマージンの相殺で AX 前も 16px だった可能性がある DsAlertsScreen.module.css:17 §10 Q3。段階0-4 の実測を監督が見て決める

9. 触ってよいもの・触ってはいけないもの

触ってよい

  • lib/prechecks/edit-drafts.ts・lib/prechecks/__tests__/edit-drafts.test.ts(段階1)
  • components/features/errors/ErrorsScreen.tsx(★段階1 の import と解消日時の1か所だけ★)・components/features/errors/ErrorsScreen.module.css(段階2)
  • components/features/alerts/AlertsScreen.tsx・components/features/alerts/AlertsScreen.module.css(段階1・2)
  • components/features/ds-alerts/DsAlertsScreen.tsx・components/features/ds-alerts/DsAlertsScreen.module.css(段階1・2・3)
  • lib/i18n.ts(★段階3 の :449-451 だけ★)
  • docs/decisions.md(★末尾への D-181 の追記だけ★)・docs/code-map.md(段階4-2)・docs/spec.md(段階4-3)・docs/fixtures.md(段階4-4 の2行)

触ってはいけない

  • ★docs/handoff/設計_制御盤ログの取り出し_20261019.md・docs/handoff/指示書AY_制御盤のログをD-Secログ画面から取り出す_20261019.md・docs/handoff/TeamWorks確認事項_第13回_*・docs/handoff/回答待ち一覧_*・docs/handoff/pdf/*★(他のセッションの作業)
  • 指示書AX・AZ・本書(指示書BA)
  • ★app/api/**・lib/db/**・lib/types/**・d-watch-api.yaml★(API を変えない。G1)
  • lib/prechecks/ の edit-drafts.ts 以外(query.ts・status-update.ts 等)・lib/ds-alerts/**・lib/error-reports/**
  • components/ui/**(FilterButton・Pagination・StatCard・Pill)・components/layout/**・他の画面の components/features/**
  • app/globals.css(★色の変数を足さない・フォントのスタックを変えない★)
  • d-watch-mock.jsx・CLAUDE.md・docs/handoff.md
  • ★docs/decisions.md の D-180 とそれ以前の本文・「実装の記録」★
  • ★認証情報(パスワード・接続文字列・生成したトークン)を文書・コード・テスト・コミット・作業報告に書くこと★
  • ★git add -A / git add .・push★

10. 確認事項(監督へ。★実装は本書のとおりに進めてよい★)

# 内容 本書の判断 監督が変えるなら
Q1 項6(アラートの「編集」を見出しの右へ)はモックと食い違わないか ★食い違わない★: モックのアラート画面(d-watch-mock.jsx:583-584)には「編集」が無い(D-165 で追加)。D-165 は「一覧の上の『編集』」で、見出しの右も当たる。モックのレポート画面(:647-650)に見出しの右のボタンの例がある —
Q2 項9 でエラー一覧の案内を D-Sec と同じ「カードの外・下に 12px」にしない ★しない★: エラー一覧は絞り込みが白いカードの中にあるので、案内もカードの中(絞り込みと表の間)が自然。文字・色・横並び・失敗件数が同じ行、は既に D-Sec と同じ カードの外に出すなら、ErrorsScreen.tsx:517-527 をカード(:408)の前に移し、.editNotice を D-Sec の形にする。★ただしそうすると案内が絞り込みより上に来る★
Q3 見出しの下の余白(エラー一覧 16・D-Sec 20・アラート ?)を揃えるか ★本書では揃えない★(アラートは今の見た目を保つだけ)。段階0-4 の実測を D-181 の実装の記録に書く 揃えるなら D-Sec の .header の margin-bottom(:17)とアラートの .header を同じ値に。指示書AZ 4d の前提(4px+16px=20px)を見直すことになる
Q4 「未解消のみ」「解消済み」の EN ★モックの対訳(Unresolved / Resolved)★。「未解消のみ」の EN が数値カードの「未解消」と同じ "Unresolved" になる "Unresolved only" 等にするなら lib/i18n.ts の1行(アラートと D-Sec の両方に効く)
Q5 項5 のエラー一覧の背景 ★既に --sf-h★(ErrorsScreen.module.css:315)。変える箇所は無い —

11. コミットの計画

順 中身 段階
1 解消日時の判定(showsResolvedTime()+テスト)と3画面での使用・アラートの t()(5ファイル) 1
2 見た目(5ファイル。2つに分けてもよい) 2
3 D-Sec の文言と辞書(2ファイル) 3
4 資料(D-181・code-map・spec・fixtures。「実装の記録」を後で埋めるなら2つ) 4・5
  • ★git add はファイルパスを明示する★。各コミットの前に git diff --cached --name-status で中身を確かめる
  • メッセージには ★何を変えたか★ と ★なぜ(指示書BA・どの項目か)★ を書く
  • ★push しない★。★監督がコミットを見てから、監督の指示で develop に push する★。PR の作成とマージは daichi のレビューの後(D-154)

12. 期待される結果

  • エラー一覧・D-Sec で、解消の行を編集モードで「未解消」「対応中」にすると、★プルダウンの下の解消日時が消える★(アラートと同じ)。showsResolvedTime() の H1〜H6 が通り、壊すと赤になる
  • アラートの「読み込み中…」・取得失敗の文言が EN で訳される
  • ★3画面とも、対応状況のバッジとプルダウンが 120px★。D-Sec はモードを切り替えても左の本文が折り返し直さない
  • D-Sec の編集モードで、備考の入力欄がカードの左の本文に出る
  • 変えた行: アラートと D-Sec のカードは同じ見た目(背景+上・右・下の枠)、エラー一覧は今のまま
  • アラートの「編集」「保存(N件)」「キャンセル」が見出しの右にあり、エラー一覧・D-Sec と同じ形・同じ幅
  • 解消日時は3画面とも左寄せ
  • 編集中、3画面とも絞り込み全体が薄く(エラー一覧の「~」「指定なし(全期間)」も)、中の部品はすべて禁止カーソル
  • 「編集中は絞り込みとページ送りを使えません」と失敗件数が、アラートでも同じ行に並ぶ
  • アラートの出発失敗のカードのバッジも 120px
  • D-Sec の状態ボタンが「未解消のみ / 全件 / 解消済み」、3枚目の数値カードが「解消済み」。EN では "Unresolved" / "All" / "Resolved"。★アラートのボタン・カードも EN で訳される★
  • D-181 があり、docs/code-map.md・docs/spec.md・docs/fixtures.md が食い違わない
  • tsc 0件・lint 0件・npm test 全件通過・USE_FIXTURES=true npm run build 成功・API・データ層・型・YAML に差分なし

13. 完了条件

  • 段階0: 657c6ff の上・作業ツリーが空・テスト件数を控えた(130 / 3,077)・見出しの下の余白を測った(または測れなかったと書いた)
  • 段階1: showsResolvedTime() と H1〜H6 を足し、★2通りに壊して赤を確かめて戻した★。3画面がこの関数を使う。アラートの「読み込み中…」・取得失敗を t() に通した。edit-drafts.ts の冒頭の説明を3画面に直した
  • 段階2: 項3〜10 を表のとおり直した。2-11 の grep が0件。★古い opacity の規則を消した(二重にしていない)★
  • 段階3: D-Sec のボタン・カードの文言を直し、辞書に2つ足し、「未解消・対応中」のキーを消した
  • 段階4: D-181 を追記した(番号を確かめた)。code-map・spec・fixtures を直し、行番号を引き直した
  • 段階5: tsc 0件・lint 0件・npm test 全件通過(件数)・USE_FIXTURES=true npm run build 成功・画面の確認(アプリ内ブラウザ。または「監督に任せる」と書いた)・最後の grep
  • D-181 の「実装の記録」を埋めた(コミット・テスト件数の前後・余白の実測・画面確認と出所・逸脱)
  • §7 の 7-1〜7-5 は直していない
  • ★push していない★
  • 作業報告に: コミット一覧(hash とメッセージ)/テスト件数(BA 前・BA 後)/壊して確かめた結果(1-3 の2通り)/見出しの下の余白の実測/画面確認の結果(出所: 当方の fixtures 由来)/段階5-6 の grep の結果/本書と違う判断をしたところ