@kohost/api-client 7.9.0 → 7.10.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 (51) hide show
  1. package/dist/lib/emergencyContacts.d.ts +27 -0
  2. package/dist/lib/index.d.ts +1 -1
  3. package/dist/lib/index.js.map +1 -1
  4. package/dist/lib/sosAudiences.d.ts +1 -1
  5. package/dist/lib/sosAudiences.js +1 -1
  6. package/dist/lib/sosAudiences.js.map +1 -1
  7. package/dist/models/announcement.js +5 -1
  8. package/dist/models/announcement.js.map +1 -1
  9. package/dist/models/sosEvent.js +2 -0
  10. package/dist/models/sosEvent.js.map +1 -1
  11. package/dist/schemas/announcement.d.ts +122 -6
  12. package/dist/schemas/announcement.js +126 -11
  13. package/dist/schemas/announcement.js.map +1 -1
  14. package/dist/schemas/definitions.d.ts +83 -1
  15. package/dist/schemas/definitions.js +40 -2
  16. package/dist/schemas/definitions.js.map +1 -1
  17. package/dist/schemas/sosEvent.d.ts +97 -2
  18. package/dist/schemas/sosEvent.js +92 -2
  19. package/dist/schemas/sosEvent.js.map +1 -1
  20. package/dist/useCases/addSOSEventNote.d.ts +36 -0
  21. package/dist/useCases/addSOSEventNote.js +47 -0
  22. package/dist/useCases/addSOSEventNote.js.map +1 -0
  23. package/dist/useCases/createAnnouncementPreset.d.ts +27 -0
  24. package/dist/useCases/createAnnouncementPreset.js +47 -0
  25. package/dist/useCases/createAnnouncementPreset.js.map +1 -0
  26. package/dist/useCases/deleteAnnouncementPreset.d.ts +36 -0
  27. package/dist/useCases/deleteAnnouncementPreset.js +47 -0
  28. package/dist/useCases/deleteAnnouncementPreset.js.map +1 -0
  29. package/dist/useCases/describeAnnouncement.d.ts +36 -0
  30. package/dist/useCases/describeAnnouncement.js +47 -0
  31. package/dist/useCases/describeAnnouncement.js.map +1 -0
  32. package/dist/useCases/exportSOSEventReport.d.ts +36 -0
  33. package/dist/useCases/exportSOSEventReport.js +47 -0
  34. package/dist/useCases/exportSOSEventReport.js.map +1 -0
  35. package/dist/useCases/fetchEmergencyContactPeople.d.ts +27 -0
  36. package/dist/useCases/fetchEmergencyContactPeople.js +47 -0
  37. package/dist/useCases/fetchEmergencyContactPeople.js.map +1 -0
  38. package/dist/useCases/index.d.ts +9 -0
  39. package/dist/useCases/index.js +19 -1
  40. package/dist/useCases/index.js.map +1 -1
  41. package/dist/useCases/listAnnouncements.d.ts +27 -0
  42. package/dist/useCases/listAnnouncements.js +47 -0
  43. package/dist/useCases/listAnnouncements.js.map +1 -0
  44. package/dist/useCases/previewSOSEventReport.d.ts +36 -0
  45. package/dist/useCases/previewSOSEventReport.js +47 -0
  46. package/dist/useCases/previewSOSEventReport.js.map +1 -0
  47. package/dist/useCases/updateAnnouncementPreset.d.ts +36 -0
  48. package/dist/useCases/updateAnnouncementPreset.js +47 -0
  49. package/dist/useCases/updateAnnouncementPreset.js.map +1 -0
  50. package/dist/validate.d.ts +0 -3
  51. package/package.json +1 -1
@@ -1,9 +1,14 @@
1
1
  import type { SISDriver } from "./sisDrivers.js";
2
+ import type { ExternalAudienceGroup } from "../schemas/definitions.js";
2
3
  export interface EmergencyContactRoleGroup {
3
4
  role: string;
4
5
  total: number;
5
6
  reachable: number;
6
7
  }
8
+ export interface ExternalGroupCounts {
9
+ total: number;
10
+ reachable: number;
11
+ }
7
12
  export interface EmergencyContactAudience {
8
13
  driver: SISDriver;
9
14
  live: boolean;
@@ -11,4 +16,26 @@ export interface EmergencyContactAudience {
11
16
  total: number;
12
17
  reachable: number;
13
18
  byRole: EmergencyContactRoleGroup[];
19
+ /** Counts for each selectable external group, whatever the send selected. */
20
+ groups: Record<ExternalAudienceGroup, ExternalGroupCounts>;
21
+ }
22
+ export interface EmergencyContactPerson {
23
+ id: string;
24
+ firstName: string;
25
+ lastName: string;
26
+ email: string | null;
27
+ phone: string | null;
28
+ roles: string[];
29
+ /** First non-student role, or null when the source system left it unmapped. */
30
+ relationship: string | null;
31
+ group: ExternalAudienceGroup;
32
+ reachable: boolean;
33
+ }
34
+ export interface EmergencyContactPeople {
35
+ driver: SISDriver;
36
+ live: boolean;
37
+ syncedAt: string | null;
38
+ /** The groups `people` was built for. */
39
+ groups: ExternalAudienceGroup[];
40
+ people: EmergencyContactPerson[];
14
41
  }
@@ -5,7 +5,7 @@ export { SIS_DRIVERS, isSISDriver, type SISDriver } from "./sisDrivers.js";
5
5
  export { SOS_AUDIENCES, type SOSAudience } from "./sosAudiences.js";
6
6
  export { MESSAGE_ERROR_CATEGORIES, categoryForMessageErrorCode, isMessageErrorCategory, type MessageErrorCategory, } from "./messageErrorCodes.js";
7
7
  export { DELIVERY_OUTCOMES, deliveryOutcomeForStatus, type DeliveryOutcome, } from "./deliveryStatus.js";
8
- export type { EmergencyContactAudience, EmergencyContactRoleGroup, } from "./emergencyContacts.js";
8
+ export type { EmergencyContactAudience, EmergencyContactPeople, EmergencyContactPerson, EmergencyContactRoleGroup, ExternalGroupCounts, } from "./emergencyContacts.js";
9
9
  export { MAX_MESSAGE_ATTACHMENTS } from "./messageAttachments.js";
10
10
  export { DEFAULT_MARKUP_TIERS, DEFAULT_DNE_AMOUNT, resolveMarkupTierTable, keyedMarkupPercent, DEFAULT_TAX_RATE, derivePrice, billTotal, billTaxAmount, billGrandTotal, formatMoney, } from "./money.js";
11
11
  export { effectiveTaxRate, taxableSubtotal, billTotals, resolveBillTaxExempt, settledBillTotal, billEffectiveDate, type BillTaxFields, type TaxableLine, type SettledBillTotalSource, type BillEffectiveDateSource, } from "./bills.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../.generated/lib/index.ts"],"sourcesContent":["export {\n inferDeviceNotifications,\n type DeviceNotificationName,\n type InferDeviceNotificationsInput,\n} from \"./deviceNotifications.js\";\nexport {\n categoryForDevice,\n SYSTEM_CATEGORIES,\n SYSTEM_CATEGORY_LABELS,\n type SystemCategory,\n type CategoryForDeviceInput,\n} from \"./systemCategories.js\";\nexport {\n getAllowedResourceIds,\n getAllowedDeviceTypes,\n getAllowedFeatures,\n type PolicyLike,\n type PolicyPermissionLike,\n} from \"./policy-resolvers.js\";\nexport { SIS_DRIVERS, isSISDriver, type SISDriver } from \"./sisDrivers.js\";\nexport { SOS_AUDIENCES, type SOSAudience } from \"./sosAudiences.js\";\nexport {\n MESSAGE_ERROR_CATEGORIES,\n categoryForMessageErrorCode,\n isMessageErrorCategory,\n type MessageErrorCategory,\n} from \"./messageErrorCodes.js\";\nexport {\n DELIVERY_OUTCOMES,\n deliveryOutcomeForStatus,\n type DeliveryOutcome,\n} from \"./deliveryStatus.js\";\nexport type {\n EmergencyContactAudience,\n EmergencyContactRoleGroup,\n} from \"./emergencyContacts.js\";\nexport { MAX_MESSAGE_ATTACHMENTS } from \"./messageAttachments.js\";\nexport {\n DEFAULT_MARKUP_TIERS,\n DEFAULT_DNE_AMOUNT,\n resolveMarkupTierTable,\n keyedMarkupPercent,\n DEFAULT_TAX_RATE,\n derivePrice,\n billTotal,\n billTaxAmount,\n billGrandTotal,\n formatMoney,\n} from \"./money.js\";\nexport {\n effectiveTaxRate,\n taxableSubtotal,\n billTotals,\n resolveBillTaxExempt,\n settledBillTotal,\n billEffectiveDate,\n type BillTaxFields,\n type TaxableLine,\n type SettledBillTotalSource,\n type BillEffectiveDateSource,\n} from \"./bills.js\";\nexport {\n KFC_STATS_TIMEZONE,\n KFC_STATS_DEFAULT_WINDOW_DAYS,\n KFC_STATS_MAX_RANGE_DAYS,\n resolveKfcStatsWindowBounds,\n type KfcStatsWindowBounds,\n} from \"./kfcStatsWindow.js\";\nexport {\n serializeRichTextBody,\n isWellFormedRichText,\n type RichTextContent,\n type RichTextBlockNode,\n type RichTextInlineNode,\n type RichTextListItemNode,\n type RichTextMentionNode,\n} from \"./ticketRichText.js\";\n"],"mappings":""}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../.generated/lib/index.ts"],"sourcesContent":["export {\n inferDeviceNotifications,\n type DeviceNotificationName,\n type InferDeviceNotificationsInput,\n} from \"./deviceNotifications.js\";\nexport {\n categoryForDevice,\n SYSTEM_CATEGORIES,\n SYSTEM_CATEGORY_LABELS,\n type SystemCategory,\n type CategoryForDeviceInput,\n} from \"./systemCategories.js\";\nexport {\n getAllowedResourceIds,\n getAllowedDeviceTypes,\n getAllowedFeatures,\n type PolicyLike,\n type PolicyPermissionLike,\n} from \"./policy-resolvers.js\";\nexport { SIS_DRIVERS, isSISDriver, type SISDriver } from \"./sisDrivers.js\";\nexport { SOS_AUDIENCES, type SOSAudience } from \"./sosAudiences.js\";\nexport {\n MESSAGE_ERROR_CATEGORIES,\n categoryForMessageErrorCode,\n isMessageErrorCategory,\n type MessageErrorCategory,\n} from \"./messageErrorCodes.js\";\nexport {\n DELIVERY_OUTCOMES,\n deliveryOutcomeForStatus,\n type DeliveryOutcome,\n} from \"./deliveryStatus.js\";\nexport type {\n EmergencyContactAudience,\n EmergencyContactPeople,\n EmergencyContactPerson,\n EmergencyContactRoleGroup,\n ExternalGroupCounts,\n} from \"./emergencyContacts.js\";\nexport { MAX_MESSAGE_ATTACHMENTS } from \"./messageAttachments.js\";\nexport {\n DEFAULT_MARKUP_TIERS,\n DEFAULT_DNE_AMOUNT,\n resolveMarkupTierTable,\n keyedMarkupPercent,\n DEFAULT_TAX_RATE,\n derivePrice,\n billTotal,\n billTaxAmount,\n billGrandTotal,\n formatMoney,\n} from \"./money.js\";\nexport {\n effectiveTaxRate,\n taxableSubtotal,\n billTotals,\n resolveBillTaxExempt,\n settledBillTotal,\n billEffectiveDate,\n type BillTaxFields,\n type TaxableLine,\n type SettledBillTotalSource,\n type BillEffectiveDateSource,\n} from \"./bills.js\";\nexport {\n KFC_STATS_TIMEZONE,\n KFC_STATS_DEFAULT_WINDOW_DAYS,\n KFC_STATS_MAX_RANGE_DAYS,\n resolveKfcStatsWindowBounds,\n type KfcStatsWindowBounds,\n} from \"./kfcStatsWindow.js\";\nexport {\n serializeRichTextBody,\n isWellFormedRichText,\n type RichTextContent,\n type RichTextBlockNode,\n type RichTextInlineNode,\n type RichTextListItemNode,\n type RichTextMentionNode,\n} from \"./ticketRichText.js\";\n"],"mappings":""}
@@ -1,2 +1,2 @@
1
- export declare const SOS_AUDIENCES: readonly ["internal", "emergencyContacts"];
1
+ export declare const SOS_AUDIENCES: readonly ["internal", "external"];
2
2
  export type SOSAudience = (typeof SOS_AUDIENCES)[number];
@@ -1,5 +1,5 @@
1
1
  //#region .generated/lib/sosAudiences.ts
2
- const SOS_AUDIENCES = ["internal", "emergencyContacts"];
2
+ const SOS_AUDIENCES = ["internal", "external"];
3
3
  //#endregion
4
4
  export { SOS_AUDIENCES };
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"sosAudiences.js","names":[],"sources":["../../.generated/lib/sosAudiences.ts"],"sourcesContent":["export const SOS_AUDIENCES = [\"internal\", \"emergencyContacts\"] as const;\n\nexport type SOSAudience = (typeof SOS_AUDIENCES)[number];\n"],"mappings":";AAAA,MAAa,gBAAgB,CAAC,YAAY,mBAAmB"}
1
+ {"version":3,"file":"sosAudiences.js","names":[],"sources":["../../.generated/lib/sosAudiences.ts"],"sourcesContent":["export const SOS_AUDIENCES = [\"internal\", \"external\"] as const;\n\nexport type SOSAudience = (typeof SOS_AUDIENCES)[number];\n"],"mappings":";AAAA,MAAa,gBAAgB,CAAC,YAAY,UAAU"}
@@ -8,13 +8,17 @@ var Announcement = class extends Entity {
8
8
  this.id = data.id;
9
9
  if (data.propertyId !== void 0) this.propertyId = data.propertyId;
10
10
  this.type = data.type;
11
+ if (data.status !== void 0) this.status = data.status;
12
+ if (data.name !== void 0) this.name = data.name;
13
+ if (data.presetId !== void 0) this.presetId = data.presetId;
11
14
  if (data.audience !== void 0) this.audience = data.audience;
12
15
  if (data.channels !== void 0) this.channels = data.channels;
13
16
  if (data.subject !== void 0) this.subject = data.subject;
14
17
  if (data.surfaces !== void 0) this.surfaces = data.surfaces;
15
- this.body = data.body;
18
+ if (data.body !== void 0) this.body = data.body;
16
19
  if (data.media !== void 0) this.media = data.media;
17
20
  if (data.sentBy !== void 0) this.sentBy = data.sentBy;
21
+ if (data.result !== void 0) this.result = data.result;
18
22
  if (data.tags !== void 0) this.tags = data.tags;
19
23
  if (data.createdAt !== void 0) this.createdAt = data.createdAt;
20
24
  if (data.updatedAt !== void 0) this.updatedAt = data.updatedAt;
@@ -1 +1 @@
1
- {"version":3,"file":"announcement.js","names":["validate"],"sources":["../../.generated/models/announcement.ts"],"sourcesContent":["/* This file is automatically generated. Do not modify it manually. */\n\nimport { Entity } from \"./entity.js\";\nimport { validateAnnouncement as validate } from \"../validate.js\";\nimport { announcementSchema, type AnnouncementSchema } from \"../schemas/announcement.js\";\n\n/**\n * Data type for Announcement constructor - exported for backwards compatibility\n */\nexport type AnnouncementData = AnnouncementSchema;\n\n/**\n * Announcement message sent to users\n */\nexport interface Announcement extends AnnouncementSchema {}\nexport class Announcement extends Entity {\n declare schema: typeof announcementSchema;\n declare validator: typeof validate;\n\n constructor(data: AnnouncementSchema) {\n super(data);\n this.id = data.id;\n if (data.propertyId !== undefined) this.propertyId = data.propertyId;\n this.type = data.type;\n if (data.audience !== undefined) this.audience = data.audience;\n if (data.channels !== undefined) this.channels = data.channels;\n if (data.subject !== undefined) this.subject = data.subject;\n if (data.surfaces !== undefined) this.surfaces = data.surfaces;\n this.body = data.body;\n if (data.media !== undefined) this.media = data.media;\n if (data.sentBy !== undefined) this.sentBy = data.sentBy;\n if (data.tags !== undefined) this.tags = data.tags;\n if (data.createdAt !== undefined) this.createdAt = data.createdAt;\n if (data.updatedAt !== undefined) this.updatedAt = data.updatedAt;\n if (data.deletedAt !== undefined) this.deletedAt = data.deletedAt;\n }\n\n\n\n\n\n\n\n\n}\n\nObject.defineProperty(Announcement.prototype, \"schema\", {\n value: announcementSchema\n});\n\nObject.defineProperty(Announcement.prototype, \"validator\", {\n get: function() { return validate; }\n});\n"],"mappings":";;;;AAeA,IAAa,eAAb,cAAkC,OAAO;CAIvC,YAAY,MAA0B;EACpC,MAAM,IAAI;EACV,KAAK,KAAK,KAAK;EACf,IAAI,KAAK,eAAe,KAAA,GAAW,KAAK,aAAa,KAAK;EAC1D,KAAK,OAAO,KAAK;EACjB,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,YAAY,KAAA,GAAW,KAAK,UAAU,KAAK;EACpD,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,KAAK,OAAO,KAAK;EACjB,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,OAAO,KAAK;EAC9C,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;CAC1D;AASF;AAEA,OAAO,eAAe,aAAa,WAAW,UAAU,EACtD,OAAO,mBACT,CAAC;AAED,OAAO,eAAe,aAAa,WAAW,aAAa,EACzD,KAAK,WAAW;CAAE,OAAOA;AAAU,EACrC,CAAC"}
1
+ {"version":3,"file":"announcement.js","names":["validate"],"sources":["../../.generated/models/announcement.ts"],"sourcesContent":["/* This file is automatically generated. Do not modify it manually. */\n\nimport { Entity } from \"./entity.js\";\nimport { validateAnnouncement as validate } from \"../validate.js\";\nimport { announcementSchema, type AnnouncementSchema } from \"../schemas/announcement.js\";\n\n/**\n * Data type for Announcement constructor - exported for backwards compatibility\n */\nexport type AnnouncementData = AnnouncementSchema;\n\n/**\n * Announcement message sent to users\n */\nexport interface Announcement extends AnnouncementSchema {}\nexport class Announcement extends Entity {\n declare schema: typeof announcementSchema;\n declare validator: typeof validate;\n\n constructor(data: AnnouncementSchema) {\n super(data);\n this.id = data.id;\n if (data.propertyId !== undefined) this.propertyId = data.propertyId;\n this.type = data.type;\n if (data.status !== undefined) this.status = data.status;\n if (data.name !== undefined) this.name = data.name;\n if (data.presetId !== undefined) this.presetId = data.presetId;\n if (data.audience !== undefined) this.audience = data.audience;\n if (data.channels !== undefined) this.channels = data.channels;\n if (data.subject !== undefined) this.subject = data.subject;\n if (data.surfaces !== undefined) this.surfaces = data.surfaces;\n if (data.body !== undefined) this.body = data.body;\n if (data.media !== undefined) this.media = data.media;\n if (data.sentBy !== undefined) this.sentBy = data.sentBy;\n if (data.result !== undefined) this.result = data.result;\n if (data.tags !== undefined) this.tags = data.tags;\n if (data.createdAt !== undefined) this.createdAt = data.createdAt;\n if (data.updatedAt !== undefined) this.updatedAt = data.updatedAt;\n if (data.deletedAt !== undefined) this.deletedAt = data.deletedAt;\n }\n\n\n\n\n\n\n\n\n}\n\nObject.defineProperty(Announcement.prototype, \"schema\", {\n value: announcementSchema\n});\n\nObject.defineProperty(Announcement.prototype, \"validator\", {\n get: function() { return validate; }\n});\n"],"mappings":";;;;AAeA,IAAa,eAAb,cAAkC,OAAO;CAIvC,YAAY,MAA0B;EACpC,MAAM,IAAI;EACV,KAAK,KAAK,KAAK;EACf,IAAI,KAAK,eAAe,KAAA,GAAW,KAAK,aAAa,KAAK;EAC1D,KAAK,OAAO,KAAK;EACjB,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,OAAO,KAAK;EAC9C,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,YAAY,KAAA,GAAW,KAAK,UAAU,KAAK;EACpD,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,KAAK;EACtD,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,OAAO,KAAK;EAC9C,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,OAAO,KAAK;EAC9C,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;CAC1D;AASF;AAEA,OAAO,eAAe,aAAa,WAAW,UAAU,EACtD,OAAO,mBACT,CAAC;AAED,OAAO,eAAe,aAAa,WAAW,aAAa,EACzD,KAAK,WAAW;CAAE,OAAOA;AAAU,EACrC,CAAC"}
@@ -14,6 +14,8 @@ var SOSEvent = class extends Entity {
14
14
  if (data.deactivatedAt !== void 0) this.deactivatedAt = data.deactivatedAt;
15
15
  if (data.deactivatedBy !== void 0) this.deactivatedBy = data.deactivatedBy;
16
16
  this.timeline = data.timeline;
17
+ if (data.notes !== void 0) this.notes = data.notes;
18
+ if (data.report !== void 0) this.report = data.report;
17
19
  if (data.createdAt !== void 0) this.createdAt = data.createdAt;
18
20
  if (data.updatedAt !== void 0) this.updatedAt = data.updatedAt;
19
21
  if (data.deletedAt !== void 0) this.deletedAt = data.deletedAt;
@@ -1 +1 @@
1
- {"version":3,"file":"sosEvent.js","names":["validate"],"sources":["../../.generated/models/sosEvent.ts"],"sourcesContent":["/* This file is automatically generated. Do not modify it manually. */\n\nimport { Entity } from \"./entity.js\";\nimport { validateSOSEvent as validate } from \"../validate.js\";\nimport { sosEventSchema, type SOSEventSchema } from \"../schemas/sosEvent.js\";\n\n/**\n * Data type for SOSEvent constructor - exported for backwards compatibility\n */\nexport type SOSEventData = SOSEventSchema;\n\n/**\n * A durable record of a single SOS activation on a Property, with an append-only timeline of updates. Persists as audit history after the SOS is cleared.\n */\nexport interface SOSEvent extends SOSEventSchema {}\nexport class SOSEvent extends Entity {\n declare schema: typeof sosEventSchema;\n declare validator: typeof validate;\n\n constructor(data: SOSEventSchema) {\n super(data);\n this.id = data.id;\n this.type = data.type;\n if (data.propertyId !== undefined) this.propertyId = data.propertyId;\n this.sosTypeIds = data.sosTypeIds;\n this.activatedAt = data.activatedAt;\n if (data.activatedBy !== undefined) this.activatedBy = data.activatedBy;\n if (data.deactivatedAt !== undefined) this.deactivatedAt = data.deactivatedAt;\n if (data.deactivatedBy !== undefined) this.deactivatedBy = data.deactivatedBy;\n this.timeline = data.timeline;\n if (data.createdAt !== undefined) this.createdAt = data.createdAt;\n if (data.updatedAt !== undefined) this.updatedAt = data.updatedAt;\n if (data.deletedAt !== undefined) this.deletedAt = data.deletedAt;\n }\n\n\n\n\n\n\n\n\n}\n\nObject.defineProperty(SOSEvent.prototype, \"schema\", {\n value: sosEventSchema\n});\n\nObject.defineProperty(SOSEvent.prototype, \"validator\", {\n get: function() { return validate; }\n});\n"],"mappings":";;;;AAeA,IAAa,WAAb,cAA8B,OAAO;CAInC,YAAY,MAAsB;EAChC,MAAM,IAAI;EACV,KAAK,KAAK,KAAK;EACf,KAAK,OAAO,KAAK;EACjB,IAAI,KAAK,eAAe,KAAA,GAAW,KAAK,aAAa,KAAK;EAC1D,KAAK,aAAa,KAAK;EACvB,KAAK,cAAc,KAAK;EACxB,IAAI,KAAK,gBAAgB,KAAA,GAAW,KAAK,cAAc,KAAK;EAC5D,IAAI,KAAK,kBAAkB,KAAA,GAAW,KAAK,gBAAgB,KAAK;EAChE,IAAI,KAAK,kBAAkB,KAAA,GAAW,KAAK,gBAAgB,KAAK;EAChE,KAAK,WAAW,KAAK;EACrB,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;CAC1D;AASF;AAEA,OAAO,eAAe,SAAS,WAAW,UAAU,EAClD,OAAO,eACT,CAAC;AAED,OAAO,eAAe,SAAS,WAAW,aAAa,EACrD,KAAK,WAAW;CAAE,OAAOA;AAAU,EACrC,CAAC"}
1
+ {"version":3,"file":"sosEvent.js","names":["validate"],"sources":["../../.generated/models/sosEvent.ts"],"sourcesContent":["/* This file is automatically generated. Do not modify it manually. */\n\nimport { Entity } from \"./entity.js\";\nimport { validateSOSEvent as validate } from \"../validate.js\";\nimport { sosEventSchema, type SOSEventSchema } from \"../schemas/sosEvent.js\";\n\n/**\n * Data type for SOSEvent constructor - exported for backwards compatibility\n */\nexport type SOSEventData = SOSEventSchema;\n\n/**\n * A durable record of a single SOS activation on a Property, with an append-only timeline of updates. Persists as audit history after the SOS is cleared.\n */\nexport interface SOSEvent extends SOSEventSchema {}\nexport class SOSEvent extends Entity {\n declare schema: typeof sosEventSchema;\n declare validator: typeof validate;\n\n constructor(data: SOSEventSchema) {\n super(data);\n this.id = data.id;\n this.type = data.type;\n if (data.propertyId !== undefined) this.propertyId = data.propertyId;\n this.sosTypeIds = data.sosTypeIds;\n this.activatedAt = data.activatedAt;\n if (data.activatedBy !== undefined) this.activatedBy = data.activatedBy;\n if (data.deactivatedAt !== undefined) this.deactivatedAt = data.deactivatedAt;\n if (data.deactivatedBy !== undefined) this.deactivatedBy = data.deactivatedBy;\n this.timeline = data.timeline;\n if (data.notes !== undefined) this.notes = data.notes;\n if (data.report !== undefined) this.report = data.report;\n if (data.createdAt !== undefined) this.createdAt = data.createdAt;\n if (data.updatedAt !== undefined) this.updatedAt = data.updatedAt;\n if (data.deletedAt !== undefined) this.deletedAt = data.deletedAt;\n }\n\n\n\n\n\n\n\n\n}\n\nObject.defineProperty(SOSEvent.prototype, \"schema\", {\n value: sosEventSchema\n});\n\nObject.defineProperty(SOSEvent.prototype, \"validator\", {\n get: function() { return validate; }\n});\n"],"mappings":";;;;AAeA,IAAa,WAAb,cAA8B,OAAO;CAInC,YAAY,MAAsB;EAChC,MAAM,IAAI;EACV,KAAK,KAAK,KAAK;EACf,KAAK,OAAO,KAAK;EACjB,IAAI,KAAK,eAAe,KAAA,GAAW,KAAK,aAAa,KAAK;EAC1D,KAAK,aAAa,KAAK;EACvB,KAAK,cAAc,KAAK;EACxB,IAAI,KAAK,gBAAgB,KAAA,GAAW,KAAK,cAAc,KAAK;EAC5D,IAAI,KAAK,kBAAkB,KAAA,GAAW,KAAK,gBAAgB,KAAK;EAChE,IAAI,KAAK,kBAAkB,KAAA,GAAW,KAAK,gBAAgB,KAAK;EAChE,KAAK,WAAW,KAAK;EACrB,IAAI,KAAK,UAAU,KAAA,GAAW,KAAK,QAAQ,KAAK;EAChD,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,SAAS,KAAK;EAClD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,cAAc,KAAA,GAAW,KAAK,YAAY,KAAK;CAC1D;AASF;AAEA,OAAO,eAAe,SAAS,WAAW,UAAU,EAClD,OAAO,eACT,CAAC;AAED,OAAO,eAAe,SAAS,WAAW,aAAa,EACrD,KAAK,WAAW;CAAE,OAAOA;AAAU,EACrC,CAAC"}
@@ -6,7 +6,7 @@ export declare const announcementSchema: {
6
6
  readonly title: "Announcement";
7
7
  readonly description: "Announcement message sent to users";
8
8
  readonly type: "object";
9
- readonly required: readonly ["id", "type", "body"];
9
+ readonly required: readonly ["id", "type"];
10
10
  readonly properties: {
11
11
  readonly id: {
12
12
  readonly $ref: "definitions.json#/definitions/id";
@@ -20,6 +20,20 @@ export declare const announcementSchema: {
20
20
  readonly enum: readonly ["announcement"];
21
21
  readonly default: "announcement";
22
22
  };
23
+ readonly status: {
24
+ readonly type: "string";
25
+ readonly description: "`sent` is a real broadcast; `preset` is a named, reusable configuration a sender loads into the composer. Absent on records written before presets existed — read as `sent`.";
26
+ readonly enum: readonly ["sent", "preset"];
27
+ readonly default: "sent";
28
+ };
29
+ readonly name: {
30
+ readonly type: "string";
31
+ readonly description: "Display name of a preset. Sent announcements have none.";
32
+ };
33
+ readonly presetId: {
34
+ readonly type: "string";
35
+ readonly description: "The preset this sent announcement was loaded from, when it was.";
36
+ };
23
37
  readonly audience: {
24
38
  readonly $ref: "definitions.json#/definitions/audience";
25
39
  readonly description: "Who this announcement was directed at on the people axis. PA surfaces are the other axis and never reach the emergency-contact roster.";
@@ -38,16 +52,16 @@ export declare const announcementSchema: {
38
52
  };
39
53
  readonly surfaces: {
40
54
  readonly type: "array";
41
- readonly description: "Surface channels the announcement was broadcast to, as the sender selected them. `category` is open for future surface kinds; only `pa` ships today.";
55
+ readonly description: "Surface channels the announcement was broadcast to, as the sender selected them. `discriminator` is the mediaSource `Device.discriminator` targeted, open for future surface types; only `paSystem` ships today.";
42
56
  readonly items: {
43
57
  readonly type: "object";
44
- readonly required: readonly ["category", "kind"];
58
+ readonly required: readonly ["discriminator", "scope"];
45
59
  readonly properties: {
46
- readonly category: {
60
+ readonly discriminator: {
47
61
  readonly type: "string";
48
- readonly enum: readonly ["pa"];
62
+ readonly enum: readonly ["paSystem"];
49
63
  };
50
- readonly kind: {
64
+ readonly scope: {
51
65
  readonly type: "string";
52
66
  readonly enum: readonly ["all", "spaces", "devices"];
53
67
  };
@@ -70,12 +84,17 @@ export declare const announcementSchema: {
70
84
  readonly type: "string";
71
85
  };
72
86
  };
87
+ readonly playlistId: {
88
+ readonly type: "string";
89
+ readonly description: "A PA playlist (driver recording) played in place of the spoken body; its zones are the playlist's own.";
90
+ };
73
91
  };
74
92
  readonly additionalProperties: false;
75
93
  };
76
94
  };
77
95
  readonly body: {
78
96
  readonly type: "string";
97
+ readonly description: "The spoken/written message. Optional only when every surface plays a preset and no channel is selected.";
79
98
  };
80
99
  readonly media: {
81
100
  readonly $ref: "mediaFile.json";
@@ -83,6 +102,103 @@ export declare const announcementSchema: {
83
102
  readonly sentBy: {
84
103
  readonly type: "string";
85
104
  };
105
+ readonly result: {
106
+ readonly type: "object";
107
+ readonly additionalProperties: false;
108
+ readonly required: readonly ["recipientsResolved", "perChannel", "skipped", "surfaces"];
109
+ readonly description: "What the send actually achieved, written once at send time and never recomputed. Absent on presets and on sends recorded before this was stored. The `audience.delivery` counts are the same send viewed per audience; this is the per-channel and per-device detail behind them.";
110
+ readonly properties: {
111
+ readonly recipientsResolved: {
112
+ readonly type: "integer";
113
+ readonly minimum: 0;
114
+ readonly description: "How many internal Users the audience selector resolved to. Zero when no personal channel was selected, however wide the selector — an announcement with no channel reaches no User.";
115
+ };
116
+ readonly external: {
117
+ readonly type: "object";
118
+ readonly additionalProperties: false;
119
+ readonly required: readonly ["recipients", "delivery"];
120
+ readonly description: "The external SIS roster this send reached. Absent when no external group was named.";
121
+ readonly properties: {
122
+ readonly recipients: {
123
+ readonly type: "integer";
124
+ readonly minimum: 0;
125
+ readonly description: "Size of the roster the named groups resolved to.";
126
+ };
127
+ readonly delivery: {
128
+ readonly type: "object";
129
+ readonly additionalProperties: false;
130
+ readonly description: "Per-channel counts, present only for the channels attempted.";
131
+ readonly properties: {
132
+ readonly sms: {
133
+ readonly $ref: "definitions.json#/definitions/deliveryCounts";
134
+ };
135
+ readonly email: {
136
+ readonly $ref: "definitions.json#/definitions/deliveryCounts";
137
+ };
138
+ };
139
+ };
140
+ };
141
+ };
142
+ readonly perChannel: {
143
+ readonly type: "object";
144
+ readonly additionalProperties: false;
145
+ readonly required: readonly ["sms", "email"];
146
+ readonly description: "Messages handed to each personal channel; zero for a channel the send did not select.";
147
+ readonly properties: {
148
+ readonly sms: {
149
+ readonly type: "integer";
150
+ };
151
+ readonly email: {
152
+ readonly type: "integer";
153
+ };
154
+ };
155
+ };
156
+ readonly skipped: {
157
+ readonly type: "array";
158
+ readonly description: "Recipients a selected channel could not carry the announcement to. A missing contact detail is a per-channel skip, not a failed send, so one recipient may appear once per channel.";
159
+ readonly items: {
160
+ readonly type: "object";
161
+ readonly required: readonly ["userId", "channel", "reason"];
162
+ readonly additionalProperties: false;
163
+ readonly properties: {
164
+ readonly userId: {
165
+ readonly type: "string";
166
+ };
167
+ readonly channel: {
168
+ readonly type: "string";
169
+ readonly enum: readonly ["sms", "email"];
170
+ };
171
+ readonly reason: {
172
+ readonly type: "string";
173
+ readonly enum: readonly ["no-phone", "no-email"];
174
+ };
175
+ };
176
+ };
177
+ };
178
+ readonly surfaces: {
179
+ readonly type: "array";
180
+ readonly description: "Per-device outcome of the surface page, one entry per device the selectors resolved to. Distinct from the top-level `surfaces`, which is the selector the sender expressed.";
181
+ readonly items: {
182
+ readonly type: "object";
183
+ readonly required: readonly ["deviceId", "status"];
184
+ readonly additionalProperties: false;
185
+ readonly properties: {
186
+ readonly deviceId: {
187
+ readonly type: "string";
188
+ };
189
+ readonly status: {
190
+ readonly type: "string";
191
+ readonly enum: readonly ["sent", "failed", "skipped"];
192
+ };
193
+ readonly reason: {
194
+ readonly type: "string";
195
+ readonly description: '`unsupported` when the driver advertises no content command; absent otherwise.';
196
+ };
197
+ };
198
+ };
199
+ };
200
+ };
201
+ };
86
202
  readonly tags: {
87
203
  readonly type: "array";
88
204
  readonly items: {
@@ -5,11 +5,7 @@ const announcementSchema = {
5
5
  title: "Announcement",
6
6
  description: "Announcement message sent to users",
7
7
  type: "object",
8
- required: [
9
- "id",
10
- "type",
11
- "body"
12
- ],
8
+ required: ["id", "type"],
13
9
  properties: {
14
10
  id: { $ref: "definitions.json#/definitions/id" },
15
11
  propertyId: {
@@ -21,6 +17,20 @@ const announcementSchema = {
21
17
  enum: ["announcement"],
22
18
  default: "announcement"
23
19
  },
20
+ status: {
21
+ type: "string",
22
+ description: "`sent` is a real broadcast; `preset` is a named, reusable configuration a sender loads into the composer. Absent on records written before presets existed — read as `sent`.",
23
+ enum: ["sent", "preset"],
24
+ default: "sent"
25
+ },
26
+ name: {
27
+ type: "string",
28
+ description: "Display name of a preset. Sent announcements have none."
29
+ },
30
+ presetId: {
31
+ type: "string",
32
+ description: "The preset this sent announcement was loaded from, when it was."
33
+ },
24
34
  audience: {
25
35
  $ref: "definitions.json#/definitions/audience",
26
36
  description: "Who this announcement was directed at on the people axis. PA surfaces are the other axis and never reach the emergency-contact roster."
@@ -39,16 +49,16 @@ const announcementSchema = {
39
49
  },
40
50
  surfaces: {
41
51
  type: "array",
42
- description: "Surface channels the announcement was broadcast to, as the sender selected them. `category` is open for future surface kinds; only `pa` ships today.",
52
+ description: "Surface channels the announcement was broadcast to, as the sender selected them. `discriminator` is the mediaSource `Device.discriminator` targeted, open for future surface types; only `paSystem` ships today.",
43
53
  items: {
44
54
  type: "object",
45
- required: ["category", "kind"],
55
+ required: ["discriminator", "scope"],
46
56
  properties: {
47
- category: {
57
+ discriminator: {
48
58
  type: "string",
49
- enum: ["pa"]
59
+ enum: ["paSystem"]
50
60
  },
51
- kind: {
61
+ scope: {
52
62
  type: "string",
53
63
  enum: [
54
64
  "all",
@@ -68,14 +78,119 @@ const announcementSchema = {
68
78
  type: "array",
69
79
  description: "PA output zones to page; all zones when omitted.",
70
80
  items: { type: "string" }
81
+ },
82
+ playlistId: {
83
+ type: "string",
84
+ description: "A PA playlist (driver recording) played in place of the spoken body; its zones are the playlist's own."
71
85
  }
72
86
  },
73
87
  additionalProperties: false
74
88
  }
75
89
  },
76
- body: { type: "string" },
90
+ body: {
91
+ type: "string",
92
+ description: "The spoken/written message. Optional only when every surface plays a preset and no channel is selected."
93
+ },
77
94
  media: { $ref: "mediaFile.json" },
78
95
  sentBy: { type: "string" },
96
+ result: {
97
+ type: "object",
98
+ additionalProperties: false,
99
+ required: [
100
+ "recipientsResolved",
101
+ "perChannel",
102
+ "skipped",
103
+ "surfaces"
104
+ ],
105
+ description: "What the send actually achieved, written once at send time and never recomputed. Absent on presets and on sends recorded before this was stored. The `audience.delivery` counts are the same send viewed per audience; this is the per-channel and per-device detail behind them.",
106
+ properties: {
107
+ recipientsResolved: {
108
+ type: "integer",
109
+ minimum: 0,
110
+ description: "How many internal Users the audience selector resolved to. Zero when no personal channel was selected, however wide the selector — an announcement with no channel reaches no User."
111
+ },
112
+ external: {
113
+ type: "object",
114
+ additionalProperties: false,
115
+ required: ["recipients", "delivery"],
116
+ description: "The external SIS roster this send reached. Absent when no external group was named.",
117
+ properties: {
118
+ recipients: {
119
+ type: "integer",
120
+ minimum: 0,
121
+ description: "Size of the roster the named groups resolved to."
122
+ },
123
+ delivery: {
124
+ type: "object",
125
+ additionalProperties: false,
126
+ description: "Per-channel counts, present only for the channels attempted.",
127
+ properties: {
128
+ sms: { $ref: "definitions.json#/definitions/deliveryCounts" },
129
+ email: { $ref: "definitions.json#/definitions/deliveryCounts" }
130
+ }
131
+ }
132
+ }
133
+ },
134
+ perChannel: {
135
+ type: "object",
136
+ additionalProperties: false,
137
+ required: ["sms", "email"],
138
+ description: "Messages handed to each personal channel; zero for a channel the send did not select.",
139
+ properties: {
140
+ sms: { type: "integer" },
141
+ email: { type: "integer" }
142
+ }
143
+ },
144
+ skipped: {
145
+ type: "array",
146
+ description: "Recipients a selected channel could not carry the announcement to. A missing contact detail is a per-channel skip, not a failed send, so one recipient may appear once per channel.",
147
+ items: {
148
+ type: "object",
149
+ required: [
150
+ "userId",
151
+ "channel",
152
+ "reason"
153
+ ],
154
+ additionalProperties: false,
155
+ properties: {
156
+ userId: { type: "string" },
157
+ channel: {
158
+ type: "string",
159
+ enum: ["sms", "email"]
160
+ },
161
+ reason: {
162
+ type: "string",
163
+ enum: ["no-phone", "no-email"]
164
+ }
165
+ }
166
+ }
167
+ },
168
+ surfaces: {
169
+ type: "array",
170
+ description: "Per-device outcome of the surface page, one entry per device the selectors resolved to. Distinct from the top-level `surfaces`, which is the selector the sender expressed.",
171
+ items: {
172
+ type: "object",
173
+ required: ["deviceId", "status"],
174
+ additionalProperties: false,
175
+ properties: {
176
+ deviceId: { type: "string" },
177
+ status: {
178
+ type: "string",
179
+ enum: [
180
+ "sent",
181
+ "failed",
182
+ "skipped"
183
+ ]
184
+ },
185
+ reason: {
186
+ type: "string",
187
+ description: "`unsupported` when the driver advertises no content command; absent otherwise."
188
+ }
189
+ }
190
+ }
191
+ }
192
+ }
193
+ },
79
194
  tags: {
80
195
  type: "array",
81
196
  items: { type: "string" }
@@ -1 +1 @@
1
- {"version":3,"file":"announcement.js","names":[],"sources":["../../.generated/schemas/announcement.ts"],"sourcesContent":["import defs, { ISODateString } from \"./definitions\";\nimport type { FromSchema } from \"json-schema-to-ts\";\n\nexport const announcementSchema = {\n $schema: \"http://json-schema.org/draft-07/schema\",\n $id: \"announcement.json\",\n title: \"Announcement\",\n description: \"Announcement message sent to users\",\n type: \"object\",\n required: [\"id\", \"type\", \"body\"],\n properties: {\n id: { $ref: \"definitions.json#/definitions/id\" },\n propertyId: {\n type: \"string\",\n description:\n \"ID of the property this entity belongs to. Optional — used as a per-document filter inside the org-scoped database.\",\n },\n type: {\n type: \"string\",\n enum: [\"announcement\"],\n default: \"announcement\",\n },\n audience: {\n $ref: \"definitions.json#/definitions/audience\",\n description:\n \"Who this announcement was directed at on the people axis. PA surfaces are the other axis and never reach the emergency-contact roster.\",\n },\n channels: {\n type: \"array\",\n description: \"Personal channels this announcement was sent over.\",\n items: {\n type: \"string\",\n enum: [\"sms\", \"email\"],\n },\n },\n subject: {\n type: \"string\",\n description: \"Email subject, and the title shown on a surface.\",\n },\n surfaces: {\n type: \"array\",\n description:\n \"Surface channels the announcement was broadcast to, as the sender selected them. `category` is open for future surface kinds; only `pa` ships today.\",\n items: {\n type: \"object\",\n required: [\"category\", \"kind\"],\n properties: {\n category: {\n type: \"string\",\n enum: [\"pa\"],\n },\n kind: {\n type: \"string\",\n enum: [\"all\", \"spaces\", \"devices\"],\n },\n spaceIds: {\n type: \"array\",\n items: { type: \"string\" },\n },\n deviceIds: {\n type: \"array\",\n items: { type: \"string\" },\n },\n outputs: {\n type: \"array\",\n description: \"PA output zones to page; all zones when omitted.\",\n items: { type: \"string\" },\n },\n },\n additionalProperties: false,\n },\n },\n body: {\n type: \"string\",\n },\n media: {\n $ref: \"mediaFile.json\",\n },\n sentBy: {\n type: \"string\",\n },\n tags: {\n type: \"array\",\n items: {\n type: \"string\",\n },\n },\n createdAt: {\n $ref: \"definitions.json#/definitions/date\",\n },\n updatedAt: {\n $ref: \"definitions.json#/definitions/date\",\n },\n deletedAt: {\n $ref: \"definitions.json#/definitions/date\",\n },\n },\n additionalProperties: false,\n} as const;\n\nexport type AnnouncementSchema = FromSchema<\n typeof announcementSchema,\n {\n references: [typeof defs];\n deserialize: [\n {\n pattern: {\n format: \"date-time\";\n };\n output: Date | ISODateString;\n },\n ];\n }\n>;\n"],"mappings":";AAGA,MAAa,qBAAqB;CAChC,SAAS;CACT,KAAK;CACL,OAAO;CACP,aAAa;CACb,MAAM;CACN,UAAU;EAAC;EAAM;EAAQ;CAAM;CAC/B,YAAY;EACV,IAAI,EAAE,MAAM,mCAAmC;EAC/C,YAAY;GACV,MAAM;GACN,aACE;EACJ;EACA,MAAM;GACJ,MAAM;GACN,MAAM,CAAC,cAAc;GACrB,SAAS;EACX;EACA,UAAU;GACR,MAAM;GACN,aACE;EACJ;EACA,UAAU;GACR,MAAM;GACN,aAAa;GACb,OAAO;IACL,MAAM;IACN,MAAM,CAAC,OAAO,OAAO;GACvB;EACF;EACA,SAAS;GACP,MAAM;GACN,aAAa;EACf;EACA,UAAU;GACR,MAAM;GACN,aACE;GACF,OAAO;IACL,MAAM;IACN,UAAU,CAAC,YAAY,MAAM;IAC7B,YAAY;KACV,UAAU;MACR,MAAM;MACN,MAAM,CAAC,IAAI;KACb;KACA,MAAM;MACJ,MAAM;MACN,MAAM;OAAC;OAAO;OAAU;MAAS;KACnC;KACA,UAAU;MACR,MAAM;MACN,OAAO,EAAE,MAAM,SAAS;KAC1B;KACA,WAAW;MACT,MAAM;MACN,OAAO,EAAE,MAAM,SAAS;KAC1B;KACA,SAAS;MACP,MAAM;MACN,aAAa;MACb,OAAO,EAAE,MAAM,SAAS;KAC1B;IACF;IACA,sBAAsB;GACxB;EACF;EACA,MAAM,EACJ,MAAM,SACR;EACA,OAAO,EACL,MAAM,iBACR;EACA,QAAQ,EACN,MAAM,SACR;EACA,MAAM;GACJ,MAAM;GACN,OAAO,EACL,MAAM,SACR;EACF;EACA,WAAW,EACT,MAAM,qCACR;EACA,WAAW,EACT,MAAM,qCACR;EACA,WAAW,EACT,MAAM,qCACR;CACF;CACA,sBAAsB;AACxB"}
1
+ {"version":3,"file":"announcement.js","names":[],"sources":["../../.generated/schemas/announcement.ts"],"sourcesContent":["import defs, { ISODateString } from \"./definitions\";\nimport type { FromSchema } from \"json-schema-to-ts\";\n\nexport const announcementSchema = {\n $schema: \"http://json-schema.org/draft-07/schema\",\n $id: \"announcement.json\",\n title: \"Announcement\",\n description: \"Announcement message sent to users\",\n type: \"object\",\n required: [\"id\", \"type\"],\n properties: {\n id: { $ref: \"definitions.json#/definitions/id\" },\n propertyId: {\n type: \"string\",\n description:\n \"ID of the property this entity belongs to. Optional — used as a per-document filter inside the org-scoped database.\",\n },\n type: {\n type: \"string\",\n enum: [\"announcement\"],\n default: \"announcement\",\n },\n status: {\n type: \"string\",\n description:\n \"`sent` is a real broadcast; `preset` is a named, reusable configuration a sender loads into the composer. Absent on records written before presets existed — read as `sent`.\",\n enum: [\"sent\", \"preset\"],\n default: \"sent\",\n },\n name: {\n type: \"string\",\n description: \"Display name of a preset. Sent announcements have none.\",\n },\n presetId: {\n type: \"string\",\n description:\n \"The preset this sent announcement was loaded from, when it was.\",\n },\n audience: {\n $ref: \"definitions.json#/definitions/audience\",\n description:\n \"Who this announcement was directed at on the people axis. PA surfaces are the other axis and never reach the emergency-contact roster.\",\n },\n channels: {\n type: \"array\",\n description: \"Personal channels this announcement was sent over.\",\n items: {\n type: \"string\",\n enum: [\"sms\", \"email\"],\n },\n },\n subject: {\n type: \"string\",\n description: \"Email subject, and the title shown on a surface.\",\n },\n surfaces: {\n type: \"array\",\n description:\n \"Surface channels the announcement was broadcast to, as the sender selected them. `discriminator` is the mediaSource `Device.discriminator` targeted, open for future surface types; only `paSystem` ships today.\",\n items: {\n type: \"object\",\n required: [\"discriminator\", \"scope\"],\n properties: {\n discriminator: {\n type: \"string\",\n enum: [\"paSystem\"],\n },\n scope: {\n type: \"string\",\n enum: [\"all\", \"spaces\", \"devices\"],\n },\n spaceIds: {\n type: \"array\",\n items: { type: \"string\" },\n },\n deviceIds: {\n type: \"array\",\n items: { type: \"string\" },\n },\n outputs: {\n type: \"array\",\n description: \"PA output zones to page; all zones when omitted.\",\n items: { type: \"string\" },\n },\n playlistId: {\n type: \"string\",\n description:\n \"A PA playlist (driver recording) played in place of the spoken body; its zones are the playlist's own.\",\n },\n },\n additionalProperties: false,\n },\n },\n body: {\n type: \"string\",\n description:\n \"The spoken/written message. Optional only when every surface plays a preset and no channel is selected.\",\n },\n media: {\n $ref: \"mediaFile.json\",\n },\n sentBy: {\n type: \"string\",\n },\n result: {\n type: \"object\",\n additionalProperties: false,\n required: [\"recipientsResolved\", \"perChannel\", \"skipped\", \"surfaces\"],\n description:\n \"What the send actually achieved, written once at send time and never recomputed. Absent on presets and on sends recorded before this was stored. The `audience.delivery` counts are the same send viewed per audience; this is the per-channel and per-device detail behind them.\",\n properties: {\n recipientsResolved: {\n type: \"integer\",\n minimum: 0,\n description:\n \"How many internal Users the audience selector resolved to. Zero when no personal channel was selected, however wide the selector — an announcement with no channel reaches no User.\",\n },\n external: {\n type: \"object\",\n additionalProperties: false,\n required: [\"recipients\", \"delivery\"],\n description:\n \"The external SIS roster this send reached. Absent when no external group was named.\",\n properties: {\n recipients: {\n type: \"integer\",\n minimum: 0,\n description: \"Size of the roster the named groups resolved to.\",\n },\n delivery: {\n type: \"object\",\n additionalProperties: false,\n description:\n \"Per-channel counts, present only for the channels attempted.\",\n properties: {\n sms: { $ref: \"definitions.json#/definitions/deliveryCounts\" },\n email: { $ref: \"definitions.json#/definitions/deliveryCounts\" },\n },\n },\n },\n },\n perChannel: {\n type: \"object\",\n additionalProperties: false,\n required: [\"sms\", \"email\"],\n description:\n \"Messages handed to each personal channel; zero for a channel the send did not select.\",\n properties: {\n sms: { type: \"integer\" },\n email: { type: \"integer\" },\n },\n },\n skipped: {\n type: \"array\",\n description:\n \"Recipients a selected channel could not carry the announcement to. A missing contact detail is a per-channel skip, not a failed send, so one recipient may appear once per channel.\",\n items: {\n type: \"object\",\n required: [\"userId\", \"channel\", \"reason\"],\n additionalProperties: false,\n properties: {\n userId: { type: \"string\" },\n channel: { type: \"string\", enum: [\"sms\", \"email\"] },\n reason: { type: \"string\", enum: [\"no-phone\", \"no-email\"] },\n },\n },\n },\n surfaces: {\n type: \"array\",\n description:\n \"Per-device outcome of the surface page, one entry per device the selectors resolved to. Distinct from the top-level `surfaces`, which is the selector the sender expressed.\",\n items: {\n type: \"object\",\n required: [\"deviceId\", \"status\"],\n additionalProperties: false,\n properties: {\n deviceId: { type: \"string\" },\n status: {\n type: \"string\",\n enum: [\"sent\", \"failed\", \"skipped\"],\n },\n reason: {\n type: \"string\",\n description:\n '`unsupported` when the driver advertises no content command; absent otherwise.',\n },\n },\n },\n },\n },\n },\n tags: {\n type: \"array\",\n items: {\n type: \"string\",\n },\n },\n createdAt: {\n $ref: \"definitions.json#/definitions/date\",\n },\n updatedAt: {\n $ref: \"definitions.json#/definitions/date\",\n },\n deletedAt: {\n $ref: \"definitions.json#/definitions/date\",\n },\n },\n additionalProperties: false,\n} as const;\n\nexport type AnnouncementSchema = FromSchema<\n typeof announcementSchema,\n {\n references: [typeof defs];\n deserialize: [\n {\n pattern: {\n format: \"date-time\";\n };\n output: Date | ISODateString;\n },\n ];\n }\n>;\n"],"mappings":"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"}
@@ -8,6 +8,14 @@ export type NotificationChannel = (typeof NOTIFICATION_CHANNELS)[number];
8
8
  */
9
9
  export declare const PLATFORM_ROLE_NAMES: readonly ["SuperAdmin", "Administrator", "Manager", "Agent", "User"];
10
10
  export type PlatformRoleName = (typeof PLATFORM_ROLE_NAMES)[number];
11
+ /**
12
+ * The people outside the platform a broadcast may name, sourced from the SIS
13
+ * roster. `students` is every system user the SIS marks as a Student;
14
+ * `parents` is everybody else on the roster — every emergency-contact
15
+ * relationship the source system carries, whatever it calls it.
16
+ */
17
+ export declare const EXTERNAL_AUDIENCE_GROUPS: readonly ["students", "parents"];
18
+ export type ExternalAudienceGroup = (typeof EXTERNAL_AUDIENCE_GROUPS)[number];
11
19
  declare const defs: {
12
20
  readonly $schema: "http://json-schema.org/draft-07/schema";
13
21
  readonly $id: "definitions.json";
@@ -234,9 +242,18 @@ declare const defs: {
234
242
  };
235
243
  };
236
244
  };
245
+ readonly external: {
246
+ readonly type: "array";
247
+ readonly uniqueItems: true;
248
+ readonly description: "Which groups of the external SIS roster were included. Human-triggered sends only; an Automation can never set it.";
249
+ readonly items: {
250
+ readonly type: "string";
251
+ readonly enum: readonly ["students", "parents"];
252
+ };
253
+ };
237
254
  readonly emergencyContacts: {
238
255
  readonly type: "boolean";
239
- readonly description: "Whether the external SIS emergency-contact roster was included. Human-triggered sends only; an Automation can never set it.";
256
+ readonly description: 'Deprecated: superseded by `external`. A stored `true` reads as `external: ["parents"]`.';
240
257
  };
241
258
  readonly users: {
242
259
  readonly type: "array";
@@ -269,10 +286,75 @@ declare const defs: {
269
286
  };
270
287
  };
271
288
  };
289
+ readonly external: {
290
+ readonly type: "object";
291
+ readonly additionalProperties: false;
292
+ readonly required: readonly ["recipients", "sent", "failed"];
293
+ readonly properties: {
294
+ readonly recipients: {
295
+ readonly type: "integer";
296
+ readonly minimum: 0;
297
+ };
298
+ readonly sent: {
299
+ readonly type: "integer";
300
+ readonly minimum: 0;
301
+ };
302
+ readonly failed: {
303
+ readonly type: "integer";
304
+ readonly minimum: 0;
305
+ };
306
+ readonly byChannel: {
307
+ readonly type: "object";
308
+ readonly additionalProperties: false;
309
+ readonly description: "Per-channel counts, present only for the channels attempted.";
310
+ readonly properties: {
311
+ readonly sms: {
312
+ readonly type: "object";
313
+ readonly additionalProperties: false;
314
+ readonly required: readonly ["recipients", "sent", "failed"];
315
+ readonly properties: {
316
+ readonly recipients: {
317
+ readonly type: "integer";
318
+ readonly minimum: 0;
319
+ };
320
+ readonly sent: {
321
+ readonly type: "integer";
322
+ readonly minimum: 0;
323
+ };
324
+ readonly failed: {
325
+ readonly type: "integer";
326
+ readonly minimum: 0;
327
+ };
328
+ };
329
+ };
330
+ readonly email: {
331
+ readonly type: "object";
332
+ readonly additionalProperties: false;
333
+ readonly required: readonly ["recipients", "sent", "failed"];
334
+ readonly properties: {
335
+ readonly recipients: {
336
+ readonly type: "integer";
337
+ readonly minimum: 0;
338
+ };
339
+ readonly sent: {
340
+ readonly type: "integer";
341
+ readonly minimum: 0;
342
+ };
343
+ readonly failed: {
344
+ readonly type: "integer";
345
+ readonly minimum: 0;
346
+ };
347
+ };
348
+ };
349
+ };
350
+ };
351
+ };
352
+ };
272
353
  readonly emergencyContacts: {
273
354
  readonly type: "object";
274
355
  readonly additionalProperties: false;
275
356
  readonly required: readonly ["recipients", "sent", "failed"];
357
+ readonly description: "Deprecated: superseded by `external`.";
276
358
  readonly properties: {
277
359
  readonly recipients: {
278
360
  readonly type: "integer";