@aiquants/daily-report 0.12.3 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +32 -0
  2. package/dist/client.d.mts +1 -1
  3. package/dist/client.d.ts +1 -1
  4. package/dist/client.js +5 -5
  5. package/dist/client.js.map +1 -1
  6. package/dist/client.mjs +5 -5
  7. package/dist/client.mjs.map +1 -1
  8. package/dist/index.d.mts +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +1 -1
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/server.d.mts +175 -21
  15. package/dist/server.d.ts +175 -21
  16. package/dist/server.js +12 -9
  17. package/dist/server.js.map +1 -1
  18. package/dist/server.mjs +12 -9
  19. package/dist/server.mjs.map +1 -1
  20. package/dist/{sse-schema-YZh7Pz7i.d.ts → sse-schema-D1oZnFg6.d.ts} +18 -0
  21. package/dist/{sse-schema-BiUnufrI.d.mts → sse-schema-lMo8yW4e.d.mts} +18 -0
  22. package/package.json +1 -1
  23. package/src/client/components/daily-report-attachment-indicator.tsx +1 -1
  24. package/src/client/components/daily-report-detail-list.tsx +3 -3
  25. package/src/client/components/daily-report-ids-stream-status.tsx +1 -1
  26. package/src/client/components/daily-report-list.tsx +3 -3
  27. package/src/client/components/daily-report-resolved-content.tsx +3 -3
  28. package/src/lucide-icons.d.ts +3 -3
  29. package/src/server/handlers.ts +181 -35
  30. package/src/server/handlers.visibility.spec.ts +458 -0
  31. package/src/server/ports.ts +48 -0
  32. package/src/server/service.spec.ts +335 -14
  33. package/src/server/service.ts +222 -37
  34. package/src/server/test-helpers/handlers-config.ts +93 -9
  35. package/src/server/visibility.spec.ts +142 -0
  36. package/src/server/visibility.ts +189 -0
  37. package/src/server.spec.ts +72 -0
  38. package/src/server.ts +20 -1
  39. package/src/shared/sse-schema.ts +15 -0
package/dist/server.d.mts 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.mjs';
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,95 @@ 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
+ * Computes a stable, bounded, collision-free cache-key digest of the set.
1614
+ * 可視集合から安定・有界・衝突不能なキャッシュキー用ダイジェストを算出する処理。
1615
+ *
1616
+ * 無制限は `"all"`、空集合は `"none"`、それ以外は**畳み込み済みトークンを昇順にそのまま連結**する。
1617
+ * 生連結のため、論理的に等価な集合は必ず同一の、論理的に異なる集合は必ず別のダイジェストになる
1618
+ * (ハッシュ衝突で別権限のキャッシュ行を配信する事故が原理的に起きない)。権限が安定している間は
1619
+ * キーが不変になるため、キャッシュは完全に再利用される (性能無退行)。
1620
+ * 区分数が異常に多い場合だけキー長を抑えるため FNV-1a 32bit へ退避し、`h:` 接頭辞で生連結と区別する。
1621
+ *
1622
+ * @param set Normalized visible set. 正規化済みの可視集合。
1623
+ * @returns Digest usable as a cache-key component. キャッシュキー構成要素として使えるダイジェスト。
1624
+ */
1625
+ declare function computeSourceTypeDigest(set: VisibleSourceTypeSet): string;
1626
+
1493
1627
  /** DailyReportHub の行型。 */
1494
1628
  type DailyReportHubRow = {
1495
1629
  id: number;
@@ -1648,15 +1782,15 @@ declare function createDailyReportService(config: DailyReportServiceConfig): {
1648
1782
  clearCache: () => Promise<void>;
1649
1783
  invalidateHubReadCaches: (hubIds: readonly number[], businessDates: readonly string[]) => Promise<void>;
1650
1784
  getUserIdByExternalId: (externalId: string) => Promise<number | null>;
1651
- getDailyReportIdsByExternalId: (externalId: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportItem[]>;
1652
- getDailyReportIdsFirstPageByExternalId: (externalId: string, limit: number) => Promise<DailyReportItem[]>;
1785
+ getDailyReportIdsByExternalId: (externalId: string, { forceRefresh, snapshot, ttlMsOverride }: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportItem[]>;
1786
+ getDailyReportIdsFirstPageByExternalId: (externalId: string, limit: number, visible: VisibleSourceTypeSet) => Promise<DailyReportItem[]>;
1653
1787
  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>;
1788
+ getDailyReportsByBusinessDateByExternalId: (businessDate: string, externalId: string, { forceRefresh, snapshot, ttlMsOverride }: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportDetail[]>;
1789
+ getDailyReportDetailById: (reportHubId: number, userId: number, { forceRefresh, snapshot, ttlMsOverride }: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportDetail | null>;
1790
+ getDailyReportDetailByIdByExternalId: (reportHubId: number, externalId: string, options: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportDetail | null>;
1657
1791
  getDraftLabelId: () => Promise<number | null>;
1658
1792
  getAttachmentsByHubIds: (hubIds: number[]) => Promise<Map<number, DailyReportAttachmentSummary[]>>;
1659
- getAttachmentForUser: (attachmentId: number, userId: number) => Promise<{
1793
+ getAttachmentForUser: (attachmentId: number, userId: number, visible: VisibleSourceTypeSet) => Promise<{
1660
1794
  fileName: string;
1661
1795
  filePath: string;
1662
1796
  fileType: string | null;
@@ -1664,10 +1798,10 @@ declare function createDailyReportService(config: DailyReportServiceConfig): {
1664
1798
  } | null>;
1665
1799
  markAttachmentMissing: (attachmentId: number) => Promise<void>;
1666
1800
  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>;
1801
+ setStarStatus: (userId: number, reportHubId: number, businessDate: string | null, isStarred: boolean, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<DailyReportUserStatusRow>;
1802
+ setReadStatus: (userId: number, reportHubId: number, businessDate: string | null, isRead: boolean, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<DailyReportUserStatusRow>;
1803
+ addComment: (userId: number, reportHubId: number, content: string, businessDate: string | null, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<DailyReportCommentItem>;
1804
+ deleteComment: (userId: number, reportHubId: number, commentId: number, businessDate: string | null, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<void>;
1671
1805
  createDailyReport: (userId: number, businessDate: string, clientTempId: string) => Promise<DailyReportDetail>;
1672
1806
  updateDailyReport: (reportHubId: number, userId: number, data: {
1673
1807
  title?: string;
@@ -1840,6 +1974,11 @@ declare const asciiFallbackFileName: (name: string) => string;
1840
1974
  type DailyReportHandlersConfig = {
1841
1975
  /** リクエスト認証ポート。 */
1842
1976
  authenticate: DailyReportAuthenticate;
1977
+ /**
1978
+ * 可視 sourceType リゾルバ。未注入なら全件 (現行互換)。
1979
+ * 全データ経路 (一覧 / 詳細 / コメント / 添付 / SSE) に一貫して効き、例外は全拒否として扱う。
1980
+ */
1981
+ resolveVisibleSourceTypes?: DailyReportResolveVisibleSourceTypes;
1843
1982
  /** データアクセスサービス。 */
1844
1983
  service: DailyReportService;
1845
1984
  /** 内部数値 ID の難読化ポート。 */
@@ -1918,6 +2057,14 @@ declare const jsonResponseWithETag: (request: Request, cookie: string | null, pa
1918
2057
  type DailyReportServerConfig = Omit<DailyReportServiceConfig, "cache" | "epochs"> & {
1919
2058
  /** リクエスト認証ポート。 */
1920
2059
  authenticate: DailyReportAuthenticate;
2060
+ /**
2061
+ * 可視 sourceType リゾルバ。未注入なら全件 (現行互換)。
2062
+ *
2063
+ * サーバー側の全データ経路 (一覧 / 詳細 / コメント / 添付 / SSE) に一貫して効く。
2064
+ * 戻り値は `DailyReportHub.sourceType` の値 (`knownSourceTypes` 参照) であり、認可リソースキーではない。
2065
+ * `undefined` / `null` は無制限、空配列は 0 件、例外は全拒否 (fail-close)。
2066
+ */
2067
+ resolveVisibleSourceTypes?: DailyReportResolveVisibleSourceTypes;
1921
2068
  /** 添付ファイル読み取りポート。未注入なら添付エンドポイントは常に 404。 */
1922
2069
  readAttachment?: DailyReportReadAttachment;
1923
2070
  /** 添付ファイルの最大バイト数 (既定 32 MiB)。サービス側のワイヤ上限より低く保つこと。 */
@@ -1994,15 +2141,15 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
1994
2141
  clearCache: () => Promise<void>;
1995
2142
  invalidateHubReadCaches: (hubIds: readonly number[], businessDates: readonly string[]) => Promise<void>;
1996
2143
  getUserIdByExternalId: (externalId: string) => Promise<number | null>;
1997
- getDailyReportIdsByExternalId: (externalId: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportItem[]>;
1998
- getDailyReportIdsFirstPageByExternalId: (externalId: string, limit: number) => Promise<DailyReportItem[]>;
2144
+ getDailyReportIdsByExternalId: (externalId: string, { forceRefresh, snapshot, ttlMsOverride }: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportItem[]>;
2145
+ getDailyReportIdsFirstPageByExternalId: (externalId: string, limit: number, visible: VisibleSourceTypeSet) => Promise<DailyReportItem[]>;
1999
2146
  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>;
2147
+ getDailyReportsByBusinessDateByExternalId: (businessDate: string, externalId: string, { forceRefresh, snapshot, ttlMsOverride }: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportDetail[]>;
2148
+ getDailyReportDetailById: (reportHubId: number, userId: number, { forceRefresh, snapshot, ttlMsOverride }: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportDetail | null>;
2149
+ getDailyReportDetailByIdByExternalId: (reportHubId: number, externalId: string, options: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportDetail | null>;
2003
2150
  getDraftLabelId: () => Promise<number | null>;
2004
2151
  getAttachmentsByHubIds: (hubIds: number[]) => Promise<Map<number, DailyReportAttachmentSummary[]>>;
2005
- getAttachmentForUser: (attachmentId: number, userId: number) => Promise<{
2152
+ getAttachmentForUser: (attachmentId: number, userId: number, visible: VisibleSourceTypeSet) => Promise<{
2006
2153
  fileName: string;
2007
2154
  filePath: string;
2008
2155
  fileType: string | null;
@@ -2010,10 +2157,10 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
2010
2157
  } | null>;
2011
2158
  markAttachmentMissing: (attachmentId: number) => Promise<void>;
2012
2159
  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>;
2160
+ setStarStatus: (userId: number, reportHubId: number, businessDate: string | null, isStarred: boolean, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<DailyReportUserStatusRow>;
2161
+ setReadStatus: (userId: number, reportHubId: number, businessDate: string | null, isRead: boolean, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<DailyReportUserStatusRow>;
2162
+ addComment: (userId: number, reportHubId: number, content: string, businessDate: string | null, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<DailyReportCommentItem>;
2163
+ deleteComment: (userId: number, reportHubId: number, commentId: number, businessDate: string | null, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<void>;
2017
2164
  createDailyReport: (userId: number, businessDate: string, clientTempId: string) => Promise<DailyReportDetail>;
2018
2165
  updateDailyReport: (reportHubId: number, userId: number, data: {
2019
2166
  title?: string;
@@ -2037,6 +2184,13 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
2037
2184
  sseReader: DailyReportSseReader;
2038
2185
  /** SSE Redis Stream キー。 */
2039
2186
  streamKey: string;
2187
+ /**
2188
+ * 既知の正準 sourceType 集合 (注入した `externalSources` の全 sourceType + `"Internal"`)。
2189
+ *
2190
+ * `resolveVisibleSourceTypes` が返すべき語彙そのものであり、消費側は起動時にこの集合と
2191
+ * 自前のマッピングを突き合わせて誤トークン (無診断で 0 件になる) を検出できる。
2192
+ */
2193
+ knownSourceTypes: readonly string[];
2040
2194
  };
2041
2195
 
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 };
2196
+ 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, type DailyReportVisibilityResolveContext, type DailyReportVisibilityResolveReason, type DailyReportVisibleSourceTypes, type EpochStore, type ExternalReportFields, type RedisStreamMessage, SqlResultCache, type SqlResultCacheQueryOptions, type StreamEntry, type VisibleSourceTypeSet, asciiFallbackFileName, buildVisibleSourceTypeCondition, computeSourceTypeDigest, createDailyReportHandlers, createDailyReportServer, createDailyReportService, createEpochStore, defineDailyReportAuthzResources, defineDailyReportSchema, deniesEverySourceType, encodeRfc8187, formatDateValue, generateETag, isSourceTypeVisible, isStreamIdLte, jsonResponseWithETag, normalizeVisibleSourceTypes, sanitizeMediaType, seedDailyReportAuthzResources, transformJsonArray };
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,95 @@ 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
+ * Computes a stable, bounded, collision-free cache-key digest of the set.
1614
+ * 可視集合から安定・有界・衝突不能なキャッシュキー用ダイジェストを算出する処理。
1615
+ *
1616
+ * 無制限は `"all"`、空集合は `"none"`、それ以外は**畳み込み済みトークンを昇順にそのまま連結**する。
1617
+ * 生連結のため、論理的に等価な集合は必ず同一の、論理的に異なる集合は必ず別のダイジェストになる
1618
+ * (ハッシュ衝突で別権限のキャッシュ行を配信する事故が原理的に起きない)。権限が安定している間は
1619
+ * キーが不変になるため、キャッシュは完全に再利用される (性能無退行)。
1620
+ * 区分数が異常に多い場合だけキー長を抑えるため FNV-1a 32bit へ退避し、`h:` 接頭辞で生連結と区別する。
1621
+ *
1622
+ * @param set Normalized visible set. 正規化済みの可視集合。
1623
+ * @returns Digest usable as a cache-key component. キャッシュキー構成要素として使えるダイジェスト。
1624
+ */
1625
+ declare function computeSourceTypeDigest(set: VisibleSourceTypeSet): string;
1626
+
1493
1627
  /** DailyReportHub の行型。 */
1494
1628
  type DailyReportHubRow = {
1495
1629
  id: number;
@@ -1648,15 +1782,15 @@ declare function createDailyReportService(config: DailyReportServiceConfig): {
1648
1782
  clearCache: () => Promise<void>;
1649
1783
  invalidateHubReadCaches: (hubIds: readonly number[], businessDates: readonly string[]) => Promise<void>;
1650
1784
  getUserIdByExternalId: (externalId: string) => Promise<number | null>;
1651
- getDailyReportIdsByExternalId: (externalId: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportItem[]>;
1652
- getDailyReportIdsFirstPageByExternalId: (externalId: string, limit: number) => Promise<DailyReportItem[]>;
1785
+ getDailyReportIdsByExternalId: (externalId: string, { forceRefresh, snapshot, ttlMsOverride }: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportItem[]>;
1786
+ getDailyReportIdsFirstPageByExternalId: (externalId: string, limit: number, visible: VisibleSourceTypeSet) => Promise<DailyReportItem[]>;
1653
1787
  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>;
1788
+ getDailyReportsByBusinessDateByExternalId: (businessDate: string, externalId: string, { forceRefresh, snapshot, ttlMsOverride }: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportDetail[]>;
1789
+ getDailyReportDetailById: (reportHubId: number, userId: number, { forceRefresh, snapshot, ttlMsOverride }: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportDetail | null>;
1790
+ getDailyReportDetailByIdByExternalId: (reportHubId: number, externalId: string, options: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportDetail | null>;
1657
1791
  getDraftLabelId: () => Promise<number | null>;
1658
1792
  getAttachmentsByHubIds: (hubIds: number[]) => Promise<Map<number, DailyReportAttachmentSummary[]>>;
1659
- getAttachmentForUser: (attachmentId: number, userId: number) => Promise<{
1793
+ getAttachmentForUser: (attachmentId: number, userId: number, visible: VisibleSourceTypeSet) => Promise<{
1660
1794
  fileName: string;
1661
1795
  filePath: string;
1662
1796
  fileType: string | null;
@@ -1664,10 +1798,10 @@ declare function createDailyReportService(config: DailyReportServiceConfig): {
1664
1798
  } | null>;
1665
1799
  markAttachmentMissing: (attachmentId: number) => Promise<void>;
1666
1800
  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>;
1801
+ setStarStatus: (userId: number, reportHubId: number, businessDate: string | null, isStarred: boolean, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<DailyReportUserStatusRow>;
1802
+ setReadStatus: (userId: number, reportHubId: number, businessDate: string | null, isRead: boolean, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<DailyReportUserStatusRow>;
1803
+ addComment: (userId: number, reportHubId: number, content: string, businessDate: string | null, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<DailyReportCommentItem>;
1804
+ deleteComment: (userId: number, reportHubId: number, commentId: number, businessDate: string | null, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<void>;
1671
1805
  createDailyReport: (userId: number, businessDate: string, clientTempId: string) => Promise<DailyReportDetail>;
1672
1806
  updateDailyReport: (reportHubId: number, userId: number, data: {
1673
1807
  title?: string;
@@ -1840,6 +1974,11 @@ declare const asciiFallbackFileName: (name: string) => string;
1840
1974
  type DailyReportHandlersConfig = {
1841
1975
  /** リクエスト認証ポート。 */
1842
1976
  authenticate: DailyReportAuthenticate;
1977
+ /**
1978
+ * 可視 sourceType リゾルバ。未注入なら全件 (現行互換)。
1979
+ * 全データ経路 (一覧 / 詳細 / コメント / 添付 / SSE) に一貫して効き、例外は全拒否として扱う。
1980
+ */
1981
+ resolveVisibleSourceTypes?: DailyReportResolveVisibleSourceTypes;
1843
1982
  /** データアクセスサービス。 */
1844
1983
  service: DailyReportService;
1845
1984
  /** 内部数値 ID の難読化ポート。 */
@@ -1918,6 +2057,14 @@ declare const jsonResponseWithETag: (request: Request, cookie: string | null, pa
1918
2057
  type DailyReportServerConfig = Omit<DailyReportServiceConfig, "cache" | "epochs"> & {
1919
2058
  /** リクエスト認証ポート。 */
1920
2059
  authenticate: DailyReportAuthenticate;
2060
+ /**
2061
+ * 可視 sourceType リゾルバ。未注入なら全件 (現行互換)。
2062
+ *
2063
+ * サーバー側の全データ経路 (一覧 / 詳細 / コメント / 添付 / SSE) に一貫して効く。
2064
+ * 戻り値は `DailyReportHub.sourceType` の値 (`knownSourceTypes` 参照) であり、認可リソースキーではない。
2065
+ * `undefined` / `null` は無制限、空配列は 0 件、例外は全拒否 (fail-close)。
2066
+ */
2067
+ resolveVisibleSourceTypes?: DailyReportResolveVisibleSourceTypes;
1921
2068
  /** 添付ファイル読み取りポート。未注入なら添付エンドポイントは常に 404。 */
1922
2069
  readAttachment?: DailyReportReadAttachment;
1923
2070
  /** 添付ファイルの最大バイト数 (既定 32 MiB)。サービス側のワイヤ上限より低く保つこと。 */
@@ -1994,15 +2141,15 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
1994
2141
  clearCache: () => Promise<void>;
1995
2142
  invalidateHubReadCaches: (hubIds: readonly number[], businessDates: readonly string[]) => Promise<void>;
1996
2143
  getUserIdByExternalId: (externalId: string) => Promise<number | null>;
1997
- getDailyReportIdsByExternalId: (externalId: string, { forceRefresh, snapshot, ttlMsOverride }?: SqlResultCacheQueryOptions) => Promise<DailyReportItem[]>;
1998
- getDailyReportIdsFirstPageByExternalId: (externalId: string, limit: number) => Promise<DailyReportItem[]>;
2144
+ getDailyReportIdsByExternalId: (externalId: string, { forceRefresh, snapshot, ttlMsOverride }: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportItem[]>;
2145
+ getDailyReportIdsFirstPageByExternalId: (externalId: string, limit: number, visible: VisibleSourceTypeSet) => Promise<DailyReportItem[]>;
1999
2146
  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>;
2147
+ getDailyReportsByBusinessDateByExternalId: (businessDate: string, externalId: string, { forceRefresh, snapshot, ttlMsOverride }: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportDetail[]>;
2148
+ getDailyReportDetailById: (reportHubId: number, userId: number, { forceRefresh, snapshot, ttlMsOverride }: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportDetail | null>;
2149
+ getDailyReportDetailByIdByExternalId: (reportHubId: number, externalId: string, options: SqlResultCacheQueryOptions | undefined, visible: VisibleSourceTypeSet) => Promise<DailyReportDetail | null>;
2003
2150
  getDraftLabelId: () => Promise<number | null>;
2004
2151
  getAttachmentsByHubIds: (hubIds: number[]) => Promise<Map<number, DailyReportAttachmentSummary[]>>;
2005
- getAttachmentForUser: (attachmentId: number, userId: number) => Promise<{
2152
+ getAttachmentForUser: (attachmentId: number, userId: number, visible: VisibleSourceTypeSet) => Promise<{
2006
2153
  fileName: string;
2007
2154
  filePath: string;
2008
2155
  fileType: string | null;
@@ -2010,10 +2157,10 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
2010
2157
  } | null>;
2011
2158
  markAttachmentMissing: (attachmentId: number) => Promise<void>;
2012
2159
  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>;
2160
+ setStarStatus: (userId: number, reportHubId: number, businessDate: string | null, isStarred: boolean, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<DailyReportUserStatusRow>;
2161
+ setReadStatus: (userId: number, reportHubId: number, businessDate: string | null, isRead: boolean, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<DailyReportUserStatusRow>;
2162
+ addComment: (userId: number, reportHubId: number, content: string, businessDate: string | null, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<DailyReportCommentItem>;
2163
+ deleteComment: (userId: number, reportHubId: number, commentId: number, businessDate: string | null, clientTempId: string, visible: VisibleSourceTypeSet) => Promise<void>;
2017
2164
  createDailyReport: (userId: number, businessDate: string, clientTempId: string) => Promise<DailyReportDetail>;
2018
2165
  updateDailyReport: (reportHubId: number, userId: number, data: {
2019
2166
  title?: string;
@@ -2037,6 +2184,13 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
2037
2184
  sseReader: DailyReportSseReader;
2038
2185
  /** SSE Redis Stream キー。 */
2039
2186
  streamKey: string;
2187
+ /**
2188
+ * 既知の正準 sourceType 集合 (注入した `externalSources` の全 sourceType + `"Internal"`)。
2189
+ *
2190
+ * `resolveVisibleSourceTypes` が返すべき語彙そのものであり、消費側は起動時にこの集合と
2191
+ * 自前のマッピングを突き合わせて誤トークン (無診断で 0 件になる) を検出できる。
2192
+ */
2193
+ knownSourceTypes: readonly string[];
2040
2194
  };
2041
2195
 
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 };
2196
+ 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, type DailyReportVisibilityResolveContext, type DailyReportVisibilityResolveReason, type DailyReportVisibleSourceTypes, type EpochStore, type ExternalReportFields, type RedisStreamMessage, SqlResultCache, type SqlResultCacheQueryOptions, type StreamEntry, type VisibleSourceTypeSet, asciiFallbackFileName, buildVisibleSourceTypeCondition, computeSourceTypeDigest, createDailyReportHandlers, createDailyReportServer, createDailyReportService, createEpochStore, defineDailyReportAuthzResources, defineDailyReportSchema, deniesEverySourceType, encodeRfc8187, formatDateValue, generateETag, isSourceTypeVisible, isStreamIdLte, jsonResponseWithETag, normalizeVisibleSourceTypes, sanitizeMediaType, seedDailyReportAuthzResources, transformJsonArray };