@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.
- package/README.md +8 -0
- package/dist/client.d.mts +11 -706
- package/dist/client.d.ts +11 -706
- package/dist/client.js +0 -1
- package/dist/client.mjs +0 -1
- package/dist/index.d.mts +5 -197
- package/dist/index.d.ts +5 -197
- package/dist/index.js +0 -1
- package/dist/index.mjs +0 -1
- package/dist/logger-D3krZrNK.d.mts +0 -14
- package/dist/logger-D3krZrNK.d.ts +0 -14
- package/dist/server.d.mts +115 -728
- package/dist/server.d.ts +115 -728
- package/dist/server.js +10 -11
- package/dist/server.mjs +10 -11
- package/dist/sse-schema-BdUGThiz.d.ts +1025 -1009
- package/dist/sse-schema-ChSFm-4q.d.mts +1025 -1009
- package/dist/types-CqgYQgbH.d.mts +0 -34
- package/dist/types-CqgYQgbH.d.ts +0 -34
- package/package.json +11 -11
- package/dist/client.js.map +0 -1
- package/dist/client.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/server.mjs.map +0 -1
- package/src/client/components/business-day-thumb-overlay.tsx +0 -19
- package/src/client/components/daily-report-attachment-indicator.spec.tsx +0 -51
- package/src/client/components/daily-report-attachment-indicator.tsx +0 -45
- package/src/client/components/daily-report-attachment-list.spec.tsx +0 -94
- package/src/client/components/daily-report-attachment-list.tsx +0 -112
- package/src/client/components/daily-report-comment-item.tsx +0 -89
- package/src/client/components/daily-report-comment-section.tsx +0 -166
- package/src/client/components/daily-report-detail-list.tsx +0 -842
- package/src/client/components/daily-report-edit-form.tsx +0 -87
- package/src/client/components/daily-report-ids-stream-status.spec.tsx +0 -93
- package/src/client/components/daily-report-ids-stream-status.tsx +0 -67
- package/src/client/components/daily-report-list.tsx +0 -1232
- package/src/client/components/daily-report-page.spec.tsx +0 -119
- package/src/client/components/daily-report-page.tsx +0 -140
- package/src/client/components/daily-report-resize-panels.spec.tsx +0 -307
- package/src/client/components/daily-report-resolved-content.tsx +0 -207
- package/src/client/components/daily-report-scroll-restoration.spec.tsx +0 -422
- package/src/client/components/report-views.spec.tsx +0 -375
- package/src/client/components/unread-indicator.tsx +0 -13
- package/src/client/config-context.tsx +0 -184
- package/src/client/contexts/daily-report-action-context.spec.tsx +0 -433
- package/src/client/contexts/daily-report-action-context.tsx +0 -1147
- package/src/client/contexts/daily-report-error-context.spec.tsx +0 -66
- package/src/client/contexts/daily-report-error-context.tsx +0 -98
- package/src/client/hooks/use-animated-number.spec.ts +0 -103
- package/src/client/hooks/use-animated-number.ts +0 -69
- package/src/client/hooks/use-daily-report-comments.ts +0 -73
- package/src/client/hooks/use-daily-report-sse-connection.ts +0 -86
- package/src/client/hooks/use-daily-report.spec.ts +0 -546
- package/src/client/hooks/use-daily-report.ts +0 -549
- package/src/client/hooks/use-dynamic-viewport-height.ts +0 -127
- package/src/client/hooks/use-responsive-layout.spec.ts +0 -74
- package/src/client/hooks/use-responsive-layout.ts +0 -63
- package/src/client/route-helpers.spec.ts +0 -100
- package/src/client/route-helpers.ts +0 -61
- package/src/client/streaming/daily-report-ids-stream-client.spec.ts +0 -910
- package/src/client/streaming/daily-report-ids-stream-client.ts +0 -730
- package/src/client/streaming/daily-report-ids-stream-session.spec.ts +0 -401
- package/src/client/streaming/daily-report-ids-stream-session.ts +0 -319
- package/src/client/ui/button.tsx +0 -42
- package/src/client/ui/cn.ts +0 -14
- package/src/client/ui/input.tsx +0 -21
- package/src/client/ui/label.tsx +0 -16
- package/src/client/ui/switch.tsx +0 -19
- package/src/client/ui/tabs.tsx +0 -40
- package/src/client/ui/textarea.tsx +0 -19
- package/src/client/utils/constants.spec.ts +0 -96
- package/src/client/utils/constants.ts +0 -84
- package/src/client.ts +0 -28
- package/src/index.ts +0 -11
- package/src/lucide-icons.d.ts +0 -6
- package/src/server/authz.spec.ts +0 -57
- package/src/server/authz.ts +0 -99
- package/src/server/cache.spec.ts +0 -556
- package/src/server/cache.ts +0 -303
- package/src/server/etag.ts +0 -18
- package/src/server/external-source.ts +0 -60
- package/src/server/handlers.action.spec.ts +0 -44
- package/src/server/handlers.attachment.spec.ts +0 -470
- package/src/server/handlers.ids-stream.spec.ts +0 -618
- package/src/server/handlers.ts +0 -1638
- package/src/server/handlers.unauthorized-cookie.spec.ts +0 -187
- package/src/server/handlers.visibility.spec.ts +0 -774
- package/src/server/ports.ts +0 -222
- package/src/server/response.ts +0 -37
- package/src/server/schema.spec.ts +0 -30
- package/src/server/schema.ts +0 -344
- package/src/server/service.spec.ts +0 -1130
- package/src/server/service.ts +0 -2024
- package/src/server/sse-reader.spec.ts +0 -302
- package/src/server/sse-reader.ts +0 -267
- package/src/server/test-helpers/handlers-config.ts +0 -321
- package/src/server/visibility.spec.ts +0 -403
- package/src/server/visibility.ts +0 -373
- package/src/server.spec.ts +0 -160
- package/src/server.ts +0 -131
- package/src/shared/business-date.spec.ts +0 -82
- package/src/shared/business-date.ts +0 -104
- package/src/shared/comment-adapter.spec.ts +0 -38
- package/src/shared/comment-adapter.ts +0 -80
- package/src/shared/ids-stream.spec.ts +0 -154
- package/src/shared/ids-stream.ts +0 -279
- package/src/shared/logger.ts +0 -47
- package/src/shared/sse-schema.spec.ts +0 -50
- package/src/shared/sse-schema.ts +0 -198
- package/src/shared/text-utils.spec.ts +0 -42
- package/src/shared/text-utils.ts +0 -65
- package/src/shared/types.ts +0 -109
- 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
|
|
2
|
-
import * as drizzle_orm_mssql_core from
|
|
3
|
-
import { AnyMsSqlColumn } from
|
|
4
|
-
import { D as DailyReportLogger } from
|
|
5
|
-
import {
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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 };
|