# マスタードキュメント - Windmillフロー管理 API一本化編 > **最終更新**: 2026-03-03 > **対象**: `windmill.keinafarm.net` / workspace `admins` > **目的**: ローカルGitとサーバーGitの衝突を避けつつ、Windmill APIを唯一の運用経路に統一する --- ## 目次 1. [この文書の役割](#1-この文書の役割) 2. [運用方針(結論)](#2-運用方針結論) 3. [現状の課題と解決方針](#3-現状の課題と解決方針) 4. [管理対象と正本の定義](#4-管理対象と正本の定義) 5. [同期・反映の仕様](#5-同期反映の仕様) 6. [競合時の動作仕様](#6-競合時の動作仕様) 7. [実装計画](#7-実装計画) 8. [標準運用手順(Runbook)](#8-標準運用手順runbook) 9. [セキュリティ・監査方針](#9-セキュリティ監査方針) 10. [障害前提の復旧設計(必須)](#10-障害前提の復旧設計必須) 11. [Windmill依存を薄くする方針(必須)](#11-windmill依存を薄くする方針必須) 12. [受け入れ条件](#12-受け入れ条件) 13. [既知の注意点](#13-既知の注意点) 14. [更新履歴](#14-更新履歴) --- ## 1. この文書の役割 この文書は、次回セッション開始時にこれだけ読めば作業を継続できることを目的とした、**運用仕様 + 実装計画の単一ソース**である。 - 暗黙知を残さない - 方針・手順・失敗時の扱いを固定化する - API経由運用に必要な実装タスクを明文化する --- ## 2. 運用方針(結論) ### 採用する方式: API一本化(Server First) 1. ローカルリポジトリは、サーバー側Gitをリモートにしない 2. Windmillの実体変更は **Windmill REST API 経由のみ** 3. 作業開始時にAPIでサーバー状態を取り込み、サーバーが新しければローカルへ同期 4. **運用単位は「workflow package(flow + schedules)」を基本**とする 5. ローカル変更はAPIでサーバーへ反映 6. サーバー側の Git Sync Workflow は定期記録用途として継続 7. ローカルGitコミットは手動(またはAI)で実施し、監査/履歴用途として扱う --- ## 3. 現状の課題と解決方針 ### 課題 - Windmill側の自動Git記録WFと、ローカルGit運用が同一系統を触ると競合が発生する - `wmill` CLIは制約があり使いにくく、運用が不安定 - サーバーとローカルのどちらが最新か判定が曖昧 ### 解決 - 更新経路をWindmill APIに統一し、競合面を縮小する - 「正本=Windmillサーバー」の原則を固定する - `hash` / `parent_hash` を使った衝突検知を標準化する --- ## 4. 管理対象と正本の定義 ### 正本 - **Windmillサーバー上のオブジェクト** - scripts (`/w/{workspace}/scripts/*`) - flows (`/w/{workspace}/flows/*`) - schedules (`/w/{workspace}/schedules/*`) ### ローカルの位置づけ - ローカルファイルは「編集用ワークツリー + 監査ログ」 - ローカルGitはサーバー同期の必須経路ではない ### 管理単位(重要) - 単体オブジェクト運用(scriptだけ、flowだけ)は補助用途 - 標準運用は **workflow package 単位** とする - `flow` 本体 - その `flow path` に紐づく `schedules`(`is_flow=true` かつ `script_path == flow.path`) ### 既存の主要オブジェクト(例) - script: `u/admin/alexa_speak` - flows: `f/app_custom/system_heartbeat`, `f/shiraou/shiraou_notification` など --- ## 5. 同期・反映の仕様 ## 5.1 Pull(サーバー -> ローカル) ### 目的 - 作業前にサーバー最新状態をローカルへ取り込む ### 判定ルール - サーバー `updated_at` / `hash` とローカル管理メタ情報を比較 - サーバーが新しければローカルを更新 ### 対象API(オブジェクト単体) - `GET /api/w/{workspace}/scripts/get/p/{path}` - `GET /api/w/{workspace}/flows/get/{path}` - `GET /api/w/{workspace}/schedules/get/{path}` ### workflow package Pull(標準) 1. `GET /flows/get/{flow_path}` で flow 本体取得 2. `GET /schedules/list` で schedule 一覧取得 3. `script_path == flow_path` の schedule 群を抽出 4. ローカルへ一括保存(flow + schedules) ## 5.2 Push(ローカル -> サーバー) ### 目的 - ローカル変更をサーバーへ安全反映 ### スクリプト反映API(標準) - `POST /api/w/{workspace}/scripts/create` 必須パラメータ(最小): - `path` - `parent_hash`(直前取得したサーバーhash) - `summary` - `description` - `content` - `schema` - `language`(TypeScriptは `bun`) - `kind`(通常 `script`) - `lock`(既存値継承) ### フロー反映API - CE制約により `PUT` 更新が不可/不安定な場合があるため、原則: 1. `DELETE /flows/delete/{path}` 2. `POST /flows/create` ### schedule反映API(workflow package の一部) - workflow package Push時は、対象 flow に紐づく schedule も同時同期する - 原則: 1. サーバー現行 schedule(`script_path == flow_path`)一覧取得 2. ローカル定義との差分計算(追加・更新・削除) 3. `DELETE /schedules/delete/{path}` と `POST /schedules/create` で収束 --- ## 6. 競合時の動作仕様 ### スクリプトPush競合 - `parent_hash` 不一致時は更新拒否(期待動作) - 対応: 1. 最新をPull 2. 差分を再適用 3. 再Push ### フローPush競合 - 削除再作成前に最新を必ずPullしてローカル保存 - 競合が疑われる場合は自動実行せず手動確認にフォールバック - **Preflight必須**: Push直前に `remote_index` の既知hashとサーバー現在hashを比較し、不一致ならPush中断(fail closed) - Push後は `post-verify`(再取得して期待JSON一致確認)を必須化 ### schedulePush競合 - `schedule.path` 重複や同名上書きに注意 - workflow package Push時は、対象 flow の schedule 群をまとめて同期し、中途半端な状態を残さない - 失敗時は flow と schedules の両方を再取得して整合を確認 - schedule 同期も Preflight/`post-verify` の対象に含める --- ## 7. 実装計画 ## Phase 0: 文書固定(完了) - 本ドキュメント作成 ## Phase 1: API運用コマンド整備(完了) `wm-api.sh` へ追加: 1. `pull-script ` 2. `push-script ` 3. `pull-flow ` 4. `push-flow ` 5. `pull-all`(scripts/flowsの一覧取得 + 一括保存) 6. `status-remote`(ローカルとサーバーのhash比較) ## Phase 2: workflow package 対応(次タスク) `wm-api.sh` へ追加: 1. `pull-workflow `(flow + schedules 一括取得) 2. `push-workflow `(flow反映 + schedules差分同期) 3. `status-workflow [flow_path]`(workflow単位の差分表示) 4. `pull-all-workflows`(flow全件を workflow package で取得) ## Phase 3: メタ情報管理 - `state/remote_index.json` を拡張し、`scripts/flows/schedules` を保持 - `state/workflow_index.json` を導入し、`workflow -> flow_hash + schedule_hashes` を保持 ## Phase 4: 標準化 - `docs/flow-manage` に操作例を固定 - 「作業開始時は必ずpull」を運用ルール化 ## Phase 5: 半自動化(任意) - AI/スクリプトで - 変更検知 - Pull提案 - Push時の競合自動リカバリ --- ## 8. 標準運用手順(Runbook) ### 8.1 日常の更新(推奨) 1. `pull-all` でサーバー最新を取得 2. ローカル編集 3. workflow修正時は `push-workflow` で反映(flow + schedules) 4. script単体修正時のみ `push-script` を使う 5. 必要に応じてローカルGitにコミット ### 8.2 サーバーで変更されたものを取り込む 1. `status-remote` 実行 2. workflow単位の変更は `status-workflow` / `pull-workflow` で取得 3. 単体変更は `pull-*` で取得 4. ローカル履歴としてコミット(任意) ### 8.3 `alexa_speak` 更新例(現在の具体例) 1. `pull-script u/admin/alexa_speak scripts/alexa_speak.ts` 2. `scripts/alexa_speak.ts` を編集 3. `push-script u/admin/alexa_speak scripts/alexa_speak.ts` 4. Windmill UIで動作確認(`device` がドロップダウン表示) 5. API反映後にUIが変わらない場合は `Edit -> Deploy` を1回実行して再確認 関連引き継ぎ文書: - `docs/flow-manage/11_引き継ぎ_alexa_speak_API反映後にUIドロップダウンが変わらない件.md` --- ## 9. セキュリティ・監査方針 - APIトークンは環境変数またはローカル限定設定で管理 - リポジトリへ平文トークンをコミットしない - 反映時刻・対象path・実行者をログ化 - サーバーGit Syncは監査証跡として維持 --- ## 10. 障害前提の復旧設計(必須) サーバー内部障害、API非冪等、通信断は防止不能とみなし、**復旧可能性を担保する**。 ### 10.1 復旧の基本原則 1. Push前に対象オブジェクトをバックアップ保存(必須) 2. Push後に `post-verify`(再取得して期待値比較)を必須化 3. Push直前に `preflight hash check` を必須化し、不一致時はPush停止(fail closed) 4. 失敗時は「再実行」ではなく「現状確認 -> 復旧」の順で実施 ### 10.2 標準復旧手順 1. `get` で現状確認(存在、content/value、version/hash) 2. 期待状態との差分を判定 3. 必要ならバックアップから復元 4. 復元後に `post-verify` 5. 復旧ログを記録(日時、path、操作者、原因、処置) ### 10.3 フロー欠落時の緊急復旧 `delete -> create` の途中失敗でフローが消失した場合: 1. 直前バックアップJSONで即時 `flows/create` 2. 依存スケジュールの有効性を確認 3. 関連ジョブの手動実行で動作確認 ### 10.4 delete -> create 運用ガード(必須) 1. `push-flow` / `push-workflow` 前に対象flowのバックアップJSONを必ず保存 2. Preflightで hash 不一致なら自動Pushしない(手動レビューへフォールバック) 3. Push後に flow と schedules を再取得し、ローカル期待値と一致確認 4. 不一致時は即時にバックアップから復元し、復旧ログを残す --- ## 11. Windmill依存を薄くする方針(必須) Windmill API依存は避けられないため、依存点を最小化する。 ### 11.1 使用APIの固定 - `scripts`: `list/get/create` - `flows`: `list/get/create/delete` - `schedules`: `list/get/create/delete`(workflow package 同期で常用) 上記以外のAPIは原則使わない。 ### 11.2 判定ロジックの優先順位 1. 実体JSON比較(content/valueの比較)を主判定 2. `hash` / `version_id` / `edited_at` は補助判定 3. 補助フィールド欠落時も動作継続できる実装にする ### 11.3 仕様変更検知 - 定期的に `smoke test` を実行してレスポンス形を検証 - 期待フィールド欠落時はPush停止(fail closed) - 仕様差分を本ドキュメントの更新履歴に反映 --- ## 12. 受け入れ条件 以下を満たせば「このプロジェクトはサーバーのワークフローを管理するためのもの」と言える状態: 1. ローカルから workflow package(flow + schedules)の Pull/Push がAPIで完結 2. サーバー更新が workflow 単位でローカル検知できる 3. 競合時の復旧手順が flow/schedule 両方で定義済み 4. 運用手順がこの文書だけで再現可能 --- ## 13. 既知の注意点 1. `wm-api.sh` は `bash` 前提。WindowsのCRLF混入で shebang 実行失敗し得るため、`.gitattributes` で `*.sh text eol=lf` を固定し、実行は `bash wm-api.sh ...` を標準とする 2. フロー更新は環境により `PUT` できないため削除再作成を標準とする 3. 削除再作成は `version_id/hash/edited_at` を更新するため、Preflight hash check がないと競合上書きを見落とす可能性がある 4. 1つのflowに複数scheduleが紐づくことがあるため、`script_path` ベースで束ねて管理する 5. API応答仕様はWindmillバージョン差で微差が出るため、初回導入時は `get` のレスポンス形を確認する --- ## 14. 更新履歴 | 日付 | 変更内容 | |------|----------| | 2026-03-03 | 初版作成(API一本化方針、同期仕様、実装計画、Runbookを定義) | | 2026-03-03 | 障害前提の復旧設計、Windmill依存を薄くする方針を必須要件として追記 | | 2026-03-03 | 運用単位を workflow package(flow + schedules)へ変更し、実装計画とRunbookを更新 | | 2026-03-03 | `delete -> create` と hash 管理の運用ガード(preflight / fail closed / post-verify)およびCRLF対策を追記 | | 2026-03-04 | `u/admin/alexa_speak` のAPI反映後にUIドロップダウンが即時反映されない事象と運用回避策(`Edit -> Deploy`)を追記 |