From 186ecc52f91e5bfe48b68ae818a596026f34ca9c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:05:47 +0000 Subject: [PATCH 01/43] Initial plan From 6e0fe9a557304455666007c635735a66e2fcee97 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:08:01 +0000 Subject: [PATCH 02/43] =?UTF-8?q?feat:=20=E8=A8=AD=E8=A8=88=E8=A8=88?= =?UTF-8?q?=E7=94=BB=E3=81=AE=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 設計Issueの計画を整理し、実装に必要な指針を明文化する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- package-lock.json | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 72e739fa7..20a169beb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -95,6 +95,7 @@ "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", @@ -755,6 +756,7 @@ "integrity": "sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -1696,6 +1698,7 @@ "integrity": "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-module-imports": "^7.28.6", @@ -2526,6 +2529,7 @@ "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@dnd-kit/accessibility": "^3.1.1", "@dnd-kit/utilities": "^3.2.2", @@ -4224,6 +4228,7 @@ "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -4441,6 +4446,7 @@ "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -4897,6 +4903,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5004,6 +5011,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -6120,6 +6128,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -9362,6 +9371,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -12695,6 +12705,7 @@ "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "^27.5.1", "import-local": "^3.0.2", @@ -13942,6 +13953,7 @@ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", + "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -15993,6 +16005,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -18385,6 +18398,7 @@ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -19064,6 +19078,7 @@ "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -19669,6 +19684,7 @@ "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "*", "@types/node": "*", @@ -20290,7 +20306,6 @@ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" } @@ -20321,6 +20336,7 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -21826,24 +21842,6 @@ } } }, - "node_modules/tailwindcss/node_modules/yaml": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, "node_modules/tapable": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", @@ -22089,6 +22087,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -22297,6 +22296,7 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "license": "(MIT OR CC0-1.0)", + "peer": true, "engines": { "node": ">=10" }, @@ -22412,6 +22412,7 @@ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -22792,6 +22793,7 @@ "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -22865,6 +22867,7 @@ "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -23341,6 +23344,7 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -23409,6 +23413,7 @@ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "rollup": "dist/bin/rollup" }, From 63bd77815462c1ede995591ab282c968953432d5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:09:45 +0000 Subject: [PATCH 03/43] =?UTF-8?q?feat:=20=E5=AE=9F=E7=B8=BE=E9=80=A3?= =?UTF-8?q?=E5=8B=95=E4=BB=95=E6=A7=98=E3=81=AE=E8=A8=AD=E8=A8=88=E8=A8=88?= =?UTF-8?q?=E7=94=BB=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit バー優先の正規化ルールとテスト方針を整理し、 実装時の責務分離と品質ゲートを明確化する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../41-actuals-linkage-bar-priority-spec.md | 80 +++++++++++++++++++ package-lock.json | 43 +++++----- 2 files changed, 99 insertions(+), 24 deletions(-) create mode 100644 .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md new file mode 100644 index 000000000..8df4a0736 --- /dev/null +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -0,0 +1,80 @@ +# Implementation Plan: 実績開始日/実績終了日/実績工数のバー優先連動 + +## 1. 機能要件 / 非機能要件 +- 機能要件: + - SSOT を (ActualStart, ActualEnd) とし、ActualEffortHours は派生値として正規化する。 + - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 + - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 + - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は 0.25h 単位で四捨五入(ties 上方向)する。 +- 非機能要件: + - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 + - ログ/表示に Secrets/PII を含めない。 + - 既存 UI/データ互換を壊さず、既存バー表示と一致すること。 + +## 2. スコープと変更対象 +- 変更ファイル(新規/修正/削除): + - 新規: `.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md` +- 影響範囲・互換性リスク: + - Task Table の実績表示、Gantt 実績バー、ロード時の既存データ表示が影響範囲。 + - 既存データの ActualEffortHours がバーと矛盾する場合、ロード時に補正される。 +- 外部依存・Secrets の扱い: + - 稼働日カレンダー、1日8時間、1人固定の前提に依存。 + - Secrets/PII は扱わない。 + +## 3. 設計方針 +- 責務分離 / データフロー(必要なら Mermaid 1 枚): + - 正規化ロジックは純粋関数として実装し、UI からは `normalizeActuals` を呼び出す。 + - 正規化は `recalcEffort`, `deriveEnd`, `deriveStart`, `roundEffortToQuarterHour` に責務分割する。 + - 半開区間を前提に稼働日カレンダー計算 API を利用する。 + +```mermaid +flowchart TD + A[normalizeActuals] --> B{Start+End} + B -->|Yes| C[recalcEffort] + B -->|No| D{Start+Effort} + D -->|Yes| E[deriveEnd -> normalize] + D -->|No| F{End+Effort} + F -->|Yes| G[deriveStart -> normalize] + F -->|No| H[Undetermined] +``` + +- エッジケース / 例外系 / リトライ方針: + - ActualStart/ActualEnd のパース不能・範囲外・start >= end は「欠落」と同等に扱い、初期表示の補完順序に従う。 + - ActualEffortHours が負数/NaN は欠落扱いとし補完を試みる。 + - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 + - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 +- ログと観測性(漏洩防止を含む): + - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 + - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 + +## 4. テスト戦略 +- テスト観点(正常 / 例外 / 境界 / 回帰): + - 初期表示 4 パターン: Start+End, Start+Effort, End+Effort, どれも無い。 + - 編集時 3 パターン: Start 編集, End 編集, Effort 編集。 + - 0.25h 丸め(1.12/1.13/1.37/1.38 等)と ties 上方向を確認。 + - 祝日/非稼働日を含む期間での effort 再計算/ end 算出。 + - 無効値(NaN/負数/start>=end)入力時の欠落扱い。 +- モック / フィクスチャ方針: + - 稼働日カレンダーは既存ユーティリティをモックし、固定カレンダーで期待値を確定させる。 +- テスト追加の実行コマンド(例: `python -m pytest`): + - `npm run test:unit`(必要に応じて `npm test` で lint/build を含めて実行) + +## 5. CI 品質ゲート +- 実行コマンド(format / lint / typecheck / test / security): + - lint/build/test: `npm test`(`test:unit` + `test:lint` + `test:build`) + - security: `npm audit`(既存 CI 運用に合わせて実行) +- 通過基準と失敗時の対応: + - すべてのテストが green であること。失敗時は正規化計算/丸め/稼働日処理を見直す。 + +## 6. ロールアウト・運用 +- ロールバック方法: + - 正規化ロジックを導入したコミットをリバートし、既存表示に戻す。 +- 監視・運用上の注意: + - 既存データの effort がロード時に補正される可能性をリリースノートで周知する。 + +## 7. オープンな課題 / ADR 要否 +- 未確定事項: + - なし。 +- ADR に残すべき判断: + - なし(本仕様で SSOT/丸め/半開区間が確定済み)。 diff --git a/package-lock.json b/package-lock.json index 20a169beb..72e739fa7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -95,7 +95,6 @@ "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", @@ -756,7 +755,6 @@ "integrity": "sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, @@ -1698,7 +1696,6 @@ "integrity": "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-module-imports": "^7.28.6", @@ -2529,7 +2526,6 @@ "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@dnd-kit/accessibility": "^3.1.1", "@dnd-kit/utilities": "^3.2.2", @@ -4228,7 +4224,6 @@ "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -4446,7 +4441,6 @@ "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -4903,7 +4897,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5011,7 +5004,6 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -6128,7 +6120,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -9371,7 +9362,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -12705,7 +12695,6 @@ "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^27.5.1", "import-local": "^3.0.2", @@ -13953,7 +13942,6 @@ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -16005,7 +15993,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -18398,7 +18385,6 @@ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -19078,7 +19064,6 @@ "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -19684,7 +19669,6 @@ "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "*", "@types/node": "*", @@ -20306,6 +20290,7 @@ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" } @@ -20336,7 +20321,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -21842,6 +21826,24 @@ } } }, + "node_modules/tailwindcss/node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/tapable": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", @@ -22087,7 +22089,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -22296,7 +22297,6 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "license": "(MIT OR CC0-1.0)", - "peer": true, "engines": { "node": ">=10" }, @@ -22412,7 +22412,6 @@ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -22793,7 +22792,6 @@ "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -22867,7 +22865,6 @@ "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -23344,7 +23341,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -23413,7 +23409,6 @@ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "rollup": "dist/bin/rollup" }, From 6b10bf67ff2d9489863970650bee648cb4d550e8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:10:56 +0000 Subject: [PATCH 04/43] =?UTF-8?q?fix:=20=E8=A8=AD=E8=A8=88=E8=A8=88?= =?UTF-8?q?=E7=94=BB=E3=81=AE=E4=B8=B8=E3=82=81=E6=9D=A1=E4=BB=B6=E3=82=92?= =?UTF-8?q?=E6=98=8E=E7=A2=BA=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit レビュー指摘に合わせて丸め境界と 無効条件の記述を調整する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../copilot/plans/41-actuals-linkage-bar-priority-spec.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 8df4a0736..7e2688940 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は 0.25h 単位で四捨五入(ties 上方向)する。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は 0.25h 単位で四捨五入(0.125h の端数は切り上げ)する。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 @@ -40,7 +40,7 @@ flowchart TD ``` - エッジケース / 例外系 / リトライ方針: - - ActualStart/ActualEnd のパース不能・範囲外・start >= end は「欠落」と同等に扱い、初期表示の補完順序に従う。 + - ActualStart/ActualEnd のパース不能・範囲外・start > end は「欠落」と同等に扱い、初期表示の補完順序に従う。 - ActualEffortHours が負数/NaN は欠落扱いとし補完を試みる。 - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 @@ -52,9 +52,9 @@ flowchart TD - テスト観点(正常 / 例外 / 境界 / 回帰): - 初期表示 4 パターン: Start+End, Start+Effort, End+Effort, どれも無い。 - 編集時 3 パターン: Start 編集, End 編集, Effort 編集。 - - 0.25h 丸め(1.12/1.13/1.37/1.38 等)と ties 上方向を確認。 + - 0.25h 丸め(1.12/1.13/1.37/1.38、境界値 1.125/1.375/1.625/1.875 は切り上げ)を確認。 - 祝日/非稼働日を含む期間での effort 再計算/ end 算出。 - - 無効値(NaN/負数/start>=end)入力時の欠落扱い。 + - 無効値(NaN/負数/start>end)入力時の欠落扱い。 - モック / フィクスチャ方針: - 稼働日カレンダーは既存ユーティリティをモックし、固定カレンダーで期待値を確定させる。 - テスト追加の実行コマンド(例: `python -m pytest`): From dae15ed3b56013a993ff14ea23cfb6b35f3927cf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:11:28 +0000 Subject: [PATCH 05/43] =?UTF-8?q?fix:=20=E4=B8=B8=E3=82=81=E4=BB=95?= =?UTF-8?q?=E6=A7=98=E3=81=AE=E8=A8=98=E8=BF=B0=E3=82=92=E6=98=8E=E7=A2=BA?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 境界値の丸め方と期待結果を追記し、 設計計画の曖昧さを解消する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 7e2688940..7eb72b009 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は 0.25h 単位で四捨五入(0.125h の端数は切り上げ)する。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は最も近い 0.25h に丸め、境界の 0.125h は切り上げ(round half up)する。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 @@ -52,7 +52,7 @@ flowchart TD - テスト観点(正常 / 例外 / 境界 / 回帰): - 初期表示 4 パターン: Start+End, Start+Effort, End+Effort, どれも無い。 - 編集時 3 パターン: Start 編集, End 編集, Effort 編集。 - - 0.25h 丸め(1.12/1.13/1.37/1.38、境界値 1.125/1.375/1.625/1.875 は切り上げ)を確認。 + - 0.25h 丸め(1.12→1.00、1.13→1.25、1.37→1.25、1.38→1.50、1.125→1.25、1.375→1.50、1.625→1.75、1.875→2.00)を確認。 - 祝日/非稼働日を含む期間での effort 再計算/ end 算出。 - 無効値(NaN/負数/start>end)入力時の欠落扱い。 - モック / フィクスチャ方針: From 9b7896bfc0b6dc0a58567fb3c18b7286d6055429 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:12:08 +0000 Subject: [PATCH 06/43] =?UTF-8?q?fix:=20=E4=B8=B8=E3=82=81=E3=83=AB?= =?UTF-8?q?=E3=83=BC=E3=83=AB=E3=81=AE=E8=AA=AC=E6=98=8E=E3=82=92=E6=95=B4?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0.125h 境界の扱いを明示し、 設計計画の記述を明確化する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 7eb72b009..16bd47eef 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は最も近い 0.25h に丸め、境界の 0.125h は切り上げ(round half up)する。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は 0.25h 刻みで差分が 0.125h 未満なら下方向、0.125h 以上なら上方向へ丸める(例: 1.125→1.25)。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 From 70e3ef3b542987163e507d11c6e22cbcdaecf3a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:12:45 +0000 Subject: [PATCH 07/43] =?UTF-8?q?fix:=20=E4=B8=B8=E3=82=81=E8=A6=8F?= =?UTF-8?q?=E5=89=87=E3=81=AE=E8=AA=AC=E6=98=8E=E3=82=92=E8=A3=9C=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0.25h 刻みの端数判定を明示し、 例示と整合する記述に修正する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 16bd47eef..0f9f755fb 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は 0.25h 刻みで差分が 0.125h 未満なら下方向、0.125h 以上なら上方向へ丸める(例: 1.125→1.25)。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は 0.25h 刻みの下限からの端数(effort % 0.25)が 0.125h 未満なら切り捨て、0.125h 以上なら切り上げる(例: 1.12→1.00、1.13→1.25)。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 From 8a122a6d31e08e1a0eac2498eaa3ab8e778c6038 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:13:49 +0000 Subject: [PATCH 08/43] =?UTF-8?q?fix:=20=E8=A8=AD=E8=A8=88=E8=A8=88?= =?UTF-8?q?=E7=94=BB=E3=81=AE=E8=A1=A8=E8=A8=98=E3=82=92=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 括弧前後の表記を整え、 計画書の可読性を高める Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../plans/41-actuals-linkage-bar-priority-spec.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 0f9f755fb..51a97ddb8 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は 0.25h 刻みの下限からの端数(effort % 0.25)が 0.125h 未満なら切り捨て、0.125h 以上なら切り上げる(例: 1.12→1.00、1.13→1.25)。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は 0.25h 刻みの下限からの端数 (effort % 0.25) が 0.125h 未満なら切り捨て、0.125h 以上なら切り上げる(例: 1.12→1.00、1.13→1.25)。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 @@ -52,18 +52,18 @@ flowchart TD - テスト観点(正常 / 例外 / 境界 / 回帰): - 初期表示 4 パターン: Start+End, Start+Effort, End+Effort, どれも無い。 - 編集時 3 パターン: Start 編集, End 編集, Effort 編集。 - - 0.25h 丸め(1.12→1.00、1.13→1.25、1.37→1.25、1.38→1.50、1.125→1.25、1.375→1.50、1.625→1.75、1.875→2.00)を確認。 + - 0.25h 丸め (1.12→1.00、1.13→1.25、1.37→1.25、1.38→1.50、1.125→1.25、1.375→1.50、1.625→1.75、1.875→2.00) を確認。 - 祝日/非稼働日を含む期間での effort 再計算/ end 算出。 - 無効値(NaN/負数/start>end)入力時の欠落扱い。 - モック / フィクスチャ方針: - - 稼働日カレンダーは既存ユーティリティをモックし、固定カレンダーで期待値を確定させる。 + - 稼働日カレンダーは既存ユーティリティのモックを用い、固定カレンダーで期待値を確定させる。 - テスト追加の実行コマンド(例: `python -m pytest`): - - `npm run test:unit`(必要に応じて `npm test` で lint/build を含めて実行) + - `npm run test:unit` (必要に応じて `npm test` で lint/build を含めて実行) ## 5. CI 品質ゲート - 実行コマンド(format / lint / typecheck / test / security): - - lint/build/test: `npm test`(`test:unit` + `test:lint` + `test:build`) - - security: `npm audit`(既存 CI 運用に合わせて実行) + - lint/build/test: `npm test` (`test:unit` + `test:lint` + `test:build`) + - security: `npm audit` (既存 CI 運用に合わせて実行) - 通過基準と失敗時の対応: - すべてのテストが green であること。失敗時は正規化計算/丸め/稼働日処理を見直す。 @@ -77,4 +77,4 @@ flowchart TD - 未確定事項: - なし。 - ADR に残すべき判断: - - なし(本仕様で SSOT/丸め/半開区間が確定済み)。 + - なし (本仕様で SSOT/丸め/半開区間が確定済み)。 From b3b877809213dd01b35038ed674abac2020b6efc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:14:18 +0000 Subject: [PATCH 09/43] =?UTF-8?q?fix:=20=E4=B8=B8=E3=82=81=E4=BE=8B?= =?UTF-8?q?=E3=81=AE=E5=8F=AF=E8=AA=AD=E6=80=A7=E3=82=92=E6=94=B9=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 例示を箇条書きに整理し、 丸めルールの参照性を高める Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../copilot/plans/41-actuals-linkage-bar-priority-spec.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 51a97ddb8..9f43acddd 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は 0.25h 刻みの下限からの端数 (effort % 0.25) が 0.125h 未満なら切り捨て、0.125h 以上なら切り上げる(例: 1.12→1.00、1.13→1.25)。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は 0.25h 刻みの下限からの端数 (effort % 0.25) が 0.125h 未満なら切り捨て、0.125h 以上なら切り上げる (例: 1.12→1.00、1.13→1.25)。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 @@ -52,7 +52,10 @@ flowchart TD - テスト観点(正常 / 例外 / 境界 / 回帰): - 初期表示 4 パターン: Start+End, Start+Effort, End+Effort, どれも無い。 - 編集時 3 パターン: Start 編集, End 編集, Effort 編集。 - - 0.25h 丸め (1.12→1.00、1.13→1.25、1.37→1.25、1.38→1.50、1.125→1.25、1.375→1.50、1.625→1.75、1.875→2.00) を確認。 + - 0.25h 丸めを確認: + - 1.12→1.00、1.13→1.25。 + - 1.37→1.25、1.38→1.50。 + - 境界値: 1.125→1.25、1.375→1.50、1.625→1.75、1.875→2.00。 - 祝日/非稼働日を含む期間での effort 再計算/ end 算出。 - 無効値(NaN/負数/start>end)入力時の欠落扱い。 - モック / フィクスチャ方針: From 5ac3d0ab800b4030e1abf4da7a9f65e5d96c2861 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:14:58 +0000 Subject: [PATCH 10/43] =?UTF-8?q?fix:=20=E4=B8=B8=E3=82=81=E8=A8=88?= =?UTF-8?q?=E7=AE=97=E5=BC=8F=E3=82=92=E6=98=8E=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0.25h 正規化の計算式を追記し、 丸め規則の曖昧さを解消する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 9f43acddd..0125541e2 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は 0.25h 刻みの下限からの端数 (effort % 0.25) が 0.125h 未満なら切り捨て、0.125h 以上なら切り上げる (例: 1.12→1.00、1.13→1.25)。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `normalized = Math.floor(effort / 0.25 + 0.5) * 0.25` で正規化する(0.25h で割った値の 0.5 は切り上げ)。例: 1.12→1.00、1.13→1.25。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 From 2f3c2cbe9f50a69f05213d62038c12d9d65c3168 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:15:29 +0000 Subject: [PATCH 11/43] =?UTF-8?q?fix:=20=E4=B8=B8=E3=82=81=E8=AA=AC?= =?UTF-8?q?=E6=98=8E=E3=81=A8=E5=A2=83=E7=95=8C=E4=BE=8B=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 四捨五入の表現を明確化し、 境界直前直後の例を追記する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 0125541e2..f50ba7546 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `normalized = Math.floor(effort / 0.25 + 0.5) * 0.25` で正規化する(0.25h で割った値の 0.5 は切り上げ)。例: 1.12→1.00、1.13→1.25。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `normalized = Math.floor(effort / 0.25 + 0.5) * 0.25` で正規化する(0.25h で割った値を四捨五入し、0.5 は上方向へ丸める)。例: 1.12→1.00、1.13→1.25。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 @@ -56,6 +56,7 @@ flowchart TD - 1.12→1.00、1.13→1.25。 - 1.37→1.25、1.38→1.50。 - 境界値: 1.125→1.25、1.375→1.50、1.625→1.75、1.875→2.00。 + - 境界直前/直後: 1.124→1.00、1.126→1.25、1.374→1.25、1.376→1.50。 - 祝日/非稼働日を含む期間での effort 再計算/ end 算出。 - 無効値(NaN/負数/start>end)入力時の欠落扱い。 - モック / フィクスチャ方針: From 5ec117487cdeb21e708aa6f0e20925ee067e3eb9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:16:03 +0000 Subject: [PATCH 12/43] =?UTF-8?q?fix:=20=E4=B8=B8=E3=82=81=E8=A8=88?= =?UTF-8?q?=E7=AE=97=E5=BC=8F=E3=82=92=E7=B0=A1=E6=BD=94=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Math.round 相当の表現に揃え、 境界条件の理解を容易にする Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index f50ba7546..158cc1220 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `normalized = Math.floor(effort / 0.25 + 0.5) * 0.25` で正規化する(0.25h で割った値を四捨五入し、0.5 は上方向へ丸める)。例: 1.12→1.00、1.13→1.25。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `normalized = Math.round(effort / 0.25) * 0.25` で正規化する(Math.round 相当の四捨五入で 0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 From 46df444b90783dc2b69b598ffdbca74f0405557c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:16:40 +0000 Subject: [PATCH 13/43] =?UTF-8?q?fix:=20=E4=B8=B8=E3=82=81=E5=88=A4?= =?UTF-8?q?=E5=AE=9A=E3=81=AE=E8=AA=AC=E6=98=8E=E3=82=92=E8=A3=9C=E8=B6=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 小数部の丸め条件を明示し、 0.25h 正規化の基準を整理する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 158cc1220..786f56b9a 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `normalized = Math.round(effort / 0.25) * 0.25` で正規化する(Math.round 相当の四捨五入で 0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `normalized = Math.round(effort / 0.25) * 0.25` で正規化する(0.25h で割った値の小数部が 0.5 未満なら切り捨て、0.5 以上なら切り上げ)。例: 1.12→1.00、1.13→1.25。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 From 5a93c48cb4f067078f18e7eab132335a3a61b835 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:17:15 +0000 Subject: [PATCH 14/43] =?UTF-8?q?fix:=20=E4=B8=B8=E3=82=81=E5=AF=BE?= =?UTF-8?q?=E8=B1=A1=E3=81=AE=E8=AA=AC=E6=98=8E=E3=82=92=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit effort/0.25 の丸めであることを明記し、 計算意図を明確化する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 786f56b9a..cb21c305f 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `normalized = Math.round(effort / 0.25) * 0.25` で正規化する(0.25h で割った値の小数部が 0.5 未満なら切り捨て、0.5 以上なら切り上げ)。例: 1.12→1.00、1.13→1.25。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `normalized = Math.round(effort / 0.25) * 0.25` で正規化する(effort/0.25 の小数部を Math.round で丸め、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 From 107bb1346ffd99426299f7cdb9c0b3d24bd379c9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:17:49 +0000 Subject: [PATCH 15/43] =?UTF-8?q?fix:=20=E4=B8=B8=E3=82=81=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E3=82=92=E6=98=8E=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit round-half-up の計算式を明記し、 丸め挙動のブレを防止する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index cb21c305f..6d653bf55 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `normalized = Math.round(effort / 0.25) * 0.25` で正規化する(effort/0.25 の小数部を Math.round で丸め、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 From 9af14d72b2f2469f571e13f8bc85deeb566e769a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:18:22 +0000 Subject: [PATCH 16/43] =?UTF-8?q?fix:=20=E4=B8=B8=E3=82=81=E5=A2=83?= =?UTF-8?q?=E7=95=8C=E3=81=AE=E8=AA=AC=E6=98=8E=E3=82=92=E8=A3=9C=E8=B6=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 上方向への閾値を追記し、 境界例の意図を明確化する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 6d653bf55..89656ba8d 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -55,6 +55,7 @@ flowchart TD - 0.25h 丸めを確認: - 1.12→1.00、1.13→1.25。 - 1.37→1.25、1.38→1.50。 + - 境界条件: effort/0.25 が 4.5 以上で上方向(1.124→1.00、1.125→1.25)。 - 境界値: 1.125→1.25、1.375→1.50、1.625→1.75、1.875→2.00。 - 境界直前/直後: 1.124→1.00、1.126→1.25、1.374→1.25、1.376→1.50。 - 祝日/非稼働日を含む期間での effort 再計算/ end 算出。 From c0e3af43421746b5921e128b4021f712a01f5aaa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:18:53 +0000 Subject: [PATCH 17/43] =?UTF-8?q?fix:=20=E4=B8=B8=E3=82=81=E5=A2=83?= =?UTF-8?q?=E7=95=8C=E3=81=AE=E8=A1=A8=E7=8F=BE=E3=82=92=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 小数部の閾値で判定することを明確化し、 説明の混乱を避ける Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 89656ba8d..0f1da6fb3 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -55,7 +55,7 @@ flowchart TD - 0.25h 丸めを確認: - 1.12→1.00、1.13→1.25。 - 1.37→1.25、1.38→1.50。 - - 境界条件: effort/0.25 が 4.5 以上で上方向(1.124→1.00、1.125→1.25)。 + - 境界条件: effort/0.25 の小数部が 0.5 以上で上方向(1.124→1.00、1.125→1.25)。 - 境界値: 1.125→1.25、1.375→1.50、1.625→1.75、1.875→2.00。 - 境界直前/直後: 1.124→1.00、1.126→1.25、1.374→1.25、1.376→1.50。 - 祝日/非稼働日を含む期間での effort 再計算/ end 算出。 From 368d1d338bc6d97cfd3eb499271d0026bebdbf33 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:32:53 +0000 Subject: [PATCH 18/43] =?UTF-8?q?fix:=20=E6=AD=A3=E8=A6=8F=E5=8C=96?= =?UTF-8?q?=E5=91=BC=E3=81=B3=E5=87=BA=E3=81=97=E8=A8=AD=E8=A8=88=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 呼び出しタイミングとworkHoursPerDay設定を明記し、 実装対象ファイル一覧を更新する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../41-actuals-linkage-bar-priority-spec.md | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 0f1da6fb3..685281ad6 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,6 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 + - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする。 - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 @@ -14,12 +15,22 @@ ## 2. スコープと変更対象 - 変更ファイル(新規/修正/削除): - - 新規: `.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md` + - 新規: + - `src/helpers/actuals-helper.ts`(正規化/補完/丸めの専用ユーティリティ) + - 修正: + - `src/types/public-types.ts`(Task に actualStart/actualEnd を追加、正規化オプション workHoursPerDay を追加) + - `src/helpers/task-helper.ts`(actualStart/actualEnd の入出力サポート) + - `src/components/gantt/gantt.tsx`(tasks 受信時の正規化適用) + - `src/components/task-list/task-list.tsx`(編集確定時に正規化を適用) + - `src/components/task-list/task-list-table.tsx`(実績開始/終了の表示列追加) + - `src/components/task-list/overlay-editor.tsx`(実績開始/終了/工数の編集対応) + - `src/test/task-list-table-editing.test.tsx`(編集時正規化の回帰テスト) + - `src/test/task-model.test.tsx`(actualStart/actualEnd シリアライズ/表示の回帰テスト) - 影響範囲・互換性リスク: - Task Table の実績表示、Gantt 実績バー、ロード時の既存データ表示が影響範囲。 - 既存データの ActualEffortHours がバーと矛盾する場合、ロード時に補正される。 - 外部依存・Secrets の扱い: - - 稼働日カレンダー、1日8時間、1人固定の前提に依存。 + - 稼働日カレンダー、1人固定の前提に依存し、1日あたりの稼働時間は workHoursPerDay で指定(未指定時は 8h)。 - Secrets/PII は扱わない。 ## 3. 設計方針 @@ -27,6 +38,11 @@ - 正規化ロジックは純粋関数として実装し、UI からは `normalizeActuals` を呼び出す。 - 正規化は `recalcEffort`, `deriveEnd`, `deriveStart`, `roundEffortToQuarterHour` に責務分割する。 - 半開区間を前提に稼働日カレンダー計算 API を利用する。 + - `normalizeActuals` の引数で `workHoursPerDay` と `calendarConfig` を受け取り、Gantt の props からデフォルト 8h を注入する。 + - 呼び出しタイミング: + - 初期表示/再描画: `Gantt` の tasks 受信時に `normalizeActuals` を適用し、正規化後の tasks で `ganttDateRange` と `convertToBarTasks` を生成する。 + - 編集確定: `TaskList` の編集確定 (`commitEditing`) で該当タスクに `normalizeActuals` を適用し、正規化済みの差分を `onUpdateTask` / `onCellCommit` へ渡す。 + - 外部更新: API 再取得や親コンポーネントの更新でも tasks prop の更新で同じ正規化が走る(冪等前提)。 ```mermaid flowchart TD @@ -44,6 +60,7 @@ flowchart TD - ActualEffortHours が負数/NaN は欠落扱いとし補完を試みる。 - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 + - workHoursPerDay が未指定/0 以下/NaN の場合は既定値 8h にフォールバックする。 - ログと観測性(漏洩防止を含む): - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 @@ -52,6 +69,7 @@ flowchart TD - テスト観点(正常 / 例外 / 境界 / 回帰): - 初期表示 4 パターン: Start+End, Start+Effort, End+Effort, どれも無い。 - 編集時 3 パターン: Start 編集, End 編集, Effort 編集。 + - workHoursPerDay の変更: 6h/8h/10h で end 算出が変わることを確認。 - 0.25h 丸めを確認: - 1.12→1.00、1.13→1.25。 - 1.37→1.25、1.38→1.50。 From dc79ce52d46d3beaac5bb4a489448875713b3760 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:34:25 +0000 Subject: [PATCH 19/43] =?UTF-8?q?fix:=20=E8=A8=AD=E8=A8=88=E8=A8=88?= =?UTF-8?q?=E7=94=BB=E3=81=AE=E8=A1=A8=E7=8F=BE=E3=82=92=E7=B5=B1=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 既定値の表記と呼び出しタイミングの説明を調整し、 設計計画の一貫性を高める Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../copilot/plans/41-actuals-linkage-bar-priority-spec.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 685281ad6..dcc036719 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -30,7 +30,7 @@ - Task Table の実績表示、Gantt 実績バー、ロード時の既存データ表示が影響範囲。 - 既存データの ActualEffortHours がバーと矛盾する場合、ロード時に補正される。 - 外部依存・Secrets の扱い: - - 稼働日カレンダー、1人固定の前提に依存し、1日あたりの稼働時間は workHoursPerDay で指定(未指定時は 8h)。 + - 稼働日カレンダー、1人固定の前提に依存し、1日あたりの稼働時間は workHoursPerDay で指定 (未指定時は 8h を既定値とする)。 - Secrets/PII は扱わない。 ## 3. 設計方針 @@ -38,10 +38,10 @@ - 正規化ロジックは純粋関数として実装し、UI からは `normalizeActuals` を呼び出す。 - 正規化は `recalcEffort`, `deriveEnd`, `deriveStart`, `roundEffortToQuarterHour` に責務分割する。 - 半開区間を前提に稼働日カレンダー計算 API を利用する。 - - `normalizeActuals` の引数で `workHoursPerDay` と `calendarConfig` を受け取り、Gantt の props からデフォルト 8h を注入する。 + - `normalizeActuals` の引数で `workHoursPerDay` と `calendarConfig`(既存の `CalendarConfig` と同義の稼働日/休日設定)を受け取り、Gantt の props から既定値 8h を注入する。 - 呼び出しタイミング: - 初期表示/再描画: `Gantt` の tasks 受信時に `normalizeActuals` を適用し、正規化後の tasks で `ganttDateRange` と `convertToBarTasks` を生成する。 - - 編集確定: `TaskList` の編集確定 (`commitEditing`) で該当タスクに `normalizeActuals` を適用し、正規化済みの差分を `onUpdateTask` / `onCellCommit` へ渡す。 + - 編集確定時: `TaskList` の `commitEditing` で該当タスクに `normalizeActuals` を適用し、正規化済みの差分を `onUpdateTask` / `onCellCommit` へ渡す。 - 外部更新: API 再取得や親コンポーネントの更新でも tasks prop の更新で同じ正規化が走る(冪等前提)。 ```mermaid From 0f8b829e726ff6080fd77d920209655355808e02 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:48:41 +0000 Subject: [PATCH 20/43] =?UTF-8?q?fix:=20=E3=82=AC=E3=83=B3=E3=83=88?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E3=81=A8=E6=A5=AD=E5=8B=99=E6=99=82=E9=96=93?= =?UTF-8?q?=E5=B8=AF=E3=81=AE=E8=A8=AD=E8=A8=88=E8=BF=BD=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit バー操作時の正規化経路と業務時間帯パラメータを 設計計画に反映する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../plans/41-actuals-linkage-bar-priority-spec.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index dcc036719..2f1b9281f 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -7,6 +7,7 @@ - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする。 + - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする。 - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 @@ -18,7 +19,7 @@ - 新規: - `src/helpers/actuals-helper.ts`(正規化/補完/丸めの専用ユーティリティ) - 修正: - - `src/types/public-types.ts`(Task に actualStart/actualEnd を追加、正規化オプション workHoursPerDay を追加) + - `src/types/public-types.ts`(Task に actualStart/actualEnd を追加、正規化オプション workHoursPerDay/workdayStartTime/workdayEndTime を追加) - `src/helpers/task-helper.ts`(actualStart/actualEnd の入出力サポート) - `src/components/gantt/gantt.tsx`(tasks 受信時の正規化適用) - `src/components/task-list/task-list.tsx`(編集確定時に正規化を適用) @@ -31,6 +32,7 @@ - 既存データの ActualEffortHours がバーと矛盾する場合、ロード時に補正される。 - 外部依存・Secrets の扱い: - 稼働日カレンダー、1人固定の前提に依存し、1日あたりの稼働時間は workHoursPerDay で指定 (未指定時は 8h を既定値とする)。 + - 業務時間帯は workdayStartTime/workdayEndTime で指定 (未指定時は 09:00〜18:00 を既定値とする)。 - Secrets/PII は扱わない。 ## 3. 設計方針 @@ -38,10 +40,11 @@ - 正規化ロジックは純粋関数として実装し、UI からは `normalizeActuals` を呼び出す。 - 正規化は `recalcEffort`, `deriveEnd`, `deriveStart`, `roundEffortToQuarterHour` に責務分割する。 - 半開区間を前提に稼働日カレンダー計算 API を利用する。 - - `normalizeActuals` の引数で `workHoursPerDay` と `calendarConfig`(既存の `CalendarConfig` と同義の稼働日/休日設定)を受け取り、Gantt の props から既定値 8h を注入する。 + - `normalizeActuals` の引数で `workHoursPerDay` と `calendarConfig`(既存の `CalendarConfig` と同義の稼働日/休日設定)、`workdayStartTime`/`workdayEndTime` を受け取り、Gantt の props から既定値 (8h, 09:00〜18:00) を注入する。 - 呼び出しタイミング: - 初期表示/再描画: `Gantt` の tasks 受信時に `normalizeActuals` を適用し、正規化後の tasks で `ganttDateRange` と `convertToBarTasks` を生成する。 - 編集確定時: `TaskList` の `commitEditing` で該当タスクに `normalizeActuals` を適用し、正規化済みの差分を `onUpdateTask` / `onCellCommit` へ渡す。 + - ガントバー操作: ガントのドラッグ/リサイズで `onDateChange` が発火し、ホストが更新した tasks を再投入する際に `normalizeActuals` を適用する(バー操作による日付変更も同じ正規化経路で収束させる)。 - 外部更新: API 再取得や親コンポーネントの更新でも tasks prop の更新で同じ正規化が走る(冪等前提)。 ```mermaid @@ -61,6 +64,9 @@ flowchart TD - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 - workHoursPerDay が未指定/0 以下/NaN の場合は既定値 8h にフォールバックする。 + - workHoursPerDay が業務時間帯 (workdayEndTime - workdayStartTime) を超える場合は、業務時間帯の長さに切り詰める。 + - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 + - end 算出/丸めは業務時間帯内で完結させ、丸め結果が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - ログと観測性(漏洩防止を含む): - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 @@ -70,6 +76,7 @@ flowchart TD - 初期表示 4 パターン: Start+End, Start+Effort, End+Effort, どれも無い。 - 編集時 3 パターン: Start 編集, End 編集, Effort 編集。 - workHoursPerDay の変更: 6h/8h/10h で end 算出が変わることを確認。 + - workdayStartTime/workdayEndTime の変更: 08:00〜17:00/09:00〜18:00/10:00〜19:00 で丸め後の end が業務時間内に収束することを確認。 - 0.25h 丸めを確認: - 1.12→1.00、1.13→1.25。 - 1.37→1.25、1.38→1.50。 From 2fba292d44b11b1e77b1d9f30573aabfaf865501 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:49:24 +0000 Subject: [PATCH 21/43] =?UTF-8?q?fix:=20=E6=A5=AD=E5=8B=99=E6=99=82?= =?UTF-8?q?=E9=96=93=E3=83=91=E3=83=A9=E3=83=A1=E3=83=BC=E3=82=BF=E3=81=AE?= =?UTF-8?q?=E4=BB=95=E6=A7=98=E3=82=92=E6=98=8E=E7=A2=BA=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit workdayStartTime形式とガント操作時の正規化順序を追記し、 設定不整合時の扱いを明示する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../copilot/plans/41-actuals-linkage-bar-priority-spec.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 2f1b9281f..f1a72a8be 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -8,6 +8,7 @@ - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする。 - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする。 + - workdayStartTime/workdayEndTime は `"HH:mm"` 形式の文字列で受け取る(例: `"09:00"`)。 - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 @@ -44,7 +45,7 @@ - 呼び出しタイミング: - 初期表示/再描画: `Gantt` の tasks 受信時に `normalizeActuals` を適用し、正規化後の tasks で `ganttDateRange` と `convertToBarTasks` を生成する。 - 編集確定時: `TaskList` の `commitEditing` で該当タスクに `normalizeActuals` を適用し、正規化済みの差分を `onUpdateTask` / `onCellCommit` へ渡す。 - - ガントバー操作: ガントのドラッグ/リサイズで `onDateChange` が発火し、ホストが更新した tasks を再投入する際に `normalizeActuals` を適用する(バー操作による日付変更も同じ正規化経路で収束させる)。 + - ガントバー操作: ガントのドラッグ/リサイズで `onDateChange` が発火し、ホスト側で更新した tasks が再投入されたタイミングで `normalizeActuals` を適用する(`onDateChange` の通知は正規化前、再描画時に正規化後の値へ収束)。 - 外部更新: API 再取得や親コンポーネントの更新でも tasks prop の更新で同じ正規化が走る(冪等前提)。 ```mermaid @@ -64,7 +65,7 @@ flowchart TD - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 - workHoursPerDay が未指定/0 以下/NaN の場合は既定値 8h にフォールバックする。 - - workHoursPerDay が業務時間帯 (workdayEndTime - workdayStartTime) を超える場合は、業務時間帯の長さに切り詰める。 + - workHoursPerDay が業務時間帯 (workdayEndTime - workdayStartTime) を超える場合は、業務時間帯の長さに切り詰め、console.warn で設定不整合を通知する。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め結果が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - ログと観測性(漏洩防止を含む): From 13a5a9e749613a4a1dd97d5e91fbd62dd4a5bd84 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:49:54 +0000 Subject: [PATCH 22/43] =?UTF-8?q?fix:=20=E6=A5=AD=E5=8B=99=E6=99=82?= =?UTF-8?q?=E9=96=93=E3=81=A8=E6=AD=A3=E8=A6=8F=E5=8C=96=E9=A0=86=E5=BA=8F?= =?UTF-8?q?=E3=82=92=E8=A3=9C=E8=B6=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit workHoursPerDay優先順位とホスト側正規化の扱いを明記し、 設計の理解を補強する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index f1a72a8be..a02deb133 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -45,7 +45,7 @@ - 呼び出しタイミング: - 初期表示/再描画: `Gantt` の tasks 受信時に `normalizeActuals` を適用し、正規化後の tasks で `ganttDateRange` と `convertToBarTasks` を生成する。 - 編集確定時: `TaskList` の `commitEditing` で該当タスクに `normalizeActuals` を適用し、正規化済みの差分を `onUpdateTask` / `onCellCommit` へ渡す。 - - ガントバー操作: ガントのドラッグ/リサイズで `onDateChange` が発火し、ホスト側で更新した tasks が再投入されたタイミングで `normalizeActuals` を適用する(`onDateChange` の通知は正規化前、再描画時に正規化後の値へ収束)。 + - ガントバー操作: ガントのドラッグ/リサイズで `onDateChange` が発火し、ホスト側で更新した tasks が再投入されたタイミングで `normalizeActuals` を適用する(`onDateChange` の通知は正規化前。ホスト側で同じ正規化を適用してから tasks を更新してもよい)。 - 外部更新: API 再取得や親コンポーネントの更新でも tasks prop の更新で同じ正規化が走る(冪等前提)。 ```mermaid @@ -65,7 +65,7 @@ flowchart TD - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 - workHoursPerDay が未指定/0 以下/NaN の場合は既定値 8h にフォールバックする。 - - workHoursPerDay が業務時間帯 (workdayEndTime - workdayStartTime) を超える場合は、業務時間帯の長さに切り詰め、console.warn で設定不整合を通知する。 + - workHoursPerDay が業務時間帯 (workdayEndTime - workdayStartTime) を超える場合は、業務時間帯の長さを優先して使用し、console.warn で設定不整合を通知する(業務時間帯の制約を最優先とする)。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め結果が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - ログと観測性(漏洩防止を含む): From f991960aa1f85c33e9ef515ee4a5d2c92617a7c9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:50:43 +0000 Subject: [PATCH 23/43] =?UTF-8?q?fix:=20=E6=A5=AD=E5=8B=99=E6=99=82?= =?UTF-8?q?=E9=96=93=E3=81=AE=E8=A7=A3=E9=87=88=E3=82=92=E6=98=8E=E7=A2=BA?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit workdayStartTimeのタイムゾーンと繰り越し計算を追記し、 業務時間帯と稼働時間の関係を整理する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../copilot/plans/41-actuals-linkage-bar-priority-spec.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index a02deb133..089d93671 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -8,7 +8,7 @@ - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする。 - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする。 - - workdayStartTime/workdayEndTime は `"HH:mm"` 形式の文字列で受け取る(例: `"09:00"`)。 + - workdayStartTime/workdayEndTime は `"HH:mm"` 形式の文字列で受け取り、タスクの日時と同じローカルタイムゾーンで解釈する(例: `"09:00"`)。 - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 @@ -65,9 +65,10 @@ flowchart TD - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 - workHoursPerDay が未指定/0 以下/NaN の場合は既定値 8h にフォールバックする。 - - workHoursPerDay が業務時間帯 (workdayEndTime - workdayStartTime) を超える場合は、業務時間帯の長さを優先して使用し、console.warn で設定不整合を通知する(業務時間帯の制約を最優先とする)。 + - workHoursPerDay が業務時間帯 (workdayEndTime - workdayStartTime) を超える場合は、休憩を考慮しない業務時間帯の長さを優先して使用し、console.warn で設定不整合を通知する(休憩を含めたい場合は workHoursPerDay で調整する)。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め結果が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 + - 繰り越しは超過分のみを次稼働日に持ち越す(例: 17:45 に 0.5h 丸めで 18:15 になった場合、翌稼働日の 09:15 にする)。 - ログと観測性(漏洩防止を含む): - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 From 1c741bf59c1dc02e2d8a307e97c17ce045ffa15b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:51:21 +0000 Subject: [PATCH 24/43] =?UTF-8?q?fix:=20=E6=A5=AD=E5=8B=99=E6=99=82?= =?UTF-8?q?=E9=96=93=E3=81=A8=E7=A8=BC=E5=83=8D=E6=99=82=E9=96=93=E3=81=AE?= =?UTF-8?q?=E6=95=B4=E5=90=88=E3=82=92=E6=98=8E=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 既定値の関係と有効稼働時間の優先順位を整理し、 繰り越し計算の手順を明文化する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../copilot/plans/41-actuals-linkage-bar-priority-spec.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 089d93671..6f99f7e17 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする。 + - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする(既定の業務時間帯 09:00〜18:00 に対して 1h の休憩を想定)。 - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする。 - workdayStartTime/workdayEndTime は `"HH:mm"` 形式の文字列で受け取り、タスクの日時と同じローカルタイムゾーンで解釈する(例: `"09:00"`)。 - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 @@ -65,10 +65,10 @@ flowchart TD - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 - workHoursPerDay が未指定/0 以下/NaN の場合は既定値 8h にフォールバックする。 - - workHoursPerDay が業務時間帯 (workdayEndTime - workdayStartTime) を超える場合は、休憩を考慮しない業務時間帯の長さを優先して使用し、console.warn で設定不整合を通知する(休憩を含めたい場合は workHoursPerDay で調整する)。 + - workHoursPerDay が業務時間帯 (workdayEndTime - workdayStartTime) を超える場合は、`effectiveWorkHoursPerDay = workdayEndTime - workdayStartTime` を適用して計算し、console.warn で設定不整合を通知する(有効な 1 日の稼働時間は常に業務時間帯の長さ以内とする)。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - - end 算出/丸めは業務時間帯内で完結させ、丸め結果が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - - 繰り越しは超過分のみを次稼働日に持ち越す(例: 17:45 に 0.5h 丸めで 18:15 になった場合、翌稼働日の 09:15 にする)。 + - end 算出/丸めは業務時間帯内で完結させ、丸め後の end が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 + - 繰り越しは `overflow = roundedEnd - workdayEndTime` とし、次稼働日の `workdayStartTime + overflow` を end とする(例: 17:45 に 0.5h 丸めで 18:15 になった場合、翌稼働日の 09:15 にする)。 - ログと観測性(漏洩防止を含む): - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 From 40e11b06f978adbbc50583979dad28134cd6fa74 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:52:06 +0000 Subject: [PATCH 25/43] =?UTF-8?q?fix:=20=E6=A5=AD=E5=8B=99=E6=99=82?= =?UTF-8?q?=E9=96=93=E5=B8=AF=E3=81=AE=E5=89=8D=E6=8F=90=E3=82=92=E8=A3=9C?= =?UTF-8?q?=E8=B6=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 休憩想定と時間差計算の単位を明記し、 業務時間帯の解釈を明確化する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../copilot/plans/41-actuals-linkage-bar-priority-spec.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 6f99f7e17..217a5c661 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -7,7 +7,7 @@ - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする(既定の業務時間帯 09:00〜18:00 に対して 1h の休憩を想定)。 - - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする。 + - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする(9h 窓に対して workHoursPerDay 既定 8h を想定し、休憩は明示指定で調整する)。 - workdayStartTime/workdayEndTime は `"HH:mm"` 形式の文字列で受け取り、タスクの日時と同じローカルタイムゾーンで解釈する(例: `"09:00"`)。 - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 - 非機能要件: @@ -65,10 +65,10 @@ flowchart TD - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 - workHoursPerDay が未指定/0 以下/NaN の場合は既定値 8h にフォールバックする。 - - workHoursPerDay が業務時間帯 (workdayEndTime - workdayStartTime) を超える場合は、`effectiveWorkHoursPerDay = workdayEndTime - workdayStartTime` を適用して計算し、console.warn で設定不整合を通知する(有効な 1 日の稼働時間は常に業務時間帯の長さ以内とする)。 + - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = businessWindowHours` を適用して計算し、console.warn で設定不整合を通知する(有効な 1 日の稼働時間は常に業務時間帯の長さ以内とする)。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め後の end が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - - 繰り越しは `overflow = roundedEnd - workdayEndTime` とし、次稼働日の `workdayStartTime + overflow` を end とする(例: 17:45 に 0.5h 丸めで 18:15 になった場合、翌稼働日の 09:15 にする)。 + - 繰り越しは `overflow = roundedEnd - workdayEndTime`(時間差を分/時の duration として扱う)とし、次稼働日の `workdayStartTime + overflow` を end とする(例: 17:45 に 0.5h 丸めで 18:15 になった場合、翌稼働日の 09:15 にする)。 - ログと観測性(漏洩防止を含む): - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 From 3773a944c7b09a08ceb7efa9d79a8f7c53c8b88f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:52:46 +0000 Subject: [PATCH 26/43] =?UTF-8?q?fix:=20=E4=BC=91=E6=86=A9=E6=89=B1?= =?UTF-8?q?=E3=81=84=E3=81=A8=E7=B9=B0=E3=82=8A=E8=B6=8A=E3=81=97=E8=A8=88?= =?UTF-8?q?=E7=AE=97=E3=82=92=E8=A3=9C=E8=B6=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit breakHoursの暗黙扱いとoverflow例を明確化し、 業務時間帯の説明を補強する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../copilot/plans/41-actuals-linkage-bar-priority-spec.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 217a5c661..15ca37f48 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする(既定の業務時間帯 09:00〜18:00 に対して 1h の休憩を想定)。 + - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする(業務時間帯の長さとの差分は `breakHours = businessWindowHours - workHoursPerDay` として暗黙に扱う)。 - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする(9h 窓に対して workHoursPerDay 既定 8h を想定し、休憩は明示指定で調整する)。 - workdayStartTime/workdayEndTime は `"HH:mm"` 形式の文字列で受け取り、タスクの日時と同じローカルタイムゾーンで解釈する(例: `"09:00"`)。 - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 @@ -65,10 +65,10 @@ flowchart TD - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 - workHoursPerDay が未指定/0 以下/NaN の場合は既定値 8h にフォールバックする。 - - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = businessWindowHours` を適用して計算し、console.warn で設定不整合を通知する(有効な 1 日の稼働時間は常に業務時間帯の長さ以内とする)。 + - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = businessWindowHours` を適用して計算し、console.warn で設定不整合を通知する(`breakHours = businessWindowHours - effectiveWorkHoursPerDay` を暗黙に扱う)。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め後の end が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - - 繰り越しは `overflow = roundedEnd - workdayEndTime`(時間差を分/時の duration として扱う)とし、次稼働日の `workdayStartTime + overflow` を end とする(例: 17:45 に 0.5h 丸めで 18:15 になった場合、翌稼働日の 09:15 にする)。 + - 繰り越しは `overflow = roundedEnd - workdayEndTime`(時間差を分/時の duration として扱う)とし、次稼働日の `workdayStartTime + overflow` を end とする(例: 17:45 に 0.5h 丸めで 18:15 になった場合、overflow は 0:15 なので翌稼働日の 09:15 にする)。 - ログと観測性(漏洩防止を含む): - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 From d32ccfbbda672863075933093613c5b8bd7c1fc3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:53:39 +0000 Subject: [PATCH 27/43] =?UTF-8?q?fix:=20windowHours=E3=81=AE=E5=AE=9A?= =?UTF-8?q?=E7=BE=A9=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 業務時間帯のduration定義とbreakHours算出を補足し、 時間計算の前提を明確化する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../copilot/plans/41-actuals-linkage-bar-priority-spec.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 15ca37f48..07ffd1e68 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする(業務時間帯の長さとの差分は `breakHours = businessWindowHours - workHoursPerDay` として暗黙に扱う)。 + - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする(`windowHours = workdayEndTime - workdayStartTime` の duration とし、差分は `breakHours = max(0, windowHours - workHoursPerDay)` として暗黙に扱う)。 - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする(9h 窓に対して workHoursPerDay 既定 8h を想定し、休憩は明示指定で調整する)。 - workdayStartTime/workdayEndTime は `"HH:mm"` 形式の文字列で受け取り、タスクの日時と同じローカルタイムゾーンで解釈する(例: `"09:00"`)。 - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 @@ -65,10 +65,10 @@ flowchart TD - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 - workHoursPerDay が未指定/0 以下/NaN の場合は既定値 8h にフォールバックする。 - - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = businessWindowHours` を適用して計算し、console.warn で設定不整合を通知する(`breakHours = businessWindowHours - effectiveWorkHoursPerDay` を暗黙に扱う)。 + - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = windowHours` を適用して計算し、console.warn で設定不整合を通知する(`windowHours = workdayEndTime - workdayStartTime` の duration、breakHours は 0 になる)。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め後の end が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - - 繰り越しは `overflow = roundedEnd - workdayEndTime`(時間差を分/時の duration として扱う)とし、次稼働日の `workdayStartTime + overflow` を end とする(例: 17:45 に 0.5h 丸めで 18:15 になった場合、overflow は 0:15 なので翌稼働日の 09:15 にする)。 + - 繰り越しは `overflow = roundedEnd - workdayEndTime`(roundedEnd は datetime、workdayEndTime は同日の時刻に変換し、時間差を分/時の duration として扱う)とし、次稼働日の `workdayStartTime + overflow` を end とする(例: 17:45 に 0.5h 丸めで 18:15 になった場合、overflow は 0:15 なので翌稼働日の 09:15 にする)。 - ログと観測性(漏洩防止を含む): - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 From accc9249538031e3372809cb2cca63e7d29951e4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:54:12 +0000 Subject: [PATCH 28/43] =?UTF-8?q?fix:=20=E7=A8=BC=E5=83=8D=E6=99=82?= =?UTF-8?q?=E9=96=93=E3=81=AE=E5=AE=9A=E7=BE=A9=E3=82=92=E8=A3=9C=E5=BC=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 有効稼働時間の最小化と0.5h表記を明確化し、 計算例の混乱を避ける Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 07ffd1e68..5faf56f3c 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする(`windowHours = workdayEndTime - workdayStartTime` の duration とし、差分は `breakHours = max(0, windowHours - workHoursPerDay)` として暗黙に扱う)。 + - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする(`windowHours = workdayEndTime - workdayStartTime` の duration とし、`effectiveWorkHoursPerDay = min(workHoursPerDay, windowHours)`、差分は `breakHours = max(0, windowHours - effectiveWorkHoursPerDay)` として暗黙に扱う)。 - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする(9h 窓に対して workHoursPerDay 既定 8h を想定し、休憩は明示指定で調整する)。 - workdayStartTime/workdayEndTime は `"HH:mm"` 形式の文字列で受け取り、タスクの日時と同じローカルタイムゾーンで解釈する(例: `"09:00"`)。 - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 @@ -68,7 +68,7 @@ flowchart TD - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = windowHours` を適用して計算し、console.warn で設定不整合を通知する(`windowHours = workdayEndTime - workdayStartTime` の duration、breakHours は 0 になる)。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め後の end が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - - 繰り越しは `overflow = roundedEnd - workdayEndTime`(roundedEnd は datetime、workdayEndTime は同日の時刻に変換し、時間差を分/時の duration として扱う)とし、次稼働日の `workdayStartTime + overflow` を end とする(例: 17:45 に 0.5h 丸めで 18:15 になった場合、overflow は 0:15 なので翌稼働日の 09:15 にする)。 + - 繰り越しは `overflow = roundedEnd - workdayEndTime`(roundedEnd は datetime、workdayEndTime は同日の時刻に変換し、時間差を分/時の duration として扱う)とし、次稼働日の `workdayStartTime + overflow` を end とする(例: 17:45 に 0.5h=30分 丸めで 18:15 になった場合、overflow は 0:15 なので翌稼働日の 09:15 にする)。 - ログと観測性(漏洩防止を含む): - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 From 5861147af018092b2b6a47ec4fd07ca3cfeb7c94 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:54:49 +0000 Subject: [PATCH 29/43] =?UTF-8?q?fix:=20breakHours=E7=AE=97=E5=87=BA?= =?UTF-8?q?=E3=82=92=E7=B0=A1=E6=BD=94=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit breakHoursの算出式と繰り越し例の説明を整理し、 冗長な記述を削減する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../copilot/plans/41-actuals-linkage-bar-priority-spec.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 5faf56f3c..96f228448 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,7 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする(`windowHours = workdayEndTime - workdayStartTime` の duration とし、`effectiveWorkHoursPerDay = min(workHoursPerDay, windowHours)`、差分は `breakHours = max(0, windowHours - effectiveWorkHoursPerDay)` として暗黙に扱う)。 + - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする(`windowHours = workdayEndTime - workdayStartTime` の duration とし、`effectiveWorkHoursPerDay = min(workHoursPerDay, windowHours)`、差分は `breakHours = windowHours - effectiveWorkHoursPerDay` として暗黙に扱う)。 - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする(9h 窓に対して workHoursPerDay 既定 8h を想定し、休憩は明示指定で調整する)。 - workdayStartTime/workdayEndTime は `"HH:mm"` 形式の文字列で受け取り、タスクの日時と同じローカルタイムゾーンで解釈する(例: `"09:00"`)。 - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 @@ -65,10 +65,10 @@ flowchart TD - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 - workHoursPerDay が未指定/0 以下/NaN の場合は既定値 8h にフォールバックする。 - - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = windowHours` を適用して計算し、console.warn で設定不整合を通知する(`windowHours = workdayEndTime - workdayStartTime` の duration、breakHours は 0 になる)。 + - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = windowHours` を適用して計算し、console.warn で設定不整合を通知する。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め後の end が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - - 繰り越しは `overflow = roundedEnd - workdayEndTime`(roundedEnd は datetime、workdayEndTime は同日の時刻に変換し、時間差を分/時の duration として扱う)とし、次稼働日の `workdayStartTime + overflow` を end とする(例: 17:45 に 0.5h=30分 丸めで 18:15 になった場合、overflow は 0:15 なので翌稼働日の 09:15 にする)。 + - 繰り越しは `overflow = roundedEnd - workdayEndTime`(roundedEnd は datetime、workdayEndTime は同日の時刻に変換し、時間差を分/時の duration として扱う)とし、次稼働日の `workdayStartTime + overflow` を end とする(例: effort を 0.5h=30分 に丸めた結果 17:45→18:15 になった場合、overflow は 0:15 なので翌稼働日の 09:15 にする)。 - ログと観測性(漏洩防止を含む): - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 From aa337f194925ef1cd161266c418b646c1e51581c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:55:22 +0000 Subject: [PATCH 30/43] =?UTF-8?q?fix:=20=E4=BC=91=E6=86=A9=E3=81=A8?= =?UTF-8?q?=E7=B9=B0=E3=82=8A=E8=B6=8A=E3=81=97=E3=81=AE=E8=A8=98=E8=BF=B0?= =?UTF-8?q?=E3=82=92=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit breakHoursの式を箇条書き化し、 繰り越し計算を手順化して可読性を高める Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../plans/41-actuals-linkage-bar-priority-spec.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 96f228448..35bcf9cf5 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,7 +6,10 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする(`windowHours = workdayEndTime - workdayStartTime` の duration とし、`effectiveWorkHoursPerDay = min(workHoursPerDay, windowHours)`、差分は `breakHours = windowHours - effectiveWorkHoursPerDay` として暗黙に扱う)。 + - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする。 + - `windowHours = workdayEndTime - workdayStartTime` の duration。 + - `effectiveWorkHoursPerDay = min(workHoursPerDay, windowHours)`。 + - `breakHours = windowHours - effectiveWorkHoursPerDay`(暗黙の休憩時間)。 - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする(9h 窓に対して workHoursPerDay 既定 8h を想定し、休憩は明示指定で調整する)。 - workdayStartTime/workdayEndTime は `"HH:mm"` 形式の文字列で受け取り、タスクの日時と同じローカルタイムゾーンで解釈する(例: `"09:00"`)。 - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 @@ -68,7 +71,10 @@ flowchart TD - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = windowHours` を適用して計算し、console.warn で設定不整合を通知する。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め後の end が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - - 繰り越しは `overflow = roundedEnd - workdayEndTime`(roundedEnd は datetime、workdayEndTime は同日の時刻に変換し、時間差を分/時の duration として扱う)とし、次稼働日の `workdayStartTime + overflow` を end とする(例: effort を 0.5h=30分 に丸めた結果 17:45→18:15 になった場合、overflow は 0:15 なので翌稼働日の 09:15 にする)。 + - 繰り越し手順: + - `overflow = roundedEnd - workdayEndTime`(roundedEnd は datetime、workdayEndTime は同日の時刻に変換し、時間差を分/時の duration として扱う)。 + - 次稼働日の `workdayStartTime + overflow` を end とする。 + - 例: effort を 0.5h=30分 に丸めた結果 17:45→18:15 になった場合、overflow は 0:15 なので翌稼働日の 09:15 にする。 - ログと観測性(漏洩防止を含む): - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 From d74801afa70611b51315c2369c21fbec49349149 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:55:50 +0000 Subject: [PATCH 31/43] =?UTF-8?q?fix:=20=E7=B9=B0=E3=82=8A=E8=B6=8A?= =?UTF-8?q?=E3=81=97=E4=BE=8B=E3=81=AE=E8=AA=AC=E6=98=8E=E3=82=92=E6=98=8E?= =?UTF-8?q?=E7=A2=BA=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 時間単位表記を調整し、 overflow算出の例を手順化する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 35bcf9cf5..ae821cd60 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -72,9 +72,9 @@ flowchart TD - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め後の end が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - 繰り越し手順: - - `overflow = roundedEnd - workdayEndTime`(roundedEnd は datetime、workdayEndTime は同日の時刻に変換し、時間差を分/時の duration として扱う)。 + - `overflow = roundedEnd - workdayEndTime`(roundedEnd は datetime、workdayEndTime は同日の時刻に変換し、時間差を分または時間の duration として扱う)。 - 次稼働日の `workdayStartTime + overflow` を end とする。 - - 例: effort を 0.5h=30分 に丸めた結果 17:45→18:15 になった場合、overflow は 0:15 なので翌稼働日の 09:15 にする。 + - 例: start 17:45、effort 0.5h=30分 → roundedEnd 18:15、workdayEndTime 18:00 のため overflow 0:15、翌稼働日の 09:15 にする。 - ログと観測性(漏洩防止を含む): - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 From 670fc1ccfda3f21111ab01e974e004e6b38a2573 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:56:19 +0000 Subject: [PATCH 32/43] =?UTF-8?q?fix:=20overflow=E5=8D=98=E4=BD=8D?= =?UTF-8?q?=E3=81=AE=E8=A1=A8=E8=A8=98=E3=82=92=E7=B5=B1=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit overflowの計算単位を分に固定し、 例示の単位表記を明確化する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index ae821cd60..dc0995f52 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -72,9 +72,9 @@ flowchart TD - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め後の end が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - 繰り越し手順: - - `overflow = roundedEnd - workdayEndTime`(roundedEnd は datetime、workdayEndTime は同日の時刻に変換し、時間差を分または時間の duration として扱う)。 + - `overflow = roundedEnd - workdayEndTime`(roundedEnd は datetime、workdayEndTime は同日の時刻に変換し、時間差を分単位の duration として扱う)。 - 次稼働日の `workdayStartTime + overflow` を end とする。 - - 例: start 17:45、effort 0.5h=30分 → roundedEnd 18:15、workdayEndTime 18:00 のため overflow 0:15、翌稼働日の 09:15 にする。 + - 例: start 17:45、effort 0.5h=30分 → roundedEnd 18:15、workdayEndTime 18:00 のため overflow 15分、翌稼働日の 09:15 にする。 - ログと観測性(漏洩防止を含む): - 既存の console.debug / console.warn の構造化ログ方針に合わせる。 - 無効値補完や矛盾補正時は rowId・フィールド名・原因のみをログに出し、値本文は必要最小限にする。 From 661e12f1211a2d036857fa3d9033a2716c4f5cb0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 03:05:53 +0000 Subject: [PATCH 33/43] =?UTF-8?q?fix:=20workHoursPerDay=E7=AE=97=E5=87=BA?= =?UTF-8?q?=E3=81=A8=E3=82=B7=E3=83=BC=E3=82=B1=E3=83=B3=E3=82=B9=E5=9B=B3?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 業務時間帯からの稼働時間算出を明記し、 初期表示/編集/バー操作の流れを図示する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../41-actuals-linkage-bar-priority-spec.md | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index dc0995f52..f1203386a 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -6,8 +6,9 @@ - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 - - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は 8h を既定値とする。 + - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は既定の業務時間帯から算出する。 - `windowHours = workdayEndTime - workdayStartTime` の duration。 + - `workHoursPerDay` 未指定時は `defaultBreakHours = 1h` として `workHoursPerDay = windowHours - defaultBreakHours`(既定値は 8h)。 - `effectiveWorkHoursPerDay = min(workHoursPerDay, windowHours)`。 - `breakHours = windowHours - effectiveWorkHoursPerDay`(暗黙の休憩時間)。 - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする(9h 窓に対して workHoursPerDay 既定 8h を想定し、休憩は明示指定で調整する)。 @@ -62,6 +63,41 @@ flowchart TD F -->|No| H[Undetermined] ``` +- シーケンス図: + +```mermaid +sequenceDiagram + participant Host + participant Gantt + participant TaskList + participant Normalize as normalizeActuals + participant Calendar + + rect rgb(240, 248, 255) + Host->>Gantt: tasks 初期投入 + Gantt->>Normalize: 正規化(workHoursPerDay/workdayStartTime等) + Normalize->>Calendar: 稼働日計算 + Normalize-->>Gantt: 正規化済み tasks + Gantt-->>Host: 表示更新 + end + + rect rgb(245, 245, 245) + Host->>TaskList: tasks 再描画 + TaskList->>Normalize: 編集確定時の正規化 + Normalize->>Calendar: 稼働日計算 + Normalize-->>TaskList: 正規化差分 + TaskList-->>Host: onUpdateTask/onCellCommit + end + + rect rgb(255, 248, 240) + Host->>Gantt: ガントバー操作 + Gantt-->>Host: onDateChange (正規化前) + Host->>Gantt: 更新済み tasks 再投入 + Gantt->>Normalize: 正規化 + Normalize-->>Gantt: 正規化済み tasks + end +``` + - エッジケース / 例外系 / リトライ方針: - ActualStart/ActualEnd のパース不能・範囲外・start > end は「欠落」と同等に扱い、初期表示の補完順序に従う。 - ActualEffortHours が負数/NaN は欠落扱いとし補完を試みる。 From db81d24e9c7844dbfd3dbdd8d6eecb04514bfa18 Mon Sep 17 00:00:00 2001 From: Yoshio Nishiyama <99854263+LevelCapTech@users.noreply.github.com> Date: Sat, 21 Feb 2026 12:59:36 +0900 Subject: [PATCH 34/43] Update .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index f1203386a..54d983fae 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -103,7 +103,7 @@ sequenceDiagram - ActualEffortHours が負数/NaN は欠落扱いとし補完を試みる。 - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 - - workHoursPerDay が未指定/0 以下/NaN の場合は既定値 8h にフォールバックする。 + - workHoursPerDay が未指定/0 以下/NaN の場合は、既定の算出ルール(`workHoursPerDay = windowHours - defaultBreakHours`、既定値 8h)にフォールバックする。 - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = windowHours` を適用して計算し、console.warn で設定不整合を通知する。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め後の end が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 From eb290ec07b8906758a2e8833763e81abfe92b15b Mon Sep 17 00:00:00 2001 From: Yoshio Nishiyama <99854263+LevelCapTech@users.noreply.github.com> Date: Sat, 21 Feb 2026 12:59:47 +0900 Subject: [PATCH 35/43] Update .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 54d983fae..2c12691bf 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -104,7 +104,8 @@ sequenceDiagram - ActualEffortHours=0 は start=end を許容し、半開区間のため effort は 0 として扱う。 - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 - workHoursPerDay が未指定/0 以下/NaN の場合は、既定の算出ルール(`workHoursPerDay = windowHours - defaultBreakHours`、既定値 8h)にフォールバックする。 - - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = windowHours` を適用して計算し、console.warn で設定不整合を通知する。 + - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = windowHours` を適用して計算し、設定不整合を警告ログで通知する。 + - 正規化は高頻度呼び出しを前提とするため、既存の `src/helpers/calendar-helper.ts` の `warnOnce` と同様に同一内容の警告は 1 回だけ出力する、または呼び出し元で事前にパラメータ検証を行う方針とする。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め後の end が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - 繰り越し手順: From a4e6fbe6294d4891a74413319f61c9eaa2fd1571 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 04:01:53 +0000 Subject: [PATCH 36/43] =?UTF-8?q?fix:=20=E3=82=B7=E3=83=BC=E3=82=B1?= =?UTF-8?q?=E3=83=B3=E3=82=B9=E5=9B=B3=E3=81=AE=E4=B8=BB=E4=BD=93=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ガントバー操作の主体をUserに明示し、 シーケンス図の呼び出し方向を整合させる Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 2c12691bf..38a7698cd 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -67,6 +67,7 @@ flowchart TD ```mermaid sequenceDiagram + participant User participant Host participant Gantt participant TaskList @@ -90,7 +91,7 @@ sequenceDiagram end rect rgb(255, 248, 240) - Host->>Gantt: ガントバー操作 + User->>Gantt: ガントバー操作 Gantt-->>Host: onDateChange (正規化前) Host->>Gantt: 更新済み tasks 再投入 Gantt->>Normalize: 正規化 From 2c21b5018b4d744d3ea43ef5931c53ededff5b3c Mon Sep 17 00:00:00 2001 From: Yoshio Nishiyama <99854263+LevelCapTech@users.noreply.github.com> Date: Sat, 21 Feb 2026 13:12:19 +0900 Subject: [PATCH 37/43] Update .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 38a7698cd..bed96374b 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -11,7 +11,7 @@ - `workHoursPerDay` 未指定時は `defaultBreakHours = 1h` として `workHoursPerDay = windowHours - defaultBreakHours`(既定値は 8h)。 - `effectiveWorkHoursPerDay = min(workHoursPerDay, windowHours)`。 - `breakHours = windowHours - effectiveWorkHoursPerDay`(暗黙の休憩時間)。 - - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする(9h 窓に対して workHoursPerDay 既定 8h を想定し、休憩は明示指定で調整する)。 + - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする(9h 窓に対して workHoursPerDay 既定 8h を想定し、休憩相当は workHoursPerDay の指定で調整し、breakHours は windowHours と effectiveWorkHoursPerDay の差分として暗黙に決まる)。 - workdayStartTime/workdayEndTime は `"HH:mm"` 形式の文字列で受け取り、タスクの日時と同じローカルタイムゾーンで解釈する(例: `"09:00"`)。 - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 - 非機能要件: From c72cbd70cb44c95ea560d6910bf7566660399095 Mon Sep 17 00:00:00 2001 From: Yoshio Nishiyama <99854263+LevelCapTech@users.noreply.github.com> Date: Sat, 21 Feb 2026 13:12:47 +0900 Subject: [PATCH 38/43] Update .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index bed96374b..adf529f36 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -45,10 +45,10 @@ - 正規化ロジックは純粋関数として実装し、UI からは `normalizeActuals` を呼び出す。 - 正規化は `recalcEffort`, `deriveEnd`, `deriveStart`, `roundEffortToQuarterHour` に責務分割する。 - 半開区間を前提に稼働日カレンダー計算 API を利用する。 - - `normalizeActuals` の引数で `workHoursPerDay` と `calendarConfig`(既存の `CalendarConfig` と同義の稼働日/休日設定)、`workdayStartTime`/`workdayEndTime` を受け取り、Gantt の props から既定値 (8h, 09:00〜18:00) を注入する。 + - `normalizeActuals` の引数で `workHoursPerDay` と `calendar`(DisplayOption; 内部的には既存の `CalendarConfig` と同義の稼働日/休日設定)、`workdayStartTime`/`workdayEndTime` を受け取り、Gantt の props から既定値 (8h, 09:00〜18:00) を注入する。 - 呼び出しタイミング: - 初期表示/再描画: `Gantt` の tasks 受信時に `normalizeActuals` を適用し、正規化後の tasks で `ganttDateRange` と `convertToBarTasks` を生成する。 - - 編集確定時: `TaskList` の `commitEditing` で該当タスクに `normalizeActuals` を適用し、正規化済みの差分を `onUpdateTask` / `onCellCommit` へ渡す。 + - 編集確定時: `TaskList` の `commitEditing` で該当タスクに `normalizeActuals` を適用し、正規化済みの差分を `onTaskUpdate` / `onCellCommit` へ渡す(内部的には `TaskList` に `onUpdateTask` として渡される)。 - ガントバー操作: ガントのドラッグ/リサイズで `onDateChange` が発火し、ホスト側で更新した tasks が再投入されたタイミングで `normalizeActuals` を適用する(`onDateChange` の通知は正規化前。ホスト側で同じ正規化を適用してから tasks を更新してもよい)。 - 外部更新: API 再取得や親コンポーネントの更新でも tasks prop の更新で同じ正規化が走る(冪等前提)。 From b006a2a3ebf4da9f9395e4bfdd9dc4e47b152505 Mon Sep 17 00:00:00 2001 From: Yoshio Nishiyama <99854263+LevelCapTech@users.noreply.github.com> Date: Sat, 21 Feb 2026 13:13:18 +0900 Subject: [PATCH 39/43] Update .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index adf529f36..96854dc15 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -13,7 +13,7 @@ - `breakHours = windowHours - effectiveWorkHoursPerDay`(暗黙の休憩時間)。 - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする(9h 窓に対して workHoursPerDay 既定 8h を想定し、休憩相当は workHoursPerDay の指定で調整し、breakHours は windowHours と effectiveWorkHoursPerDay の差分として暗黙に決まる)。 - workdayStartTime/workdayEndTime は `"HH:mm"` 形式の文字列で受け取り、タスクの日時と同じローカルタイムゾーンで解釈する(例: `"09:00"`)。 - - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。 + - 期間は [ActualStart, ActualEnd) の半開区間とし、ActualEffortHours は `q = effort / 0.25` に対して `normalized = Math.floor(q + 0.5) * 0.25` を適用する(round-half-up を明示し、0.5 は上方向)。例: 1.12→1.00、1.13→1.25。なお実装では、`effort` を分(または 15 分単位)の整数に変換してからこの丸めを適用するか、`q` 計算時に微小な epsilon(例: `q = effort / 0.25 + Number.EPSILON`)を加えるなど、二進浮動小数誤差に強い丸め方針を用いること。 - 非機能要件: - 正規化は冪等で、高頻度呼び出しに耐える軽量な計算であること。 - ログ/表示に Secrets/PII を含めない。 From b87c2e7921a0f77856de8db1274223405c5af3f0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 04:15:23 +0000 Subject: [PATCH 40/43] =?UTF-8?q?fix:=20=E5=AE=9F=E7=B8=BE=E5=B7=A5?= =?UTF-8?q?=E6=95=B0=E3=81=AE=E5=91=BD=E5=90=8D=E3=81=A8=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E8=A6=B3=E7=82=B9=E3=82=92=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit actualEffortの扱いと既定算出の前提を明記し、 異常系テスト観点を追加する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .../copilot/plans/41-actuals-linkage-bar-priority-spec.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 96854dc15..7acb23078 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -3,6 +3,7 @@ ## 1. 機能要件 / 非機能要件 - 機能要件: - SSOT を (ActualStart, ActualEnd) とし、ActualEffortHours は派生値として正規化する。 + - ActualEffortHours は既存の `Task.actualEffort`(hours)を指す表現とし、新しい公開APIの追加は行わない。 - 初期表示時に 4 パターンの補完/矛盾解決を実施し、常に矛盾ゼロの表示にする。 - 編集時は 2 項目確定で残り 1 項目を自動更新し、バー優先(start/end)を保持する。 - ActualEffortHours 編集時は ActualStart を固定し、稼働日計算で ActualEnd を算出する。 @@ -35,8 +36,9 @@ - 影響範囲・互換性リスク: - Task Table の実績表示、Gantt 実績バー、ロード時の既存データ表示が影響範囲。 - 既存データの ActualEffortHours がバーと矛盾する場合、ロード時に補正される。 + - 既存の `actualEffort` フィールドを hours として扱い、`actualEffortHours` は表示上の呼称に留める。 - 外部依存・Secrets の扱い: - - 稼働日カレンダー、1人固定の前提に依存し、1日あたりの稼働時間は workHoursPerDay で指定 (未指定時は 8h を既定値とする)。 + - 稼働日カレンダー、1人固定の前提に依存し、1日あたりの稼働時間は workHoursPerDay で指定 (未指定時は windowHours と defaultBreakHours から算出する)。 - 業務時間帯は workdayStartTime/workdayEndTime で指定 (未指定時は 09:00〜18:00 を既定値とする)。 - Secrets/PII は扱わない。 @@ -123,6 +125,8 @@ sequenceDiagram - 編集時 3 パターン: Start 編集, End 編集, Effort 編集。 - workHoursPerDay の変更: 6h/8h/10h で end 算出が変わることを確認。 - workdayStartTime/workdayEndTime の変更: 08:00〜17:00/09:00〜18:00/10:00〜19:00 で丸め後の end が業務時間内に収束することを確認。 + - workHoursPerDay > windowHours のクランプと warnOnce 相当の警告が 1 回だけ出ることを確認。 + - workdayStartTime/workdayEndTime の不正値フォールバックと overflow 繰り越しが次稼働日に反映されることを確認。 - 0.25h 丸めを確認: - 1.12→1.00、1.13→1.25。 - 1.37→1.25、1.38→1.50。 From e3247777f62bcac22b622c7466a8b50577f3a470 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 04:16:06 +0000 Subject: [PATCH 41/43] =?UTF-8?q?fix:=20=E7=A8=BC=E5=83=8D=E6=99=82?= =?UTF-8?q?=E9=96=93=E7=AE=97=E5=87=BA=E3=81=AE=E5=BC=8F=E3=82=92=E6=98=8E?= =?UTF-8?q?=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit workHoursPerDayの算出式とクランプ値を追記し、 仕様の曖昧さを解消する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 7acb23078..7d5c72e65 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -38,7 +38,7 @@ - 既存データの ActualEffortHours がバーと矛盾する場合、ロード時に補正される。 - 既存の `actualEffort` フィールドを hours として扱い、`actualEffortHours` は表示上の呼称に留める。 - 外部依存・Secrets の扱い: - - 稼働日カレンダー、1人固定の前提に依存し、1日あたりの稼働時間は workHoursPerDay で指定 (未指定時は windowHours と defaultBreakHours から算出する)。 + - 稼働日カレンダー、1人固定の前提に依存し、1日あたりの稼働時間は workHoursPerDay で指定 (未指定時は `workHoursPerDay = windowHours - defaultBreakHours` で算出する)。 - 業務時間帯は workdayStartTime/workdayEndTime で指定 (未指定時は 09:00〜18:00 を既定値とする)。 - Secrets/PII は扱わない。 @@ -125,7 +125,7 @@ sequenceDiagram - 編集時 3 パターン: Start 編集, End 編集, Effort 編集。 - workHoursPerDay の変更: 6h/8h/10h で end 算出が変わることを確認。 - workdayStartTime/workdayEndTime の変更: 08:00〜17:00/09:00〜18:00/10:00〜19:00 で丸め後の end が業務時間内に収束することを確認。 - - workHoursPerDay > windowHours のクランプと warnOnce 相当の警告が 1 回だけ出ることを確認。 + - workHoursPerDay > windowHours のクランプ(`effectiveWorkHoursPerDay = windowHours`)と warnOnce 相当の警告が 1 回だけ出ることを確認。 - workdayStartTime/workdayEndTime の不正値フォールバックと overflow 繰り越しが次稼働日に反映されることを確認。 - 0.25h 丸めを確認: - 1.12→1.00、1.13→1.25。 From 462a6cb9f4c3e65542fa201204b5577cb921e4b6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 04:16:40 +0000 Subject: [PATCH 42/43] =?UTF-8?q?fix:=20=E7=A8=BC=E5=83=8D=E6=99=82?= =?UTF-8?q?=E9=96=93=E7=94=A8=E8=AA=9E=E3=81=AE=E5=AE=9A=E7=BE=A9=E3=82=92?= =?UTF-8?q?=E8=A3=9C=E8=B6=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit windowHours/defaultBreakHoursの定義と 警告メッセージの要件を明記する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index 7d5c72e65..c45559515 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -38,7 +38,7 @@ - 既存データの ActualEffortHours がバーと矛盾する場合、ロード時に補正される。 - 既存の `actualEffort` フィールドを hours として扱い、`actualEffortHours` は表示上の呼称に留める。 - 外部依存・Secrets の扱い: - - 稼働日カレンダー、1人固定の前提に依存し、1日あたりの稼働時間は workHoursPerDay で指定 (未指定時は `workHoursPerDay = windowHours - defaultBreakHours` で算出する)。 + - 稼働日カレンダー、1人固定の前提に依存し、1日あたりの稼働時間は workHoursPerDay で指定 (未指定時は `workHoursPerDay = windowHours - defaultBreakHours` で算出する。`windowHours` は workdayStartTime〜workdayEndTime の duration、`defaultBreakHours` は 1h)。 - 業務時間帯は workdayStartTime/workdayEndTime で指定 (未指定時は 09:00〜18:00 を既定値とする)。 - Secrets/PII は扱わない。 @@ -125,7 +125,7 @@ sequenceDiagram - 編集時 3 パターン: Start 編集, End 編集, Effort 編集。 - workHoursPerDay の変更: 6h/8h/10h で end 算出が変わることを確認。 - workdayStartTime/workdayEndTime の変更: 08:00〜17:00/09:00〜18:00/10:00〜19:00 で丸め後の end が業務時間内に収束することを確認。 - - workHoursPerDay > windowHours のクランプ(`effectiveWorkHoursPerDay = windowHours`)と warnOnce 相当の警告が 1 回だけ出ることを確認。 + - workHoursPerDay > windowHours のクランプ(`effectiveWorkHoursPerDay = windowHours`)と warnOnce 相当の警告が 1 回だけ出ることを確認(警告は「workHoursPerDay が業務時間帯を超過している」旨と採用値を含む)。 - workdayStartTime/workdayEndTime の不正値フォールバックと overflow 繰り越しが次稼働日に反映されることを確認。 - 0.25h 丸めを確認: - 1.12→1.00、1.13→1.25。 From d878ad477d7d8a1f3878b6f9ce2f0c0a89300ca7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 04:17:25 +0000 Subject: [PATCH 43/43] =?UTF-8?q?fix:=20=E7=A8=BC=E5=83=8D=E6=99=82?= =?UTF-8?q?=E9=96=93=E3=81=AE=E7=9F=AD=E6=99=82=E9=96=93=E3=82=B1=E3=83=BC?= =?UTF-8?q?=E3=82=B9=E3=82=92=E8=A3=9C=E8=B6=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit windowHoursが短い場合の算出ルールと warnOnceの適用範囲を明記する Co-authored-by: LevelCapTech <99854263+LevelCapTech@users.noreply.github.com> --- .github/copilot/plans/41-actuals-linkage-bar-priority-spec.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md index c45559515..1a566fc69 100644 --- a/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md +++ b/.github/copilot/plans/41-actuals-linkage-bar-priority-spec.md @@ -10,6 +10,7 @@ - 稼働時間/日 (workHoursPerDay) は呼び出し元パラメータで指定可能とし、未指定時は既定の業務時間帯から算出する。 - `windowHours = workdayEndTime - workdayStartTime` の duration。 - `workHoursPerDay` 未指定時は `defaultBreakHours = 1h` として `workHoursPerDay = windowHours - defaultBreakHours`(既定値は 8h)。 + - `windowHours <= defaultBreakHours` の場合は `workHoursPerDay = windowHours` とし、`breakHours = 0` とする(業務時間帯が短い場合は休憩を持たない)。 - `effectiveWorkHoursPerDay = min(workHoursPerDay, windowHours)`。 - `breakHours = windowHours - effectiveWorkHoursPerDay`(暗黙の休憩時間)。 - 業務開始/終了時刻 (workdayStartTime/workdayEndTime) を呼び出し元パラメータで指定可能とし、未指定時は 09:00〜18:00 を既定値とする(9h 窓に対して workHoursPerDay 既定 8h を想定し、休憩相当は workHoursPerDay の指定で調整し、breakHours は windowHours と effectiveWorkHoursPerDay の差分として暗黙に決まる)。 @@ -108,7 +109,7 @@ sequenceDiagram - 非稼働日跨ぎはカレンダー API に委譲し、加算/差分計算は稼働日のみを対象にする。 - workHoursPerDay が未指定/0 以下/NaN の場合は、既定の算出ルール(`workHoursPerDay = windowHours - defaultBreakHours`、既定値 8h)にフォールバックする。 - workHoursPerDay が業務時間帯の長さ(workdayStartTime/workdayEndTime を時間差に換算した値)を超える場合は、`effectiveWorkHoursPerDay = windowHours` を適用して計算し、設定不整合を警告ログで通知する。 - - 正規化は高頻度呼び出しを前提とするため、既存の `src/helpers/calendar-helper.ts` の `warnOnce` と同様に同一内容の警告は 1 回だけ出力する、または呼び出し元で事前にパラメータ検証を行う方針とする。 + - 正規化は高頻度呼び出しを前提とするため、既存の `src/helpers/calendar-helper.ts` の `warnOnce` と同様に同一内容の警告は 1 回だけ出力する(プロセス内の記憶で抑制し、永続化はしない)。 - workdayStartTime/workdayEndTime が未指定/不正/逆転の場合は既定値 09:00〜18:00 にフォールバックする。 - end 算出/丸めは業務時間帯内で完結させ、丸め後の end が workdayEndTime を超える場合は次稼働日の workdayStartTime に繰り越す。 - 繰り越し手順: @@ -126,6 +127,7 @@ sequenceDiagram - workHoursPerDay の変更: 6h/8h/10h で end 算出が変わることを確認。 - workdayStartTime/workdayEndTime の変更: 08:00〜17:00/09:00〜18:00/10:00〜19:00 で丸め後の end が業務時間内に収束することを確認。 - workHoursPerDay > windowHours のクランプ(`effectiveWorkHoursPerDay = windowHours`)と warnOnce 相当の警告が 1 回だけ出ることを確認(警告は「workHoursPerDay が業務時間帯を超過している」旨と採用値を含む)。 + - windowHours <= defaultBreakHours の場合に `workHoursPerDay = windowHours` となり、休憩時間が 0 になることを確認。 - workdayStartTime/workdayEndTime の不正値フォールバックと overflow 繰り越しが次稼働日に反映されることを確認。 - 0.25h 丸めを確認: - 1.12→1.00、1.13→1.25。