@takagaki/cortex-decisions-viewer 0.12.53 → 0.12.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/render.js +39 -73
  2. package/package.json +2 -2
package/dist/render.js CHANGED
@@ -2169,19 +2169,17 @@ function calendarStateRow(rows) {
2169
2169
  * 接続状態ストアの行から、案件カレンダーの ID を引く(#428・#452)。
2170
2170
  *
2171
2171
  * 🔴 **ID は「最新の行」ではなく「ID を持つ最新の行」から引く。** 状態を運ぶ行
2172
- * (`calendarStateRow`)と別に引く理由は「共有を更新」——押すと裏の経路が番兵
2173
- * (`ref = "calendar"`)の `requested` を書き、それが最新になる。最新の1行だけから
2174
- * ID を引くと、**既にあるカレンダーのリンクとコピー欄が最長20分ぶん画面から消え**、
2175
- * さらに待つと「作成が終わっていません」まで出る(既にあるカレンダーについて)。
2172
+ * (`calendarStateRow`)と別に引く理由は、**カレンダーが出来ている案件にも
2173
+ * `requested` の行が立つ**から——受け口(`?op=calendar-request`)は共有の是正にも
2174
+ * 使われ、裏の経路が番兵(`ref = "calendar"`)の `requested` を書いてそれが最新になる。
2175
+ * 最新の1行だけから ID を引くと、**既にあるカレンダーのリンクとコピー欄が
2176
+ * 最長20分ぶん画面から消え**、さらに待つと「作成が終わっていません」まで出る。
2176
2177
  * **一度できたカレンダーは消えない**ので、ID は落とさないのが正しい。
2177
2178
  *
2178
- * 🔴 **「ストア側に ID を持つ行があるか」の判定を、ここに1本だけ置く(#452)。**
2179
- * これは `calendarPhase` が**「作成の依頼が処理中」と「共有の更新が処理中」を分ける
2180
- * 唯一の材料**でもある——依頼はサーバに飛ぶ 1 本きりで、`status` はどちらも
2181
- * `requested` だから、`status` だけでは種別が分からない。分かれるのは `ref` で、
2182
- * intake は**カレンダーが出来ている案件の依頼にだけ ID を載せる**(#427)。
2183
- * 判定を2枚に割ると片方だけ直り、**一括作成の直後に「共有を更新しています」**が
2184
- * 出る形へ静かに戻る。
2179
+ * かつては `calendarPhase` が**「作成の依頼が処理中」と「共有の更新が処理中」を
2180
+ * 分ける唯一の材料**としてもこれを呼んでいた(#452)。その出し分けは
2181
+ * **#544 で画面から「共有を更新」を外したときに無くなった**(出す先が消えたため)。
2182
+ * ここが残っているのは ID を落とさないためだけ。
2185
2183
  *
2186
2184
  * **クロージャを持たない純関数に保つこと**(`.toString()` でクライアントへ渡す)。
2187
2185
  */
@@ -2267,8 +2265,8 @@ function calendarRowCount(raw) {
2267
2265
  * - `none` … まだ無い(行が 1 本も無い)→ 「この案件のカレンダーを作る」
2268
2266
  * - `pending` … 依頼が立っている → 「作成中(最長 N 分)」
2269
2267
  * - `stale` … 約束の 3 倍を過ぎた → 「作成が終わっていません(依頼は届いています)」
2270
- * - `ready` … ID がある → 手順の画像/Google カレンダーに追加/ID のコピー/共有を更新/
2271
- * この案件のミーティングを作成(#452 の並び)
2268
+ * - `ready` … ID がある → 手順の画像/Google カレンダーに追加/ID のコピー/
2269
+ * この案件のミーティングを作成(#452 の並び。「共有を更新」は #544 で外した)
2272
2270
  * - `failed` … 作れなかった → 理由の1行+もう一度
2273
2271
  *
2274
2272
  * 🔴 **`none` は「行が 1 本も無い」ときだけ。** 契約(裏の経路 #427)は
@@ -2302,28 +2300,18 @@ function calendarPhase(s, rows, ctx, nowMs) {
2302
2300
  var unclear = { phase: "unclear", calendarId: "", detail: "", note: "", at: at };
2303
2301
  // ---- ID があれば必ず ready(最新の行が何であっても降ろさない) ----
2304
2302
  if (id) {
2305
- // 進行中・失敗は**添える1行**として渡す。「作れませんでした」とは言わない
2303
+ // 失敗は**添える1行**として渡す。「作れませんでした」とは言わない
2306
2304
  //(出来ているので嘘になり、押し直すと 2 本目が作られる)
2307
2305
  //
2308
- // 🔴 **「共有を更新しています」は、共有の更新が実際に立っているときだけ出す(#452)。**
2309
- // 「作る」と「共有を更新」は**サーバに飛ぶ依頼が同じ1本**(本文は projectKey だけ・
2310
- // 冪等・#427)なので、`status` だけでは種別が分からない。区別できる材料は
2311
- // **その行が ID を載せているか**だけ:
2312
- // - intake は行の `ref` に `write.response.calendarId || "calendar"` を書く
2313
- // (`infra/lambda/intake/index.mjs`)。**カレンダーが出来ている案件で「共有を更新」を
2314
- // 押すと、ID を載せた `requested` の行**になる(`planCalendarItemWrite` が
2315
- // `existing.calendarId` を返すため)
2316
- // - 一括作成がまだ閉じていない案件は `calendarId` が空なので**番兵のまま**で、
2317
- // ID は夜間の集計(fleet)からしか引けない
2318
- // ⚠ 行は「増える」のではなく**同じ SK に上書き**される(接続状態ストアの SK は `ref` を
2319
- // 含むので、番兵の行と ID の行は別の SK)。だから「作成時の行が残っているから分かる」
2320
- // ではなく、**押した依頼そのものが ID を載せて書かれるから分かる**。
2321
- // ここを見ないと、**一括作成の直後に「共有を更新しています(最長 20 分)。」が出る**
2322
- //(#452 の実機確認)。押してもいない人には、できることの無い1行になる。
2306
+ // 🔴 **`requested`(依頼が立っている)は note にしない(#544)。**
2307
+ // かつては「共有を更新しています(最長 20 分)。」を出すための材料で、
2308
+ // 「押した人にだけ出す」ために **その行が ID を載せているか**を見ていた(#452)。
2309
+ // **その画面のボタンは #544 で外した**ので、出す先が無い——残すと
2310
+ // 「誰も読まない値を計算し続ける」ことになり、次に触る人が使えると誤解する。
2311
+ // ⚠ **失敗の枝は残す。** これは「共有を更新」由来とは限らず、
2312
+ // **作成の書き戻し失敗**(カレンダーは出来ているのに報告が書けなかった回)でも立つ
2323
2313
  var note = "";
2324
- if (status === "requested" && calendarIdFromRows(rows))
2325
- note = "requested";
2326
- else if ((BAD_STATE_STATUSES.calendar || []).indexOf(status) >= 0)
2314
+ if ((BAD_STATE_STATUSES.calendar || []).indexOf(status) >= 0)
2327
2315
  note = detail || "failed";
2328
2316
  return { phase: "ready", calendarId: id, detail: "", note: note, at: at };
2329
2317
  }
@@ -4098,7 +4086,8 @@ a.ds-tile:hover { text-decoration: none; }
4098
4086
  見分けられなかったので、下の2規則(主ボタンと控えめな文字リンク)に格を分けてある */
4099
4087
  /* 必ず 1 回押す主ボタン(#452)。見た目は .ds-toggle-btn から借りるので、ここは
4100
4088
  リンク固有の分だけ——値を写すと色と枠が 2 枚になる。**太さも足さない**
4101
- (隣の「共有を更新」は既定の太さなので、ここだけ太いと「同じ見た目」から外れる) */
4089
+ (借り元の .ds-toggle-btn が既定の太さなので、ここだけ太いと「同じ見た目」から外れる。
4090
+ 隣に並んでいた「共有を更新」は #544 で外した) */
4102
4091
  .mt-cal-primary { display: inline-block; margin: 8px 0 0; text-decoration: none; }
4103
4092
  /* 素の a:hover が下線を引く。**ボタンの見た目に下線が出ると壊れて見える**ので打ち消す。
4104
4093
  ⚠ この CSS はテンプレート文字列の中なので、コメントにバッククォートを書かないこと */
@@ -4543,10 +4532,9 @@ ${deriveCapTile.toString()}
4543
4532
  // (語を2枚持たないため)ので、宣言の前に呼ぶと undefined を読む
4544
4533
  ${isCalendarId.toString()}
4545
4534
  ${calendarStateRow.toString()}
4546
- // calendarIdOf calendarPhase の両方が呼ぶ(#452)。「ストア側に ID を持つ行があるか」は
4547
- // 「共有を更新しています」を出すかどうかの唯一の材料。**読みやすさのために呼ぶ側より前に
4548
- // 置いてあるだけ**——関数宣言は巻き上がるので、上の BAD_STATE_STATUSES(var)と違って
4549
- // 順序そのものは効かない
4535
+ // calendarIdOf が呼ぶ(#452。#544 calendarPhase 側の呼び出しは無くなった)。
4536
+ // **読みやすさのために呼ぶ側より前に置いてあるだけ**——関数宣言は巻き上がるので、
4537
+ // 上の BAD_STATE_STATUSES(var)と違って順序そのものは効かない
4550
4538
  ${calendarIdFromRows.toString()}
4551
4539
  ${calendarIdOf.toString()}
4552
4540
  ${calendarRowCount.toString()}
@@ -6988,23 +6976,9 @@ ${calendarAddUrl.toString()}
6988
6976
  function calendarCanRequest() { return !CALENDAR_DENIED && !!actorTicket(); }
6989
6977
 
6990
6978
  /**
6991
- * この画面で「共有を更新」を押したか(#452)。
6992
- *
6993
- * 🔴 **押した手応えを消さないために要る。** 「共有を更新しています(最長 N 分)。」は
6994
- * ストアの行が ID を載せているときだけ出す(calendarPhase の項)が、**一括作成が
6995
- * まだ閉じていない案件では、押しても番兵の行しか書かれない**。押すと行の時刻が変わって
6996
- * meetingCalendarSig が変わり、liveList が箱を作り直す——ボタン脇の
6997
- * 「✓ 依頼しました」ごと消えるので、**押した人の画面が押す前と 1 文字も変わらない**。
6998
- *
6999
- * 判定を 2 枚にはしていない(calendarPhase は純関数のまま)。ここが持っているのは
7000
- * 「サーバが何を知っているか」ではなく **「この人が押したか」**で、これは
7001
- * サーバの行から復元できない——CALENDAR_DENIED を画面が覚えているのと同じ事情。
7002
- * 画面を開き直せば消える(そのときは行が答えを持っている)。
7003
- *
7004
6979
  * ⚠ ここから下は CLIENT_JS のテンプレート文字列の中。**コメントにバッククォートを
7005
6980
  * 書かないこと**(文字列がそこで終わり、ビルドが丸ごと壊れる)。
7006
6981
  */
7007
- var CALENDAR_SHARE_PRESSED = false;
7008
6982
 
7009
6983
  /**
7010
6984
  * 案件カレンダーの行(#428・設計は #418 の §6)。
@@ -7088,26 +7062,20 @@ ${calendarAddUrl.toString()}
7088
7062
  // 色は**見る人ごとの設定**で、仕組みでは揃えられない(#418 の調査4)。
7089
7063
  // 質問にはせず、事実として1行だけ置く(オーナー決定 A-5: 画面に計器は出さない)
7090
7064
  box.appendChild(el("p", { class: "mt-cal-note", text: "色はご自身のカレンダーで変えられます。" }));
7091
- // 🔴 **「押してください」は、押せる人にだけ出す(#452)。** calendarRequestButton は
7092
- // 名乗り券やオーナー権限が無い人にはボタンではなく別の案内を返すので、
7093
- // その人に説明の1行だけ出すと「押してください」が嘘になる
7094
- if (calendarCanRequest()) {
7095
- // 🔴 **毎時の自動追従(#451)を必ず書く。** これが無いと「押さないと共有されない」と
7096
- // 読ませることになり、押し忘れを心配させる。押すのは「すぐに反映したいとき」だけ
7097
- box.appendChild(el("p", { class: "mt-cal-note", text: "案件にメンバーを足したら押してください。その人もこのカレンダーを見られるようになります(1 時間ごとに自動でも更新されます)" }));
7098
- }
7099
- // 作成済みのまま進行中・失敗の報告が最新なら、その1行だけ添える。
7100
- // **「作れませんでした」とは言わない**(出来ているので嘘になり、押し直すと 2 本目が作られる)
7065
+ // 🔴 **「共有を更新」のボタンと説明はここに在った(#452)。#544 で外した。**
7066
+ // ポータル側が**メンバーの増減のたびに**共有を直させるようになったので、
7067
+ // 押す理由が無くなった(取りこぼしは毎時の便が最長 1 時間で埋める)。
7068
+ // 押す場所が無い画面に「共有を更新しています」「終わっていません」だけを出さない
7069
+ // ——利用者にできることが無い 1 行になる。**受け口(?op=calendar-request)は残っている**
7070
+ // ので、運用が直接叩いて是正できる(docs/calendar-provisioning-runbook.md)。
7101
7071
  //
7102
- // 🔴 **押した人には必ず出す(#452)。** 一括作成がまだ閉じていない案件では、押しても
7103
- // 行は番兵のままなので cal.note は空になる。そのまま出さないと、押した直後の
7104
- // 作り直しで「✓ 依頼しました」も消え、**画面が押す前と 1 文字も変わらない**
7105
- if (cal.note === "requested" || CALENDAR_SHARE_PRESSED) {
7106
- box.appendChild(el("p", { class: "mt-cal-note", text: "共有を更新しています(最長 " + CALENDAR_WAIT_MIN + " 分)。" }));
7107
- } else if (cal.note) {
7072
+ // 作成済みのまま失敗の報告が最新なら、その1行だけ添える。
7073
+ // **これは「共有を更新」由来とは限らない**(作成の書き戻し失敗でも立つ。#452)ので、
7074
+ // ボタンと一緒に消さない。**「作れませんでした」とは言わない**
7075
+ //(出来ているので嘘になり、押し直すと 2 本目が作られる)
7076
+ if (cal.note) {
7108
7077
  box.appendChild(el("p", { class: "mt-cal-warn", text: "共有の更新が終わっていません(" + cal.note + ")。" }));
7109
7078
  }
7110
- box.appendChild(calendarRequestButton("共有を更新", "share"));
7111
7079
  // 🔴 **主ボタンと格を分ける(#452)。** 同じ大きさ・同じ色で2本並ぶと、
7112
7080
  // 必ず押すもの(Google カレンダーに追加)がどれか分からない。予定を作るのは
7113
7081
  // たまにしかしないので、一番下に小さく薄い文字リンクで出す
@@ -7154,10 +7122,11 @@ ${calendarAddUrl.toString()}
7154
7122
  }
7155
7123
 
7156
7124
  /**
7157
- * 依頼を出すボタン。**3つ(作る・共有を更新・もう一度)とも同じ1本の経路**で、
7125
+ * 依頼を出すボタン。**2つ(作る・もう一度)とも同じ1本の経路**で、
7158
7126
  * 押した直後の見え方だけが違う(裏の経路は冪等・#427)。
7127
+ * ⚠ 3 つ目の「共有を更新」は #544 で外した(受け口はそのまま残っている)。
7159
7128
  *
7160
- * **確認を出すのは「作る」だけ。** 「共有を更新」「もう一度」は取り返しがつく
7129
+ * **確認を出すのは「作る」だけ。** 「もう一度」は取り返しがつく
7161
7130
  * (同じ依頼が立ち直るだけ)ので、確認を挟むと押す手が増えるだけになる。
7162
7131
  *
7163
7132
  * 🔴 **本文は空**(projectKey だけ)。共有先のメールをブラウザから受け取らない——
@@ -7210,9 +7179,6 @@ ${calendarAddUrl.toString()}
7210
7179
  // 待ちの言い方は行から描く 1 行(pending)と揃える(#540)。
7211
7180
  // 片方だけ「最長 20 分」だと、同じ待ちが 2 通りに見える
7212
7181
  msg.textContent = "✓ 依頼しました。作成中です(数分〜十数分)。";
7213
- // **押したことを覚える(#452)。** 下の取り直しで箱ごと作り直されると
7214
- // この 1 行は消えるので、消えない側(行から描く 1 行)に引き継ぐ
7215
- if (kind === "share") CALENDAR_SHARE_PRESSED = true;
7216
7182
  // pending-ops(#388)は使わない。**あれは registeredNow のキーで live 判定する
7217
7183
  // 仕組みで、カレンダーは stateNow 由来**。fresh で取り直せば「作成中」が出る
7218
7184
  loadLiveFleet(true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takagaki/cortex-decisions-viewer",
3
- "version": "0.12.53",
3
+ "version": "0.12.54",
4
4
  "description": "Cortexの意思決定記録(Decisions/*.md)を静的サイトにビルドして閲覧する。各レコードに「Edit on GitHub」リンクを付与する。",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -21,7 +21,7 @@
21
21
  "build": "tsc -p tsconfig.json",
22
22
  "prepublishOnly": "npm run build",
23
23
  "demo": "npm run build && node dist/cli.js build ../../aidd-project-cortex/Cortex/Decisions/records --out .demo-site",
24
- "test": "npm run test:syntax && npm run build && node --test test/*.test.mjs",
24
+ "test": "npm run test:syntax && npm run build && node --test --test-concurrency=4 test/*.test.mjs",
25
25
  "test:syntax": "node --test test/embedded-js-syntax.test.mjs"
26
26
  },
27
27
  "dependencies": {