@zhin.js/plugin-ledger 1.0.4 → 1.0.6

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 凉菜
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -38,6 +38,14 @@ ledger:
38
38
  | `reportTime` | `22:00` | 日报发送时间(`HH:MM`,按 `timezone`) |
39
39
  | `reportWhenEmpty` | `false` | 当天没有记账时是否仍发送日报 |
40
40
 
41
+ ## 分层配置(ADR 0050 / 0055)
42
+
43
+ 启停开关支持全部四个层级。在 Console「功能」区可以按适配器、账号或会话单独停用;上级停用后下级锁定。日报发给订阅者的私聊,私聊的会话层设置只能在 Console 修改。
44
+
45
+ - 日报发送前按订阅者的私聊会话检查开关:已停用的不发送,当天不再补发。
46
+ - `reportWhenEmpty` 可以在适配器、账号、会话层覆盖(`conversationFields`),按订阅者的私聊会话解析。
47
+ - `timezone`、`reportTime` 决定共享的调度时间,只能在全局层修改。
48
+
41
49
  ## 指令
42
50
 
43
51
  以下示例省略 Endpoint 的命令前缀。每条指令也有英文名(括号内),`--help` 显示参数说明。
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAChD,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAE3C,eAAO,MAAM,YAAY;;;;;;;;;;;;;;CAIvB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,YAAY,CAAC,CAAC;AAE9D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC;AAaD,kGAAkG;AAClG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,GAAG,oBAAoB,CAOnG"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAChD,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAE3C,eAAO,MAAM,YAAY;;;;;;;;;;;;;;CAKuF,CAAC;AAEjH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,YAAY,CAAC,CAAC;AAE9D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC;AAaD,kGAAkG;AAClG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,GAAG,oBAAoB,CAOnG"}
package/lib/config.js CHANGED
@@ -2,10 +2,11 @@ import { Schema } from 'zhin.js';
2
2
  export const DEFAULT_TIMEZONE = 'Asia/Shanghai';
3
3
  export const DEFAULT_REPORT_TIME = '22:00';
4
4
  export const ledgerConfig = Schema.object({
5
- timezone: Schema.string().default(DEFAULT_TIMEZONE).description('计算今日、本周(周一开始)、本月与日报日期所用的 IANA 时区').i18n({ "en": { "description": "IANA timezone used to calculate today, this week (starting Monday), this month and daily-report dates." } }).effect('reload'),
6
- reportTime: Schema.string().default(DEFAULT_REPORT_TIME).description('记账日报的发送时间(HH:MM,按 timezone);只发给用「记账日报 开启」订阅的用户').i18n({ "en": { "description": "Daily ledger report time (HH:MM in timezone); sent only to users who explicitly subscribed to daily reports." } }).effect('reload'),
5
+ // ADR 0050 / 0055: timezone and report time drive the shared schedule, so they stay global.
6
+ timezone: Schema.string().default(DEFAULT_TIMEZONE).description('计算今日、本周(周一开始)、本月与日报日期所用的 IANA 时区').i18n({ "en": { "description": "IANA timezone used to calculate today, this week (starting Monday), this month and daily-report dates." } }).effect('reload').fieldLevels(['global']),
7
+ reportTime: Schema.string().default(DEFAULT_REPORT_TIME).description('记账日报的发送时间(HH:MM,按 timezone);只发给用「记账日报 开启」订阅的用户').i18n({ "en": { "description": "Daily ledger report time (HH:MM in timezone); sent only to users who explicitly subscribed to daily reports." } }).effect('reload').fieldLevels(['global']),
7
8
  reportWhenEmpty: Schema.boolean().default(false).description('当天没有记账时是否仍发送日报').i18n({ "en": { "description": "Send a daily report even when no transactions were recorded that day." } }).effect('reload'),
8
- });
9
+ }).featureLevels(['global', 'adapter', 'endpoint', 'conversation'], { conversationFields: ['reportWhenEmpty'] });
9
10
  const REPORT_TIME_PATTERN = /^(?:[01]\d|2[0-3]):[0-5]\d$/u;
10
11
  function assertTimezone(timezone) {
11
12
  try {
package/lib/config.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,CAAC,MAAM,gBAAgB,GAAG,eAAe,CAAC;AAChD,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAO,CAAC;AAE3C,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,WAAW,CAAC,kCAAkC,CAAC,CAAC,IAAI,CAAC,EAAC,IAAI,EAAE,EAAC,aAAa,EAAE,wGAAwG,EAAC,EAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IAC5P,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,WAAW,CAAC,gDAAgD,CAAC,CAAC,IAAI,CAAC,EAAC,IAAI,EAAE,EAAC,aAAa,EAAE,8GAA8G,EAAC,EAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IACrR,eAAe,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAC,IAAI,EAAE,EAAC,aAAa,EAAE,uEAAuE,EAAC,EAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;CACvM,CAAC,CAAC;AAUH,MAAM,mBAAmB,GAAG,8BAA8B,CAAC;AAE3D,SAAS,cAAc,CAAC,QAAgB;IACtC,IAAI,CAAC;QACH,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,QAAQ,CAAC,IAAI,EAAE,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,uBAAuB,CAAC,CAAC;QACxH,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,SAAS,CAAC,8BAA8B,QAAQ,EAAE,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,mBAAmB,CAAC,MAAyC;IAC3E,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,gBAAgB,CAAC;IACtD,MAAM,UAAU,GAAG,MAAM,EAAE,UAAU,IAAI,mBAAmB,CAAC;IAC7D,MAAM,eAAe,GAAG,MAAM,EAAE,eAAe,IAAI,KAAK,CAAC;IACzD,cAAc,CAAC,QAAQ,CAAC,CAAC;IACzB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,2BAA2B,UAAU,EAAE,CAAC,CAAC;IACxG,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;AACnD,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,CAAC,MAAM,gBAAgB,GAAG,eAAe,CAAC;AAChD,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAO,CAAC;AAE3C,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IACxC,4FAA4F;IAC5F,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,WAAW,CAAC,kCAAkC,CAAC,CAAC,IAAI,CAAC,EAAC,IAAI,EAAE,EAAC,aAAa,EAAE,wGAAwG,EAAC,EAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC;IACpR,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,WAAW,CAAC,gDAAgD,CAAC,CAAC,IAAI,CAAC,EAAC,IAAI,EAAE,EAAC,aAAa,EAAE,8GAA8G,EAAC,EAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC7S,eAAe,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAC,IAAI,EAAE,EAAC,aAAa,EAAE,uEAAuE,EAAC,EAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;CACvM,CAAC,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,CAAC,EAAE,EAAE,kBAAkB,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;AAUjH,MAAM,mBAAmB,GAAG,8BAA8B,CAAC;AAE3D,SAAS,cAAc,CAAC,QAAgB;IACtC,IAAI,CAAC;QACH,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,QAAQ,CAAC,IAAI,EAAE,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,uBAAuB,CAAC,CAAC;QACxH,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,SAAS,CAAC,8BAA8B,QAAQ,EAAE,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,mBAAmB,CAAC,MAAyC;IAC3E,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,gBAAgB,CAAC;IACtD,MAAM,UAAU,GAAG,MAAM,EAAE,UAAU,IAAI,mBAAmB,CAAC;IAC7D,MAAM,eAAe,GAAG,MAAM,EAAE,eAAe,IAAI,KAAK,CAAC;IACzD,cAAc,CAAC,QAAQ,CAAC,CAAC;IACzB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,2BAA2B,UAAU,EAAE,CAAC,CAAC;IACxG,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;AACnD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAalD,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,gBAAgB,CA0BhF"}
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAalD,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,gBAAgB,CA4BhF"}
package/lib/console.js CHANGED
@@ -11,6 +11,8 @@ function resolveService(provided, call) {
11
11
  }
12
12
  export function createLedgerConsoleRpc(service) {
13
13
  const rpc = definePluginConsoleRpc({
14
+ // Day-to-day edits belong to operators; `:write` would otherwise infer `manage` (ADR 0049).
15
+ permissions: [{ id: 'ledger:write', level: 'operate', description: '记账' }],
14
16
  status: {
15
17
  page: 'index',
16
18
  requiredPermissions: ['ledger:read'],
@@ -1 +1 @@
1
- {"version":3,"file":"console.js","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GAGtB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGlD,SAAS,cAAc,CACrB,QAAmC,EACnC,IAA0B;IAE1B,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,cAAc,GAAG,IAAI,CAAC,OAAoF,CAAC;IACjH,MAAM,WAAW,GAAG,cAAc,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,CAAC;IAC9D,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IACpC,MAAM,IAAI,qBAAqB,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAuB;IAC5D,MAAM,GAAG,GAAG,sBAAsB,CAAC;QACjC,MAAM,EAAE;YACN,IAAI,EAAE,OAAO;YACb,mBAAmB,EAAE,CAAC,aAAa,CAAC;YACpC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI;gBACxB,OAAO,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,kBAAkB,EAAE,CAAC;YAC5D,CAAC;SACF;QACD,OAAO,EAAE;YACP,mBAAmB,EAAE;gBACnB,IAAI,EAAE,OAAO;gBACb,mBAAmB,EAAE,CAAC,cAAc,CAAC;gBACrC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI;oBACxB,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,eAAe,EAAE,CAAC;oBACnE,OAAO,EAAE,IAAI,EAAE,CAAC;gBAClB,CAAC;aACF;SACF;KACF,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,GAAG,CAAC,OAAsE,CAAC;IAC3F,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,KAAK,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClG,OAAO,CAAC,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,KAAK,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClG,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"console.js","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GAGtB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGlD,SAAS,cAAc,CACrB,QAAmC,EACnC,IAA0B;IAE1B,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,cAAc,GAAG,IAAI,CAAC,OAAoF,CAAC;IACjH,MAAM,WAAW,GAAG,cAAc,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,CAAC;IAC9D,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IACpC,MAAM,IAAI,qBAAqB,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAuB;IAC5D,MAAM,GAAG,GAAG,sBAAsB,CAAC;QACjC,4FAA4F;QAC5F,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QAC1E,MAAM,EAAE;YACN,IAAI,EAAE,OAAO;YACb,mBAAmB,EAAE,CAAC,aAAa,CAAC;YACpC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI;gBACxB,OAAO,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,kBAAkB,EAAE,CAAC;YAC5D,CAAC;SACF;QACD,OAAO,EAAE;YACP,mBAAmB,EAAE;gBACnB,IAAI,EAAE,OAAO;gBACb,mBAAmB,EAAE,CAAC,cAAc,CAAC;gBACrC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI;oBACxB,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,eAAe,EAAE,CAAC;oBACnE,OAAO,EAAE,IAAI,EAAE,CAAC;gBAClB,CAAC;aACF;SACF;KACF,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,GAAG,CAAC,OAAsE,CAAC;IAC3F,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,KAAK,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClG,OAAO,CAAC,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,KAAK,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClG,OAAO,GAAG,CAAC;AACb,CAAC"}
package/lib/service.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type OutboundHost, type PluginDatabaseHost } from 'zhin.js';
1
+ import { type DeliveryTarget, type OutboundHost, type PluginDatabaseHost } from 'zhin.js';
2
2
  import type { ResolvedLedgerConfig } from './config.js';
3
3
  import type { LedgerCaller } from './identity.js';
4
4
  import { type LedgerPeriod } from './period.js';
@@ -18,6 +18,12 @@ export type LedgerConsoleSnapshot = {
18
18
  export interface LedgerServiceOptions {
19
19
  /** Wall clock; tests pass a fake. */
20
20
  readonly now?: () => number;
21
+ /**
22
+ * Layered feature view (ADR 0050 / 0055). Daily reports are not messages, so the service asks
23
+ * whether ledger is on for each subscriber's private conversation and reads `reportWhenEmpty` there.
24
+ */
25
+ readonly isEnabledFor?: (target: DeliveryTarget) => boolean;
26
+ readonly reportWhenEmptyFor?: (target: DeliveryTarget) => boolean;
21
27
  }
22
28
  /**
23
29
  * Personal expense ledger. Every operation is scoped to the caller's own `ownerKey`.
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkC,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACrG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAuD,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAYrG,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,KAAK,GAAG,QAAQ,CAAC;AAExD,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC1D,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,qCAAqC;IACrC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,qBAAa,aAAa;;gBAUZ,QAAQ,EAAE,kBAAkB,EAAE,QAAQ,EAAE,YAAY,GAAG,SAAS,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,GAAE,oBAAyB;IAwCxI,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAsB7D,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiB/D,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAM1E,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAM/E,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IA8BxE,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA2BzG;;;;OAIG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IAwBlC,kBAAkB,IAAI,OAAO,CAAC,qBAAqB,CAAC;CAc3D"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACrG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAuD,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAYrG,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,KAAK,GAAG,QAAQ,CAAC;AAExD,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC1D,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,qCAAqC;IACrC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC;IAC5D,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC;CACnE;AAED;;;;;;GAMG;AACH,qBAAa,aAAa;;gBAYZ,QAAQ,EAAE,kBAAkB,EAAE,QAAQ,EAAE,YAAY,GAAG,SAAS,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,GAAE,oBAAyB;IA0CxI,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAsB7D,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiB/D,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAM1E,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAM/E,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAkCxE,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA2BzG;;;;OAIG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IAyBlC,kBAAkB,IAAI,OAAO,CAAC,qBAAqB,CAAC;CAc3D"}
package/lib/service.js CHANGED
@@ -19,6 +19,8 @@ export class LedgerService {
19
19
  #outbound;
20
20
  #config;
21
21
  #now;
22
+ #enabledFor;
23
+ #reportWhenEmptyFor;
22
24
  /** Serialises writes per user so two quick `记` commands never share an `#id`. */
23
25
  #userQueues = new Map();
24
26
  /** Private targets already saved this process, to skip redundant writes. */
@@ -28,6 +30,8 @@ export class LedgerService {
28
30
  this.#outbound = outbound;
29
31
  this.#config = config;
30
32
  this.#now = options.now ?? (() => Date.now());
33
+ this.#enabledFor = options.isEnabledFor ?? (() => true);
34
+ this.#reportWhenEmptyFor = options.reportWhenEmptyFor ?? (() => config.reportWhenEmpty);
31
35
  }
32
36
  #withUserLock(ownerKey, operation) {
33
37
  const previous = this.#userQueues.get(ownerKey) ?? Promise.resolve();
@@ -135,7 +139,12 @@ export class LedgerService {
135
139
  if (!sendTarget)
136
140
  return false;
137
141
  try {
138
- await sendTarget.call(this.#outbound, await this.#privateTargetOf(caller), content, { locale: resolveLocale(caller.locale) });
142
+ const target = await this.#privateTargetOf(caller);
143
+ // ADR 0050 / 0055: a push to the caller's private chat is not a message there, so the
144
+ // dispatch gate never sees it; a switched-off private conversation gets the masked reply.
145
+ if (!this.#enabledFor(target))
146
+ return false;
147
+ await sendTarget.call(this.#outbound, target, content, { locale: resolveLocale(caller.locale) });
139
148
  return true;
140
149
  }
141
150
  catch (error) {
@@ -191,8 +200,10 @@ export class LedgerService {
191
200
  await this.#store.markReported(subscriber.ownerKey, today);
192
201
  if (!subscriber.reportTarget || !this.#outbound?.sendTarget)
193
202
  continue;
203
+ if (!this.#enabledFor(subscriber.reportTarget))
204
+ continue;
194
205
  const entries = await this.#entriesIn(subscriber.ownerKey, 'today');
195
- if (entries.length === 0 && !this.#config.reportWhenEmpty)
206
+ if (entries.length === 0 && !this.#reportWhenEmptyFor(subscriber.reportTarget))
196
207
  continue;
197
208
  const summary = formatPeriodSummary(summarize(entries, 'today', nowMs, timezone, subscriber.reportLocale), subscriber.reportLocale);
198
209
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/plugin-ledger",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Personal expense ledger for Zhin.js (Plugin Runtime): per-user entries in integer cents, period and category summaries, group privacy and an opt-in daily report",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -37,19 +37,19 @@
37
37
  "url": "https://github.com/lc-cn"
38
38
  },
39
39
  "dependencies": {
40
- "@zhin.js/console-contract": "1.1.4",
41
- "@zhin.js/page": "1.1.16",
42
- "@zhin.js/skill": "1.1.15",
43
- "@zhin.js/tool": "1.1.17"
40
+ "zod": "^4.6.7",
41
+ "@zhin.js/console-contract": "1.1.6",
42
+ "@zhin.js/page": "1.1.18",
43
+ "@zhin.js/skill": "1.1.17",
44
+ "@zhin.js/tool": "1.1.19"
44
45
  },
45
46
  "peerDependencies": {
46
- "zod": "^4.0.0",
47
- "zhin.js": "^1.1.23",
48
- "@zhin.js/command": "^1.1.16",
49
- "@zhin.js/page": "^1.1.16",
50
- "@zhin.js/schedule-feature": "^1.1.14",
51
- "@zhin.js/skill": "^1.1.15",
52
- "@zhin.js/tool": "^1.1.17"
47
+ "zhin.js": "^1.1.26",
48
+ "@zhin.js/command": "^1.2.0",
49
+ "@zhin.js/page": "^1.1.18",
50
+ "@zhin.js/schedule-feature": "^1.1.16",
51
+ "@zhin.js/skill": "^1.1.17",
52
+ "@zhin.js/tool": "^1.1.19"
53
53
  },
54
54
  "peerDependenciesMeta": {
55
55
  "@zhin.js/command": {
@@ -57,18 +57,14 @@
57
57
  },
58
58
  "@zhin.js/schedule-feature": {
59
59
  "optional": true
60
- },
61
- "zod": {
62
- "optional": true
63
60
  }
64
61
  },
65
62
  "devDependencies": {
66
63
  "typescript": "^6.0.3",
67
64
  "vitest": "^4.1.10",
68
- "zod": "^4.4.3",
69
- "@zhin.js/schedule-feature": "1.1.14",
70
- "@zhin.js/testing": "1.0.9",
71
- "zhin.js": "1.1.23"
65
+ "@zhin.js/schedule-feature": "1.1.16",
66
+ "@zhin.js/testing": "1.0.10",
67
+ "zhin.js": "1.1.26"
72
68
  },
73
69
  "engines": {
74
70
  "node": ">=22.19.0"
@@ -115,6 +111,7 @@
115
111
  },
116
112
  "scripts": {
117
113
  "build": "tsc",
114
+ "clean": "rimraf lib",
118
115
  "check": "tsc -p tsconfig.check.json",
119
116
  "test": "vitest run --root ../../.. plugins/utils/ledger/tests"
120
117
  }
@@ -52,10 +52,19 @@ export default createDeclarativePage({
52
52
  {
53
53
  id: 'config',
54
54
  title: { zh: '配置详情', en: 'Configuration' },
55
- entries: (data) => [
56
- { label: 'Timezone', value: data.timezone },
57
- { label: 'Report Time', value: data.reportTime },
58
- { label: 'Report When Empty', value: data.reportWhenEmpty ? 'Yes' : 'No' },
55
+ entries: [
56
+ { label: 'Timezone', dataKey: 'timezone' },
57
+ { label: 'Report Time', dataKey: 'reportTime' },
58
+ {
59
+ label: 'Report When Empty',
60
+ value: {
61
+ $map: {
62
+ path: 'reportWhenEmpty',
63
+ cases: { true: 'Yes', false: 'No' },
64
+ default: 'No',
65
+ },
66
+ },
67
+ },
59
68
  ],
60
69
  },
61
70
  ],
@@ -54,10 +54,19 @@ export default createDeclarativePage<LedgerConsoleSnapshot>({
54
54
  {
55
55
  id: 'config',
56
56
  title: { zh: '配置详情', en: 'Configuration' },
57
- entries: (data) => [
58
- { label: 'Timezone', value: data.timezone },
59
- { label: 'Report Time', value: data.reportTime },
60
- { label: 'Report When Empty', value: data.reportWhenEmpty ? 'Yes' : 'No' },
57
+ entries: [
58
+ { label: 'Timezone', dataKey: 'timezone' },
59
+ { label: 'Report Time', dataKey: 'reportTime' },
60
+ {
61
+ label: 'Report When Empty',
62
+ value: {
63
+ $map: {
64
+ path: 'reportWhenEmpty',
65
+ cases: { true: 'Yes', false: 'No' },
66
+ default: 'No',
67
+ },
68
+ },
69
+ },
61
70
  ],
62
71
  },
63
72
  ],
package/plugin.js CHANGED
@@ -25,7 +25,12 @@ export default definePlugin({
25
25
  ],
26
26
  schedules: ['daily-report'],
27
27
  skills: ['ledger'],
28
- tools: ['ledger_add', 'ledger_delete', 'ledger_list', 'ledger_summary'],
28
+ tools: [
29
+ 'skill/ledger/ledger_add',
30
+ 'skill/ledger/ledger_delete',
31
+ 'skill/ledger/ledger_list',
32
+ 'skill/ledger/ledger_summary',
33
+ ],
29
34
  pages: ['index'],
30
35
  },
31
36
  }),
@@ -34,7 +39,11 @@ export default definePlugin({
34
39
  const database = context.resources.use(databaseHostToken);
35
40
  defineLedgerTables(database);
36
41
  const outbound = context.resources.has(outboundHostToken) ? context.resources.use(outboundHostToken) : undefined;
37
- const service = ledgerServiceStore.provide(context, new LedgerService(database, outbound, config));
42
+ const service = ledgerServiceStore.provide(context, new LedgerService(database, outbound, config, {
43
+ // ADR 0050 / 0055: switch and `reportWhenEmpty` resolved for each subscriber's private conversation.
44
+ isEnabledFor: target => context.isEnabledFor({ conversation: target }),
45
+ reportWhenEmptyFor: target => context.configFor({ conversation: target }).reportWhenEmpty ?? config.reportWhenEmpty,
46
+ }));
38
47
  return {
39
48
  consoleRpc: createLedgerConsoleRpc(service),
40
49
  };
package/schema.json CHANGED
@@ -1,13 +1,27 @@
1
1
  {
2
2
  "type": "object",
3
3
  "additionalProperties": false,
4
+ "x-zhin-config": {
5
+ "levels": [
6
+ "global",
7
+ "adapter",
8
+ "endpoint",
9
+ "conversation"
10
+ ],
11
+ "conversationFields": [
12
+ "reportWhenEmpty"
13
+ ]
14
+ },
4
15
  "properties": {
5
16
  "timezone": {
6
17
  "type": "string",
7
18
  "description": "计算今日、本周(周一开始)、本月与日报日期所用的 IANA 时区",
8
19
  "default": "Asia/Shanghai",
9
20
  "x-zhin-config": {
10
- "effect": "reload"
21
+ "effect": "reload",
22
+ "levels": [
23
+ "global"
24
+ ]
11
25
  },
12
26
  "x-i18n": {
13
27
  "en": {
@@ -21,7 +35,10 @@
21
35
  "default": "22:00",
22
36
  "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d$",
23
37
  "x-zhin-config": {
24
- "effect": "reload"
38
+ "effect": "reload",
39
+ "levels": [
40
+ "global"
41
+ ]
25
42
  },
26
43
  "x-i18n": {
27
44
  "en": {
package/src/config.ts CHANGED
@@ -4,10 +4,11 @@ export const DEFAULT_TIMEZONE = 'Asia/Shanghai';
4
4
  export const DEFAULT_REPORT_TIME = '22:00';
5
5
 
6
6
  export const ledgerConfig = Schema.object({
7
- timezone: Schema.string().default(DEFAULT_TIMEZONE).description('计算今日、本周(周一开始)、本月与日报日期所用的 IANA 时区').i18n({"en": {"description": "IANA timezone used to calculate today, this week (starting Monday), this month and daily-report dates."}}).effect('reload'),
8
- reportTime: Schema.string().default(DEFAULT_REPORT_TIME).description('记账日报的发送时间(HH:MM,按 timezone);只发给用「记账日报 开启」订阅的用户').i18n({"en": {"description": "Daily ledger report time (HH:MM in timezone); sent only to users who explicitly subscribed to daily reports."}}).effect('reload'),
7
+ // ADR 0050 / 0055: timezone and report time drive the shared schedule, so they stay global.
8
+ timezone: Schema.string().default(DEFAULT_TIMEZONE).description('计算今日、本周(周一开始)、本月与日报日期所用的 IANA 时区').i18n({"en": {"description": "IANA timezone used to calculate today, this week (starting Monday), this month and daily-report dates."}}).effect('reload').fieldLevels(['global']),
9
+ reportTime: Schema.string().default(DEFAULT_REPORT_TIME).description('记账日报的发送时间(HH:MM,按 timezone);只发给用「记账日报 开启」订阅的用户').i18n({"en": {"description": "Daily ledger report time (HH:MM in timezone); sent only to users who explicitly subscribed to daily reports."}}).effect('reload').fieldLevels(['global']),
9
10
  reportWhenEmpty: Schema.boolean().default(false).description('当天没有记账时是否仍发送日报').i18n({"en": {"description": "Send a daily report even when no transactions were recorded that day."}}).effect('reload'),
10
- });
11
+ }).featureLevels(['global', 'adapter', 'endpoint', 'conversation'], { conversationFields: ['reportWhenEmpty'] });
11
12
 
12
13
  export type LedgerConfig = Schema.Output<typeof ledgerConfig>;
13
14
 
package/src/console.ts CHANGED
@@ -20,6 +20,8 @@ function resolveService(
20
20
 
21
21
  export function createLedgerConsoleRpc(service?: LedgerService): PluginConsoleRpc {
22
22
  const rpc = definePluginConsoleRpc({
23
+ // Day-to-day edits belong to operators; `:write` would otherwise infer `manage` (ADR 0049).
24
+ permissions: [{ id: 'ledger:write', level: 'operate', description: '记账' }],
23
25
  status: {
24
26
  page: 'index',
25
27
  requiredPermissions: ['ledger:read'],
package/src/service.ts CHANGED
@@ -36,6 +36,12 @@ export type LedgerConsoleSnapshot = {
36
36
  export interface LedgerServiceOptions {
37
37
  /** Wall clock; tests pass a fake. */
38
38
  readonly now?: () => number;
39
+ /**
40
+ * Layered feature view (ADR 0050 / 0055). Daily reports are not messages, so the service asks
41
+ * whether ledger is on for each subscriber's private conversation and reads `reportWhenEmpty` there.
42
+ */
43
+ readonly isEnabledFor?: (target: DeliveryTarget) => boolean;
44
+ readonly reportWhenEmptyFor?: (target: DeliveryTarget) => boolean;
39
45
  }
40
46
 
41
47
  /**
@@ -50,6 +56,8 @@ export class LedgerService {
50
56
  readonly #outbound: OutboundHost | undefined;
51
57
  readonly #config: ResolvedLedgerConfig;
52
58
  readonly #now: () => number;
59
+ readonly #enabledFor: (target: DeliveryTarget) => boolean;
60
+ readonly #reportWhenEmptyFor: (target: DeliveryTarget) => boolean;
53
61
  /** Serialises writes per user so two quick `记` commands never share an `#id`. */
54
62
  readonly #userQueues = new Map<string, Promise<unknown>>();
55
63
  /** Private targets already saved this process, to skip redundant writes. */
@@ -60,6 +68,8 @@ export class LedgerService {
60
68
  this.#outbound = outbound;
61
69
  this.#config = config;
62
70
  this.#now = options.now ?? (() => Date.now());
71
+ this.#enabledFor = options.isEnabledFor ?? (() => true);
72
+ this.#reportWhenEmptyFor = options.reportWhenEmptyFor ?? (() => config.reportWhenEmpty);
63
73
  }
64
74
 
65
75
  #withUserLock<T>(ownerKey: string, operation: () => Promise<T>): Promise<T> {
@@ -168,7 +178,11 @@ export class LedgerService {
168
178
  const sendTarget = this.#outbound?.sendTarget;
169
179
  if (!sendTarget) return false;
170
180
  try {
171
- await sendTarget.call(this.#outbound, await this.#privateTargetOf(caller), content, { locale: resolveLocale(caller.locale) });
181
+ const target = await this.#privateTargetOf(caller);
182
+ // ADR 0050 / 0055: a push to the caller's private chat is not a message there, so the
183
+ // dispatch gate never sees it; a switched-off private conversation gets the masked reply.
184
+ if (!this.#enabledFor(target)) return false;
185
+ await sendTarget.call(this.#outbound, target, content, { locale: resolveLocale(caller.locale) });
172
186
  return true;
173
187
  } catch (error) {
174
188
  logger.debug(`private delivery unavailable: ${error instanceof Error ? error.message : String(error)}`);
@@ -219,8 +233,9 @@ export class LedgerService {
219
233
  if (subscriber.lastReportDate === today) continue;
220
234
  await this.#store.markReported(subscriber.ownerKey, today);
221
235
  if (!subscriber.reportTarget || !this.#outbound?.sendTarget) continue;
236
+ if (!this.#enabledFor(subscriber.reportTarget)) continue;
222
237
  const entries = await this.#entriesIn(subscriber.ownerKey, 'today');
223
- if (entries.length === 0 && !this.#config.reportWhenEmpty) continue;
238
+ if (entries.length === 0 && !this.#reportWhenEmptyFor(subscriber.reportTarget)) continue;
224
239
  const summary = formatPeriodSummary(summarize(entries, 'today', nowMs, timezone, subscriber.reportLocale), subscriber.reportLocale);
225
240
  try {
226
241
  await this.#outbound.sendTarget(subscriber.reportTarget, t(subscriber.reportLocale, 'report', { text: summary.full }), { locale: resolveLocale(subscriber.reportLocale) });