@aiquants/daily-report 0.20.0 → 0.21.0

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