diff --git a/.claude/launch.json b/.claude/launch.json index 807d024..6f5ab5d 100644 --- a/.claude/launch.json +++ b/.claude/launch.json @@ -6,6 +6,12 @@ "runtimeExecutable": "dotnet", "runtimeArgs": ["run", "--project", "src/MesApp.Api", "--urls", "http://localhost:5210"], "port": 5210 + }, + { + "name": "guide", + "runtimeExecutable": "powershell", + "runtimeArgs": ["-NoProfile", "-Command", "jekyll serve -s docs -d $env:TEMP\\mes-docs-site --port 4000"], + "port": 4000 } ] } diff --git a/docs-dev/FactoryTour.md b/docs-dev/FactoryTour.md new file mode 100644 index 0000000..3cf2bd7 --- /dev/null +++ b/docs-dev/FactoryTour.md @@ -0,0 +1,358 @@ +# 工場模型で見る 製造から出荷まで 仕様書 + +サンプルのギアポンプ製造を、**動く工場模型**と、それに連動する **MES の記録の変化**で見せるガイドの新ページを作る。 +1カード=1セッションで進める(`Orchestration.md` §4.1)。カードの間はセッションをクリアし、次へ進む前に前のカードをコミットする。 +新しいセッションでは「`docs-dev/FactoryTour.md` の TOUR-01 を実行して」とだけ頼めば着手できるように書いてある。 + +## 背景 + +`docs/walkthrough.md` は図と画面写真で流れを説明しているが、次の理由で分かりにくい。 + +- 図が箱と矢印の抽象図で、**工場のどこで起きているか**が見えない +- 物の動きと記録の変化が別々の章にあり、読者が頭の中でつなぐ必要がある + +このページで伝えることは1つ。**「現場で物が動くと、誰がどの画面に入力し、MES のどの記録が変わるか」**。 + +## 決定事項(2026-11-03) + +| 論点 | 決定 | 理由 | +|:--|:--|:--| +| 置き場所 | 新しい全幅ページ `docs/factory-tour.html`。`walkthrough.md` は画面写真つきの詳細編として残す | サイドバーがなく模型を大きく見せられる。操作の詳細は既存ページに任せられる | +| 進め方 | 模型 → 5場面 → 15場面の順に作り、模型と5場面のそれぞれで利用者の確認を受ける | 演出を確かめる前に全場面のデータを作ると、手戻りが大きい | +| 描画 | 等角投影の SVG を素の JavaScript で生成する。外部ライブラリ・ビルド・外部通信なし | 説明に回転は不要。軽く、日本語ラベルが鮮明で、GitHub Pages にそのまま置ける | +| 場面の持ち方 | 描画処理と場面データを分ける | サンプルが変わってもデータの修正で済む | +| 動きの進行 | 既定は「次へ」で1場面ずつ。「再生」を押すと自動で進む | 読む速さは人によって違う | +| 反映の見せ方 | 信号は**人の端末から** MES へ飛ばす。設備から直接は飛ばさない | 設備からの自動収集は将来拡張(Spec.md 3章の製造実施・設備稼働報告)。実際にない連携に見せない | +| 数値の正 | 在庫と作業指示の状態は `samples/actual-csv` の **01〜15 だけを取り込んだ時点**の値 | 16 以降の在庫操作(24 の払出戻し、30 の保管サンプルなど)まで含めると、物語の数字とずれる | +| 01〜15 に入らないもの | 次の3つは実データとの照合の対象にしない。**差立(場面4)**と**完了承認(場面11)**は CSV に無く、画面で操作する場面と明記する。**設備の停止(場面5・10)**は `16_equipment-logs.csv` の記録で、台帳の数字に影響しない演出として扱う | 照合できないものを基準に含めると、受入基準が満たせなくなる | +| 最終検査(PR-40)の担当 | **op001**。サンプルマスタで op001 に有効な SK-03 を足す(TOUR-03) | 実績入力は現場作業者・生産管理・管理者だけ(`MesRoleGroups.ShopFloorRecord`)なので qc001 は入力できず、op002 の SK-03 は期限切れで着手を拒否される。今のサンプルには担当できる人がいない | +| 外注(PR-20)の担当 | **op001**(昼勤)が戻りを確認して実績を入力する | 工順に作業区・スキルの指定がなく、CSV にも作業者の列がない。夜勤の op003 は勤務を終えている | +| 場面のURL | `#machining` のように場面の `id` を使う。画面に出す番号は `no` に持つ | 場面を足しても既存のリンクが壊れない | +| 多言語 | 日本語のみ | ユーザーガイド全体が日本語のみで、`I18nCheck.ps1` の対象外 | + +`Spec.md` は変更しない(アプリの機能を変えない、説明用のページのため)。 + +## 対象外 + +- 本物の3D表示(カメラの回転・拡大)、動画の書き出し +- アプリ本体(`src/`)への組み込み、実データとの接続 +- 保全・治工具・棚卸・不適合処置・リワーク(物語の外。`walkthrough.md` 10章に任せる) +- `walkthrough.md` の図の削除や作り替え(導線の追加と、TOUR-03・TOUR-05 に書いた文言の修正だけを行う) + +## 画面仕様 + +### レイアウト + +幅 1000px 以上: + +``` +┌ ガイドへ戻る ─────── ページ名 ──────────────┐ +│ ┌ 工場模型 ───────────┐ ┌ 場面 5/15 ────┐ │ +│ │ │ │ タイトル・日時 │ │ +│ │ 等角の工場 │ │ 現場で起きること│ │ +│ │ 物・人・信号が動く │ │ 誰がどの画面に │ │ +│ │ │ │ MESで変わること │ │ +│ └──────────────────────┘ │ 詳しく見る → │ │ +│ [◀ 前へ][▶ 再生][次へ ▶] └─────────────────┘ │ +│ ○─○─○─●─○─○ 場面の列(押すと移動) │ +│ ┌ MES の台帳 ─ 在庫 ──────── 作業指示の状態 ┐ │ +│ └───────────────────────────────────────────┘ │ +└───────────────────────────────────────────────┘ +``` + +幅 1000px 未満:模型 → 変化の帯 → 操作 → 説明 → 台帳の縦積み。横スクロールは出さない。 + +**第4拍の変化は、模型と同時に見えること**(このページの主題)。 + +- 幅 1000px 以上:1440×900 で模型と台帳が同時に収まるように、模型の高さを画面に合わせる。台帳は在庫と作業指示の2段組とし、収まらなければ欄の中でスクロールして、変わった行を見える位置へ送る +- 幅 1000px 未満:模型の直下に**変化の帯**を置き、今の場面で変わった行だけを出す + +スマホ幅(375px)では全景だとラベルが読めないので、**カメラ(SVG の viewBox)を今の場面の範囲に寄せる**。範囲は `station`・`actors`・`moves` の置場をすべて含む矩形とし、全体を見せる場面だけ `camera: 'all'` を指定する。 + +**模型のラベルは全幅で「部分」を既定とし、操作の「ラベル 部分/全部」で切り替える**(すべて出すと重なって読めないため)。部分では次だけを出す。全部ではすべて出す(重なりは許容する)。 + +- 今の作業とその前後の持ち場(`station`・`actors`・`moves` の置場と `around`)のラベルと、そこに置かれた物の数量 +- 場面の担当者(`actors`)、動かす設備(`equipment`)、異常(`alerts`)、MES サーバー +- 開始前は持ち場の名前だけ + +### 工場の配置 + +U字の流れとする。下の配置図は並びの正とし、座標は `TOUR-01` で見た目を見ながら決める。 + +``` + 事務所(pm001) MES サーバー + +受入ヤード → WH-M01/WH-M02 → WC-MC1 ─────────→ 搬出口 → 外注先(工場の外) + 部材倉庫 EQ-01・EQ-05 │ + │ WIP-01 │ + │ 部材 │ + └──────────────────────┐ ▼ +出荷ヤード ← WH-P01 ← WC-PK1 ← WC-QC1 ← WC-AS1 ←──────── WIP-02 +(SHIP-01) 製品倉庫 EQ-04 EQ-03 EQ-02 +``` + +| 模型の要素 | 表し方 | +|:--|:--| +| 作業区・倉庫 | 床に区画を引き、コードとマスタの名前のラベルを付ける(`WC-MC1 マシニング加工`) | +| 設備 | 箱を組み合わせた簡単な形。実績のあった設備だけ使う(加工は EQ-01。EQ-05 は置くだけ) | +| 物 | 色分けした小さな立方体。部材・半製品・製品で形か色を変え、数量ラベルを付ける | +| 人 | ロール色の簡単な人形と、ユーザーID。持ち場に立つ | +| 端末 | 人の横に小さなタブレット。入力するときに光る | +| MES サーバー | 事務所の横に置く、信号の行き先。カメラを寄せて画面の外に出るときは、画面の端に固定の目印を出して、そこへ信号を飛ばす | +| トラック | 受入ヤード、搬出口、出荷ヤード | + +対象外の置場(WH-S01 保全部品棚)は模型に置かない。 + +### 1場面の演出(4拍) + +1. **現場が動く**:物が持ち場へ移動し、設備が動く +2. **人が入力する**:端末が光り、右の「誰がどの画面に」が強調される +3. **信号が飛ぶ**:端末から MES サーバーへ点線が流れる +4. **記録が変わる**:台帳(狭い画面では変化の帯)の数字が変わり、変わった行を約1秒強調する + +**実際に起きた異常**(`alerts`)では、持ち場を赤く光らせ、説明に赤の項目を足す。起きていないこと(判定が無ければ止まる、など)は赤くせず `note` に書く。 + +### MES の台帳 + +| 欄 | 内容 | +|:--|:--| +| 在庫 | 下の9ロットの置場と数量(単位つき)。まだ無いロットは薄く表示する | +| 作業指示の状態 | `SMP-SF-001-10` など5件の状態。工程展開の前は薄く表示する | +| 説明 | 「部材は作業指示への投入で減る」「在庫に入るのは最終工程の良品だけ」など、数字の見方を場面に応じて短く添える | + +スマホ幅では台帳の全行を畳み、「すべて表示」で開く(変わった行は変化の帯に出ている)。 + +場面を飛ばしても表示が合うように、各場面は**差分**を持ち、1場面目から足し直して表示する。**台帳(`effects`)も模型の物(`moves`)も同じ畳み込みで作る**。 + +### 操作 + +| 操作 | 動き | +|:--|:--| +| 開いたとき | ハッシュなしなら**開始前**(全景。物はなく、説明欄に案内を出す)。「次へ」か「再生」で場面1の4拍から始まる。ハッシュつきならその場面の最終状態を表示する | +| 次へ | 次の場面の4拍を再生する。4拍の途中で押すと今の場面を最終状態にしてから進む | +| 前へ・場面の列 | 移動先の最終状態をアニメーションなしで表示する。自動再生中なら一時停止する。場面1では「前へ」を無効にする | +| もう一度 | 今の場面の4拍を、その場面の直前の状態から再生する | +| 再生/一時停止 | 4拍の後、説明を読む時間(約5秒)を置いて次へ進む。最後の場面で止まる。最後の場面で押すと場面1から再生し直す | +| ラベル 部分/全部 | 模型のラベルの出し方を切り替える。再生と場面の位置には影響しない(再読込で部分に戻る) | +| キーボード | ← → で前後、Space で再生・一時停止。**ボタン・リンクにフォーカスがあるときの Space はそのボタンの操作だけにする**。修飾キーつきは無視する | +| URL | `#machining` で該当場面を開く。手で移動したときは履歴に積み(`pushState`)、自動再生中は積まない(`replaceState`)。ブラウザの戻る・進むと手で書き換えたハッシュには `hashchange` で追従し、未知のハッシュは開始前にする | + +### 見た目とアクセシビリティ + +- ロール色は `docs/assets/style.css` の `--r-pm` `--r-op` `--r-lg` `--r-qc` `--r-ng` をそのまま使う(ガイドの図と色を合わせる)。模型の本体は無彩色 +- ダークモードは `prefers-color-scheme` で追従する(ガイドと同じ。切替ボタンは置かない) +- `prefers-reduced-motion: reduce` では動かさず、各場面の最終状態だけを表示する(「もう一度」も同じ)。自動再生の間隔はそのまま使える +- 説明と台帳は SVG の外の HTML に置く。場面が変わったら `aria-live="polite"` で要約を読み上げる。SVG には `role="img"` と場面ごとの説明の `aria-label` を付ける +- 色だけで伝えない(異常には「逸脱」などの語を添える) +- JavaScript が無いときは `