ken_nogi/ClaudePleasanter/MSS回覧板システム/.claude/skills/pleasanter-site-spec/SKILL.md
Kenichiro NOGI ed33892f08 chore: 作業中の変更を整理しコミット(複数プロジェクト分)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-02 11:09:50 +09:00

23 KiB
Raw Blame History

name description
pleasanter-site-spec Pleasanterのサイト設定JSONget-site-config.js / api-site-get の getsite レスポンスから、SiteSettingsを読み解いたMarkdown仕様書を生成し、Scripts/Styles/ServerScripts/Processesの抽出・編集・反映extract-site-config.js / build-desired-config.js / apply-site-config.jsを行う。また、ユーザー/組織/グループのマスターデータ取得get-master-data.js、別サイトへのSiteSettings丸ごと適用や項目の追加・連番リネームといった構造変更restructure-site-*.js / apply-to-site-*.js、権限Permissionsの名前指定での追加apply-permission-grant.jsにも対応する。「仕様書を作って」「サイト仕様書」「SiteSettingsをドキュメント化」「スクリプトを抜き出して」「プロセス設定を直して反映して」「別サイトに丸ごと適用して」「項目を追加して連番をズラして」「この人と同じ権限を追加して」「site-spec」等の依頼で使う。

Pleasanter サイト仕様書生成・構成管理

configs/site-{SiteId}_{サイト名}/sitesettings/site-{SiteId}_latest.jsongetsite APIレスポンス、Response.Data 配下にサイト情報)を読み解き、 configs/site-{SiteId}_{サイト名}/docs/site-{SiteId}_spec.md として日本語のMarkdown仕様書を出力する。

フォルダ構成configs/ 配下)

configs/
  master/                                … ユーザー/組織/グループのマスターデータget-master-data.js
    master_users.json
    master_depts.json
    master_groups.json
  site-{SiteId}_{サイト名}/
    sitesettings/                        … getsiteの生JSONget-site-config.jsが保存。latest.json + タイムスタンプ付き履歴)
      site-{SiteId}_latest.json
      site-{SiteId}_{timestamp}.json
    scripts/ styles/ serverscripts/ html/ processes.json / manifest.json
                                          … extract-site-config.js による分割済みファイル(従来通り)
    docs/                                … 仕様書(.md)や改善要望プラン等、sitesettings以外の関連ドキュメント
    modify/{リクエストラベル}/            … 修正依頼のたびに新規作成。変更前後のconfigファイル・
                                            差分プレビュー・送信結果に加え、summary.md後述を
                                            必ずひとまとめに保管する

修正を1件でも反映した場合、modify/{リクエストラベル}/ フォルダに機械可読な生JSON差分プレビュー・送信結果だけでなく、 人間が読めるサマリー summary_{timestamp}.md を必ず作成・保存する(ユーザーの明示指示が無くても毎回行う)。 {timestamp} は同じ反映で生成される送信結果ファイル(site-{SiteId}_full_update_result_{timestamp}.json 等)と 揃える。summary.md のような固定名で毎回上書きせず、反映のたびに別ファイルとして残す。記載内容の目安:

  • 対象サイト・反映日時・反映方法実行したコマンド・反映結果HTTPステータス・メッセージ
  • 依頼内容ごとの変更点(変更前 → 変更後を表や箇条書きで)
  • 保留・見送りにした事項(あれば) .mdファイルのため、内容を原始人口調で書くか通常の日本語で書くかは、他のテキストファイル生成と同様に一度だけユーザーに確認する。

パス解決は site-paths.js に共通化されている(findSiteDir / ensureSiteDir / sitesettingsDir / docsDir / newModifyDir / latestModifyDir / latestJsonPath)。新しいスクリプトを書くときはここを再利用し、 パス組み立てを重複させない。

入力の特定

  1. ユーザーがJSONファイルパスやSiteIdを指定した場合はそれを使う。
  2. 指定がなければ configs/site-*/sitesettings/site-*_latest.json を探す。複数ある場合はユーザーに確認する。
  3. 対象サイトの sitesettings/site-{SiteId}_latest.json が無ければ、先に node get-site-config.js の実行を提案する (エンドポイントは /api/items/{SiteId}/getsite を使うこと。/api/items/{SiteId}/get はアイテム一覧取得APIであり別物なので注意

出力ファイル

configs/site-{SiteId}_{サイト名}/docs/site-{SiteId}_spec.md(既存があれば上書きしてよい)。

仕様書の構成(この順番・見出しレベルを踏襲する)

# サイト仕様書:{Title}SiteId: {SiteId}

- 取得元データ: [site-{SiteId}_latest.json](../sitesettings/site-{SiteId}_latest.json)
- 取得日時: {UpdatedTime}(サイト更新日時)/設定バージョン `Ver: {Ver}`

## 1. サイト基本情報
TenantId, Title, ReferenceType, ParentId, InheritPermission, Publish,
  DisableCrossSearch, Creator/Updator, CreatedTime, SiteSettings.Version を表形式で)

## 2. アクセス権限Permissions
Permissions配列を 種別/対象ID/権限レベル の表に分解。可能であれば `resolve-names.js``resolveName` でユーザー名・組織名・グループ名も併記する。
  InheritPermissionが自サイト以外を指している場合は、権限の実体はそちらのサイトにある旨を明記し、
  継承元サイトのPermissionsも取得できていれば併せて記載する。
  「権限値はビットフラグの加算方式のため正確な意味は環境のロール定義に依存する」旨を注記)

## 3. 画面構成
### 3.1 一覧画面GridColumns
GridColumns配列を 順番/列名/表示ラベル の表に。ラベルはColumns配列から解決、
  無ければ「項目種別の判定ルール」のデフォルト名を使う)

### 3.2 編集画面レイアウトEditorColumnHash / Sections
EditorColumnHashの各タブ配列を 順番/項目名(内部名)/ラベル名 の表に。
  `_Section-N` はラベル名欄に「―(セクション「{LabelText}」開始)」と記載。
  続けてSections配列を Id/ラベル/AllowExpand/Expand の表で示す)

### 3.3 タイトル表示TitleColumns / TitleSeparator
TitleColumns配列をTitleSeparatorで連結した式を明記

## 4. 項目定義Columns
Columns配列を 列名(内部)/種別/表示ラベル/説明・入力ガイド/備考 の表に。
  種別は下記「項目種別の判定ルール」で推定。
  備考にはNoWrap, FieldCss, ExtendedHtmlAfterControlの有無などを記載

### 4.1 項目ごとの補足HTMLExtendedHtmlAfterControl
(該当項目があれば 列名/色styleやclassから読み取れれば/内容 の表。無ければこの節は省略)

## 5. 作成・更新権限(フィールド単位)
PermissionForCreating / PermissionForUpdating を表で。無ければ「設定なし」と明記)

## 6. 集計設定Aggregations
存在する場合のみ。Id/GroupBy/Type/Target を表で)

## 7. 他サイト連携Links / ルックアップ)
(存在する場合のみ。起点列/参照先SiteId/参照先の値→自コピー先/JsonFormat を表で。
  「参照先サイトの{From}列の値を、このサイトの{To}列にコピーする」という関係性を文章でも補足)

## 8. プロセス設定Processes
(存在する場合のみ。定義ファイルへのリンク ../processes.json を明記した上で、
  Id/Name・DisplayName/実行条件(CurrentStatus→ChangedStatus)/動作(OnClick等)/成功メッセージ を表で)

## 9. スタイルStyles
存在する場合のみ。Id/Title/適用範囲(New/Edit/Index等のフラグ)/ファイルへのリンクを表で。
  CSS本体はMarkdownに貼らず、抽出済みファイルへのリンクのみとする

## 10. スクリプトScriptsサーバースクリプトServerScripts
存在する場合のみ。Id/Title/適用画面/ファイルへのリンクを表で。
  スクリプト本体はMarkdownに貼らず、抽出済みファイルへのリンクのみとする。
  概要は「何をするスクリプトか」を1〜2行で要約。
  本文中にAPIキー・Webhook URL・パスワード等の秘密情報らしき文字列`API_KEY`, `SECRET`, `Bearer `,
  URLに埋め込まれたトークン等を見つけた場合は、値そのものをMarkdownに転記せず、
  「気になる点」に必ずセキュリティ上の指摘として記載する)

## 11. その他設定
NoDisplayIfReadOnly, HideLink, SectionLatestId, 各種ガイド文の設定有無, Commentsの使用有無など

---

## 気になる点(レビュー観点)
(プレースホルダーらしき文言、権限設定の偏り、項目単位の権限の抜け、
  未設定のガイド文など、気づいた点を箇条書きで)

項目種別の判定ルールColumns内 ColumnName のプレフィックスから推定)

プレフィックス/名前 種別
ClassA〜Z 文字列(分類)
Class001〜040等3桁連番 文字列(拡張分類)。Hide: trueの場合が多く、他項目のルックアップ先の値を裏で保持する用途が多い
NumA〜Z 数値
DateA〜Z 日付
DescriptionA〜Z 説明(複数行文字列)
CheckA〜Z チェックボックス
AttachmentsA〜Z 添付ファイル
Owner, Manager, Assignee等 ユーザー選択
Status 状態
{対象}IdResultId, IssueId等 自動採番ID
Title タイトル
Comments コメント欄

「予定/実行/無し/備考」の4列1組パターンDateNNN/Date(NNN+100)/Check(NNN+100)/ClassNNN、NNNは3桁ゼロ埋め連番が 繰り返し登場するサイトもある。この場合 DateNNN.Description が入力担当(部署名等)、DateNNN.GridLabelText が 項目の表示名を表す。詳細は下記「クロスサイト構造変更(新項目追加・連番リネーム)」を参照。

注意事項

  • SiteSettingsに存在しない項目・空の設定例: ClassHash, NumHash などのラベル定義ハッシュが {})は 「標準ラベルのまま」として仕様書に明記し、存在しないかのように省略しない。
  • 表形式を基本とし、箇条書きより表を優先する(今回のレビューで「編集画面レイアウトは項目名とラベル名を併記」との 指摘を受けた経緯があるため、内部名とラベル名は必ず併記する)。
  • 出力言語は日本語。

関連ツールScripts/Styles/ServerScripts/Processesの抽出・編集・反映

仕様書化とは別に、「スクリプトを個別ファイルに分けて」「プロセス設定を直して反映して」等の依頼では、 以下のツールチェーンを使う(詳細は README.md 参照)。

  1. node get-site-config.jsconfigs/site-{SiteId}_{サイト名}/sitesettings/site-{SiteId}_latest.json を取得し、 続けて自動的に抽出も行う(extract-site-config.js が内部から呼ばれ、configs/site-{SiteId}_{サイト名}/ に以下を分割保存する。未取得なら先にこれを実行)
    • scripts/{Id}_{Title}.js(クライアントスクリプト本体)
    • styles/{Id}_{Title}.css(スタイル本体)
    • serverscripts/{Id}_{Title}.js(サーバースクリプト本体)
    • html/{GuideName}.htmlGridGuide等のガイドHTML。SiteSettingsではなくサイトデータ直下の項目
    • processes.jsonSiteSettings.Processes の定義ファイル、1ファイルにまとめる。分割しない
    • manifest.json上記ファイルとId/Titleの対応表。再構成に必須
    • config.jsonSiteId はカンマ区切りで複数指定可能。また、取得したサイトの InheritPermission が 自サイト以外を指している場合、権限の実体を持つそのサイトも自動的に追いかけて取得する(後述)。
    • 抽出だけをやり直したい場合(latest.jsonは既に取得済み)は node extract-site-config.js を単独実行してもよい
    • 注意: get-site-config.js を再実行すると、その時点のサイトの生の状態で scripts/ styles/ 等が 上書きされる。あるサイトの内容を「別サイトへ適用するための下書き」として編集している最中に、 同じサイトへ get-site-config.js を再実行すると編集内容が失われるので、クロスサイト作業中は むやみに元サイトを再取得しない(詳しくは後述の「クロスサイト構造変更」参照)。
    • 下書きファイルの整理: scripts/ styles/ serverscripts/ 配下に _修正 等のサフィックス付きで manifest.json 未登録の下書きファイルが残っていることがある(過去に本文を直接編集した際の作業ファイル)。 再取得後は、この下書きファイルと対応する正規ファイル(manifest.jsonFile に記載された方)を diffで比較する。内容が完全一致していれば、下書きの編集内容は既にサイトへ反映済みということなので、 その下書きファイルは削除してよい。内容が異なる場合は未反映の編集が残っている可能性があるため、 削除せずユーザーに確認する。
  2. ユーザーの指示に従い、scripts/*.js 等の中身を直接編集する(manifest.json のId/メタ情報は変更しない)。 新規追加の場合は manifest.json に対応エントリ(Idは既存と重複しない値、File名)を追加してからファイルを作成する。
  3. node build-desired-config.js site-{SiteId} … 分割ファイルを再構成し desired_config.json を生成(送信なし)。 フォルダ名はサイト名まで含む正式名(site-{SiteId}_{サイト名})だが、site-{SiteId} の前方一致指定でも configs/配下から自動解決される
  4. node apply-site-config.js … ドライラン確認差分・送信Body・curlコマンド表示のみ、送信なし
  5. 内容をユーザーに確認してもらい、問題なければ表示されたcurlコマンドをユーザー自身が手動実行する

関連ツール:ユーザー/組織/グループのマスターデータ取得

権限Permissionsやスクリプト内の担当者振り分けなどをID表記ではなく名前で扱いたい場合に使う。

  1. node get-master-data.jsconfigs/master/ へ以下を取得・保存する(ページング自動対応。 /api/users/get はレスポンスの TotalCount が1回あたりの件数を超えることがあるため、 トップレベルの Offset パラメータで全件を取得しきるまでループする)。
    • master_users.jsonUserId / LoginId / Name / DeptId 等)
    • master_depts.jsonDeptId / DeptCode / DeptName
    • master_groups.jsonGroupId / GroupName / GroupMembers[] / GroupChildren[]
    • 参照した公式マニュアル: ユーザ取得(全て) / 組織取得 / グループ取得
  2. resolve-names.js をスクリプトから require して使う:
    • loadMasterData(baseDir) … 3つの master_*.json を読み込む
    • resolveName(master, { Type: "User"|"Dept"|"Group", Id }) … IDから名前を引く
    • resolveId(master, { Type, Name }) … 名前から一致するIDの配列を引く完全一致。0件/複数件はエラーとして扱う)

関連ツール:クロスサイト構造変更(項目追加・連番リネーム・別サイトへの丸ごと適用)

「Aサイトを土台に項目を追加してBサイトへ適用して」「この項目の後ろに新しい項目を追加して、以降の連番を ズラして」のような依頼で使うパターン。2026-07-16に SiteId 480111 → 496626 への適用(「解体紹介料申請」項目の 追加・連番リネーム・GridDesign一括改修・改善要望3件の反映で実際に使った構成を一般化したもの。 restructure-site-480111.js / apply-to-site-496626.js / apply-permission-grant.js は、その際の実例 (そのまま次回動かせるテンプレートとして残っている)。次回別の依頼が来たら、これらをコピーして 対象サイトIDやフェーズの中身を書き換えて使う(汎用パラメータ化はしていない。要望ごとに列の増減や チェックリストの中身が違うため、都度スクリプトとして書き下ろす方が確実)。

全体の流れ

  1. マスターデータ+サイト情報の取得: node get-master-data.jsnode get-site-config.js config.jsonSiteId を一時的に "元サイトId,対象サイトId" にして実行し、終わったら単一IDへ戻すInheritPermission が自サイト以外を指していれば、その継承元サイトも自動的に追いかけて取得される。
  2. 抽出済みScripts/Stylesの編集: 元サイトの configs/site-{元SiteId}_.../scripts/*.js 等を直接編集する。 ⚠️ ここは元サイト自身の抽出フォルダなので、元サイトを get-site-config.js で再取得すると 編集内容が消える。編集後は速やかに restructure スクリプト(次項)を走らせて modify/ フォルダへ 本文を取り込んでおくこと。
  3. restructure-site-{元SiteId}.js(新規作成): 元サイトの sitesettings/latest.json を読み込み、 構造変更列の挿入・連番リネーム・GridDesign書き換え等を行い、manifest.json 経由で 編集済みのScripts/Styles本文を組み込んだ上で、対象サイトの modify/{リクエストラベル}/ フォルダへ site-{元SiteId}_updated.json として書き出す(site-paths.jsfindSiteDir / newModifyDir を使う)。 同じフォルダへ対象サイトの変更前スナップショット(before_site-{対象SiteId}_latest.json)も コピーしておく。書き込み前に、想定した件数増分・重複の有無などの整合性チェックを必ず入れる 今回の実装では「フェーズA:事前ガード」「フェーズH:整合性チェック」として実施)。
  4. apply-to-site-{対象SiteId}.js(新規作成): modify/ フォルダの site-{元SiteId}_updated.jsonupdatesiteMode:"full")で対象サイトへ送る。Title/ReferenceType/ParentId/InheritPermission対象サイト自身の現状値から取得し、SiteSettingsのみ元サイト由来の内容で置き換える。 Permissionsは送信ボディに含めない(対象サイトが権限を継承している場合、直接の書き込み対象ではないため。 継承有無は InheritPermission で判定する)。デフォルトは差分プレビュー+アーティファクト保存のみ、 --execute 指定時のみ実際に送信する。差分プレビュー・送信結果は同じ modify/ フォルダへ保存する。
  5. 権限を名前指定で追加する場合: apply-permission-grant.js のパターンで、対象サイトの InheritPermission が指す継承元サイトに対して行う(対象サイト自身の Permissions は空配列=継承の ままにしておき、直接は変更しない)。Permissions はサイトデータ直下の項目で "Type,Id,PermissionType" 形式の文字列配列(例: "User,579,15")。updatesitesettings部分更新APIはPermissionsを更新対象に 含まないことを公式マニュアルで確認済みのため、updatesite(全体更新)を使い、継承元サイトの SiteSettings 等は一切変更せずそのまま再送信しつつ Permissions のみ新規エントリを追加する。 ⚠️ 公式マニュアルには updatesite のリクエストボディで Permissions を指定できるという明記が 無いため、実行前に必ずプレビュー出力をユーザーに確認してもらうこと。
  6. 内容確認 → 実行: 生成された modify/ フォルダの中身(before_*.json / site-*_updated.json / *_diff_*.txt)をユーザーに提示し、レビューを受けてから --execute を実行する。

厳守事項(安全設計、クロスサイト構造変更にも適用)

  • apply-site-config.js は常にドライラン。Claude自身がAPIへ実送信することはしない ENABLE_ACTUAL_SEND を有効化する改修や、curlコマンドの代理実行も行わない。これは変更しない。
  • 一方で apply-to-site-{対象SiteId}.js / apply-permission-grant.js のような専用の直接実行スクリプトは、 ユーザーがその場で明示的に「今回は直接実行してよい」と許可した場合に限り作成・実行してよい 2026-07-16の実例。これは その依頼一回限りの例外 であり、標準運用(ドライラン+手動反映)を 恒久的に変更するものではない。次回以降も、実送信を伴うスクリプトを作る/--execute を走らせる前には、 改めてユーザーに差分プレビューを提示し、明示的な許可を得ること。
  • build-desired-config.js が作る desired_config.jsonMode:"partial"updatesitesettings)専用。 Scripts/Styles/ServerScripts/Processes以外のサイト設定には触れない。Columns/EditorColumnHash/Sections/ GridColumns/Permissions等の構造変更は、この節で説明した restructure-site-*.js パターンで行う。
  • ガイドHTMLhtml/*.html)は updatesitesettings では反映できない(サイト直下の項目のため)。 反映が必要なら Mode:"full"updatesite用の別JSONが要ることをユーザーに伝える。自動生成はしない。
  • 抽出したスクリプト・サーバースクリプトの中に APIキーやWebhook URL等の秘密情報がハードコードされている場合がある (実例あり)。抽出・編集作業でこれらの値を見つけたら、チャット上にそのまま貼り付けず、ユーザーに直接ファイルを確認してもらう。 また configs/ フォルダと config.json.gitignore 済みだが、誤ってコミットしないよう注意喚起する。
  • 権限変更・別サイトへの丸ごと上書きはブラスト半径が大きい。実行前に必ず差分プレビューを提示し、 対象サイトIDや継承関係InheritPermission)の理解が誤っていないか、実行のたびに確認する。