@aiquants/daily-report 0.19.0 → 0.20.1

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 (115) hide show
  1. package/README.md +8 -0
  2. package/dist/client.d.mts +11 -706
  3. package/dist/client.d.ts +11 -706
  4. package/dist/client.js +0 -1
  5. package/dist/client.mjs +0 -1
  6. package/dist/index.d.mts +5 -197
  7. package/dist/index.d.ts +5 -197
  8. package/dist/index.js +0 -1
  9. package/dist/index.mjs +0 -1
  10. package/dist/logger-D3krZrNK.d.mts +0 -14
  11. package/dist/logger-D3krZrNK.d.ts +0 -14
  12. package/dist/server.d.mts +115 -728
  13. package/dist/server.d.ts +115 -728
  14. package/dist/server.js +10 -11
  15. package/dist/server.mjs +10 -11
  16. package/dist/sse-schema-BdUGThiz.d.ts +1025 -1009
  17. package/dist/sse-schema-ChSFm-4q.d.mts +1025 -1009
  18. package/dist/types-CqgYQgbH.d.mts +0 -34
  19. package/dist/types-CqgYQgbH.d.ts +0 -34
  20. package/package.json +11 -11
  21. package/dist/client.js.map +0 -1
  22. package/dist/client.mjs.map +0 -1
  23. package/dist/index.js.map +0 -1
  24. package/dist/index.mjs.map +0 -1
  25. package/dist/server.js.map +0 -1
  26. package/dist/server.mjs.map +0 -1
  27. package/src/client/components/business-day-thumb-overlay.tsx +0 -19
  28. package/src/client/components/daily-report-attachment-indicator.spec.tsx +0 -51
  29. package/src/client/components/daily-report-attachment-indicator.tsx +0 -45
  30. package/src/client/components/daily-report-attachment-list.spec.tsx +0 -94
  31. package/src/client/components/daily-report-attachment-list.tsx +0 -112
  32. package/src/client/components/daily-report-comment-item.tsx +0 -89
  33. package/src/client/components/daily-report-comment-section.tsx +0 -166
  34. package/src/client/components/daily-report-detail-list.tsx +0 -842
  35. package/src/client/components/daily-report-edit-form.tsx +0 -87
  36. package/src/client/components/daily-report-ids-stream-status.spec.tsx +0 -93
  37. package/src/client/components/daily-report-ids-stream-status.tsx +0 -67
  38. package/src/client/components/daily-report-list.tsx +0 -1232
  39. package/src/client/components/daily-report-page.spec.tsx +0 -119
  40. package/src/client/components/daily-report-page.tsx +0 -140
  41. package/src/client/components/daily-report-resize-panels.spec.tsx +0 -307
  42. package/src/client/components/daily-report-resolved-content.tsx +0 -207
  43. package/src/client/components/daily-report-scroll-restoration.spec.tsx +0 -422
  44. package/src/client/components/report-views.spec.tsx +0 -375
  45. package/src/client/components/unread-indicator.tsx +0 -13
  46. package/src/client/config-context.tsx +0 -184
  47. package/src/client/contexts/daily-report-action-context.spec.tsx +0 -433
  48. package/src/client/contexts/daily-report-action-context.tsx +0 -1147
  49. package/src/client/contexts/daily-report-error-context.spec.tsx +0 -66
  50. package/src/client/contexts/daily-report-error-context.tsx +0 -98
  51. package/src/client/hooks/use-animated-number.spec.ts +0 -103
  52. package/src/client/hooks/use-animated-number.ts +0 -69
  53. package/src/client/hooks/use-daily-report-comments.ts +0 -73
  54. package/src/client/hooks/use-daily-report-sse-connection.ts +0 -86
  55. package/src/client/hooks/use-daily-report.spec.ts +0 -546
  56. package/src/client/hooks/use-daily-report.ts +0 -549
  57. package/src/client/hooks/use-dynamic-viewport-height.ts +0 -127
  58. package/src/client/hooks/use-responsive-layout.spec.ts +0 -74
  59. package/src/client/hooks/use-responsive-layout.ts +0 -63
  60. package/src/client/route-helpers.spec.ts +0 -100
  61. package/src/client/route-helpers.ts +0 -61
  62. package/src/client/streaming/daily-report-ids-stream-client.spec.ts +0 -910
  63. package/src/client/streaming/daily-report-ids-stream-client.ts +0 -730
  64. package/src/client/streaming/daily-report-ids-stream-session.spec.ts +0 -401
  65. package/src/client/streaming/daily-report-ids-stream-session.ts +0 -319
  66. package/src/client/ui/button.tsx +0 -42
  67. package/src/client/ui/cn.ts +0 -14
  68. package/src/client/ui/input.tsx +0 -21
  69. package/src/client/ui/label.tsx +0 -16
  70. package/src/client/ui/switch.tsx +0 -19
  71. package/src/client/ui/tabs.tsx +0 -40
  72. package/src/client/ui/textarea.tsx +0 -19
  73. package/src/client/utils/constants.spec.ts +0 -96
  74. package/src/client/utils/constants.ts +0 -84
  75. package/src/client.ts +0 -28
  76. package/src/index.ts +0 -11
  77. package/src/lucide-icons.d.ts +0 -6
  78. package/src/server/authz.spec.ts +0 -57
  79. package/src/server/authz.ts +0 -99
  80. package/src/server/cache.spec.ts +0 -556
  81. package/src/server/cache.ts +0 -303
  82. package/src/server/etag.ts +0 -18
  83. package/src/server/external-source.ts +0 -60
  84. package/src/server/handlers.action.spec.ts +0 -44
  85. package/src/server/handlers.attachment.spec.ts +0 -470
  86. package/src/server/handlers.ids-stream.spec.ts +0 -618
  87. package/src/server/handlers.ts +0 -1638
  88. package/src/server/handlers.unauthorized-cookie.spec.ts +0 -187
  89. package/src/server/handlers.visibility.spec.ts +0 -774
  90. package/src/server/ports.ts +0 -222
  91. package/src/server/response.ts +0 -37
  92. package/src/server/schema.spec.ts +0 -30
  93. package/src/server/schema.ts +0 -344
  94. package/src/server/service.spec.ts +0 -1130
  95. package/src/server/service.ts +0 -2024
  96. package/src/server/sse-reader.spec.ts +0 -302
  97. package/src/server/sse-reader.ts +0 -267
  98. package/src/server/test-helpers/handlers-config.ts +0 -321
  99. package/src/server/visibility.spec.ts +0 -403
  100. package/src/server/visibility.ts +0 -373
  101. package/src/server.spec.ts +0 -160
  102. package/src/server.ts +0 -131
  103. package/src/shared/business-date.spec.ts +0 -82
  104. package/src/shared/business-date.ts +0 -104
  105. package/src/shared/comment-adapter.spec.ts +0 -38
  106. package/src/shared/comment-adapter.ts +0 -80
  107. package/src/shared/ids-stream.spec.ts +0 -154
  108. package/src/shared/ids-stream.ts +0 -279
  109. package/src/shared/logger.ts +0 -47
  110. package/src/shared/sse-schema.spec.ts +0 -50
  111. package/src/shared/sse-schema.ts +0 -198
  112. package/src/shared/text-utils.spec.ts +0 -42
  113. package/src/shared/text-utils.ts +0 -65
  114. package/src/shared/types.ts +0 -109
  115. package/src/styles/standalone.entry.css +0 -51
package/dist/server.d.ts CHANGED
@@ -1,22 +1,13 @@
1
- import { f as DailyReportInterviewer, e as DailyReportExternalComment, a as DailyReportItem, b as DailyReportDetail, D as DailyReportAttachmentSummary, h as DailyReportPostedComment } from './types-CqgYQgbH.js';
2
- import * as drizzle_orm_mssql_core from 'drizzle-orm/mssql-core';
3
- import { AnyMsSqlColumn } from 'drizzle-orm/mssql-core';
4
- import { D as DailyReportLogger } from './logger-D3krZrNK.js';
5
- import { SQL } from 'drizzle-orm';
6
-
7
- /**
8
- * DI ports (structural interfaces) consumed by the daily-report server layer.
9
- * daily-report サーバー層が消費する DI ポート (構造的インターフェース) 群。
10
- *
11
- * redis / 認証 / ユーザー解決 / ID 難読化はすべてアプリ実装を注入する。
12
- * redis の型は `redis` パッケージへ依存しないよう、使用する最小面のみ構造定義する。
13
- */
14
- /** Redis Stream の 1 エントリ (xRead / xRange の結果要素)。 */
1
+ import { f as DailyReportInterviewer, e as DailyReportExternalComment, a as DailyReportItem, b as DailyReportDetail, D as DailyReportAttachmentSummary, h as DailyReportPostedComment } from "./types-CqgYQgbH.js";
2
+ import * as drizzle_orm_mssql_core from "drizzle-orm/mssql-core";
3
+ import { AnyMsSqlColumn } from "drizzle-orm/mssql-core";
4
+ import { D as DailyReportLogger } from "./logger-D3krZrNK.js";
5
+ import { TransactionRetryOptions } from "@aiquants/mssql";
6
+ import { SQL } from "drizzle-orm";
15
7
  type RedisStreamMessage = {
16
8
  id: string;
17
9
  message: Record<string, string>;
18
10
  };
19
- /** 通常操作用 Redis クライアントの最小面 (共有クライアント)。 */
20
11
  type DailyReportRedisClient = {
21
12
  get(key: string): Promise<string | null>;
22
13
  incr(key: string): Promise<number>;
@@ -28,7 +19,6 @@ type DailyReportRedisClient = {
28
19
  COUNT?: number;
29
20
  }): Promise<RedisStreamMessage[]>;
30
21
  };
31
- /** ブロッキング xRead 用 Redis クライアントの最小面 (SSE リーダー専用接続)。 */
32
22
  type DailyReportRedisBlockingClient = {
33
23
  isOpen: boolean;
34
24
  on(event: "error", listener: (err: Error) => void): unknown;
@@ -44,32 +34,17 @@ type DailyReportRedisBlockingClient = {
44
34
  }> | null>;
45
35
  quit(): Promise<unknown>;
46
36
  };
47
- /**
48
- * Redis provider port: shared client for commands + dedicated client factory for blocking reads.
49
- * Redis プロバイダーポート。コマンド用共有クライアントと、ブロッキング読み取り用専用クライアント生成を提供する。
50
- */
51
37
  type DailyReportRedisProvider = {
52
- /** 共有クライアントを取得する (未接続・失敗時は undefined)。 */
53
38
  getClient(): Promise<DailyReportRedisClient | undefined>;
54
- /** ブロッキング xRead 用の専用クライアントを生成する (失敗時は undefined)。 */
55
39
  createClient(): Promise<DailyReportRedisBlockingClient | undefined>;
56
40
  };
57
- /** 認証結果 (ユーザーは外部 ID を持つ最小形状)。 */
58
41
  type DailyReportAuthResult = {
59
42
  user?: {
60
43
  id: string;
61
44
  };
62
45
  cookie?: string;
63
46
  };
64
- /**
65
- * Request authentication port (e.g. session/OpenID check in the host app).
66
- * リクエスト認証ポート (ホストアプリのセッション / OpenID 検証)。
67
- *
68
- * `failureRedirect` が文字列の場合、未認証時は実装側で redirect を throw すること。
69
- * null の場合は throw せず `user` 無しで解決する。
70
- */
71
47
  interface DailyReportAuthenticate {
72
- /** 失敗時は必ずリダイレクトを throw するため、正常復帰時の `user` は常に存在する。 */
73
48
  (request: Request, options: {
74
49
  failureRedirect: string;
75
50
  }): Promise<{
@@ -78,214 +53,55 @@ interface DailyReportAuthenticate {
78
53
  };
79
54
  cookie?: string;
80
55
  }>;
81
- /** リダイレクトを発生させないモード。未認証では `user` を持たない結果が返る。 */
82
56
  (request: Request, options: {
83
57
  failureRedirect: null;
84
58
  }): Promise<DailyReportAuthResult>;
85
59
  }
86
- /**
87
- * Per-dimension visible source types (report body vs. comments).
88
- * 次元ごとの可視 sourceType (本文とコメント)。
89
- *
90
- * コメントの閲覧・記入を本文の可視性から独立して絞るための形。
91
- *
92
- * - `read`: 本文 (日報行) を閲覧してよい sourceType。**空配列は 0 件**。
93
- * - `comment` **省略**: コメント次元は `read` に従う (単一次元と同義・現行互換)。
94
- * - `comment: []`: コメント 0 件かつ記入不可。
95
- *
96
- * ❗ `comment` に `null` は受け付けない。「`read` に従う」の綴りを 2 つ作ると、
97
- * ポート全体の nullish (= 無制限) と次元レベルの nullish が混ざって 4 状態になり、
98
- * 本ファイルが一貫して避けている「無制限と全拒否の取り違え」を次元単位で再発させる。
99
- *
100
- * ❗ `read` の外側にあるコメントトークンは意味を持たない (コメントは必ず read で絞られた
101
- * 詳細の内側にしか載らない)。`DailyReportViewerScope.restrictTo` が構築時に
102
- * `read` との積集合へ狭めるため、設定ミスは黙って安全側へ倒れる。
103
- */
104
60
  type DailyReportVisibilityDimensions = {
105
- /** 本文を閲覧してよい sourceType。空配列は 0 件。 */
106
61
  read: readonly string[];
107
- /** コメントを閲覧・記入してよい sourceType。省略時は `read` に従う。空配列は 0 件かつ記入不可。 */
108
62
  comment?: readonly string[];
109
63
  };
110
- /**
111
- * Raw return of the visible-source-type resolver.
112
- * 可視 sourceType リゾルバの生戻り値。
113
- *
114
- * - `undefined` / `null`: 無制限 (全件)。ポート未注入時と同じ既定の意味。
115
- * - `string[]`: 本文・コメントの双方をその集合に限定。要素は `DailyReportHub.sourceType` の値であり、
116
- * **空配列は 0 件**。`{ read: <配列> }` と完全に同義。
117
- * - `{ read, comment? }`: 次元ごとに指定する ({@link DailyReportVisibilityDimensions})。
118
- *
119
- * 中立契約: いかなる認可パッケージの型 (`PermissionView` 等) にも依存しない素の文字列と配列のみ。
120
- */
121
64
  type DailyReportVisibleSourceTypes = readonly string[] | DailyReportVisibilityDimensions | null | undefined;
122
- /**
123
- * Why the visible-source-type resolver is being called.
124
- * 可視 sourceType リゾルバが呼ばれた理由。
125
- *
126
- * - `initial`: リクエスト処理の開始時 (読み取り / ミューテーション / 添付 / SSE 接続確立)。
127
- * - `refresh`: 長寿命の SSE 接続が権限失効を検出するための定期再解決。
128
- *
129
- * ❗ `refresh` は接続時と**同一の `Request` インスタンス**で呼ばれる (SSE 接続の生存期間中、
130
- * 他に握れるハンドルが無いため)。したがってリクエストスコープで記憶化する実装は、
131
- * `refresh` のときだけキャッシュを迂回しなければ再解決が常に古い値を返し、失効が反映されない。
132
- */
133
65
  type DailyReportVisibilityResolveReason = "initial" | "refresh";
134
- /**
135
- * Context handed to the visible-source-type resolver.
136
- * 可視 sourceType リゾルバへ渡される文脈。
137
- */
138
66
  type DailyReportVisibilityResolveContext = {
139
- /** 呼び出し理由。`refresh` のときリクエストスコープのキャッシュを迂回すること。 */
140
67
  reason: DailyReportVisibilityResolveReason;
141
68
  };
142
- /**
143
- * Resolves which report source types a request may view.
144
- * リクエストが閲覧してよい日報 sourceType を解決するポート。
145
- *
146
- * サーバー側の全データ経路 (一覧 / 詳細 / コメント / 添付 / SSE) に一貫して効く。
147
- *
148
- * ❗ 例外を投げた場合、ハンドラは**空集合 (全拒否) にフォールバック**する。認可ストアの
149
- * 障害時に無制限へ倒れないための fail-close であり、実装側で握り潰さないこと。
150
- * ❗ 全読み取りリクエストのクリティカルパス上で 1 回呼ばれる (キャッシュキーが戻り値に依存する)。
151
- * 高速に保つこと。記憶化する場合はセッション / ユーザー単位の短時間 TTL (60 秒以下) とし、
152
- * `context.reason === "refresh"` では必ずキャッシュを迂回すること
153
- * (迂回しないと SSE の定期再解決が失効を観測できず、権限剥奪後も配信が続く)。
154
- */
155
69
  type DailyReportResolveVisibleSourceTypes = (request: Request, context: DailyReportVisibilityResolveContext) => DailyReportVisibleSourceTypes | Promise<DailyReportVisibleSourceTypes>;
156
- /**
157
- * Resolves an external user id (e.g. Google sub) to the internal numeric user id.
158
- * 外部ユーザー ID (例: Google sub) を内部数値ユーザー ID へ解決するポート。
159
- */
160
70
  type DailyReportResolveUserId = (externalUserId: string) => Promise<number | null>;
161
- /**
162
- * Obfuscates an internal numeric user id for client exposure.
163
- * 内部数値ユーザー ID をクライアント公開用に難読化するポート。
164
- */
165
71
  type DailyReportEncodeUserId = (id: number) => string;
166
- /**
167
- * Reversible obfuscation codec for an internal numeric id exposed to clients.
168
- * クライアントへ公開する内部数値 ID の可逆難読化コーデック。
169
- *
170
- * これは難読化であって認可ではない。トークンを能力 (capability) として扱ってはならず、
171
- * 認可は必ずサーバー側の述語で行うこと。ID 空間を混ぜないため、リソース種別ごとに
172
- * 別インスタンス (別 alphabet 等) を注入することを推奨する。
173
- */
174
72
  type DailyReportIdCodec = {
175
- /** 内部数値 ID をトークンへ変換する。 */
176
73
  encode: (id: number) => string;
177
- /** トークンを内部数値 ID へ戻す。復号できない場合は null。 */
178
74
  decode: (token: string) => number | null;
179
75
  };
180
- /**
181
- * Failure kinds a caller maps onto HTTP statuses.
182
- * 呼び出し側が HTTP ステータスへ写像する失敗種別。
183
- *
184
- * - `not_found`: 実体が存在しない (消失・未正規化 URI)
185
- * - `denied`: ストレージ側で拒否された (サンドボックス外・ACL)
186
- * - `too_large`: 上限超過 (事前サイズ判定またはワイヤ上限)
187
- * - `invalid_path`: 受け入れないスキーム・不正なパス (データ不備)
188
- * - `unavailable`: ストレージサービスへ到達できない・締め切り超過
189
- */
190
76
  type DailyReportAttachmentFailure = "not_found" | "denied" | "too_large" | "invalid_path" | "unavailable";
191
- /** 添付ファイル読み取りの成功結果。 */
192
77
  type DailyReportAttachmentBytes = {
193
78
  ok: true;
194
- /**
195
- * Byte view backed by an `ArrayBuffer`.
196
- * `ArrayBuffer` を裏に持つバイトビュー。
197
- *
198
- * 素の `Uint8Array` と書くと `Uint8Array<ArrayBufferLike>` へ広がり `BodyInit` へ代入できない
199
- * (TypeScript 5.7 以降の既定型引数)。`Response` のボディへそのまま渡すため narrow 型で受ける。
200
- * `head` が true の呼び出しでは長さ 0 のビューを返してよい (実サイズは `size` で申告する)。
201
- */
202
79
  bytes: Uint8Array<ArrayBuffer>;
203
- /** バックエンドが申告した MIME 型。判定できない場合は null。 */
204
80
  contentType?: string | null;
205
- /**
206
- * Entity size in bytes, independent of how many bytes `bytes` actually holds.
207
- * 実体のバイト数。`bytes` が実際に保持している長さとは独立に申告する値。
208
- *
209
- * HEAD 応答の `Content-Length` は同じ URI への GET が返す値と一致しなければならない
210
- * (RFC 9110 §9.3.2)。`head` が true の呼び出しは本体を読まないため `bytes` は空になるので、
211
- * ここで実サイズを申告しないと HEAD が常に `Content-Length: 0` を返してしまう。
212
- * 申告できない場合は省略してよく、そのとき呼び出し側は `bytes.byteLength` を使う。
213
- */
214
81
  size?: number;
215
82
  };
216
- /** 添付ファイル読み取りの失敗結果。 */
217
83
  type DailyReportAttachmentError = {
218
84
  ok: false;
219
85
  reason: DailyReportAttachmentFailure;
220
- /** 診断ログ用の生のストレージエラーコード。HTTP ステータスの決定には使わない。 */
221
86
  code?: string;
222
87
  };
223
- /**
224
- * Reads attachment bytes from the host application's storage backend.
225
- * ホストアプリのストレージバックエンドから添付ファイルのバイト列を読み取るポート。
226
- *
227
- * `filePath` はサーバー内部にとどまり、クライアントへは決して渡らない。
228
- * 失敗は種別付きで返すこと (例外を投げない・単一の null へ潰さない)。
229
- * 種別を潰すと「実体が消えた」「上限超過」「サービス停止」が運用上区別できなくなる。
230
- *
231
- * `head` が true のときは実体を読まずメタデータのみ取得する。HEAD 要求で本体を読んで
232
- * 捨てると、認証済み呼び出し元が任意に転送量とレイテンシを増幅できる経路になる。
233
- */
234
88
  type DailyReportReadAttachment = (filePath: string, options: {
235
89
  maxBytes: number;
236
90
  head: boolean;
237
91
  principal?: string;
238
92
  }) => Promise<DailyReportAttachmentBytes | DailyReportAttachmentError>;
239
-
240
- /**
241
- * In-memory SQL result cache with TTL, snapshot, and cross-worker epoch (via redis) support.
242
- * TTL・スナップショット・クロスワーカー epoch (redis 経由) を備えた SQL 結果のインメモリキャッシュ。
243
- *
244
- * epoch は任意注入の redis ポート経由で取得・更新する (未注入時は常に 0 = epoch 無効)。
245
- */
246
-
247
93
  type SqlResultCacheQueryOptions = {
248
94
  forceRefresh?: boolean;
249
95
  snapshot?: boolean;
250
96
  ttlMsOverride?: number;
251
97
  epochKey?: string;
252
- /**
253
- * ヒット時にバケット年齢が ttl × ratio を超えていたら、キャッシュ値を即返しつつ
254
- * 裏で 1 本だけ再フェッチして置き換える (未指定は従来動作 = 何もしない)。
255
- * 有効域は 0 <= ratio < 1: ヒット判定が「未失効」を要求するため年齢は常に ttl 未満であり、
256
- * ratio 1 は事実上発火しない。ratio 0 は毎ヒット裏更新 (undefined とは区別される)。
257
- * 定期的にアクセスされるキーの「TTL 切れ直後のコールド遭遇」を対話リクエストから排除する。
258
- */
259
98
  refreshAheadRatio?: number;
260
99
  };
261
- /**
262
- * Creates epoch helpers bound to an optional redis provider.
263
- * 任意の redis プロバイダーに束縛された epoch ヘルパーを生成する処理。
264
- */
265
100
  declare const createEpochStore: (redis?: DailyReportRedisProvider) => {
266
- /**
267
- * Gets the current epoch value, or null when it cannot be determined.
268
- * 現在のエポック値を取得する処理。判定不能なら null。
269
- *
270
- * - `null` = redis 未注入、または一時的な失敗。**エポックによる横断無効化は判定不能**。
271
- * - `0` = redis に到達したがキーが無い (一度も increment されていない正当な初期値)。
272
- *
273
- * ❗ `0` を「不明」の代用にしてはならない。記録側も `0` のとき両辺が一致してしまい、
274
- * stale 検出が黙って無効化される (無効化されたこと自体がどこにも現れない)。
275
- * 「常に 0 = safe 方向」が成り立つのは一時的失敗のときだけで、未注入時には偽である。
276
- */
277
101
  getEpoch(epochKey: string): Promise<number | null>;
278
- /**
279
- * Increments the epoch counter in Redis.
280
- * Redis のエポックカウンターをインクリメントする。
281
- */
282
102
  incrementEpoch(epochKey: string): Promise<void>;
283
103
  };
284
104
  type EpochStore = ReturnType<typeof createEpochStore>;
285
- /**
286
- * In-memory cache for SQL query results with TTL and snapshot support.
287
- * TTLとスナップショット機能を備えたSQLクエリ結果のインメモリキャッシュ。
288
- */
289
105
  declare class SqlResultCache {
290
106
  private readonly config;
291
107
  private readonly epochStore;
@@ -294,75 +110,18 @@ declare class SqlResultCache {
294
110
  constructor(config: {
295
111
  defaultTtlMs: number;
296
112
  }, epochStore: EpochStore);
297
- /**
298
- * Invalidates a specific cache bucket.
299
- * 指定されたキャッシュバケットを無効化します。
300
- */
301
113
  invalidate: (cacheKey: string) => void;
302
- /**
303
- * Kicks a single background refetch when the bucket has aged past ttl * ratio.
304
- * バケット年齢が ttl × ratio を超えたヒット時に、裏で 1 本だけ再フェッチを起動する処理。
305
- *
306
- * 応答は誰も待たない。完了までは旧バケットがそのまま生きているため、並行するヒットは
307
- * 従来どおりキャッシュから即答する (バケットを先に消す forceRefresh 委譲はスタンピードに
308
- * なるため使わない)。バケットが有効な間は失敗しても旧バケットが残るだけ (safe 方向)。
309
- * 裏フェッチ中に TTL が完全に切れて in-flight へ相乗りした前面リクエストには、通常の
310
- * in-flight 共有と同じく失敗が伝播する (相乗りしなくても自前フェッチが同様に失敗する状況)。
311
- * in-flight が既に居れば起動しない (前面リクエストの結果で足りる)。
312
- */
313
114
  private maybeRefreshAhead;
314
- /**
315
- * Retrieves records from cache or fetches them if expired/missing.
316
- * キャッシュからレコードを取得するか、期限切れや未存在の場合はフェッチします。
317
- */
318
115
  getOrFetch: <T>(opts: {
319
116
  cacheKey: string;
320
117
  fetcher: () => Promise<readonly T[]>;
321
- /**
322
- * 本呼び出しが実際にフェッチャーを起動した瞬間に 1 度だけ呼ばれる。
323
- *
324
- * 「返す配列がこの呼び出し自身の新規フェッチ結果である」ことの**因果的な証明**として使う。
325
- * バケットヒット・進行中フェッチへの相乗り・refresh-ahead の裏側更新では**呼ばれない** —
326
- * それらの経路が返す配列は本呼び出しより古くなりうるためである。
327
- *
328
- * ids ストリームはこの合図で高速先頭ページのクエリを起動する。合図の後に始まる以上、
329
- * 先頭ページは全量配列より古くなり得ず、「先頭ページに在って全量に無い行 = 削除済み」
330
- * という判定が初めて健全になる (逆順を許すと作成直後の日報を削除してしまう)。
331
- */
332
118
  onFetchStart?: () => void;
333
119
  } & SqlResultCacheQueryOptions) => Promise<readonly T[]>;
334
- /**
335
- * Clears the cache for a specific key.
336
- * 指定されたキーのキャッシュをクリアします。
337
- */
338
120
  flush: (cacheKey: string) => void;
339
- /**
340
- * Clears all cached buckets and in-flight requests.
341
- * すべてのキャッシュバケットと進行中のリクエストを全クリアします。
342
- */
343
121
  clearAll: () => void;
344
- /**
345
- * Invalidates cache buckets matching a prefix.
346
- * 指定されたプレフィックスに一致するキャッシュバケットを無効化します。
347
- */
348
122
  invalidatePrefix: (prefix: string) => void;
349
- /**
350
- * Cleans up all expired cache buckets to prevent memory accumulation.
351
- * メモリー蓄積を防ぐため、期限切れのキャッシュバケットをすべてクリーンアップする処理。
352
- */
353
123
  private cleanExpired;
354
124
  }
355
-
356
- /**
357
- * External source adapter contract for legacy/foreign daily-report tables.
358
- * レガシー・外部由来の日報テーブルを取り込む外部ソースアダプタ契約。
359
- *
360
- * DailyReportHub.source_type がアダプタの `sourceType` に一致する行は、
361
- * `table` を `Hub.source_id_num = idColumn` で LEFT JOIN し、その行を
362
- * `mapRow` で表示フィールドへ変換する (例: 別システムのレガシー日報テーブルの取り込み)。
363
- */
364
-
365
- /** 外部ソース行から詳細表示へ供給するフィールド群。 */
366
125
  type ExternalReportFields = {
367
126
  content?: string | null;
368
127
  employeeName?: string | null;
@@ -374,29 +133,17 @@ type ExternalReportFields = {
374
133
  interviewers?: DailyReportInterviewer[];
375
134
  externalComments?: DailyReportExternalComment[];
376
135
  };
377
- /** 外部ソースアダプタ。 */
378
136
  type DailyReportExternalSource = {
379
- /** DailyReportHub.source_type の一致値 (例 "legacy")。 */
380
137
  sourceType: string;
381
- /** LEFT JOIN する drizzle テーブル。 */
382
138
  table: unknown;
383
- /** Hub.source_id_num と突き合わせる ID 列。 */
384
139
  idColumn: AnyMsSqlColumn;
385
- /** 結合行を表示フィールドへ変換する処理。 */
386
140
  mapRow: (row: Record<string, unknown>) => ExternalReportFields;
387
141
  };
388
- /**
389
- * Parses JSON array payloads and maps each element (fail-soft: returns [] on error).
390
- * JSON 配列のペイロードを解析し各要素を変換する処理 (エラー時は空配列)。
391
- */
392
142
  declare const transformJsonArray: <TRaw, TResult>(payload: string | null, label: string, mapper: (raw: TRaw) => TResult | null, logger?: DailyReportLogger) => TResult[];
393
-
394
- /** 注入する外部ユーザーテーブルの最小形 (id / display_name)。 */
395
143
  type DailyReportUserTable = {
396
144
  id: AnyMsSqlColumn;
397
145
  displayName: AnyMsSqlColumn;
398
146
  };
399
- /** DailyReportHub テーブルの構造形。 */
400
147
  type DailyReportHubTable = {
401
148
  id: AnyMsSqlColumn;
402
149
  sourceType: AnyMsSqlColumn;
@@ -413,7 +160,6 @@ type DailyReportHubTable = {
413
160
  deletedAt: AnyMsSqlColumn;
414
161
  deletedBy: AnyMsSqlColumn;
415
162
  };
416
- /** DailyReportInternal テーブルの構造形。 */
417
163
  type DailyReportInternalTable = {
418
164
  hubId: AnyMsSqlColumn;
419
165
  body: AnyMsSqlColumn;
@@ -423,7 +169,6 @@ type DailyReportInternalTable = {
423
169
  updatedAt: AnyMsSqlColumn;
424
170
  updatedBy: AnyMsSqlColumn;
425
171
  };
426
- /** 投稿コメントテーブル (物理名 DailyReportComment) の構造形。 */
427
172
  type DailyReportCommentTable = {
428
173
  id: AnyMsSqlColumn;
429
174
  hubId: AnyMsSqlColumn;
@@ -434,7 +179,6 @@ type DailyReportCommentTable = {
434
179
  updatedAt: AnyMsSqlColumn;
435
180
  updatedBy: AnyMsSqlColumn;
436
181
  };
437
- /** DailyReportLabel テーブルの構造形。 */
438
182
  type DailyReportLabelTable = {
439
183
  id: AnyMsSqlColumn;
440
184
  userId: AnyMsSqlColumn;
@@ -446,14 +190,12 @@ type DailyReportLabelTable = {
446
190
  updatedAt: AnyMsSqlColumn;
447
191
  updatedBy: AnyMsSqlColumn;
448
192
  };
449
- /** DailyReportHub_Label 中間テーブルの構造形。 */
450
193
  type DailyReportHubLabelTable = {
451
194
  hubId: AnyMsSqlColumn;
452
195
  labelId: AnyMsSqlColumn;
453
196
  createdAt: AnyMsSqlColumn;
454
197
  createdBy: AnyMsSqlColumn;
455
198
  };
456
- /** DailyReportUserStatus テーブルの構造形。 */
457
199
  type DailyReportUserStatusTable = {
458
200
  hubId: AnyMsSqlColumn;
459
201
  userId: AnyMsSqlColumn;
@@ -464,13 +206,6 @@ type DailyReportUserStatusTable = {
464
206
  updatedAt: AnyMsSqlColumn;
465
207
  updatedBy: AnyMsSqlColumn;
466
208
  };
467
- /**
468
- * DailyReportAttachment テーブルの構造形。
469
- *
470
- * `uploadedBy` は外部取込ソース由来の行に投稿者が存在しないため NULL 許容。
471
- * `sourceKey` は取込の冪等 upsert の自然キー。
472
- * `objectCheckedAt` / `objectMissingAt` から実体存在の三値 (unknown / present / absent) を導出する。
473
- */
474
209
  type DailyReportAttachmentTable = {
475
210
  id: AnyMsSqlColumn;
476
211
  hubId: AnyMsSqlColumn;
@@ -487,13 +222,6 @@ type DailyReportAttachmentTable = {
487
222
  updatedAt: AnyMsSqlColumn;
488
223
  updatedBy: AnyMsSqlColumn;
489
224
  };
490
- /**
491
- * サービスへ注入するテーブル一式 (アプリ既存モデルまたは本ファクトリ生成物)。
492
- *
493
- * `attachment` のみ任意。添付テーブルを持たない消費アプリでも本パッケージを使えるようにするため。
494
- * 未注入時は詳細の `attachments` が常に空配列になり、添付エンドポイントは全トークンで 404 を返す
495
- * (意図した縮退動作)。
496
- */
497
225
  type DailyReportTables = {
498
226
  hub: DailyReportHubTable;
499
227
  internal: DailyReportInternalTable;
@@ -503,13 +231,6 @@ type DailyReportTables = {
503
231
  hubLabel: DailyReportHubLabelTable;
504
232
  userStatus: DailyReportUserStatusTable;
505
233
  };
506
- /**
507
- * Generic factory: build the seven daily-report tables under an arbitrary schema name.
508
- * 任意のスキーマ名の下に日報 7 テーブルを生成する汎用ファクトリ。
509
- *
510
- * 制約・索引名は `${schemaName}_<Table>_...` 規約で生成する。
511
- * ユーザーテーブルへの FK は注入された `userTable` を参照する。
512
- */
513
234
  declare function defineDailyReportSchema<S extends string>(schemaName: S, opts: {
514
235
  userTable: DailyReportUserTable;
515
236
  }): {
@@ -544,7 +265,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
544
265
  isPrimaryKey: false;
545
266
  isAutoincrement: false;
546
267
  hasRuntimeDefault: false;
547
- enumValues: [string, ...string[]];
268
+ enumValues: [
269
+ string,
270
+ ...string[]
271
+ ];
548
272
  baseColumn: never;
549
273
  identity: undefined;
550
274
  generated: undefined;
@@ -560,7 +284,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
560
284
  isPrimaryKey: false;
561
285
  isAutoincrement: false;
562
286
  hasRuntimeDefault: false;
563
- enumValues: [string, ...string[]];
287
+ enumValues: [
288
+ string,
289
+ ...string[]
290
+ ];
564
291
  baseColumn: never;
565
292
  identity: undefined;
566
293
  generated: undefined;
@@ -626,7 +353,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
626
353
  isPrimaryKey: false;
627
354
  isAutoincrement: false;
628
355
  hasRuntimeDefault: false;
629
- enumValues: [string, ...string[]];
356
+ enumValues: [
357
+ string,
358
+ ...string[]
359
+ ];
630
360
  baseColumn: never;
631
361
  identity: undefined;
632
362
  generated: undefined;
@@ -642,7 +372,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
642
372
  isPrimaryKey: false;
643
373
  isAutoincrement: false;
644
374
  hasRuntimeDefault: false;
645
- enumValues: [string, ...string[]];
375
+ enumValues: [
376
+ string,
377
+ ...string[]
378
+ ];
646
379
  baseColumn: never;
647
380
  identity: undefined;
648
381
  generated: undefined;
@@ -674,7 +407,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
674
407
  isPrimaryKey: false;
675
408
  isAutoincrement: false;
676
409
  hasRuntimeDefault: false;
677
- enumValues: [string, ...string[]];
410
+ enumValues: [
411
+ string,
412
+ ...string[]
413
+ ];
678
414
  baseColumn: never;
679
415
  identity: undefined;
680
416
  generated: undefined;
@@ -706,7 +442,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
706
442
  isPrimaryKey: false;
707
443
  isAutoincrement: false;
708
444
  hasRuntimeDefault: false;
709
- enumValues: [string, ...string[]];
445
+ enumValues: [
446
+ string,
447
+ ...string[]
448
+ ];
710
449
  baseColumn: never;
711
450
  identity: undefined;
712
451
  generated: undefined;
@@ -738,7 +477,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
738
477
  isPrimaryKey: false;
739
478
  isAutoincrement: false;
740
479
  hasRuntimeDefault: false;
741
- enumValues: [string, ...string[]];
480
+ enumValues: [
481
+ string,
482
+ ...string[]
483
+ ];
742
484
  baseColumn: never;
743
485
  identity: undefined;
744
486
  generated: undefined;
@@ -777,7 +519,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
777
519
  isPrimaryKey: false;
778
520
  isAutoincrement: false;
779
521
  hasRuntimeDefault: false;
780
- enumValues: [string, ...string[]];
522
+ enumValues: [
523
+ string,
524
+ ...string[]
525
+ ];
781
526
  baseColumn: never;
782
527
  identity: undefined;
783
528
  generated: undefined;
@@ -793,7 +538,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
793
538
  isPrimaryKey: false;
794
539
  isAutoincrement: false;
795
540
  hasRuntimeDefault: false;
796
- enumValues: [string, ...string[]];
541
+ enumValues: [
542
+ string,
543
+ ...string[]
544
+ ];
797
545
  baseColumn: never;
798
546
  identity: undefined;
799
547
  generated: undefined;
@@ -825,7 +573,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
825
573
  isPrimaryKey: false;
826
574
  isAutoincrement: false;
827
575
  hasRuntimeDefault: false;
828
- enumValues: [string, ...string[]];
576
+ enumValues: [
577
+ string,
578
+ ...string[]
579
+ ];
829
580
  baseColumn: never;
830
581
  identity: undefined;
831
582
  generated: undefined;
@@ -857,7 +608,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
857
608
  isPrimaryKey: false;
858
609
  isAutoincrement: false;
859
610
  hasRuntimeDefault: false;
860
- enumValues: [string, ...string[]];
611
+ enumValues: [
612
+ string,
613
+ ...string[]
614
+ ];
861
615
  baseColumn: never;
862
616
  identity: undefined;
863
617
  generated: undefined;
@@ -928,7 +682,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
928
682
  isPrimaryKey: false;
929
683
  isAutoincrement: false;
930
684
  hasRuntimeDefault: false;
931
- enumValues: [string, ...string[]];
685
+ enumValues: [
686
+ string,
687
+ ...string[]
688
+ ];
932
689
  baseColumn: never;
933
690
  identity: undefined;
934
691
  generated: undefined;
@@ -960,7 +717,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
960
717
  isPrimaryKey: false;
961
718
  isAutoincrement: false;
962
719
  hasRuntimeDefault: false;
963
- enumValues: [string, ...string[]];
720
+ enumValues: [
721
+ string,
722
+ ...string[]
723
+ ];
964
724
  baseColumn: never;
965
725
  identity: undefined;
966
726
  generated: undefined;
@@ -992,7 +752,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
992
752
  isPrimaryKey: false;
993
753
  isAutoincrement: false;
994
754
  hasRuntimeDefault: false;
995
- enumValues: [string, ...string[]];
755
+ enumValues: [
756
+ string,
757
+ ...string[]
758
+ ];
996
759
  baseColumn: never;
997
760
  identity: undefined;
998
761
  generated: undefined;
@@ -1063,7 +826,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1063
826
  isPrimaryKey: false;
1064
827
  isAutoincrement: false;
1065
828
  hasRuntimeDefault: false;
1066
- enumValues: [string, ...string[]];
829
+ enumValues: [
830
+ string,
831
+ ...string[]
832
+ ];
1067
833
  baseColumn: never;
1068
834
  identity: undefined;
1069
835
  generated: undefined;
@@ -1079,7 +845,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1079
845
  isPrimaryKey: false;
1080
846
  isAutoincrement: false;
1081
847
  hasRuntimeDefault: false;
1082
- enumValues: [string, ...string[]];
848
+ enumValues: [
849
+ string,
850
+ ...string[]
851
+ ];
1083
852
  baseColumn: never;
1084
853
  identity: undefined;
1085
854
  generated: undefined;
@@ -1095,7 +864,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1095
864
  isPrimaryKey: false;
1096
865
  isAutoincrement: false;
1097
866
  hasRuntimeDefault: false;
1098
- enumValues: [string, ...string[]];
867
+ enumValues: [
868
+ string,
869
+ ...string[]
870
+ ];
1099
871
  baseColumn: never;
1100
872
  identity: undefined;
1101
873
  generated: undefined;
@@ -1111,7 +883,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1111
883
  isPrimaryKey: false;
1112
884
  isAutoincrement: false;
1113
885
  hasRuntimeDefault: false;
1114
- enumValues: [string, ...string[]];
886
+ enumValues: [
887
+ string,
888
+ ...string[]
889
+ ];
1115
890
  baseColumn: never;
1116
891
  identity: undefined;
1117
892
  generated: undefined;
@@ -1191,7 +966,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1191
966
  isPrimaryKey: false;
1192
967
  isAutoincrement: false;
1193
968
  hasRuntimeDefault: false;
1194
- enumValues: [string, ...string[]];
969
+ enumValues: [
970
+ string,
971
+ ...string[]
972
+ ];
1195
973
  baseColumn: never;
1196
974
  identity: undefined;
1197
975
  generated: undefined;
@@ -1223,7 +1001,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1223
1001
  isPrimaryKey: false;
1224
1002
  isAutoincrement: false;
1225
1003
  hasRuntimeDefault: false;
1226
- enumValues: [string, ...string[]];
1004
+ enumValues: [
1005
+ string,
1006
+ ...string[]
1007
+ ];
1227
1008
  baseColumn: never;
1228
1009
  identity: undefined;
1229
1010
  generated: undefined;
@@ -1278,7 +1059,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1278
1059
  isPrimaryKey: false;
1279
1060
  isAutoincrement: false;
1280
1061
  hasRuntimeDefault: false;
1281
- enumValues: [string, ...string[]];
1062
+ enumValues: [
1063
+ string,
1064
+ ...string[]
1065
+ ];
1282
1066
  baseColumn: never;
1283
1067
  identity: undefined;
1284
1068
  generated: undefined;
@@ -1294,7 +1078,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1294
1078
  isPrimaryKey: false;
1295
1079
  isAutoincrement: false;
1296
1080
  hasRuntimeDefault: false;
1297
- enumValues: [string, ...string[]];
1081
+ enumValues: [
1082
+ string,
1083
+ ...string[]
1084
+ ];
1298
1085
  baseColumn: never;
1299
1086
  identity: undefined;
1300
1087
  generated: undefined;
@@ -1342,7 +1129,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1342
1129
  isPrimaryKey: false;
1343
1130
  isAutoincrement: false;
1344
1131
  hasRuntimeDefault: false;
1345
- enumValues: [string, ...string[]];
1132
+ enumValues: [
1133
+ string,
1134
+ ...string[]
1135
+ ];
1346
1136
  baseColumn: never;
1347
1137
  identity: undefined;
1348
1138
  generated: undefined;
@@ -1374,7 +1164,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1374
1164
  isPrimaryKey: false;
1375
1165
  isAutoincrement: false;
1376
1166
  hasRuntimeDefault: false;
1377
- enumValues: [string, ...string[]];
1167
+ enumValues: [
1168
+ string,
1169
+ ...string[]
1170
+ ];
1378
1171
  baseColumn: never;
1379
1172
  identity: undefined;
1380
1173
  generated: undefined;
@@ -1445,7 +1238,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1445
1238
  isPrimaryKey: false;
1446
1239
  isAutoincrement: false;
1447
1240
  hasRuntimeDefault: false;
1448
- enumValues: [string, ...string[]];
1241
+ enumValues: [
1242
+ string,
1243
+ ...string[]
1244
+ ];
1449
1245
  baseColumn: never;
1450
1246
  identity: undefined;
1451
1247
  generated: undefined;
@@ -1548,7 +1344,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1548
1344
  isPrimaryKey: false;
1549
1345
  isAutoincrement: false;
1550
1346
  hasRuntimeDefault: false;
1551
- enumValues: [string, ...string[]];
1347
+ enumValues: [
1348
+ string,
1349
+ ...string[]
1350
+ ];
1552
1351
  baseColumn: never;
1553
1352
  identity: undefined;
1554
1353
  generated: undefined;
@@ -1580,7 +1379,10 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1580
1379
  isPrimaryKey: false;
1581
1380
  isAutoincrement: false;
1582
1381
  hasRuntimeDefault: false;
1583
- enumValues: [string, ...string[]];
1382
+ enumValues: [
1383
+ string,
1384
+ ...string[]
1385
+ ];
1584
1386
  baseColumn: never;
1585
1387
  identity: undefined;
1586
1388
  generated: undefined;
@@ -1589,200 +1391,22 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
1589
1391
  dialect: "mssql";
1590
1392
  }>;
1591
1393
  };
1592
-
1593
- /**
1594
- * Source-type visibility set: normalization, digest, and predicate helpers.
1595
- * sourceType 可視集合の正規化・ダイジェスト・判定ヘルパー群。
1596
- *
1597
- * 中立文字列 (`DailyReportHub.sourceType` の値) のみを扱い、いかなる認可パッケージの型にも
1598
- * 依存しない。可視集合は 2 状態を厳密に区別する:
1599
- *
1600
- * - `null` = 無制限 (全件)。ポート未注入時の既定であり、現行互換の意味を持つ。
1601
- * - `Set` = その集合に限定。**空集合は 0 件 (fail-close)** であって無制限ではない。
1602
- *
1603
- * この 2 状態の取り違えは情報漏洩か機能停止に直結するため、判定・畳み込み・キー生成を
1604
- * 本ファイルへ一元化し、ハンドラ層とサービス層の双方がここだけを参照する。
1605
- *
1606
- * 閲覧範囲は**次元ごと**にこの 2 状態を持つ:
1607
- *
1608
- * - `visible` = 本文 (日報行) を閲覧してよい区分。
1609
- * - `commentable` = コメントを閲覧・記入してよい区分。常に `visible` の部分集合。
1610
- *
1611
- * 次元が増えても状態数は増やさない。「もう一方の次元に従う」は
1612
- * {@link DailyReportViewerScope.restrictTo} が**構築時に解決**するため、各次元は最後まで
1613
- * 厳密に 2 状態であり、本ファイルの判定ヘルパーは次元を問わずそのまま適用できる。
1614
- */
1615
-
1616
- /**
1617
- * Normalized visible set. null = unrestricted (all rows), ReadonlySet = restricted (empty = zero rows).
1618
- * 正規化済みの可視集合。null は無制限 (全件)、ReadonlySet は限定 (空集合は 0 件)。
1619
- */
1620
1394
  type VisibleSourceTypeSet = ReadonlySet<string> | null;
1621
- /**
1622
- * Normalizes a raw resolver return into a VisibleSourceTypeSet.
1623
- * ポートの生戻り値を正規化済み可視集合へ変換する処理。
1624
- *
1625
- * `null` / `undefined` は無制限 (`null`) へ。配列は各要素を畳み込み・空文字除去・重複排除して
1626
- * `Set` 化する。**空配列は空 `Set` (0 件) を返し、`null` (無制限) へは決して倒さない** —
1627
- * この取り違えが情報漏洩か機能停止に直結するため。
1628
- *
1629
- * ❗ 引数は**単一次元のトークン配列に限る**。次元別オブジェクト
1630
- * ({@link DailyReportVisibilityDimensions}) をここへ渡すと配列ガードに掛かって全拒否になるため、
1631
- * 次元の解体は {@link DailyReportViewerScope.restrictTo} が行い、ここには常に配列だけが届く。
1632
- *
1633
- * ❗ オーバーロードで「**配列を渡した場合は決して `null` (無制限) を返さない**」という不変条件を
1634
- * 型に載せている。これは実装の偶然ではなく本ファイルの中核契約 (空配列は 0 件であって無制限では
1635
- * ない) そのものであり、呼び出し側が `null` 分岐を書いて無制限へ倒す余地を型で塞ぐ。
1636
- *
1637
- * @param raw Raw single-dimension resolver value. 単一次元の生値。
1638
- * @returns Normalized visible set. 正規化済みの可視集合。
1639
- */
1640
1395
  declare function normalizeVisibleSourceTypes(raw: readonly string[]): ReadonlySet<string>;
1641
1396
  declare function normalizeVisibleSourceTypes(raw: readonly string[] | null | undefined): VisibleSourceTypeSet;
1642
- /**
1643
- * Tests whether a report's sourceType is visible under the given set.
1644
- * ある日報の sourceType が可視集合に含まれるかの三値判定。
1645
- *
1646
- * - 無制限 (`null`): 常に `true`。
1647
- * - 限定 + sourceType 判明: 畳み込み一致で判定。
1648
- * - 限定 + sourceType 不明 (`null` / `undefined`): `false` — 制限された閲覧者は「不明な区分」を
1649
- * 見られない。区分を運ばない旧 SSE エントリ等を fail-close 側へ倒すための規則。
1650
- *
1651
- * @param set Normalized visible set. 正規化済みの可視集合。
1652
- * @param sourceType The row's source type, if known. 判明していれば当該行のソース種別。
1653
- * @returns True when visible. 可視なら true。
1654
- */
1655
1397
  declare function isSourceTypeVisible(set: VisibleSourceTypeSet, sourceType: string | null | undefined): boolean;
1656
- /**
1657
- * Tells whether the set denies everything (zero rows).
1658
- * 可視集合が全拒否 (0 件) を意味するかを判定する処理。
1659
- *
1660
- * 真のとき呼び出し側は DB へ問い合わせず即座に空を返してよい (無駄クエリの排除)。
1661
- * これは性能上の短絡であり、認可の防御そのものは {@link buildVisibleSourceTypeCondition} が担う。
1662
- *
1663
- * @param set Normalized visible set. 正規化済みの可視集合。
1664
- * @returns True when nothing is visible. 何も可視でないなら true。
1665
- */
1666
1398
  declare function deniesEverySourceType(set: VisibleSourceTypeSet): boolean;
1667
- /**
1668
- * Builds the SQL condition restricting rows to the visible source types.
1669
- * 可視 sourceType へ行を限定する SQL 条件を生成する処理 (三値)。
1670
- *
1671
- * {@link isSourceTypeVisible} の SQL 版であり、同じ三値を同じ向きへ写像する:
1672
- *
1673
- * - 無制限 (`null`): `undefined` を返す。drizzle の `and(...)` は `undefined` を無視するため、
1674
- * 既存の述語がそのまま残る (現行互換)。
1675
- * - 全拒否 (空集合): `1 = 0` を返す。**決して `undefined` へ倒さない** — 呼び出し側の短絡漏れが
1676
- * あっても生成器自身が fail-close する二重防御であり、ここを緩めると認可が反転する。
1677
- * - 限定: `LOWER(<column>) IN (...)`。トークンは正規化時に小文字畳み込み済みなので両辺が小文字となり、
1678
- * DB の照合順序 (collation) に依存せず決定的に大小文字非依存で一致する。
1679
- *
1680
- * @param sourceTypeColumn The source-type column to constrain. 制限対象の sourceType 列。
1681
- * @param set Normalized visible set. 正規化済みの可視集合。
1682
- * @returns Condition, or undefined when unrestricted. 条件 (無制限なら undefined)。
1683
- */
1684
1399
  declare function buildVisibleSourceTypeCondition(sourceTypeColumn: AnyMsSqlColumn, set: VisibleSourceTypeSet): SQL | undefined;
1685
- /**
1686
- * Request-scoped viewer scope carrying the normalized visible source-type set.
1687
- * 正規化済みの可視 sourceType 集合を運ぶ、リクエストスコープの閲覧範囲。
1688
- *
1689
- * このクラスは private フィールドを持つことで**名目型**になっており、`{ visible: null }` のような
1690
- * 構造的偽造も、`{ ...scope, visible: null }` のようなスプレッドによる widening も型が拒否する
1691
- * (`unique symbol` ブランドでは後者を防げないことを実測で確認済み)。
1692
- *
1693
- * 生成経路は {@link DailyReportViewerScope.restrictTo} と {@link DailyReportViewerScope.unrestricted}
1694
- * の 2 つだけであり、`null` を「可視性」としてそのまま綴ることはできない。結果として、
1695
- * **絞り込まれない読み取りは必ず `unrestricted(理由)` として現れる**ため、
1696
- * `grep -rn "DailyReportViewerScope.unrestricted("` が fail-open の全数リストになる。
1697
- */
1698
1400
  declare class DailyReportViewerScope {
1699
1401
  #private;
1700
1402
  private constructor();
1701
- /** 正規化済みの本文可視集合。`null` は無制限、空集合は 0 件 (fail-close)。 */
1702
1403
  get visible(): VisibleSourceTypeSet;
1703
- /**
1704
- * 正規化済みのコメント可視集合。`null` は無制限、空集合は 0 件 (fail-close)。
1705
- *
1706
- * 常に `visible` の部分集合である (構築時に積集合を取っているため)。
1707
- */
1708
1404
  get commentable(): VisibleSourceTypeSet;
1709
- /**
1710
- * Builds a scope restricted to the given source types (empty input = zero rows).
1711
- * 指定した sourceType へ限定した閲覧範囲を生成する処理 (空入力は 0 件)。
1712
- *
1713
- * 入力は {@link normalizeVisibleSourceTypes} を通るため、大小文字・前後空白・重複・非文字列は
1714
- * ここで吸収される。素の配列は `{ read: <配列> }` と同義で、コメント次元は `read` に従う。
1715
- *
1716
- * ❗ 引数は `null` / `undefined` を**受け付けない**。受け付けると「restrict」という名前のまま
1717
- * 無制限スコープを生む第 2 の入口になり、「絞り込まれない読み取りは必ず
1718
- * {@link DailyReportViewerScope.unrestricted} に現れる」という監査不変条件が崩れる。
1719
- * 無制限は必ず理由付きで明示すること。
1720
- *
1721
- * ❗ 判別に `Array.isArray` を使ってはならない。型述語が `arg is any[]` であり
1722
- * `readonly string[]` を負の分岐から除去できないため、`.read` 参照が TS2339 になる
1723
- * (実測済み)。`"read" in input` で判別する。文字列など object でない契約違反入力は
1724
- * `in` が実行時に throw するので、先に `typeof` で弾いてから
1725
- * {@link normalizeVisibleSourceTypes} の fail-close 経路へ落とす。
1726
- *
1727
- * @param input Visible source-type tokens, or per-dimension sets. 可視 sourceType のトークン群、または次元別の集合。
1728
- * @returns The scope. 生成した閲覧範囲。
1729
- */
1730
1405
  static restrictTo(input: readonly string[] | DailyReportVisibilityDimensions): DailyReportViewerScope;
1731
- /**
1732
- * Builds an unrestricted scope; every call site is an audited fail-open.
1733
- * 無制限の閲覧範囲を生成する処理。全呼び出し箇所が監査対象の fail-open となる。
1734
- *
1735
- * ❗ 理由文字列は必須。読み捨てるが、呼び出し箇所の全数列挙と「なぜここは絞らなくてよいか」の
1736
- * 記録を強制するために受け取る。
1737
- *
1738
- * ❗ **両次元**を無制限にする。片方だけ残すと「無制限」という名前が嘘になり、監査 grep の
1739
- * 結果が「絞られていない読み取りの全数」でなくなる。
1740
- *
1741
- * @param auditReason Why unrestricted access is correct here. なぜここで無制限が正当かの理由。
1742
- * @returns The unrestricted scope. 無制限の閲覧範囲。
1743
- */
1744
1406
  static unrestricted(auditReason: string): DailyReportViewerScope;
1745
1407
  }
1746
- /**
1747
- * Computes the cache-key digest for a whole viewer scope (all dimensions).
1748
- * 閲覧範囲全体 (全次元) からキャッシュキー用ダイジェストを算出する処理。
1749
- *
1750
- * スコープに次元が増えてもキャッシュキーの生成点を 1 つに保つための入口。
1751
- *
1752
- * ❗ **必ず全次元を畳み込むこと。** 本文次元だけを畳み込むと、コメント権限だけを剥奪された
1753
- * 同一ユーザーが剥奪前のキャッシュバケットを共有し続け、TTL の間コメント本文入りの詳細を
1754
- * 受け取り続ける (キーが変わらないため無効化も走らない)。
1755
- *
1756
- * 両次元が一致する既定形 (コメント次元が `read` に従う) では**本文のみのダイジェストと同一値**を
1757
- * 返す。既存配備のキャッシュキーは 1 文字も変わらず、キャッシュ再利用率は無退行となる。
1758
- * 次元が分かれるときだけ `d:` 名前空間の下へ**長さ接頭辞付きで連結**するため、写像は単射であり
1759
- * sentinel (`all` / `none`) や単一次元表記 (`s:` / `sh:`) と衝突しない。
1760
- *
1761
- * @param scope Viewer scope. 閲覧範囲。
1762
- * @returns Digest usable as a cache-key component. キャッシュキー構成要素として使えるダイジェスト。
1763
- */
1764
1408
  declare function computeViewerScopeDigest(scope: DailyReportViewerScope): string;
1765
- /**
1766
- * Computes a stable and bounded cache-key digest of the set.
1767
- * 可視集合から安定・有界なキャッシュキー用ダイジェストを算出する処理。
1768
- *
1769
- * 無制限は `"all"`、空集合は `"none"`、それ以外は `s:` 名前空間の下へ**長さ接頭辞付きトークンを昇順連結**する。
1770
- * 連結は長さ接頭辞付きなので**単射**であり、通常経路 (`s:`) では論理的に等価な集合が必ず同一の、
1771
- * 異なる集合が必ず別のダイジェストになる。sentinel (`all` / `none`) とも名前空間が分かれるため、
1772
- * 限定集合が無制限 / 全拒否と同じバケットを共有することはない。権限が安定している間はキーが
1773
- * 不変になるため、キャッシュは完全に再利用される (性能無退行)。
1774
- *
1775
- * ❗ 区分数が異常に多い場合だけキー長を抑えるため FNV-1a 32bit へ退避し `sh:` 接頭辞を付ける。
1776
- * **この退避経路に限り理論上の衝突がありうる** (32bit)。衝突しても影響は同一ユーザーの
1777
- * キャッシュ再利用に留まり、認可判定そのものは SQL 述語が担うため漏洩には至らない。
1778
- * 通常の区分数 (数個) では到達しない。
1779
- *
1780
- * @param set Normalized visible set. 正規化済みの可視集合。
1781
- * @returns Digest usable as a cache-key component. キャッシュキー構成要素として使えるダイジェスト。
1782
- */
1783
1409
  declare function computeSourceTypeDigest(set: VisibleSourceTypeSet): string;
1784
-
1785
- /** DailyReportHub の行型。 */
1786
1410
  type DailyReportHubRow = {
1787
1411
  id: number;
1788
1412
  sourceType: string;
@@ -1799,7 +1423,6 @@ type DailyReportHubRow = {
1799
1423
  deletedAt: Date | string | null;
1800
1424
  deletedBy: string | null;
1801
1425
  };
1802
- /** DailyReportInternal の行型。 */
1803
1426
  type DailyReportInternalRow = {
1804
1427
  hubId: number;
1805
1428
  body: string | null;
@@ -1809,7 +1432,6 @@ type DailyReportInternalRow = {
1809
1432
  updatedAt: Date | string;
1810
1433
  updatedBy: string;
1811
1434
  };
1812
- /** DailyReportUserStatus の行型。 */
1813
1435
  type DailyReportUserStatusRow = {
1814
1436
  hubId: number;
1815
1437
  userId: number;
@@ -1820,7 +1442,6 @@ type DailyReportUserStatusRow = {
1820
1442
  updatedAt: Date | string;
1821
1443
  updatedBy: string;
1822
1444
  };
1823
- /** 投稿コメント行 (物理テーブル DailyReportComment) の行型。 */
1824
1445
  type DailyReportCommentRow = {
1825
1446
  id: number;
1826
1447
  hubId: number;
@@ -1857,7 +1478,6 @@ interface UpdateChain<T> {
1857
1478
  interface DeleteChain {
1858
1479
  where(cond: unknown): PromiseLike<unknown>;
1859
1480
  }
1860
- /** サービスが要求する drizzle mssql データベースの最小面 (トランザクション込み)。 */
1861
1481
  interface DailyReportDb {
1862
1482
  select<T = Record<string, unknown>>(fields?: unknown): SelectChain<T>;
1863
1483
  insert<T = Record<string, unknown>>(t: unknown): InsertChain<T>;
@@ -1866,73 +1486,28 @@ interface DailyReportDb {
1866
1486
  transaction<T>(fn: (tx: DailyReportDb) => Promise<T>, config?: unknown): Promise<T>;
1867
1487
  }
1868
1488
  type DailyReportServiceConfig = {
1869
- /** drizzle mssql データベースハンドル。 */
1870
1489
  db: DailyReportDb;
1871
- /** 日報 7 テーブル (アプリ既存モデルまたは defineDailyReportSchema 生成物)。`attachment` のみ任意。 */
1872
1490
  tables: DailyReportTables;
1873
- /** 表示名解決に使う外部ユーザーテーブル ({ id, displayName })。 */
1874
1491
  userTable: DailyReportUserTable;
1875
- /** 外部ユーザー ID → 内部数値 ID の解決ポート。 */
1876
1492
  resolveUserId: DailyReportResolveUserId;
1877
- /** 内部数値 ID の難読化ポート。 */
1878
1493
  encodeUserId: DailyReportEncodeUserId;
1879
- /** SSE publish / epoch 用 redis (省略時は SSE publish スキップ・epoch 無効)。 */
1880
1494
  redis?: DailyReportRedisProvider;
1881
- /** レガシー等の外部ソースアダプタ群。 */
1882
1495
  externalSources?: DailyReportExternalSource[];
1883
- /** SQL 結果キャッシュ (facade が生成して注入)。 */
1884
1496
  cache: SqlResultCache;
1885
- /** クロスワーカー epoch ストア (facade が生成して注入)。 */
1886
1497
  epochs: EpochStore;
1887
- /**
1888
- * 下書きラベル名 (単一または配列で指定可能)。
1889
- * 消費アプリ側で自 DB のラベル名や作成区分の候補名 ("下書き", "DRAFT" など) を注入できる。
1890
- */
1498
+ transactionRetry?: TransactionRetryOptions;
1891
1499
  draftLabelName?: string;
1892
1500
  draftLabelNames?: string[];
1893
- /** SSE Redis Stream キー (既定 "daily-report:sse-stream")。 */
1894
1501
  streamKey?: string;
1895
- /** SSE Stream の MAXLEN (既定 10000)。 */
1896
1502
  streamMaxLen?: number;
1897
- /** IDs 一覧キャッシュ TTL (既定 180,000ms)。 */
1898
1503
  idsTtlMs?: number;
1899
- /** 営業日別キャッシュ TTL (既定 300,000ms)。 */
1900
1504
  businessDateTtlMs?: number;
1901
- /** 外部 ID → 内部 ID のプロセス内キャッシュを無効化 (テスト用)。 */
1902
1505
  disableUserIdCache?: boolean;
1903
- /**
1904
- * 添付 ID の難読化コーデック。
1905
- *
1906
- * 任意にしているのは、添付テーブルを注入しない消費アプリと既存テストのフィクスチャを
1907
- * 壊さないため。未注入なら添付一覧は常に空になる (縮退動作)。
1908
- * ユーザー ID 用のコーデックとは **別インスタンス**を渡すこと。同一だと
1909
- * レスポンス中の `userId` トークンがそのまま添付トークンとして解釈できてしまう。
1910
- */
1911
1506
  attachmentIdCodec?: DailyReportIdCodec;
1912
- /** ロガー (既定は console ベース)。 */
1913
1507
  logger?: DailyReportLogger;
1914
1508
  };
1915
- /** createDailyReportService の返却型。 */
1916
1509
  type DailyReportService = ReturnType<typeof createDailyReportService>;
1917
- /**
1918
- * Creates the daily-report data-access service bound to the injected dependencies.
1919
- * 注入された依存に束縛された日報データアクセスサービスを生成する処理。
1920
- */
1921
1510
  type DatePattern = "YYYY-MM-DD HH:mm:ss" | "YYYY-MM-DD";
1922
- /**
1923
- * Formats date-like values to a given pattern using local-time fields (no Intl allocation).
1924
- * 日付相当の値をローカル時刻フィールドで指定パターンへ整形する処理 (Intl 非生成)。
1925
- *
1926
- * ローカル時刻フィールドの手組み整形。旧実装 (ja-JP ロケール + 2-digit toLocale*) と出力互換。
1927
- * ❗ toLocale* 系へ戻さないこと: あれは呼び出しごとに Intl.DateTimeFormat を生成し
1928
- * (実測 約 66μs/呼)、全量 ids の 227k 行 map で 15〜20 秒の同期 CPU 洪水になる。
1929
- * business-date / SSE の全応答が人質化した実害バグの根本原因だった。
1930
- * モジュールスコープの export であり、バレル (src/server.ts の `export *`) 経由で
1931
- * `@aiquants/daily-report/server` の公開 API の一部になる (テストからの直接検証と
1932
- * ホスト側での汎用日時整形の再利用を意図した、意図的な公開)。
1933
- * 1000 年未満の年は旧実装 (年ゼロ詰めなし) から意図的に乖離し、ISO 準拠の 4 桁ゼロ詰めで出す
1934
- * (負の年は符号を除いた絶対値を 4 桁詰め。DB の date/datetime からは到達しない文字列入力のみの領域)。
1935
- */
1936
1511
  declare const formatDateValue: (value: Date | string | null | undefined, pattern: DatePattern) => string | null;
1937
1512
  declare function createDailyReportService(config: DailyReportServiceConfig): {
1938
1513
  streamKey: string;
@@ -1974,45 +1549,17 @@ declare function createDailyReportService(config: DailyReportServiceConfig): {
1974
1549
  updateDailyReportInternal: (tx: DailyReportDb, hubId: number, data: Partial<DailyReportInternalRow>) => Promise<void>;
1975
1550
  deleteDailyReportLabel: (tx: DailyReportDb, hubId: number, labelId: number) => Promise<void>;
1976
1551
  };
1977
-
1978
- /**
1979
- * Fan-Out shared reader for the daily report SSE Redis Stream.
1980
- * 日報 SSE 用 Redis Stream の共有リーダーモジュール。
1981
- *
1982
- * 単一の xRead BLOCK ループで全接続にメッセージをブロードキャストし、
1983
- * 接続ごとに Redis TCP を張る問題を解消する。
1984
- */
1985
-
1986
- /**
1987
- * Compares two Redis Stream IDs numerically.
1988
- * Redis Stream ID を数値比較し、a <= b なら true を返す。
1989
- *
1990
- * Stream ID は `<timestamp_ms>-<sequence>` 形式。
1991
- * 辞書順比較では sequence が可変長のとき不正確になるため、数値分割で比較する。
1992
- */
1993
1552
  declare const isStreamIdLte: (a: string, b: string) => boolean;
1994
- /** xRead 結果の 1 エントリに相当する型。 */
1995
1553
  type StreamEntry = {
1996
1554
  id: string;
1997
1555
  message: Record<string, string>;
1998
1556
  };
1999
1557
  type DailyReportSseReaderConfig = {
2000
- /** ブロッキング xRead 用の専用クライアントを生成する redis プロバイダー。 */
2001
1558
  redis?: DailyReportRedisProvider;
2002
- /** SSE Redis Stream キー。 */
2003
1559
  streamKey: string;
2004
- /** 受信メッセージに応じてローカル SQL キャッシュを無効化する対象キャッシュ。 */
2005
1560
  cache: SqlResultCache;
2006
- /** ロガー (既定は console ベース)。 */
2007
1561
  logger?: DailyReportLogger;
2008
1562
  };
2009
- /**
2010
- * Shared xRead loop that fans out entries to all active SSE connections.
2011
- * 全 SSE 接続に対してメッセージをファンアウトする共有 xRead ループ。
2012
- *
2013
- * - "entry" イベント: 新着エントリ (StreamEntry) をブロードキャスト
2014
- * - "error" イベント: 回復不能エラーをブロードキャスト
2015
- * */
2016
1563
  declare class DailyReportSseReader {
2017
1564
  private readonly config;
2018
1565
  private _emitter;
@@ -2022,38 +1569,12 @@ declare class DailyReportSseReader {
2022
1569
  private _client;
2023
1570
  private readonly _logger;
2024
1571
  constructor(config: DailyReportSseReaderConfig);
2025
- /**
2026
- * Subscribes to the shared reader. Starts the loop on first subscriber.
2027
- * 共有リーダーを購読する。最初の購読者でループを開始する。
2028
- *
2029
- * @param onEntry - 新着エントリのコールバック
2030
- * @param onError - 回復不能エラーのコールバック (省略可)
2031
- * @returns unsubscribe 関数。呼び出すと両リスナーを解除し、最後の購読者解除でループを停止する。
2032
- */
2033
1572
  subscribe(onEntry: (entry: StreamEntry) => void, onError?: (err: Error) => void): () => void;
2034
- /**
2035
- * Destroys the reader for test cleanup.
2036
- * テストクリーンアップ用のデストラクタ。
2037
- */
2038
1573
  destroy(): Promise<void>;
2039
- /**
2040
- * Internal xRead BLOCK loop.
2041
- * 内部 xRead BLOCK ループ。
2042
- */
2043
1574
  private _startLoop;
2044
- /**
2045
- * Stops the xRead loop by closing the client.
2046
- * クライアントを閉じて xRead ループを停止する。
2047
- */
2048
1575
  private _stopLoop;
2049
- /**
2050
- * Emits an "error" event only when a listener exists (bare "error" emit throws).
2051
- * リスナーが居るときだけ "error" イベントを emit する処理 (リスナー 0 の "error" emit は
2052
- * EventEmitter 仕様で throw し、非同期文脈では unhandled rejection = プロセス危険になるため)。
2053
- */
2054
1576
  private _emitError;
2055
1577
  }
2056
-
2057
1578
  type AuthzResourceItem = {
2058
1579
  resourceKey: string;
2059
1580
  name: string;
@@ -2065,15 +1586,7 @@ type DailyReportSourceTypeInput = {
2065
1586
  description?: string | null;
2066
1587
  includeCommentResource?: boolean;
2067
1588
  };
2068
- /**
2069
- * Dynamically builds neutral Authz resource definitions from provided source type inputs.
2070
- * 指定されたソース種別定義から中立な認可リソース定義リストを生成するファクトリ。
2071
- */
2072
1589
  declare function defineDailyReportAuthzResources(sources?: DailyReportSourceTypeInput[]): AuthzResourceItem[];
2073
- /**
2074
- * Ensures all daily-report standard resources exist in the authz TMResource table idempotently.
2075
- * authz データベース内に日報機能の標準認可リソースが存在することを自動保証(冪等シード)する処理。
2076
- */
2077
1590
  declare function seedDailyReportAuthzResources(db: unknown, authzTables: {
2078
1591
  TMResource: unknown;
2079
1592
  }, opts: {
@@ -2082,102 +1595,31 @@ declare function seedDailyReportAuthzResources(db: unknown, authzTables: {
2082
1595
  sources?: DailyReportSourceTypeInput[];
2083
1596
  resources?: AuthzResourceItem[];
2084
1597
  }): Promise<void>;
2085
-
2086
- /**
2087
- * Generates a SHA-256 ETag for the given data.
2088
- * 指定されたデータの SHA-256 ETag を生成します。
2089
- *
2090
- * @param data The data to hash (will be JSON stringified).
2091
- * @returns The ETag string (wrapped in quotes).
2092
- */
2093
1598
  declare const generateETag: (data: unknown) => string;
2094
-
2095
1599
  type LoaderArgs = {
2096
1600
  request: Request;
2097
1601
  params: Record<string, string | undefined>;
2098
1602
  };
2099
- /**
2100
- * Accepts a media type only when it is header-safe and well-formed.
2101
- * ヘッダー安全かつ MIME 型の形をしている場合のみ採用する処理。
2102
- *
2103
- * CR/LF や 0x00-0xFF 外の文字が混ざった値を `new Headers()` へ渡すと TypeError になり、
2104
- * 認可済みのダウンロードが 500 になる。
2105
- *
2106
- * **これは第 2 層である。** 現在の配信経路では、注入値はインライン許可リストに完全一致しないため
2107
- * 必ず `application/octet-stream` へ落ち、ヘッダーには到達しない。つまり本関数を外しても
2108
- * 現状の挙動は変わらない (ミューテーションテストで確認済み)。
2109
- * 許可判定を前方一致や「DB の型を信じる」形へ変えた瞬間に効き始める防御なので、
2110
- * 到達不能なまま放置せず **直接の単体テストで固定する**目的でエクスポートしている。
2111
- *
2112
- * @param value Candidate media type. 候補となる media type。
2113
- * @returns The value when acceptable, otherwise null. 採用可なら値、それ以外は null。
2114
- */
2115
1603
  declare const sanitizeMediaType: (value: string | null | undefined) => string | null;
2116
- /**
2117
- * Percent-encodes a file name for the RFC 8187 `filename*` parameter.
2118
- * RFC 8187 の `filename*` 用にファイル名をパーセントエンコードする処理。
2119
- *
2120
- * `encodeURIComponent` は `'` `(` `)` `*` を残すが、いずれも RFC 8187 の attr-char ではない。
2121
- *
2122
- * @param name Raw file name. 生のファイル名。
2123
- * @returns Encoded value. エンコード済みの値。
2124
- */
2125
1604
  declare const encodeRfc8187: (name: string) => string;
2126
- /**
2127
- * Builds the ASCII fallback used by the plain `filename` parameter.
2128
- * 素の `filename` パラメータ用の ASCII フォールバックを組み立てる処理。
2129
- *
2130
- * @param name Raw file name. 生のファイル名。
2131
- * @returns ASCII-only, quote-free name. ASCII のみで引用符を含まない名前。
2132
- */
2133
1605
  declare const asciiFallbackFileName: (name: string) => string;
2134
1606
  type DailyReportHandlersConfig = {
2135
- /** リクエスト認証ポート。 */
2136
1607
  authenticate: DailyReportAuthenticate;
2137
- /**
2138
- * 可視 sourceType リゾルバ。未注入なら全件 (現行互換)。
2139
- * 全データ経路 (一覧 / 詳細 / コメント / 添付 / SSE) に一貫して効き、例外は全拒否として扱う。
2140
- */
2141
1608
  resolveVisibleSourceTypes?: DailyReportResolveVisibleSourceTypes;
2142
- /** データアクセスサービス。 */
2143
1609
  service: DailyReportService;
2144
- /** 内部数値 ID の難読化ポート。 */
2145
1610
  encodeUserId: DailyReportEncodeUserId;
2146
- /**
2147
- * 添付 ID の難読化コーデック。未注入なら添付エンドポイントは常に 404。
2148
- * ユーザー ID 用とは別インスタンスを渡すこと (ID 空間の分離)。
2149
- */
2150
1611
  attachmentIdCodec?: DailyReportIdCodec;
2151
- /** 添付ファイル読み取りポート。未注入なら添付エンドポイントは常に 404。 */
2152
1612
  readAttachment?: DailyReportReadAttachment;
2153
- /** 添付ファイルの最大バイト数 (既定 32 MiB)。サービス側のワイヤ上限より低く保つこと。 */
2154
1613
  attachmentMaxBytes?: number;
2155
- /** 添付エンドポイントの 1 分あたり呼び出し上限 (ユーザー単位・既定 60)。 */
2156
1614
  attachmentRateLimitPerMinute?: number;
2157
- /** 添付読み取りの同時実行上限 (プロセス単位・既定 4)。 */
2158
1615
  attachmentConcurrency?: number;
2159
- /** SSE 用 redis プロバイダー (catch-up の xRange / xRevRange に使用)。 */
2160
1616
  redis?: DailyReportRedisProvider;
2161
- /** SSE Fan-Out 共有リーダー。 */
2162
1617
  sseReader: DailyReportSseReader;
2163
- /** SSE Redis Stream キー。 */
2164
1618
  streamKey: string;
2165
- /** 未ログイン時のリダイレクト先 (index.loader 用、既定 "/auth/login")。 */
2166
1619
  loginRedirectPath?: string;
2167
- /**
2168
- * `intent=clearCache` (全サーバーキャッシュの一括破棄) を許可するか。既定 false。
2169
- * 開発用アフォーダンスであり、有効化すると認証済みユーザーなら誰でも全ワーカーの
2170
- * キャッシュを無制限に破棄できるため、本番では必ず無効のままにする
2171
- * (消費アプリは開発環境でのみ true を注入する)。
2172
- */
2173
1620
  enableDevCacheClear?: boolean;
2174
- /** ロガー (既定は console ベース)。 */
2175
1621
  logger?: DailyReportLogger;
2176
1622
  };
2177
- /**
2178
- * Creates the daily-report loaders/actions bound to the injected dependencies.
2179
- * 注入依存に束縛された日報 loader / action 群を生成する処理。
2180
- */
2181
1623
  declare function createDailyReportHandlers(config: DailyReportHandlersConfig): {
2182
1624
  index: {
2183
1625
  loader: ({ request }: LoaderArgs) => Promise<{
@@ -2201,62 +1643,19 @@ declare function createDailyReportHandlers(config: DailyReportHandlersConfig): {
2201
1643
  loader: ({ request, params }: LoaderArgs) => Promise<Response>;
2202
1644
  };
2203
1645
  };
2204
-
2205
- /**
2206
- * JSON response helper with shared security headers and ETag support.
2207
- * 共有セキュリティヘッダーと ETag 対応を備えた JSON レスポンスヘルパー。
2208
- */
2209
-
2210
- /**
2211
- * Creates JSON response with shared security headers and ETag support.
2212
- * 共有のセキュリティヘッダーと ETag サポート付き JSON レスポンスを生成。
2213
- */
2214
1646
  declare const jsonResponseWithETag: (request: Request, cookie: string | null, payload: Record<string, unknown>, status?: number, logger?: DailyReportLogger) => Response;
2215
-
2216
- /** createDailyReportServer の設定 (サービス設定 + 認証ポート + ハンドラ設定)。 */
2217
1647
  type DailyReportServerConfig = Omit<DailyReportServiceConfig, "cache" | "epochs"> & {
2218
- /** リクエスト認証ポート。 */
2219
1648
  authenticate: DailyReportAuthenticate;
2220
- /**
2221
- * 可視 sourceType リゾルバ。未注入なら全件 (現行互換)。
2222
- *
2223
- * サーバー側の全データ経路 (一覧 / 詳細 / コメント / 添付 / SSE) に一貫して効く。
2224
- * 戻り値は `DailyReportHub.sourceType` の値 (`knownSourceTypes` 参照) であり、認可リソースキーではない。
2225
- * `undefined` / `null` は無制限、空配列は 0 件、例外は全拒否 (fail-close)。
2226
- */
2227
1649
  resolveVisibleSourceTypes?: DailyReportResolveVisibleSourceTypes;
2228
- /** 添付ファイル読み取りポート。未注入なら添付エンドポイントは常に 404。 */
2229
1650
  readAttachment?: DailyReportReadAttachment;
2230
- /** 添付ファイルの最大バイト数 (既定 32 MiB)。サービス側のワイヤ上限より低く保つこと。 */
2231
1651
  attachmentMaxBytes?: number;
2232
- /** 添付エンドポイントの 1 分あたり呼び出し上限 (ユーザー単位・既定 60)。 */
2233
1652
  attachmentRateLimitPerMinute?: number;
2234
- /** 添付読み取りの同時実行上限 (プロセス単位・既定 4)。 */
2235
1653
  attachmentConcurrency?: number;
2236
- /** 未ログイン時のリダイレクト先 (index.loader 用、既定 "/auth/login")。 */
2237
1654
  loginRedirectPath?: string;
2238
- /**
2239
- * `intent=clearCache` (全サーバーキャッシュの一括破棄) を許可するか。既定 false。
2240
- * 開発用アフォーダンス。有効化すると認証済みなら誰でも全ワーカーのキャッシュを
2241
- * 無制限破棄できるため、本番では無効のままにする (消費アプリは開発環境のみ true 注入)。
2242
- */
2243
1655
  enableDevCacheClear?: boolean;
2244
- /** SQL 結果キャッシュの既定 TTL (既定 60,000ms)。 */
2245
1656
  cacheDefaultTtlMs?: number;
2246
- /** 外部ソースアダプタ群 (レガシー日報テーブル等)。 */
2247
1657
  externalSources?: DailyReportExternalSource[];
2248
1658
  };
2249
- /**
2250
- * One-stop factory wiring cache, service, SSE fan-out reader, and route handlers.
2251
- * キャッシュ・サービス・SSE Fan-Out リーダー・ルートハンドラを一括結線するファクトリ。
2252
- *
2253
- * @example
2254
- * const server = createDailyReportServer({ db, tables, userTable, resolveUserId, encodeUserId, authenticate, redis })
2255
- * // routes:
2256
- * // daily_report._index → server.index.loader (+ data() ラップ)
2257
- * // daily_report.api.$endpoint → server.api.loader / server.api.action
2258
- * // sse.daily_report.$endpoint → server.sse.loader
2259
- */
2260
1659
  declare function createDailyReportServer(config: DailyReportServerConfig): {
2261
1660
  index: {
2262
1661
  loader: ({ request }: {
@@ -2294,7 +1693,6 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
2294
1693
  params: Record<string, string | undefined>;
2295
1694
  }) => Promise<Response>;
2296
1695
  };
2297
- /** データアクセスサービス (CRUD + キャッシュ + SSE publish)。 */
2298
1696
  service: {
2299
1697
  streamKey: string;
2300
1698
  streamMaxLen: number;
@@ -2335,24 +1733,13 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
2335
1733
  updateDailyReportInternal: (tx: DailyReportDb, hubId: number, data: Partial<DailyReportInternalRow>) => Promise<void>;
2336
1734
  deleteDailyReportLabel: (tx: DailyReportDb, hubId: number, labelId: number) => Promise<void>;
2337
1735
  };
2338
- /** SQL 結果キャッシュ (サービス・SSE リーダー共有インスタンス)。 */
2339
1736
  cache: SqlResultCache;
2340
- /** クロスワーカー epoch ストア。 */
2341
1737
  epochs: {
2342
1738
  getEpoch(epochKey: string): Promise<number | null>;
2343
1739
  incrementEpoch(epochKey: string): Promise<void>;
2344
1740
  };
2345
- /** SSE Fan-Out 共有リーダー。 */
2346
1741
  sseReader: DailyReportSseReader;
2347
- /** SSE Redis Stream キー。 */
2348
1742
  streamKey: string;
2349
- /**
2350
- * 既知の正準 sourceType 集合 (注入した `externalSources` の全 sourceType + `"Internal"`)。
2351
- *
2352
- * `resolveVisibleSourceTypes` が返すべき語彙そのものであり、消費側は起動時にこの集合と
2353
- * 自前のマッピングを突き合わせて誤トークン (無診断で 0 件になる) を検出できる。
2354
- */
2355
1743
  knownSourceTypes: readonly string[];
2356
1744
  };
2357
-
2358
1745
  export { type AuthzResourceItem, type DailyReportAttachmentBytes, type DailyReportAttachmentError, type DailyReportAttachmentFailure, type DailyReportAttachmentTable, type DailyReportAuthResult, type DailyReportAuthenticate, type DailyReportCommentRow, type DailyReportCommentTable, type DailyReportDb, type DailyReportEncodeUserId, type DailyReportExternalSource, type DailyReportHandlersConfig, type DailyReportHubLabelTable, type DailyReportHubRow, type DailyReportHubTable, type DailyReportIdCodec, type DailyReportInternalRow, type DailyReportInternalTable, type DailyReportLabelTable, type DailyReportReadAttachment, type DailyReportRedisBlockingClient, type DailyReportRedisClient, type DailyReportRedisProvider, type DailyReportResolveUserId, type DailyReportResolveVisibleSourceTypes, type DailyReportServerConfig, type DailyReportService, type DailyReportServiceConfig, type DailyReportSourceTypeInput, DailyReportSseReader, type DailyReportSseReaderConfig, type DailyReportTables, type DailyReportUserStatusRow, type DailyReportUserStatusTable, type DailyReportUserTable, DailyReportViewerScope, type DailyReportVisibilityDimensions, type DailyReportVisibilityResolveContext, type DailyReportVisibilityResolveReason, type DailyReportVisibleSourceTypes, type EpochStore, type ExternalReportFields, type RedisStreamMessage, SqlResultCache, type SqlResultCacheQueryOptions, type StreamEntry, type VisibleSourceTypeSet, asciiFallbackFileName, buildVisibleSourceTypeCondition, computeSourceTypeDigest, computeViewerScopeDigest, createDailyReportHandlers, createDailyReportServer, createDailyReportService, createEpochStore, defineDailyReportAuthzResources, defineDailyReportSchema, deniesEverySourceType, encodeRfc8187, formatDateValue, generateETag, isSourceTypeVisible, isStreamIdLte, jsonResponseWithETag, normalizeVisibleSourceTypes, sanitizeMediaType, seedDailyReportAuthzResources, transformJsonArray };