@aiquants/daily-report 0.45.0 → 0.46.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/README.md +18 -7
- package/dist/client.js +5 -5
- package/dist/client.mjs +5 -5
- package/dist/server.d.mts +9 -3
- package/dist/server.d.ts +9 -3
- package/dist/server.js +11 -11
- package/dist/server.mjs +11 -11
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@aiquants/daily-report` are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.46.1 (2026-10-16)
|
|
6
|
+
|
|
7
|
+
版番号は 0.46.1 (patch) とする: 公開の型は変えず、外部ソースの日報へ誤って書き込む経路を閉じる。
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **外部ソースの日報は、持ち主でも変えられない**: 編集と削除の入口 (DetailList のカードと List の側面ペインのボタン、ダブルクリック) と下書きの
|
|
12
|
+
自動の編集は、閲覧者が持ち主かどうかだけで出ていた。そのため外部ソースの日報 (ホストの `externalSources` のアダプタが外部の表から読む日報) の
|
|
13
|
+
持ち主にも出ていた。保存すると件名だけが hub に書かれて外部の表と食い違い、本文は内部の表に行が無いので何も書かれないまま成功を答えた
|
|
14
|
+
(画面は保存の直後だけ新しい本文を見せ、読み直すと元の本文に戻る)。削除と公開も hub に書けた。
|
|
15
|
+
今は、入口と下書きの自動の編集を、パッケージ自身の区分 (`Internal`。字面のまま比べる) の持ち主の日報にだけ出す。サーバーの更新・公開・削除は、
|
|
16
|
+
外部ソースの日報を持ち主を比べる前に断り (action は 403 `{"error":"Reports from this source are read-only"}`、サービスは `Forbidden`)、
|
|
17
|
+
何も書かず知らせない。区分の判定は 1 つの関数 (`isMutableDailyReportSource`) にあり、サーバーの関門とクライアントの入口が同じものを読む。
|
|
18
|
+
ホストへの影響: サービスの `updateDailyReport`・`publishDailyReport`・`deleteDailyReport` を外部ソースの日報で呼んでいた所は `Forbidden` を受ける
|
|
19
|
+
(どれも書き込みが外部の表と食い違う経路だった)。
|
|
20
|
+
|
|
21
|
+
## 0.46.0 (2026-10-16)
|
|
22
|
+
|
|
23
|
+
版番号は 0.46.0 (minor) とする: 設定の `streamKey` と公開の `buildDailyReportSseStreamKey` を置き換える (下の Breaking)。
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **Redis のキーは 1 つの接頭辞から組む**: SSE のストリームとワーカーをまたぐ 3 種の epoch (ID の一覧・営業日・詳細) のキーを、サービスの設定
|
|
28
|
+
`redisKeyPrefix` (既定 `daily-report`) から組む (`<接頭辞>:sse-stream:v4`・`<接頭辞>:ids:epoch`・`<接頭辞>:date-epoch:<営業日>`・
|
|
29
|
+
`<接頭辞>:detail-epoch:<日報の ID>`)。epoch のキーは固定の名前だったので、同じ Redis を使う環境 (開発と本番など) は、ストリームのキーを分けても
|
|
30
|
+
互いのキャッシュを無効にし合った。環境ごとに接頭辞を 1 つ渡せば、知らせも epoch も重ならない。既定の接頭辞のキーは 0.45.0 と字面まで同じ。
|
|
31
|
+
|
|
32
|
+
### Breaking
|
|
33
|
+
|
|
34
|
+
- **設定の `streamKey` は `redisKeyPrefix` に置き換わる**: 設定に `streamKey` があると、値によらず生成のときに `TypeError`
|
|
35
|
+
(`[daily-report] redisKeyPrefix must be given in place of the removed key streamKey`) で止まる。接頭辞は空白も制御文字も含まない 1 文字以上で、`:` で
|
|
36
|
+
始まらず終わらないもの。ほかの値は `RangeError` (`[daily-report] redisKeyPrefix must be a Redis key prefix of …; got <値>`) で止まる。
|
|
37
|
+
Migration: `streamKey` に基のキーを渡していたホストは、環境を見分ける名前を `redisKeyPrefix` に渡す (ストリームは `<接頭辞>:sse-stream:v4` になり、
|
|
38
|
+
前の `<基のキー>:v4` のストリームは書かれなくなって手で消せる)。既定のまま使っていたホストは何も変えなくてよい。
|
|
39
|
+
- **公開の `buildDailyReportSseStreamKey(streamKey)` は `buildDailyReportRedisKeys(redisKeyPrefix)` に置き換わる**: 接頭辞の下のどのキーも返す
|
|
40
|
+
(`DailyReportRedisKeys`: `sseStream`・`idsEpoch`・`dateEpochPrefix`・`detailEpochPrefix`)。
|
|
41
|
+
Migration: `buildDailyReportSseStreamKey(base)` は `buildDailyReportRedisKeys(prefix).sseStream` に替え、epoch を直に読み書きする試験は返したキーを使う。
|
|
42
|
+
|
|
5
43
|
## 0.45.0 (2026-10-16)
|
|
6
44
|
|
|
7
45
|
版番号は 0.45.0 (minor) とする: ピアの `@aiquants/swipe-overlay` の下限を上げる (下の Breaking)。
|
package/README.md
CHANGED
|
@@ -526,7 +526,10 @@ its payload — with one strict parser each, after authentication and before any
|
|
|
526
526
|
`{"error":"Report visibility is unavailable"}` with `Retry-After: 5` and `Cache-Control: no-store`, before the internal user lookup and any intent.
|
|
527
527
|
Then the internal user (`User not found`, 404). A `create` whose scope does not show the package's own source type (`Internal`) is 403
|
|
528
528
|
`{"error":"Creating reports is restricted"}` before any query; the other intents answer a report the scope hides as 404 (**Where it applies** in
|
|
529
|
-
[Source-type visibility](#source-type-visibility)).
|
|
529
|
+
[Source-type visibility](#source-type-visibility)). An `update`, `publish` or `delete` of a report the scope shows but of an external source (any
|
|
530
|
+
source type other than the package's own `Internal`, compared exactly) is 403 `{"error":"Reports from this source are read-only"}` before the owner
|
|
531
|
+
is compared and before any write: the package writes only the reports it stores itself, and its client draws the edit and delete entrances and a
|
|
532
|
+
draft's automatic editor only for the viewer's own `Internal` reports.
|
|
530
533
|
- **One wire contract for the action and the JSON endpoints**, which the server, the package's client and a host that calls the routes itself all read
|
|
531
534
|
from the shared entry (`@aiquants/daily-report`; neither side restates a name):
|
|
532
535
|
- the intents (`DAILY_REPORT_ACTION_INTENTS` and their type `DailyReportActionIntent`, from which the server's form reading and the client's
|
|
@@ -605,7 +608,7 @@ its payload — with one strict parser each, after authentication and before any
|
|
|
605
608
|
shared draft-label test, beside the hub row) or true when its creation category is one of the names; a row whose flag reads as anything but 1 or 0
|
|
606
609
|
throws.
|
|
607
610
|
The client compares no name: the views open the viewer's own draft in the editor by `isDraft` alone, so a draft named by any of the names, or by a
|
|
608
|
-
variant the collation equates, behaves as one ([Client wiring](#client-wiring)). The SSE stream's key carries the wire version (`<
|
|
611
|
+
variant the collation equates, behaves as one ([Client wiring](#client-wiring)). The SSE stream's key carries the wire version (`<redisKeyPrefix>:sse-stream:v4`; [Realtime architecture](#realtime-architecture)),
|
|
609
612
|
so an entry written before `isDraft` existed is never read.
|
|
610
613
|
- `resolveVisibleSourceTypes(request, { reason })` — **Required row-level authorization port.** Returns the `Hub.source_type` values this request may
|
|
611
614
|
view, or the explicit opt-out `{ unrestricted: "<reason>" }` of a deployment that does not restrict by source type. Applies uniformly to every server
|
|
@@ -665,11 +668,18 @@ its payload — with one strict parser each, after authentication and before any
|
|
|
665
668
|
The JSON answers themselves write nothing, and no line carries a request header's value or traces an answer given before the endpoint (the 401, 404
|
|
666
669
|
and 405), so a client decides neither the number nor the size of the lines.
|
|
667
670
|
- Primary tuning parameters: `idsTtlMs` (180 s) / `businessDateTtlMs` (300 s) / `cacheDefaultTtlMs` (60 s) / `cacheMaxBuckets` (4,096) /
|
|
668
|
-
`cacheMaxBytes` (512 MiB per process; both **The SQL result cache** in [The API route](#the-api-route)) / `
|
|
671
|
+
`cacheMaxBytes` (512 MiB per process; both **The SQL result cache** in [The API route](#the-api-route)) / `streamMaxLen` (10,000
|
|
669
672
|
entries); the attachment tuning lives in the `attachments` block ([Attachments](#attachments)).
|
|
670
673
|
Every number among them is an integer of at least 1, and only an omitted one takes its default: `0`, a negative number, `NaN`, a fraction or 2^53
|
|
671
674
|
stops `createDailyReportService` and `createDailyReportServer` with a `RangeError` that names the key
|
|
672
675
|
(`[daily-report] idsTtlMs must be an integer >= 1; got 0`).
|
|
676
|
+
- `redisKeyPrefix` (`daily-report` by default) — the prefix of every Redis key of the service: the SSE stream `<prefix>:sse-stream:v4` and the
|
|
677
|
+
cross-worker epochs `<prefix>:ids:epoch`, `<prefix>:date-epoch:<business date>` and `<prefix>:detail-epoch:<report id>`. Environments that share
|
|
678
|
+
one Redis (development and production, say) each pass their own prefix, so that neither reads the other's notifications nor drops the other's
|
|
679
|
+
cached reads. The prefix is one or more characters without whitespace or control characters, neither
|
|
680
|
+
starting nor ending with `:`, and only an omitted one takes the default: any other value stops `createDailyReportService` and
|
|
681
|
+
`createDailyReportServer` with a `RangeError` (`[daily-report] redisKeyPrefix must be a Redis key prefix of …; got ""`), and a configuration that
|
|
682
|
+
carries `streamKey` stops with a `TypeError` that names `redisKeyPrefix` instead.
|
|
673
683
|
|
|
674
684
|
#### Configuration errors
|
|
675
685
|
|
|
@@ -1637,10 +1647,10 @@ and without the retry the victim would answer 500 and lose what it wrote.
|
|
|
1637
1647
|
|
|
1638
1648
|
### Realtime architecture
|
|
1639
1649
|
|
|
1640
|
-
1. Mutation services publish to Redis Stream (`<
|
|
1650
|
+
1. Mutation services publish to Redis Stream (`<redisKeyPrefix>:sse-stream:v4`, `daily-report:sse-stream:v4` by default: the key carries the wire version of the
|
|
1641
1651
|
stream's messages and their embedded report, so a deployment that changes a required key of them reads no entry an older version wrote, and the stream of the previous version
|
|
1642
1652
|
stops growing and can be deleted by hand; a host that reads or writes the stream itself, such as an integration test, builds the key with the
|
|
1643
|
-
server entry's `
|
|
1653
|
+
server entry's `buildDailyReportRedisKeys(redisKeyPrefix).sseStream` instead of restating the version) in sequence:
|
|
1644
1654
|
`invalidate -> epoch increment -> SSE publish`.
|
|
1645
1655
|
2. `DailyReportSseReader` uses a single blocking `xRead` loop to fan-out events to all SSE connections (eliminating per-connection Redis TCP
|
|
1646
1656
|
connections). `createDailyReportServer` creates it; `createDailyReportHandlers` takes the reader as `sseReader` typed by the port
|
|
@@ -4596,8 +4606,9 @@ Documenting a name here is no reason to export it, and the values that tune the
|
|
|
4596
4606
|
`DAILY_REPORT_SHARP_THUMBNAIL_DECODE_BUDGET_BYTES` / `DAILY_REPORT_SHARP_THUMBNAIL_DECODE_WORK_MODEL` (the render deadline `renderMs` and the
|
|
4597
4607
|
decode-work and walk bounds, for a host's conformance checks) / `DAILY_REPORT_ATTACHMENT_THUMBNAIL_OUTPUT_MEDIA_TYPES` /
|
|
4598
4608
|
`DAILY_REPORT_ATTACHMENT_THUMBNAIL_MAX_OUTPUT_BYTES`.
|
|
4599
|
-
- SSE and caching: `
|
|
4600
|
-
with the wire version
|
|
4609
|
+
- SSE and caching: `buildDailyReportRedisKeys(redisKeyPrefix)` (`DailyReportRedisKeys`: the keys the service builds under the prefix, the SSE
|
|
4610
|
+
stream `sseStream` with the wire version, `<prefix>:sse-stream:v4`, and the epoch keys `idsEpoch`, `dateEpochPrefix` and `detailEpochPrefix`,
|
|
4611
|
+
for a host that reads or writes the stream or the epochs itself) / `DailyReportSseReader` /
|
|
4601
4612
|
`readDailyReportSseStreamEntry(raw, logger)` (reads one Redis stream entry, `{ id, message }` as the client returns it, once: `{ entry, json }`,
|
|
4602
4613
|
the frozen `StreamEntry` the shared reader hands every subscriber and the entry's parsed JSON value; for a host whose own reader keeps the same
|
|
4603
4614
|
contract) /
|