@camstack/addon-notifiers 1.2.80 → 1.2.82

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/dist/addon.js CHANGED
@@ -8084,13 +8084,28 @@ var RecordingBandSchema = object({
8084
8084
  end: string().regex(HHMM),
8085
8085
  mode: RecordingBandModeSchema,
8086
8086
  triggers: RecordingBandTriggersSchema.optional(),
8087
+ /**
8088
+ * RETIRED (D381). A band no longer carries a pre-buffer of its own.
8089
+ *
8090
+ * It was the retroactive KEEP bound — which already-written segments survive
8091
+ * a trigger — and it had to be at least as wide as the widest pre-roll the
8092
+ * broker could serve, or the gate would delete the seconds the ring had just
8093
+ * handed the writer. That "at least as wide as" is the tell: it was a second
8094
+ * expression of the broker's retention, in different units, in a different
8095
+ * addon, with an invariant the operator had to maintain by hand. The keep
8096
+ * bound is now derived from the one prebuffer ceiling and there is nothing
8097
+ * left to configure here.
8098
+ *
8099
+ * The key survives in the SHAPE so a config written before that record still
8100
+ * parses and can be migrated deliberately — `RecordingBandSchema` is not
8101
+ * strict, so simply deleting it would strip an operator's value in silence on
8102
+ * the next save (the failure D380 came one commit from shipping). Nothing
8103
+ * reads it: {@link stripRetiredBandPreBufferSec} removes it on load.
8104
+ */
8087
8105
  preBufferSec: number().min(0).optional(),
8088
8106
  postBufferSec: number().min(0).optional()
8089
8107
  });
8090
- ({
8091
- preBufferSec: 15,
8092
- postBufferSec: 30
8093
- }).postBufferSec * 1e3;
8108
+ ({ postBufferSec: 30 }).postBufferSec * 1e3;
8094
8109
  /**
8095
8110
  * Per-device retention overrides. Every field is optional; an unset or `0`
8096
8111
  * value inherits the node-wide recorder default. Only footage-lifetime limits
@@ -10686,12 +10701,30 @@ var BackupDestinationInfoSchema = object({
10686
10701
  lastSuccessAt: number().optional(),
10687
10702
  /** Newest-archive size from `manifests.json`, or undefined. */
10688
10703
  lastSuccessSizeBytes: number().optional(),
10689
- /** Per-destination cron expression. Empty = manual-only (no schedule). */
10704
+ /**
10705
+ * Cron cadence(s) of the ENABLED schedules that fan out to this
10706
+ * destination, comma-joined. Absent when no enabled schedule targets it
10707
+ * — a destination nothing is scheduled to write to must not advertise a
10708
+ * cadence (D384). This is never the `backup_destination_policies.cron`
10709
+ * column: that per-location cron has scheduled nothing since 2026-07-28
10710
+ * and reading it made a destination with a DISABLED schedule claim a
10711
+ * nightly run.
10712
+ */
10690
10713
  cron: string().optional(),
10691
- /** ms-epoch of next computed firing for this destination's cron, if any. */
10714
+ /** ms-epoch of the next firing across those schedules (earliest), if any. */
10692
10715
  nextRunAt: number().optional(),
10693
- /** ms-epoch of last successful scheduled run (mirrors policy.lastRunAt). */
10694
- lastRunAt: number().optional()
10716
+ /**
10717
+ * ms-epoch of the last time a run ATTEMPTED to write here — success or
10718
+ * failure. Never a success stamp: pair it with `lastSuccessAt` (the
10719
+ * newest archive that actually landed) and `lastError`.
10720
+ */
10721
+ lastAttemptAt: number().optional(),
10722
+ /**
10723
+ * Why the last attempt failed, verbatim. Absent when the last attempt
10724
+ * landed the archive. A destination that has never been written to has
10725
+ * neither this nor `lastAttemptAt`.
10726
+ */
10727
+ lastError: string().optional()
10695
10728
  });
10696
10729
  /**
10697
10730
  * Per-archive entry returned by `backup.listArchives({ destinationId })`.
@@ -10854,8 +10887,16 @@ var BackupScheduleSchema = object({
10854
10887
  retentionCount: number().int().min(1).max(1e3),
10855
10888
  /** Optional subset of source locations to include; omitted = all. */
10856
10889
  dataSources: array(string()).readonly().optional(),
10857
- /** ms-epoch of last successful run. */
10858
- lastRunAt: number().optional(),
10890
+ /**
10891
+ * ms-epoch of the last tick that FIRED this schedule. Stamped before the
10892
+ * archive runs (it is the dedupe anchor), so it says "attempted", never
10893
+ * "succeeded" — a run refused by every destination stamps it too.
10894
+ */
10895
+ lastAttemptAt: number().optional(),
10896
+ /** ms-epoch of the last run of this schedule that landed at ≥1 destination. */
10897
+ lastSuccessAt: number().optional(),
10898
+ /** Why the last fired run failed, verbatim. Absent when it succeeded. */
10899
+ lastError: string().optional(),
10859
10900
  /** ms-epoch of next computed firing (read-only, filled on list). */
10860
10901
  nextRunAt: number().optional()
10861
10902
  });
@@ -10904,14 +10945,7 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
10904
10945
  locationId: string(),
10905
10946
  enabled: boolean(),
10906
10947
  retentionCount: number().int().min(1).max(1e3),
10907
- label: string().optional(),
10908
- /**
10909
- * Per-destination cron expression. Empty string clears the
10910
- * schedule (manual-only). Validated server-side via croner;
10911
- * malformed expressions reject the upsert with an actionable
10912
- * message.
10913
- */
10914
- cron: string().optional()
10948
+ label: string().optional()
10915
10949
  }), _void(), {
10916
10950
  kind: "mutation",
10917
10951
  auth: "admin"
package/dist/addon.mjs CHANGED
@@ -8057,13 +8057,28 @@ var RecordingBandSchema = object({
8057
8057
  end: string().regex(HHMM),
8058
8058
  mode: RecordingBandModeSchema,
8059
8059
  triggers: RecordingBandTriggersSchema.optional(),
8060
+ /**
8061
+ * RETIRED (D381). A band no longer carries a pre-buffer of its own.
8062
+ *
8063
+ * It was the retroactive KEEP bound — which already-written segments survive
8064
+ * a trigger — and it had to be at least as wide as the widest pre-roll the
8065
+ * broker could serve, or the gate would delete the seconds the ring had just
8066
+ * handed the writer. That "at least as wide as" is the tell: it was a second
8067
+ * expression of the broker's retention, in different units, in a different
8068
+ * addon, with an invariant the operator had to maintain by hand. The keep
8069
+ * bound is now derived from the one prebuffer ceiling and there is nothing
8070
+ * left to configure here.
8071
+ *
8072
+ * The key survives in the SHAPE so a config written before that record still
8073
+ * parses and can be migrated deliberately — `RecordingBandSchema` is not
8074
+ * strict, so simply deleting it would strip an operator's value in silence on
8075
+ * the next save (the failure D380 came one commit from shipping). Nothing
8076
+ * reads it: {@link stripRetiredBandPreBufferSec} removes it on load.
8077
+ */
8060
8078
  preBufferSec: number().min(0).optional(),
8061
8079
  postBufferSec: number().min(0).optional()
8062
8080
  });
8063
- ({
8064
- preBufferSec: 15,
8065
- postBufferSec: 30
8066
- }).postBufferSec * 1e3;
8081
+ ({ postBufferSec: 30 }).postBufferSec * 1e3;
8067
8082
  /**
8068
8083
  * Per-device retention overrides. Every field is optional; an unset or `0`
8069
8084
  * value inherits the node-wide recorder default. Only footage-lifetime limits
@@ -10659,12 +10674,30 @@ var BackupDestinationInfoSchema = object({
10659
10674
  lastSuccessAt: number().optional(),
10660
10675
  /** Newest-archive size from `manifests.json`, or undefined. */
10661
10676
  lastSuccessSizeBytes: number().optional(),
10662
- /** Per-destination cron expression. Empty = manual-only (no schedule). */
10677
+ /**
10678
+ * Cron cadence(s) of the ENABLED schedules that fan out to this
10679
+ * destination, comma-joined. Absent when no enabled schedule targets it
10680
+ * — a destination nothing is scheduled to write to must not advertise a
10681
+ * cadence (D384). This is never the `backup_destination_policies.cron`
10682
+ * column: that per-location cron has scheduled nothing since 2026-07-28
10683
+ * and reading it made a destination with a DISABLED schedule claim a
10684
+ * nightly run.
10685
+ */
10663
10686
  cron: string().optional(),
10664
- /** ms-epoch of next computed firing for this destination's cron, if any. */
10687
+ /** ms-epoch of the next firing across those schedules (earliest), if any. */
10665
10688
  nextRunAt: number().optional(),
10666
- /** ms-epoch of last successful scheduled run (mirrors policy.lastRunAt). */
10667
- lastRunAt: number().optional()
10689
+ /**
10690
+ * ms-epoch of the last time a run ATTEMPTED to write here — success or
10691
+ * failure. Never a success stamp: pair it with `lastSuccessAt` (the
10692
+ * newest archive that actually landed) and `lastError`.
10693
+ */
10694
+ lastAttemptAt: number().optional(),
10695
+ /**
10696
+ * Why the last attempt failed, verbatim. Absent when the last attempt
10697
+ * landed the archive. A destination that has never been written to has
10698
+ * neither this nor `lastAttemptAt`.
10699
+ */
10700
+ lastError: string().optional()
10668
10701
  });
10669
10702
  /**
10670
10703
  * Per-archive entry returned by `backup.listArchives({ destinationId })`.
@@ -10827,8 +10860,16 @@ var BackupScheduleSchema = object({
10827
10860
  retentionCount: number().int().min(1).max(1e3),
10828
10861
  /** Optional subset of source locations to include; omitted = all. */
10829
10862
  dataSources: array(string()).readonly().optional(),
10830
- /** ms-epoch of last successful run. */
10831
- lastRunAt: number().optional(),
10863
+ /**
10864
+ * ms-epoch of the last tick that FIRED this schedule. Stamped before the
10865
+ * archive runs (it is the dedupe anchor), so it says "attempted", never
10866
+ * "succeeded" — a run refused by every destination stamps it too.
10867
+ */
10868
+ lastAttemptAt: number().optional(),
10869
+ /** ms-epoch of the last run of this schedule that landed at ≥1 destination. */
10870
+ lastSuccessAt: number().optional(),
10871
+ /** Why the last fired run failed, verbatim. Absent when it succeeded. */
10872
+ lastError: string().optional(),
10832
10873
  /** ms-epoch of next computed firing (read-only, filled on list). */
10833
10874
  nextRunAt: number().optional()
10834
10875
  });
@@ -10877,14 +10918,7 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
10877
10918
  locationId: string(),
10878
10919
  enabled: boolean(),
10879
10920
  retentionCount: number().int().min(1).max(1e3),
10880
- label: string().optional(),
10881
- /**
10882
- * Per-destination cron expression. Empty string clears the
10883
- * schedule (manual-only). Validated server-side via croner;
10884
- * malformed expressions reject the upsert with an actionable
10885
- * message.
10886
- */
10887
- cron: string().optional()
10921
+ label: string().optional()
10888
10922
  }), _void(), {
10889
10923
  kind: "mutation",
10890
10924
  auth: "admin"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-notifiers",
3
- "version": "1.2.80",
3
+ "version": "1.2.82",
4
4
  "description": "System notifiers addon for CamStack — a `notification-output` collection provider hosting per-kind notifier adapters (ntfy, pushover, gotify, telegram, discord, webhook, zentik).",
5
5
  "keywords": [
6
6
  "camstack",