@aiquants/daily-report 0.12.4 → 0.14.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 +35 -0
- package/dist/client.d.mts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +5 -5
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +5 -5
- package/dist/client.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.mts +238 -23
- package/dist/server.d.ts +238 -23
- package/dist/server.js +12 -9
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +12 -9
- package/dist/server.mjs.map +1 -1
- package/dist/{sse-schema-YZh7Pz7i.d.ts → sse-schema-D1oZnFg6.d.ts} +18 -0
- package/dist/{sse-schema-BiUnufrI.d.mts → sse-schema-lMo8yW4e.d.mts} +18 -0
- package/dist/styles/daily-report.standalone.css +1 -1
- package/package.json +11 -9
- package/src/server/handlers.ids-stream.spec.ts +4 -2
- package/src/server/handlers.ts +185 -35
- package/src/server/handlers.visibility.spec.ts +528 -0
- package/src/server/ports.ts +48 -0
- package/src/server/service.spec.ts +368 -18
- package/src/server/service.ts +232 -42
- package/src/server/test-helpers/handlers-config.ts +93 -9
- package/src/server/visibility.spec.ts +268 -0
- package/src/server/visibility.ts +284 -0
- package/src/server.spec.ts +72 -0
- package/src/server.ts +20 -1
- package/src/shared/sse-schema.ts +15 -0
package/dist/server.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { g as DailyReportInterviewer, e as DailyReportComment, a as DailyReportI
|
|
|
2
2
|
import * as drizzle_orm_mssql_core from 'drizzle-orm/mssql-core';
|
|
3
3
|
import { AnyMsSqlColumn } from 'drizzle-orm/mssql-core';
|
|
4
4
|
import { D as DailyReportLogger } from './logger-D3krZrNK.js';
|
|
5
|
+
import { SQL } from 'drizzle-orm';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* DI ports (structural interfaces) consumed by the daily-report server layer.
|
|
@@ -72,6 +73,50 @@ type DailyReportAuthenticate = (request: Request, options: {
|
|
|
72
73
|
} | {
|
|
73
74
|
failureRedirect: null;
|
|
74
75
|
}) => Promise<DailyReportAuthResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Raw return of the visible-source-type resolver.
|
|
78
|
+
* 可視 sourceType リゾルバの生戻り値。
|
|
79
|
+
*
|
|
80
|
+
* - `undefined` / `null`: 無制限 (全件)。ポート未注入時と同じ既定の意味。
|
|
81
|
+
* - `string[]`: その集合に限定。要素は `DailyReportHub.sourceType` の値であり、**空配列は 0 件**。
|
|
82
|
+
*
|
|
83
|
+
* 中立契約: いかなる認可パッケージの型 (`PermissionView` 等) にも依存しない素の文字列配列。
|
|
84
|
+
*/
|
|
85
|
+
type DailyReportVisibleSourceTypes = readonly string[] | null | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* Why the visible-source-type resolver is being called.
|
|
88
|
+
* 可視 sourceType リゾルバが呼ばれた理由。
|
|
89
|
+
*
|
|
90
|
+
* - `initial`: リクエスト処理の開始時 (読み取り / ミューテーション / 添付 / SSE 接続確立)。
|
|
91
|
+
* - `refresh`: 長寿命の SSE 接続が権限失効を検出するための定期再解決。
|
|
92
|
+
*
|
|
93
|
+
* ❗ `refresh` は接続時と**同一の `Request` インスタンス**で呼ばれる (SSE 接続の生存期間中、
|
|
94
|
+
* 他に握れるハンドルが無いため)。したがってリクエストスコープで記憶化する実装は、
|
|
95
|
+
* `refresh` のときだけキャッシュを迂回しなければ再解決が常に古い値を返し、失効が反映されない。
|
|
96
|
+
*/
|
|
97
|
+
type DailyReportVisibilityResolveReason = "initial" | "refresh";
|
|
98
|
+
/**
|
|
99
|
+
* Context handed to the visible-source-type resolver.
|
|
100
|
+
* 可視 sourceType リゾルバへ渡される文脈。
|
|
101
|
+
*/
|
|
102
|
+
type DailyReportVisibilityResolveContext = {
|
|
103
|
+
/** 呼び出し理由。`refresh` のときリクエストスコープのキャッシュを迂回すること。 */
|
|
104
|
+
reason: DailyReportVisibilityResolveReason;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Resolves which report source types a request may view.
|
|
108
|
+
* リクエストが閲覧してよい日報 sourceType を解決するポート。
|
|
109
|
+
*
|
|
110
|
+
* サーバー側の全データ経路 (一覧 / 詳細 / コメント / 添付 / SSE) に一貫して効く。
|
|
111
|
+
*
|
|
112
|
+
* ❗ 例外を投げた場合、ハンドラは**空集合 (全拒否) にフォールバック**する。認可ストアの
|
|
113
|
+
* 障害時に無制限へ倒れないための fail-close であり、実装側で握り潰さないこと。
|
|
114
|
+
* ❗ 全読み取りリクエストのクリティカルパス上で 1 回呼ばれる (キャッシュキーが戻り値に依存する)。
|
|
115
|
+
* 高速に保つこと。記憶化する場合はセッション / ユーザー単位の短時間 TTL (60 秒以下) とし、
|
|
116
|
+
* `context.reason === "refresh"` では必ずキャッシュを迂回すること
|
|
117
|
+
* (迂回しないと SSE の定期再解決が失効を観測できず、権限剥奪後も配信が続く)。
|
|
118
|
+
*/
|
|
119
|
+
type DailyReportResolveVisibleSourceTypes = (request: Request, context: DailyReportVisibilityResolveContext) => DailyReportVisibleSourceTypes | Promise<DailyReportVisibleSourceTypes>;
|
|
75
120
|
/**
|
|
76
121
|
* Resolves an external user id (e.g. Google sub) to the internal numeric user id.
|
|
77
122
|
* 外部ユーザー ID (例: Google sub) を内部数値ユーザー ID へ解決するポート。
|
|
@@ -1490,6 +1535,156 @@ declare function defineDailyReportSchema<S extends string>(schemaName: S, opts:
|
|
|
1490
1535
|
}>;
|
|
1491
1536
|
};
|
|
1492
1537
|
|
|
1538
|
+
/**
|
|
1539
|
+
* Source-type visibility set: normalization, digest, and predicate helpers.
|
|
1540
|
+
* sourceType 可視集合の正規化・ダイジェスト・判定ヘルパー群。
|
|
1541
|
+
*
|
|
1542
|
+
* 中立文字列 (`DailyReportHub.sourceType` の値) のみを扱い、いかなる認可パッケージの型にも
|
|
1543
|
+
* 依存しない。可視集合は 2 状態を厳密に区別する:
|
|
1544
|
+
*
|
|
1545
|
+
* - `null` = 無制限 (全件)。ポート未注入時の既定であり、現行互換の意味を持つ。
|
|
1546
|
+
* - `Set` = その集合に限定。**空集合は 0 件 (fail-close)** であって無制限ではない。
|
|
1547
|
+
*
|
|
1548
|
+
* この 2 状態の取り違えは情報漏洩か機能停止に直結するため、判定・畳み込み・キー生成を
|
|
1549
|
+
* 本ファイルへ一元化し、ハンドラ層とサービス層の双方がここだけを参照する。
|
|
1550
|
+
*/
|
|
1551
|
+
|
|
1552
|
+
/**
|
|
1553
|
+
* Normalized visible set. null = unrestricted (all rows), ReadonlySet = restricted (empty = zero rows).
|
|
1554
|
+
* 正規化済みの可視集合。null は無制限 (全件)、ReadonlySet は限定 (空集合は 0 件)。
|
|
1555
|
+
*/
|
|
1556
|
+
type VisibleSourceTypeSet = ReadonlySet<string> | null;
|
|
1557
|
+
/**
|
|
1558
|
+
* Normalizes a raw resolver return into a VisibleSourceTypeSet.
|
|
1559
|
+
* ポートの生戻り値を正規化済み可視集合へ変換する処理。
|
|
1560
|
+
*
|
|
1561
|
+
* `null` / `undefined` は無制限 (`null`) へ。配列は各要素を畳み込み・空文字除去・重複排除して
|
|
1562
|
+
* `Set` 化する。**空配列は空 `Set` (0 件) を返し、`null` (無制限) へは決して倒さない** —
|
|
1563
|
+
* この取り違えが情報漏洩か機能停止に直結するため。
|
|
1564
|
+
*
|
|
1565
|
+
* @param raw Raw resolver return value. ポートの生戻り値。
|
|
1566
|
+
* @returns Normalized visible set. 正規化済みの可視集合。
|
|
1567
|
+
*/
|
|
1568
|
+
declare function normalizeVisibleSourceTypes(raw: DailyReportVisibleSourceTypes): VisibleSourceTypeSet;
|
|
1569
|
+
/**
|
|
1570
|
+
* Tests whether a report's sourceType is visible under the given set.
|
|
1571
|
+
* ある日報の sourceType が可視集合に含まれるかの三値判定。
|
|
1572
|
+
*
|
|
1573
|
+
* - 無制限 (`null`): 常に `true`。
|
|
1574
|
+
* - 限定 + sourceType 判明: 畳み込み一致で判定。
|
|
1575
|
+
* - 限定 + sourceType 不明 (`null` / `undefined`): `false` — 制限された閲覧者は「不明な区分」を
|
|
1576
|
+
* 見られない。区分を運ばない旧 SSE エントリ等を fail-close 側へ倒すための規則。
|
|
1577
|
+
*
|
|
1578
|
+
* @param set Normalized visible set. 正規化済みの可視集合。
|
|
1579
|
+
* @param sourceType The row's source type, if known. 判明していれば当該行のソース種別。
|
|
1580
|
+
* @returns True when visible. 可視なら true。
|
|
1581
|
+
*/
|
|
1582
|
+
declare function isSourceTypeVisible(set: VisibleSourceTypeSet, sourceType: string | null | undefined): boolean;
|
|
1583
|
+
/**
|
|
1584
|
+
* Tells whether the set denies everything (zero rows).
|
|
1585
|
+
* 可視集合が全拒否 (0 件) を意味するかを判定する処理。
|
|
1586
|
+
*
|
|
1587
|
+
* 真のとき呼び出し側は DB へ問い合わせず即座に空を返してよい (無駄クエリの排除)。
|
|
1588
|
+
* これは性能上の短絡であり、認可の防御そのものは {@link buildVisibleSourceTypeCondition} が担う。
|
|
1589
|
+
*
|
|
1590
|
+
* @param set Normalized visible set. 正規化済みの可視集合。
|
|
1591
|
+
* @returns True when nothing is visible. 何も可視でないなら true。
|
|
1592
|
+
*/
|
|
1593
|
+
declare function deniesEverySourceType(set: VisibleSourceTypeSet): boolean;
|
|
1594
|
+
/**
|
|
1595
|
+
* Builds the SQL condition restricting rows to the visible source types.
|
|
1596
|
+
* 可視 sourceType へ行を限定する SQL 条件を生成する処理 (三値)。
|
|
1597
|
+
*
|
|
1598
|
+
* {@link isSourceTypeVisible} の SQL 版であり、同じ三値を同じ向きへ写像する:
|
|
1599
|
+
*
|
|
1600
|
+
* - 無制限 (`null`): `undefined` を返す。drizzle の `and(...)` は `undefined` を無視するため、
|
|
1601
|
+
* 既存の述語がそのまま残る (現行互換)。
|
|
1602
|
+
* - 全拒否 (空集合): `1 = 0` を返す。**決して `undefined` へ倒さない** — 呼び出し側の短絡漏れが
|
|
1603
|
+
* あっても生成器自身が fail-close する二重防御であり、ここを緩めると認可が反転する。
|
|
1604
|
+
* - 限定: `LOWER(<column>) IN (...)`。トークンは正規化時に小文字畳み込み済みなので両辺が小文字となり、
|
|
1605
|
+
* DB の照合順序 (collation) に依存せず決定的に大小文字非依存で一致する。
|
|
1606
|
+
*
|
|
1607
|
+
* @param sourceTypeColumn The source-type column to constrain. 制限対象の sourceType 列。
|
|
1608
|
+
* @param set Normalized visible set. 正規化済みの可視集合。
|
|
1609
|
+
* @returns Condition, or undefined when unrestricted. 条件 (無制限なら undefined)。
|
|
1610
|
+
*/
|
|
1611
|
+
declare function buildVisibleSourceTypeCondition(sourceTypeColumn: AnyMsSqlColumn, set: VisibleSourceTypeSet): SQL | undefined;
|
|
1612
|
+
/**
|
|
1613
|
+
* Request-scoped viewer scope carrying the normalized visible source-type set.
|
|
1614
|
+
* 正規化済みの可視 sourceType 集合を運ぶ、リクエストスコープの閲覧範囲。
|
|
1615
|
+
*
|
|
1616
|
+
* このクラスは private フィールドを持つことで**名目型**になっており、`{ visible: null }` のような
|
|
1617
|
+
* 構造的偽造も、`{ ...scope, visible: null }` のようなスプレッドによる widening も型が拒否する
|
|
1618
|
+
* (`unique symbol` ブランドでは後者を防げないことを実測で確認済み)。
|
|
1619
|
+
*
|
|
1620
|
+
* 生成経路は {@link DailyReportViewerScope.restrictTo} と {@link DailyReportViewerScope.unrestricted}
|
|
1621
|
+
* の 2 つだけであり、`null` を「可視性」としてそのまま綴ることはできない。結果として、
|
|
1622
|
+
* **絞り込まれない読み取りは必ず `unrestricted(理由)` として現れる**ため、
|
|
1623
|
+
* `grep -rn "DailyReportViewerScope.unrestricted("` が fail-open の全数リストになる。
|
|
1624
|
+
*/
|
|
1625
|
+
declare class DailyReportViewerScope {
|
|
1626
|
+
#private;
|
|
1627
|
+
private constructor();
|
|
1628
|
+
/** 正規化済みの可視集合。`null` は無制限、空集合は 0 件 (fail-close)。 */
|
|
1629
|
+
get visible(): VisibleSourceTypeSet;
|
|
1630
|
+
/**
|
|
1631
|
+
* Builds a scope restricted to the given source types (empty input = zero rows).
|
|
1632
|
+
* 指定した sourceType へ限定した閲覧範囲を生成する処理 (空入力は 0 件)。
|
|
1633
|
+
*
|
|
1634
|
+
* 入力は {@link normalizeVisibleSourceTypes} を通るため、大小文字・前後空白・重複・非文字列は
|
|
1635
|
+
* ここで吸収される。
|
|
1636
|
+
*
|
|
1637
|
+
* ❗ 引数は `readonly string[]` に**狭めてある**。`null` / `undefined` を受け付けると、
|
|
1638
|
+
* 「restrict」という名前のまま無制限スコープを生む第 2 の入口になり、
|
|
1639
|
+
* 「絞り込まれない読み取りは必ず {@link DailyReportViewerScope.unrestricted} に現れる」
|
|
1640
|
+
* という監査不変条件が崩れる。無制限は必ず理由付きで明示すること。
|
|
1641
|
+
*
|
|
1642
|
+
* @param sourceTypes Visible source-type tokens. 可視 sourceType のトークン群。
|
|
1643
|
+
* @returns The scope. 生成した閲覧範囲。
|
|
1644
|
+
*/
|
|
1645
|
+
static restrictTo(sourceTypes: readonly string[]): DailyReportViewerScope;
|
|
1646
|
+
/**
|
|
1647
|
+
* Builds an unrestricted scope; every call site is an audited fail-open.
|
|
1648
|
+
* 無制限の閲覧範囲を生成する処理。全呼び出し箇所が監査対象の fail-open となる。
|
|
1649
|
+
*
|
|
1650
|
+
* ❗ 理由文字列は必須。読み捨てるが、呼び出し箇所の全数列挙と「なぜここは絞らなくてよいか」の
|
|
1651
|
+
* 記録を強制するために受け取る。
|
|
1652
|
+
*
|
|
1653
|
+
* @param auditReason Why unrestricted access is correct here. なぜここで無制限が正当かの理由。
|
|
1654
|
+
* @returns The unrestricted scope. 無制限の閲覧範囲。
|
|
1655
|
+
*/
|
|
1656
|
+
static unrestricted(auditReason: string): DailyReportViewerScope;
|
|
1657
|
+
}
|
|
1658
|
+
/**
|
|
1659
|
+
* Computes the cache-key digest for a whole viewer scope.
|
|
1660
|
+
* 閲覧範囲全体からキャッシュキー用ダイジェストを算出する処理。
|
|
1661
|
+
*
|
|
1662
|
+
* スコープに次元が増えてもキャッシュキーの生成点を 1 つに保つための入口。
|
|
1663
|
+
*
|
|
1664
|
+
* @param scope Viewer scope. 閲覧範囲。
|
|
1665
|
+
* @returns Digest usable as a cache-key component. キャッシュキー構成要素として使えるダイジェスト。
|
|
1666
|
+
*/
|
|
1667
|
+
declare function computeViewerScopeDigest(scope: DailyReportViewerScope): string;
|
|
1668
|
+
/**
|
|
1669
|
+
* Computes a stable and bounded cache-key digest of the set.
|
|
1670
|
+
* 可視集合から安定・有界なキャッシュキー用ダイジェストを算出する処理。
|
|
1671
|
+
*
|
|
1672
|
+
* 無制限は `"all"`、空集合は `"none"`、それ以外は `s:` 名前空間の下へ**長さ接頭辞付きトークンを昇順連結**する。
|
|
1673
|
+
* 連結は長さ接頭辞付きなので**単射**であり、通常経路 (`s:`) では論理的に等価な集合が必ず同一の、
|
|
1674
|
+
* 異なる集合が必ず別のダイジェストになる。sentinel (`all` / `none`) とも名前空間が分かれるため、
|
|
1675
|
+
* 限定集合が無制限 / 全拒否と同じバケットを共有することはない。権限が安定している間はキーが
|
|
1676
|
+
* 不変になるため、キャッシュは完全に再利用される (性能無退行)。
|
|
1677
|
+
*
|
|
1678
|
+
* ❗ 区分数が異常に多い場合だけキー長を抑えるため FNV-1a 32bit へ退避し `sh:` 接頭辞を付ける。
|
|
1679
|
+
* **この退避経路に限り理論上の衝突がありうる** (32bit)。衝突しても影響は同一ユーザーの
|
|
1680
|
+
* キャッシュ再利用に留まり、認可判定そのものは SQL 述語が担うため漏洩には至らない。
|
|
1681
|
+
* 通常の区分数 (数個) では到達しない。
|
|
1682
|
+
*
|
|
1683
|
+
* @param set Normalized visible set. 正規化済みの可視集合。
|
|
1684
|
+
* @returns Digest usable as a cache-key component. キャッシュキー構成要素として使えるダイジェスト。
|
|
1685
|
+
*/
|
|
1686
|
+
declare function computeSourceTypeDigest(set: VisibleSourceTypeSet): string;
|
|
1687
|
+
|
|
1493
1688
|
/** DailyReportHub の行型。 */
|
|
1494
1689
|
type DailyReportHubRow = {
|
|
1495
1690
|
id: number;
|
|
@@ -1648,15 +1843,15 @@ declare function createDailyReportService(config: DailyReportServiceConfig): {
|
|
|
1648
1843
|
clearCache: () => Promise<void>;
|
|
1649
1844
|
invalidateHubReadCaches: (hubIds: readonly number[], businessDates: readonly string[]) => Promise<void>;
|
|
1650
1845
|
getUserIdByExternalId: (externalId: string) => Promise<number | null>;
|
|
1651
|
-
getDailyReportIdsByExternalId: (externalId: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportItem[]>;
|
|
1652
|
-
getDailyReportIdsFirstPageByExternalId: (externalId: string, limit: number) => Promise<DailyReportItem[]>;
|
|
1653
|
-
getDailyReportsByBusinessDate: (businessDate: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail[]>;
|
|
1654
|
-
getDailyReportsByBusinessDateByExternalId: (businessDate: string, externalId: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail[]>;
|
|
1655
|
-
getDailyReportDetailById: (reportHubId: number, userId: number, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail | null>;
|
|
1656
|
-
getDailyReportDetailByIdByExternalId: (reportHubId: number, externalId: string, options?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail | null>;
|
|
1846
|
+
getDailyReportIdsByExternalId: (scope: DailyReportViewerScope, externalId: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportItem[]>;
|
|
1847
|
+
getDailyReportIdsFirstPageByExternalId: (scope: DailyReportViewerScope, externalId: string, limit: number) => Promise<DailyReportItem[]>;
|
|
1848
|
+
getDailyReportsByBusinessDate: (scope: DailyReportViewerScope, businessDate: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail[]>;
|
|
1849
|
+
getDailyReportsByBusinessDateByExternalId: (scope: DailyReportViewerScope, businessDate: string, externalId: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail[]>;
|
|
1850
|
+
getDailyReportDetailById: (scope: DailyReportViewerScope, reportHubId: number, userId: number, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail | null>;
|
|
1851
|
+
getDailyReportDetailByIdByExternalId: (scope: DailyReportViewerScope, reportHubId: number, externalId: string, options?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail | null>;
|
|
1657
1852
|
getDraftLabelId: () => Promise<number | null>;
|
|
1658
1853
|
getAttachmentsByHubIds: (hubIds: number[]) => Promise<Map<number, DailyReportAttachmentSummary[]>>;
|
|
1659
|
-
getAttachmentForUser: (attachmentId: number, userId: number) => Promise<{
|
|
1854
|
+
getAttachmentForUser: (scope: DailyReportViewerScope, attachmentId: number, userId: number) => Promise<{
|
|
1660
1855
|
fileName: string;
|
|
1661
1856
|
filePath: string;
|
|
1662
1857
|
fileType: string | null;
|
|
@@ -1664,10 +1859,10 @@ declare function createDailyReportService(config: DailyReportServiceConfig): {
|
|
|
1664
1859
|
} | null>;
|
|
1665
1860
|
markAttachmentMissing: (attachmentId: number) => Promise<void>;
|
|
1666
1861
|
markAttachmentPresent: (attachmentId: number) => Promise<void>;
|
|
1667
|
-
setStarStatus: (userId: number, reportHubId: number, businessDate: string | null, isStarred: boolean, clientTempId: string) => Promise<DailyReportUserStatusRow>;
|
|
1668
|
-
setReadStatus: (userId: number, reportHubId: number, businessDate: string | null, isRead: boolean, clientTempId: string) => Promise<DailyReportUserStatusRow>;
|
|
1669
|
-
addComment: (userId: number, reportHubId: number, content: string, businessDate: string | null, clientTempId: string) => Promise<DailyReportCommentItem>;
|
|
1670
|
-
deleteComment: (userId: number, reportHubId: number, commentId: number, businessDate: string | null, clientTempId: string) => Promise<void>;
|
|
1862
|
+
setStarStatus: (scope: DailyReportViewerScope, userId: number, reportHubId: number, businessDate: string | null, isStarred: boolean, clientTempId: string) => Promise<DailyReportUserStatusRow>;
|
|
1863
|
+
setReadStatus: (scope: DailyReportViewerScope, userId: number, reportHubId: number, businessDate: string | null, isRead: boolean, clientTempId: string) => Promise<DailyReportUserStatusRow>;
|
|
1864
|
+
addComment: (scope: DailyReportViewerScope, userId: number, reportHubId: number, content: string, businessDate: string | null, clientTempId: string) => Promise<DailyReportCommentItem>;
|
|
1865
|
+
deleteComment: (scope: DailyReportViewerScope, userId: number, reportHubId: number, commentId: number, businessDate: string | null, clientTempId: string) => Promise<void>;
|
|
1671
1866
|
createDailyReport: (userId: number, businessDate: string, clientTempId: string) => Promise<DailyReportDetail>;
|
|
1672
1867
|
updateDailyReport: (reportHubId: number, userId: number, data: {
|
|
1673
1868
|
title?: string;
|
|
@@ -1840,6 +2035,11 @@ declare const asciiFallbackFileName: (name: string) => string;
|
|
|
1840
2035
|
type DailyReportHandlersConfig = {
|
|
1841
2036
|
/** リクエスト認証ポート。 */
|
|
1842
2037
|
authenticate: DailyReportAuthenticate;
|
|
2038
|
+
/**
|
|
2039
|
+
* 可視 sourceType リゾルバ。未注入なら全件 (現行互換)。
|
|
2040
|
+
* 全データ経路 (一覧 / 詳細 / コメント / 添付 / SSE) に一貫して効き、例外は全拒否として扱う。
|
|
2041
|
+
*/
|
|
2042
|
+
resolveVisibleSourceTypes?: DailyReportResolveVisibleSourceTypes;
|
|
1843
2043
|
/** データアクセスサービス。 */
|
|
1844
2044
|
service: DailyReportService;
|
|
1845
2045
|
/** 内部数値 ID の難読化ポート。 */
|
|
@@ -1918,6 +2118,14 @@ declare const jsonResponseWithETag: (request: Request, cookie: string | null, pa
|
|
|
1918
2118
|
type DailyReportServerConfig = Omit<DailyReportServiceConfig, "cache" | "epochs"> & {
|
|
1919
2119
|
/** リクエスト認証ポート。 */
|
|
1920
2120
|
authenticate: DailyReportAuthenticate;
|
|
2121
|
+
/**
|
|
2122
|
+
* 可視 sourceType リゾルバ。未注入なら全件 (現行互換)。
|
|
2123
|
+
*
|
|
2124
|
+
* サーバー側の全データ経路 (一覧 / 詳細 / コメント / 添付 / SSE) に一貫して効く。
|
|
2125
|
+
* 戻り値は `DailyReportHub.sourceType` の値 (`knownSourceTypes` 参照) であり、認可リソースキーではない。
|
|
2126
|
+
* `undefined` / `null` は無制限、空配列は 0 件、例外は全拒否 (fail-close)。
|
|
2127
|
+
*/
|
|
2128
|
+
resolveVisibleSourceTypes?: DailyReportResolveVisibleSourceTypes;
|
|
1921
2129
|
/** 添付ファイル読み取りポート。未注入なら添付エンドポイントは常に 404。 */
|
|
1922
2130
|
readAttachment?: DailyReportReadAttachment;
|
|
1923
2131
|
/** 添付ファイルの最大バイト数 (既定 32 MiB)。サービス側のワイヤ上限より低く保つこと。 */
|
|
@@ -1994,15 +2202,15 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
|
|
|
1994
2202
|
clearCache: () => Promise<void>;
|
|
1995
2203
|
invalidateHubReadCaches: (hubIds: readonly number[], businessDates: readonly string[]) => Promise<void>;
|
|
1996
2204
|
getUserIdByExternalId: (externalId: string) => Promise<number | null>;
|
|
1997
|
-
getDailyReportIdsByExternalId: (externalId: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportItem[]>;
|
|
1998
|
-
getDailyReportIdsFirstPageByExternalId: (externalId: string, limit: number) => Promise<DailyReportItem[]>;
|
|
1999
|
-
getDailyReportsByBusinessDate: (businessDate: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail[]>;
|
|
2000
|
-
getDailyReportsByBusinessDateByExternalId: (businessDate: string, externalId: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail[]>;
|
|
2001
|
-
getDailyReportDetailById: (reportHubId: number, userId: number, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail | null>;
|
|
2002
|
-
getDailyReportDetailByIdByExternalId: (reportHubId: number, externalId: string, options?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail | null>;
|
|
2205
|
+
getDailyReportIdsByExternalId: (scope: DailyReportViewerScope, externalId: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportItem[]>;
|
|
2206
|
+
getDailyReportIdsFirstPageByExternalId: (scope: DailyReportViewerScope, externalId: string, limit: number) => Promise<DailyReportItem[]>;
|
|
2207
|
+
getDailyReportsByBusinessDate: (scope: DailyReportViewerScope, businessDate: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail[]>;
|
|
2208
|
+
getDailyReportsByBusinessDateByExternalId: (scope: DailyReportViewerScope, businessDate: string, externalId: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail[]>;
|
|
2209
|
+
getDailyReportDetailById: (scope: DailyReportViewerScope, reportHubId: number, userId: number, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail | null>;
|
|
2210
|
+
getDailyReportDetailByIdByExternalId: (scope: DailyReportViewerScope, reportHubId: number, externalId: string, options?: SqlResultCacheQueryOptions) => Promise<DailyReportDetail | null>;
|
|
2003
2211
|
getDraftLabelId: () => Promise<number | null>;
|
|
2004
2212
|
getAttachmentsByHubIds: (hubIds: number[]) => Promise<Map<number, DailyReportAttachmentSummary[]>>;
|
|
2005
|
-
getAttachmentForUser: (attachmentId: number, userId: number) => Promise<{
|
|
2213
|
+
getAttachmentForUser: (scope: DailyReportViewerScope, attachmentId: number, userId: number) => Promise<{
|
|
2006
2214
|
fileName: string;
|
|
2007
2215
|
filePath: string;
|
|
2008
2216
|
fileType: string | null;
|
|
@@ -2010,10 +2218,10 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
|
|
|
2010
2218
|
} | null>;
|
|
2011
2219
|
markAttachmentMissing: (attachmentId: number) => Promise<void>;
|
|
2012
2220
|
markAttachmentPresent: (attachmentId: number) => Promise<void>;
|
|
2013
|
-
setStarStatus: (userId: number, reportHubId: number, businessDate: string | null, isStarred: boolean, clientTempId: string) => Promise<DailyReportUserStatusRow>;
|
|
2014
|
-
setReadStatus: (userId: number, reportHubId: number, businessDate: string | null, isRead: boolean, clientTempId: string) => Promise<DailyReportUserStatusRow>;
|
|
2015
|
-
addComment: (userId: number, reportHubId: number, content: string, businessDate: string | null, clientTempId: string) => Promise<DailyReportCommentItem>;
|
|
2016
|
-
deleteComment: (userId: number, reportHubId: number, commentId: number, businessDate: string | null, clientTempId: string) => Promise<void>;
|
|
2221
|
+
setStarStatus: (scope: DailyReportViewerScope, userId: number, reportHubId: number, businessDate: string | null, isStarred: boolean, clientTempId: string) => Promise<DailyReportUserStatusRow>;
|
|
2222
|
+
setReadStatus: (scope: DailyReportViewerScope, userId: number, reportHubId: number, businessDate: string | null, isRead: boolean, clientTempId: string) => Promise<DailyReportUserStatusRow>;
|
|
2223
|
+
addComment: (scope: DailyReportViewerScope, userId: number, reportHubId: number, content: string, businessDate: string | null, clientTempId: string) => Promise<DailyReportCommentItem>;
|
|
2224
|
+
deleteComment: (scope: DailyReportViewerScope, userId: number, reportHubId: number, commentId: number, businessDate: string | null, clientTempId: string) => Promise<void>;
|
|
2017
2225
|
createDailyReport: (userId: number, businessDate: string, clientTempId: string) => Promise<DailyReportDetail>;
|
|
2018
2226
|
updateDailyReport: (reportHubId: number, userId: number, data: {
|
|
2019
2227
|
title?: string;
|
|
@@ -2037,6 +2245,13 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
|
|
|
2037
2245
|
sseReader: DailyReportSseReader;
|
|
2038
2246
|
/** SSE Redis Stream キー。 */
|
|
2039
2247
|
streamKey: string;
|
|
2248
|
+
/**
|
|
2249
|
+
* 既知の正準 sourceType 集合 (注入した `externalSources` の全 sourceType + `"Internal"`)。
|
|
2250
|
+
*
|
|
2251
|
+
* `resolveVisibleSourceTypes` が返すべき語彙そのものであり、消費側は起動時にこの集合と
|
|
2252
|
+
* 自前のマッピングを突き合わせて誤トークン (無診断で 0 件になる) を検出できる。
|
|
2253
|
+
*/
|
|
2254
|
+
knownSourceTypes: readonly string[];
|
|
2040
2255
|
};
|
|
2041
2256
|
|
|
2042
|
-
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 DailyReportServerConfig, type DailyReportService, type DailyReportServiceConfig, type DailyReportSourceTypeInput, DailyReportSseReader, type DailyReportSseReaderConfig, type DailyReportTables, type DailyReportUserStatusRow, type DailyReportUserStatusTable, type DailyReportUserTable, type EpochStore, type ExternalReportFields, type RedisStreamMessage, SqlResultCache, type SqlResultCacheQueryOptions, type StreamEntry, asciiFallbackFileName, createDailyReportHandlers, createDailyReportServer, createDailyReportService, createEpochStore, defineDailyReportAuthzResources, defineDailyReportSchema, encodeRfc8187, formatDateValue, generateETag, isStreamIdLte, jsonResponseWithETag, sanitizeMediaType, seedDailyReportAuthzResources, transformJsonArray };
|
|
2257
|
+
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 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 };
|