@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.
- package/README.md +229 -8
- package/dist/client.d.mts +201 -739
- package/dist/client.d.ts +201 -739
- package/dist/client.js +5 -6
- package/dist/client.mjs +5 -6
- package/dist/index.d.mts +5 -197
- package/dist/index.d.ts +5 -197
- package/dist/index.js +1 -2
- package/dist/index.mjs +1 -2
- package/dist/logger-D3krZrNK.d.mts +0 -14
- package/dist/logger-D3krZrNK.d.ts +0 -14
- package/dist/server.d.mts +114 -744
- package/dist/server.d.ts +114 -744
- package/dist/server.js +1 -2
- package/dist/server.mjs +1 -2
- package/dist/{sse-schema-ChSFm-4q.d.mts → sse-schema-DCxpdETM.d.mts} +1106 -1090
- package/dist/{sse-schema-BdUGThiz.d.ts → sse-schema-DoQw8_om.d.ts} +1106 -1090
- package/dist/types-CqgYQgbH.d.mts +0 -34
- package/dist/types-CqgYQgbH.d.ts +0 -34
- package/package.json +9 -10
- 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 -2045
- 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/transaction-retry.spec.ts +0 -63
- 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.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
|
|
2
|
-
import * as drizzle_orm_mssql_core from
|
|
3
|
-
import { AnyMsSqlColumn } from
|
|
4
|
-
import { D as DailyReportLogger } from
|
|
5
|
-
import { TransactionRetryOptions } from
|
|
6
|
-
import { SQL } from
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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: [
|
|
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 };
|