@xinhehuimeng/cli 0.2.0 → 0.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xinhehuimeng/cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "心河 OA 客户端 CLI(Node 版):多维表格 / 应用 / 权限的唯一命令行入口",
5
5
  "keywords": [
6
6
  "xinhe-oa",
@@ -11,19 +11,9 @@
11
11
  //
12
12
  // ## 为什么 `report rule --create` 会顺手开当期(服务端行为,CLI 只如实带出)
13
13
  //
14
- // 开窗原本只有服务端 `report_tick`(cron)能做,而部署面没有任何调度配置 ——
15
- // 症状是"规则建好了、命令全返回成功,但 `report --due` 永远为空、`--save/--submit`
16
- // 一律 `report.period_not_open`",排障的人只会以为"日报功能是坏的"(docs/05 决策 74①)。
17
- // 服务端从 2026-10-15 起在 `POST /reports/rules` 之后调用 `_open_current_period`,
18
- // 于是响应多出一段 `period: {period_key, due_at, assignments_created, opened}`:
19
- //
20
- // - `period_key` 可以直接喂给 `report --save/--submit`,所以 CLI 把它写进 `next_step`,
21
- // 省掉"自己猜周期键"这一步;
22
- // - **只开当期、不补开历史**(`backfill_max=1`:刚建的规则补 30 期等于让全公司补写
23
- // 一个月前的工作日志),历史补开仍归 tick;
24
- // - `assignments_created=0` 是**要紧的信号**:说明 `fillers` 没展开出任何人
25
- // (这条规则"谁都不该交"),十有八九是 `fillers` 写窄了。CLI **不额外造字段**
26
- // 去解释它(`--json` 的 `data` 形状必须与 Rust 版逐字一致),只保证原样带出。
14
+ // 2026-10-28 起,当前周期由服务端按规则和日期实时计算,提交直接落
15
+ // `report_instance`;`report_tick` 只负责可选提醒,不再阻断日报提交。
16
+ // `--period` 仍保留给补交/历史查询,但日常 `--save/--submit/--stats` 可以省略。
27
17
  //
28
18
  // ## 为什么显式旗标要覆盖 `--from` 的同名字段
29
19
  //
@@ -240,14 +230,12 @@ async function reportDomain(args, runtime) {
240
230
  if (picked === '--save') {
241
231
  only(args, 'report --save', ['--rule', '--period', '--content']);
242
232
  requireRule(args, 'report --save');
243
- requirePeriod(args, 'report --save');
244
233
  requireContent(args, 'report --save');
245
234
  return save(runtime, args);
246
235
  }
247
236
  if (picked === '--submit') {
248
237
  only(args, 'report --submit', ['--rule', '--period', '--content', '--cc']);
249
238
  requireRule(args, 'report --submit');
250
- requirePeriod(args, 'report --submit');
251
239
  requireContent(args, 'report --submit');
252
240
  return submit(runtime, args);
253
241
  }
@@ -272,13 +260,11 @@ async function reportDomain(args, runtime) {
272
260
  if (picked === '--stats') {
273
261
  only(args, 'report --stats', ['--rule', '--period', '--dept', '--include-sub']);
274
262
  requireRule(args, 'report --stats');
275
- requirePeriod(args, 'report --stats');
276
263
  return stats(runtime, args);
277
264
  }
278
265
  if (picked === '--remind') {
279
266
  only(args, 'report --remind', ['--rule', '--period']);
280
267
  requireRule(args, 'report --remind');
281
- requirePeriod(args, 'report --remind');
282
268
  return remind(runtime, args);
283
269
  }
284
270
  if (picked === '--reopen') {
@@ -464,12 +450,12 @@ async function due(runtime, args) {
464
450
  runtime.finishFrom(response, dataOf(response));
465
451
  }
466
452
 
467
- /** `report --save --rule <r> --period <p> --content <json>`:存草稿。 */
453
+ /** `report --save --rule <r> [--period <p>] --content <json>`:存草稿。 */
468
454
  async function save(runtime, args) {
469
455
  const rule = requireRule(args, 'report --save');
470
- const period = requirePeriod(args, 'report --save');
456
+ const period = flagValue(args, '--period');
471
457
  const content = parseJsonFlag(requireContent(args, 'report --save'), '--content');
472
- const path = `/reports/${rule}/${period}`;
458
+ const path = isBlank(period) ? `/reports/${rule}` : `/reports/${rule}/${trimmed(period)}`;
473
459
  const spec = requestSpec({
474
460
  body: sortKeysDeep({ content }),
475
461
  idempotencyKey: idempotencyKey('report-save'),
@@ -478,20 +464,24 @@ async function save(runtime, args) {
478
464
  const response = await runtime.sendAuthed('PUT', path, spec);
479
465
  const data = dataOf(response);
480
466
  if (isPlainObject(data)) {
481
- data.next_step = `提交:xinhe-oa-cli report --submit --rule ${rule} --period ${period} --content <JSON>`;
467
+ data.next_step =
468
+ `提交:xinhe-oa-cli report --submit --rule ${rule} --content <JSON>` +
469
+ (isBlank(period) ? '' : `(复用历史期时加 --period ${trimmed(period)})`);
482
470
  }
483
471
  runtime.finishFrom(response, data);
484
472
  }
485
473
 
486
- /** `report --submit --rule <r> --period <p> --content <json> [--cc <uids>]`:提交(幂等)。 */
474
+ /** `report --submit --rule <r> [--period <p>] --content <json> [--cc <uids>]`:提交(幂等)。 */
487
475
  async function submit(runtime, args) {
488
476
  const rule = requireRule(args, 'report --submit');
489
- const period = requirePeriod(args, 'report --submit');
477
+ const period = flagValue(args, '--period');
490
478
  const content = parseJsonFlag(requireContent(args, 'report --submit'), '--content');
491
479
  const body = { content };
492
480
  const cc = ccUserIds(args);
493
481
  if (cc.length > 0) body.cc = cc;
494
- const path = `/reports/${rule}/${period}/submit`;
482
+ const path = isBlank(period)
483
+ ? `/reports/${rule}/submit`
484
+ : `/reports/${rule}/${trimmed(period)}/submit`;
495
485
  const spec = requestSpec({
496
486
  body: sortKeysDeep(body),
497
487
  // 幂等键必填:同周期重复提交返回首次结果,不产生第二份。
@@ -574,14 +564,12 @@ async function show(runtime, id, args) {
574
564
  runtime.finishFrom(response, data);
575
565
  }
576
566
 
577
- /** `report --stats --rule <r> --period <p> [--dept <d>] [--include-sub]`:应交 / 已交 / 未交。 */
567
+ /** `report --stats --rule <r> [--period <p>] [--dept <d>] [--include-sub]`:应交 / 已交 / 未交。 */
578
568
  async function stats(runtime, args) {
579
569
  const rule = requireRule(args, 'report --stats');
580
- const period = requirePeriod(args, 'report --stats');
581
- const query = [
582
- ['rule_id', rule],
583
- ['period_key', period],
584
- ];
570
+ const period = flagValue(args, '--period');
571
+ const query = [['rule_id', rule]];
572
+ if (!isBlank(period)) query.push(['period_key', trimmed(period)]);
585
573
  pushQuery(query, 'dept_id', flagValue(args, '--dept'));
586
574
  if (isGiven(args, '--include-sub')) query.push(['include_sub', 'true']);
587
575
  const spec = requestSpec({ query });
@@ -590,12 +578,14 @@ async function stats(runtime, args) {
590
578
  runtime.finishFrom(response, dataOf(response));
591
579
  }
592
580
 
593
- /** `report --remind --rule <r> --period <p>`:手动催交(**只发事件**)。 */
581
+ /** `report --remind --rule <r> [--period <p>]`:手动催交(**只发事件**)。 */
594
582
  async function remind(runtime, args) {
595
583
  const rule = requireRule(args, 'report --remind');
596
- const period = requirePeriod(args, 'report --remind');
584
+ const period = flagValue(args, '--period');
585
+ const body = { rule_id: rule };
586
+ if (!isBlank(period)) body.period_key = trimmed(period);
597
587
  const spec = requestSpec({
598
- body: sortKeysDeep({ rule_id: rule, period_key: period }),
588
+ body: sortKeysDeep(body),
599
589
  idempotencyKey: idempotencyKey('report-remind'),
600
590
  });
601
591
  if (runtime.dryRun) return runtime.dryRunReport('POST', '/reports/remind', spec);