21 KiB
| name | description |
|---|---|
| pleasanter-site-spec | Pleasanterのサイト設定JSON(get-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.json(getsite 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の生JSON(get-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ファイル・
差分プレビュー・送信結果をひとまとめに保管する
パス解決は site-paths.js に共通化されている(findSiteDir / ensureSiteDir / sitesettingsDir / docsDir /
newModifyDir / latestModifyDir / latestJsonPath)。新しいスクリプトを書くときはここを再利用し、
パス組み立てを重複させない。
入力の特定
- ユーザーがJSONファイルパスやSiteIdを指定した場合はそれを使う。
- 指定がなければ
configs/site-*/sitesettings/site-*_latest.jsonを探す。複数ある場合はユーザーに確認する。 - 対象サイトの
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 項目ごとの補足HTML(ExtendedHtmlAfterControl)
(該当項目があれば 列名/色(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 | 状態 |
| {対象}Id(ResultId, 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 参照)。
node get-site-config.js…configs/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}.html(GridGuide等のガイドHTML。SiteSettingsではなくサイトデータ直下の項目)processes.json(SiteSettings.Processesの定義ファイル、1ファイルにまとめる。分割しない)manifest.json(上記ファイルとId/Titleの対応表。再構成に必須)config.jsonのSiteIdはカンマ区切りで複数指定可能。また、取得したサイトのInheritPermissionが 自サイト以外を指している場合、権限の実体を持つそのサイトも自動的に追いかけて取得する(後述)。- 抽出だけをやり直したい場合(
latest.jsonは既に取得済み)はnode extract-site-config.jsを単独実行してもよい - 注意:
get-site-config.jsを再実行すると、その時点のサイトの生の状態でscripts/styles/等が 上書きされる。あるサイトの内容を「別サイトへ適用するための下書き」として編集している最中に、 同じサイトへget-site-config.jsを再実行すると編集内容が失われるので、クロスサイト作業中は むやみに元サイトを再取得しない(詳しくは後述の「クロスサイト構造変更」参照)。
- ユーザーの指示に従い、
scripts/*.js等の中身を直接編集する(manifest.jsonのId/メタ情報は変更しない)。 新規追加の場合はmanifest.jsonに対応エントリ(Idは既存と重複しない値、File名)を追加してからファイルを作成する。 node build-desired-config.js site-{SiteId}… 分割ファイルを再構成しdesired_config.jsonを生成(送信なし)。 フォルダ名はサイト名まで含む正式名(site-{SiteId}_{サイト名})だが、site-{SiteId}の前方一致指定でもconfigs/配下から自動解決されるnode apply-site-config.js… ドライラン確認(差分・送信Body・curlコマンド表示のみ、送信なし)- 内容をユーザーに確認してもらい、問題なければ表示されたcurlコマンドをユーザー自身が手動実行する
関連ツール:ユーザー/組織/グループのマスターデータ取得
権限(Permissions)やスクリプト内の担当者振り分けなどをID表記ではなく名前で扱いたい場合に使う。
node get-master-data.js…configs/master/へ以下を取得・保存する(ページング自動対応。/api/users/getはレスポンスのTotalCountが1回あたりの件数を超えることがあるため、 トップレベルのOffsetパラメータで全件を取得しきるまでループする)。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やフェーズの中身を書き換えて使う(汎用パラメータ化はしていない。要望ごとに列の増減や
チェックリストの中身が違うため、都度スクリプトとして書き下ろす方が確実)。
全体の流れ
- マスターデータ+サイト情報の取得:
node get-master-data.js→node get-site-config.js(config.jsonのSiteIdを一時的に"元サイトId,対象サイトId"にして実行し、終わったら単一IDへ戻す)。InheritPermissionが自サイト以外を指していれば、その継承元サイトも自動的に追いかけて取得される。 - 抽出済みScripts/Stylesの編集: 元サイトの
configs/site-{元SiteId}_.../scripts/*.js等を直接編集する。 ⚠️ ここは元サイト自身の抽出フォルダなので、元サイトをget-site-config.jsで再取得すると 編集内容が消える。編集後は速やかに restructure スクリプト(次項)を走らせてmodify/フォルダへ 本文を取り込んでおくこと。 restructure-site-{元SiteId}.js(新規作成): 元サイトのsitesettings/latest.jsonを読み込み、 構造変更(列の挿入・連番リネーム・GridDesign書き換え等)を行い、manifest.json経由で 編集済みのScripts/Styles本文を組み込んだ上で、対象サイトのmodify/{リクエストラベル}/フォルダへsite-{元SiteId}_updated.jsonとして書き出す(site-paths.jsのfindSiteDir/newModifyDirを使う)。 同じフォルダへ対象サイトの変更前スナップショット(before_site-{対象SiteId}_latest.json)も コピーしておく。書き込み前に、想定した件数増分・重複の有無などの整合性チェックを必ず入れる (今回の実装では「フェーズA:事前ガード」「フェーズH:整合性チェック」として実施)。apply-to-site-{対象SiteId}.js(新規作成):modify/フォルダのsite-{元SiteId}_updated.jsonをupdatesite(Mode:"full")で対象サイトへ送る。Title/ReferenceType/ParentId/InheritPermissionは 対象サイト自身の現状値から取得し、SiteSettingsのみ元サイト由来の内容で置き換える。Permissionsは送信ボディに含めない(対象サイトが権限を継承している場合、直接の書き込み対象ではないため。 継承有無はInheritPermissionで判定する)。デフォルトは差分プレビュー+アーティファクト保存のみ、--execute指定時のみ実際に送信する。差分プレビュー・送信結果は同じmodify/フォルダへ保存する。- 権限を名前指定で追加する場合:
apply-permission-grant.jsのパターンで、対象サイトのInheritPermissionが指す継承元サイトに対して行う(対象サイト自身のPermissionsは空配列=継承の ままにしておき、直接は変更しない)。Permissionsはサイトデータ直下の項目で"Type,Id,PermissionType"形式の文字列配列(例:"User,579,15")。updatesitesettings(部分更新)APIはPermissionsを更新対象に 含まないことを公式マニュアルで確認済みのため、updatesite(全体更新)を使い、継承元サイトのSiteSettings等は一切変更せずそのまま再送信しつつPermissionsのみ新規エントリを追加する。 ⚠️ 公式マニュアルにはupdatesiteのリクエストボディでPermissionsを指定できるという明記が 無いため、実行前に必ずプレビュー出力をユーザーに確認してもらうこと。 - 内容確認 → 実行: 生成された
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.jsonはMode:"partial"(updatesitesettings)専用。 Scripts/Styles/ServerScripts/Processes以外のサイト設定には触れない。Columns/EditorColumnHash/Sections/ GridColumns/Permissions等の構造変更は、この節で説明したrestructure-site-*.jsパターンで行う。- ガイドHTML(
html/*.html)はupdatesitesettingsでは反映できない(サイト直下の項目のため)。 反映が必要ならMode:"full"(updatesite)用の別JSONが要ることをユーザーに伝える。自動生成はしない。 - 抽出したスクリプト・サーバースクリプトの中に APIキーやWebhook URL等の秘密情報がハードコードされている場合がある
(実例あり)。抽出・編集作業でこれらの値を見つけたら、チャット上にそのまま貼り付けず、ユーザーに直接ファイルを確認してもらう。
また
configs/フォルダとconfig.jsonは.gitignore済みだが、誤ってコミットしないよう注意喚起する。 - 権限変更・別サイトへの丸ごと上書きはブラスト半径が大きい。実行前に必ず差分プレビューを提示し、
対象サイトIDや継承関係(
InheritPermission)の理解が誤っていないか、実行のたびに確認する。