grm-shared-library 1.1.210 → 1.1.212

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 (108) hide show
  1. package/README.md +58 -0
  2. package/dist/cjs/kafka/dtos/account-deletion/account-deletion-request-payload.dto.js +6 -0
  3. package/dist/cjs/kafka/dtos/account-deletion/account-deletion-request-payload.dto.js.map +1 -1
  4. package/dist/cjs/kafka/dtos/otp/create-otp-payload.dto.js +6 -0
  5. package/dist/cjs/kafka/dtos/otp/create-otp-payload.dto.js.map +1 -1
  6. package/dist/cjs/kafka/dtos/password/password-reset-payload.dto.js +6 -0
  7. package/dist/cjs/kafka/dtos/password/password-reset-payload.dto.js.map +1 -1
  8. package/dist/cjs/kafka/dtos/user/create-user-registered-payload.dto.js +6 -0
  9. package/dist/cjs/kafka/dtos/user/create-user-registered-payload.dto.js.map +1 -1
  10. package/dist/cjs/modules/notification/constants/notification-sender.const.js +30 -0
  11. package/dist/cjs/modules/notification/constants/notification-sender.const.js.map +1 -0
  12. package/dist/cjs/modules/notification/dtos/organization-notification-settings.dto.js +354 -0
  13. package/dist/cjs/modules/notification/dtos/organization-notification-settings.dto.js.map +1 -0
  14. package/dist/cjs/modules/notification/enums/email-sender-verification.enum.js +33 -0
  15. package/dist/cjs/modules/notification/enums/email-sender-verification.enum.js.map +1 -0
  16. package/dist/cjs/modules/notification/enums/notification-branding-source.enum.js +22 -0
  17. package/dist/cjs/modules/notification/enums/notification-branding-source.enum.js.map +1 -0
  18. package/dist/cjs/modules/notification/enums/notification-sender-source.enum.js +15 -0
  19. package/dist/cjs/modules/notification/enums/notification-sender-source.enum.js.map +1 -0
  20. package/dist/cjs/modules/notification/enums/notification-sender-status.enum.js +24 -0
  21. package/dist/cjs/modules/notification/enums/notification-sender-status.enum.js.map +1 -0
  22. package/dist/cjs/modules/notification/enums/sms-provider-name.enum.js +5 -0
  23. package/dist/cjs/modules/notification/enums/sms-provider-name.enum.js.map +1 -1
  24. package/dist/cjs/modules/notification/enums/sms-sender-type.enum.js +22 -0
  25. package/dist/cjs/modules/notification/enums/sms-sender-type.enum.js.map +1 -0
  26. package/dist/cjs/modules/notification/index.js +10 -0
  27. package/dist/cjs/modules/notification/index.js.map +1 -1
  28. package/dist/cjs/modules/notification/interfaces/organization-notification-settings.js +3 -0
  29. package/dist/cjs/modules/notification/interfaces/organization-notification-settings.js.map +1 -0
  30. package/dist/cjs/modules/notification/utils/notification-sender.util.js +67 -0
  31. package/dist/cjs/modules/notification/utils/notification-sender.util.js.map +1 -0
  32. package/dist/cjs/modules/permission/data/permissions.data.js +12 -0
  33. package/dist/cjs/modules/permission/data/permissions.data.js.map +1 -1
  34. package/dist/cjs/modules/permission/enums/permission-actions.enum.js +31 -0
  35. package/dist/cjs/modules/permission/enums/permission-actions.enum.js.map +1 -1
  36. package/dist/cjs/modules/permission/enums/permissions-module.enum.js +1 -0
  37. package/dist/cjs/modules/permission/enums/permissions-module.enum.js.map +1 -1
  38. package/dist/cjs/modules/role/constants/roles-by-scope.js +2 -1
  39. package/dist/cjs/modules/role/constants/roles-by-scope.js.map +1 -1
  40. package/dist/cjs/modules/role/data/roles.data.js +95 -2
  41. package/dist/cjs/modules/role/data/roles.data.js.map +1 -1
  42. package/dist/cjs/modules/role/enums/role.enum.js +6 -0
  43. package/dist/cjs/modules/role/enums/role.enum.js.map +1 -1
  44. package/dist/esm/kafka/dtos/account-deletion/account-deletion-request-payload.dto.js +7 -1
  45. package/dist/esm/kafka/dtos/account-deletion/account-deletion-request-payload.dto.js.map +1 -1
  46. package/dist/esm/kafka/dtos/otp/create-otp-payload.dto.js +7 -1
  47. package/dist/esm/kafka/dtos/otp/create-otp-payload.dto.js.map +1 -1
  48. package/dist/esm/kafka/dtos/password/password-reset-payload.dto.js +7 -1
  49. package/dist/esm/kafka/dtos/password/password-reset-payload.dto.js.map +1 -1
  50. package/dist/esm/kafka/dtos/user/create-user-registered-payload.dto.js +7 -1
  51. package/dist/esm/kafka/dtos/user/create-user-registered-payload.dto.js.map +1 -1
  52. package/dist/esm/modules/notification/constants/notification-sender.const.js +27 -0
  53. package/dist/esm/modules/notification/constants/notification-sender.const.js.map +1 -0
  54. package/dist/esm/modules/notification/dtos/organization-notification-settings.dto.js +343 -0
  55. package/dist/esm/modules/notification/dtos/organization-notification-settings.dto.js.map +1 -0
  56. package/dist/esm/modules/notification/enums/email-sender-verification.enum.js +30 -0
  57. package/dist/esm/modules/notification/enums/email-sender-verification.enum.js.map +1 -0
  58. package/dist/esm/modules/notification/enums/notification-branding-source.enum.js +19 -0
  59. package/dist/esm/modules/notification/enums/notification-branding-source.enum.js.map +1 -0
  60. package/dist/esm/modules/notification/enums/notification-sender-source.enum.js +12 -0
  61. package/dist/esm/modules/notification/enums/notification-sender-source.enum.js.map +1 -0
  62. package/dist/esm/modules/notification/enums/notification-sender-status.enum.js +21 -0
  63. package/dist/esm/modules/notification/enums/notification-sender-status.enum.js.map +1 -0
  64. package/dist/esm/modules/notification/enums/sms-provider-name.enum.js +5 -0
  65. package/dist/esm/modules/notification/enums/sms-provider-name.enum.js.map +1 -1
  66. package/dist/esm/modules/notification/enums/sms-sender-type.enum.js +19 -0
  67. package/dist/esm/modules/notification/enums/sms-sender-type.enum.js.map +1 -0
  68. package/dist/esm/modules/notification/index.js +10 -0
  69. package/dist/esm/modules/notification/index.js.map +1 -1
  70. package/dist/esm/modules/notification/interfaces/organization-notification-settings.js +2 -0
  71. package/dist/esm/modules/notification/interfaces/organization-notification-settings.js.map +1 -0
  72. package/dist/esm/modules/notification/utils/notification-sender.util.js +60 -0
  73. package/dist/esm/modules/notification/utils/notification-sender.util.js.map +1 -0
  74. package/dist/esm/modules/permission/data/permissions.data.js +12 -0
  75. package/dist/esm/modules/permission/data/permissions.data.js.map +1 -1
  76. package/dist/esm/modules/permission/enums/permission-actions.enum.js +31 -0
  77. package/dist/esm/modules/permission/enums/permission-actions.enum.js.map +1 -1
  78. package/dist/esm/modules/permission/enums/permissions-module.enum.js +1 -0
  79. package/dist/esm/modules/permission/enums/permissions-module.enum.js.map +1 -1
  80. package/dist/esm/modules/role/constants/roles-by-scope.js +2 -1
  81. package/dist/esm/modules/role/constants/roles-by-scope.js.map +1 -1
  82. package/dist/esm/modules/role/data/roles.data.js +95 -2
  83. package/dist/esm/modules/role/data/roles.data.js.map +1 -1
  84. package/dist/esm/modules/role/enums/role.enum.js +6 -0
  85. package/dist/esm/modules/role/enums/role.enum.js.map +1 -1
  86. package/dist/types/kafka/dtos/account-deletion/account-deletion-request-payload.dto.d.ts +6 -0
  87. package/dist/types/kafka/dtos/otp/create-otp-payload.dto.d.ts +6 -0
  88. package/dist/types/kafka/dtos/password/password-reset-payload.dto.d.ts +6 -0
  89. package/dist/types/kafka/dtos/user/create-user-registered-payload.dto.d.ts +6 -0
  90. package/dist/types/modules/notification/constants/notification-sender.const.d.ts +16 -0
  91. package/dist/types/modules/notification/dtos/organization-notification-settings.dto.d.ts +64 -0
  92. package/dist/types/modules/notification/enums/email-sender-verification.enum.d.ts +27 -0
  93. package/dist/types/modules/notification/enums/notification-branding-source.enum.d.ts +17 -0
  94. package/dist/types/modules/notification/enums/notification-sender-source.enum.d.ts +10 -0
  95. package/dist/types/modules/notification/enums/notification-sender-status.enum.d.ts +19 -0
  96. package/dist/types/modules/notification/enums/sms-provider-name.enum.d.ts +6 -1
  97. package/dist/types/modules/notification/enums/sms-sender-type.enum.d.ts +17 -0
  98. package/dist/types/modules/notification/index.d.ts +9 -0
  99. package/dist/types/modules/notification/interfaces/email-send-request.d.ts +6 -0
  100. package/dist/types/modules/notification/interfaces/email-send-result.d.ts +7 -0
  101. package/dist/types/modules/notification/interfaces/organization-notification-settings.d.ts +163 -0
  102. package/dist/types/modules/notification/interfaces/provider-attempt.d.ts +5 -0
  103. package/dist/types/modules/notification/interfaces/sms-send-result.d.ts +7 -0
  104. package/dist/types/modules/notification/utils/notification-sender.util.d.ts +25 -0
  105. package/dist/types/modules/permission/enums/permission-actions.enum.d.ts +20 -1
  106. package/dist/types/modules/permission/enums/permissions-module.enum.d.ts +2 -1
  107. package/dist/types/modules/role/enums/role.enum.d.ts +6 -0
  108. package/package.json +1 -1
@@ -0,0 +1,64 @@
1
+ import { CountryCode } from '../../country/enums/country-code.enum';
2
+ import { IncidentAppId } from '../../incident/enums/incident-app-id.enum';
3
+ import { NotificationSenderStatus } from '../enums/notification-sender-status.enum';
4
+ import { SmsProviderName } from '../enums/sms-provider-name.enum';
5
+ import { SmsSenderType } from '../enums/sms-sender-type.enum';
6
+ export declare class NotificationSocialLinksDto {
7
+ facebook?: string | null;
8
+ x?: string | null;
9
+ instagram?: string | null;
10
+ linkedin?: string | null;
11
+ }
12
+ /**
13
+ * Saves an organization's branding. A PUT of the whole profile: a field sent as
14
+ * null (or "") stops overriding and inherits again; a field left out is untouched.
15
+ */
16
+ export declare class UpsertOrganizationNotificationBrandingDto {
17
+ appId?: IncidentAppId | null;
18
+ companyName?: string | null;
19
+ appName?: string | null;
20
+ logoUrl?: string | null;
21
+ primaryColour?: string | null;
22
+ primaryColourDark?: string | null;
23
+ accentColour?: string | null;
24
+ physicalAddress?: string | null;
25
+ phoneNumber?: string | null;
26
+ contactEmail?: string | null;
27
+ supportEmail?: string | null;
28
+ websiteUrl?: string | null;
29
+ clientBaseUrl?: string | null;
30
+ social?: NotificationSocialLinksDto | null;
31
+ }
32
+ export declare class CreateOrganizationEmailSenderDto {
33
+ fromEmail: string;
34
+ fromName?: string | null;
35
+ replyTo?: string | null;
36
+ isDefault?: boolean;
37
+ }
38
+ export declare class UpdateOrganizationEmailSenderDto {
39
+ fromName?: string | null;
40
+ replyTo?: string | null;
41
+ isDefault?: boolean;
42
+ active?: boolean;
43
+ }
44
+ export declare class CreateOrganizationSmsSenderDto {
45
+ provider: SmsProviderName;
46
+ countryCode?: CountryCode | null;
47
+ senderType: SmsSenderType;
48
+ senderId: string;
49
+ notes?: string | null;
50
+ }
51
+ export declare class UpdateOrganizationSmsSenderDto {
52
+ countryCode?: CountryCode | null;
53
+ senderType?: SmsSenderType;
54
+ senderId?: string;
55
+ notes?: string | null;
56
+ }
57
+ /** Platform operators only: records the outcome of registering the sender with the provider. */
58
+ export declare class ReviewOrganizationSmsSenderDto {
59
+ status: NotificationSenderStatus;
60
+ notes?: string | null;
61
+ }
62
+ export declare class SendTestNotificationEmailDto {
63
+ to: string;
64
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Whether an email provider will accept mail FROM an organization's address.
3
+ *
4
+ * Tracked per provider because the answer differs per provider: an address can be
5
+ * a verified sender in Twilio SendGrid while its domain is unknown to Mailgun.
6
+ * A provider only ever sends from an address it has VERIFIED; for every other
7
+ * state that provider falls back to the platform sender (keeping the
8
+ * organization's display name and reply-to), so a half-configured organization
9
+ * never loses mail to an "unverified sender" rejection.
10
+ */
11
+ export declare enum EmailSenderVerificationStatus {
12
+ /** The provider does not know this address or its domain. */
13
+ UNVERIFIED = "UNVERIFIED",
14
+ /** Verification was started and is waiting on the owner (inbox click or DNS records). */
15
+ PENDING = "PENDING",
16
+ /** The provider accepts mail from this address. */
17
+ VERIFIED = "VERIFIED",
18
+ /** The last check could not be completed (provider error); the previous answer no longer holds. */
19
+ FAILED = "FAILED"
20
+ }
21
+ /** How the provider recognises the address. */
22
+ export declare enum EmailSenderVerificationMethod {
23
+ /** The exact address was verified on its own (SendGrid Single Sender Verification). */
24
+ SINGLE_SENDER = "SINGLE_SENDER",
25
+ /** The whole domain is authenticated (SendGrid domain authentication, Mailgun domain). */
26
+ DOMAIN = "DOMAIN"
27
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Where one resolved branding value came from. Branding is resolved field by
3
+ * field, highest precedence first, so a half-filled profile still produces a
4
+ * complete email:
5
+ *
6
+ * PROFILE the organization's notification settings
7
+ * ORGANIZATION the organization record (clarion-organization)
8
+ * APP_DEFAULT the legacy per-app defaults (deprecated; kept so nothing
9
+ * changes for an organization that has configured nothing)
10
+ * PLATFORM_DEFAULT the platform's own branding
11
+ */
12
+ export declare enum NotificationBrandingSource {
13
+ PROFILE = "PROFILE",
14
+ ORGANIZATION = "ORGANIZATION",
15
+ APP_DEFAULT = "APP_DEFAULT",
16
+ PLATFORM_DEFAULT = "PLATFORM_DEFAULT"
17
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Whose identity a message actually went out under. Recorded on every delivery
3
+ * log so "why did this customer get an Upesy-branded SMS?" is a query, not a guess.
4
+ */
5
+ export declare enum NotificationSenderSource {
6
+ /** The organization's own verified email address / active SMS sender. */
7
+ ORGANIZATION = "ORGANIZATION",
8
+ /** The platform's default (country-aware) sender. */
9
+ PLATFORM_DEFAULT = "PLATFORM_DEFAULT"
10
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Lifecycle of an organization-owned SMS sender.
3
+ *
4
+ * A sender ID only works once the provider (and, behind it, the telco) has
5
+ * registered it, which happens outside Clarion. So an organization REQUESTS a
6
+ * sender and a platform operator ACTIVATES it after the registration is real.
7
+ * Only ACTIVE senders are ever used to send; every other state falls back to the
8
+ * platform's country-aware default sender.
9
+ */
10
+ export declare enum NotificationSenderStatus {
11
+ /** Requested by the organization; not yet confirmed as registered with the provider. */
12
+ PENDING = "PENDING",
13
+ /** Registered with the provider and in use. */
14
+ ACTIVE = "ACTIVE",
15
+ /** Temporarily taken out of use (e.g. the telco suspended it). Kept for history. */
16
+ SUSPENDED = "SUSPENDED",
17
+ /** The provider or the operator refused the registration. */
18
+ REJECTED = "REJECTED"
19
+ }
@@ -1,9 +1,14 @@
1
1
  /**
2
2
  * Identifiers for the SMS providers the notification service can dispatch through.
3
3
  * Provider order/fallback is configuration-driven; new providers can be appended.
4
+ *
5
+ * A code here only RESERVES the name. Whether a provider can actually be used is
6
+ * answered by the notification service's provider catalog
7
+ * (`SmsProviderDescriptor`), which lists only providers with a registered adapter.
4
8
  */
5
9
  export declare enum SmsProviderName {
6
10
  TWILIO = "twilio",
7
11
  UWAZII = "uwazii",
8
- AFRICASTALKING = "africastalking"
12
+ AFRICASTALKING = "africastalking",
13
+ CELCOM = "celcom"
9
14
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * What kind of identity an SMS is sent from.
3
+ *
4
+ * The type decides how the value is validated and how a provider is handed it:
5
+ * an alphanumeric name and a phone number both travel as the provider's "from",
6
+ * while a Twilio Messaging Service SID replaces the from entirely.
7
+ */
8
+ export declare enum SmsSenderType {
9
+ /** A registered alphanumeric sender name, e.g. `G4S`. At most 11 characters. */
10
+ ALPHANUMERIC = "ALPHANUMERIC",
11
+ /** An E.164 long number, e.g. `+254711000000`. */
12
+ PHONE_NUMBER = "PHONE_NUMBER",
13
+ /** A telco short code, e.g. `22384`. */
14
+ SHORT_CODE = "SHORT_CODE",
15
+ /** A provider-side sender pool (Twilio Messaging Service SID, `MG…`). */
16
+ MESSAGING_SERVICE = "MESSAGING_SERVICE"
17
+ }
@@ -3,6 +3,11 @@ export * from './enums/sms-provider-name.enum';
3
3
  export * from './enums/email-provider-name.enum';
4
4
  export * from './enums/notification-overall-status.enum';
5
5
  export * from './enums/provider-failure-reason.enum';
6
+ export * from './enums/sms-sender-type.enum';
7
+ export * from './enums/notification-sender-status.enum';
8
+ export * from './enums/email-sender-verification.enum';
9
+ export * from './enums/notification-sender-source.enum';
10
+ export * from './enums/notification-branding-source.enum';
6
11
  export * from './interfaces/provider-attempt';
7
12
  export * from './interfaces/per-channel-result';
8
13
  export * from './interfaces/sms-send-result';
@@ -10,3 +15,7 @@ export * from './interfaces/email-send-result';
10
15
  export * from './interfaces/notification-dispatch-result';
11
16
  export * from './interfaces/sms-send-request';
12
17
  export * from './interfaces/email-send-request';
18
+ export * from './interfaces/organization-notification-settings';
19
+ export * from './dtos/organization-notification-settings.dto';
20
+ export * from './constants/notification-sender.const';
21
+ export * from './utils/notification-sender.util';
@@ -32,4 +32,10 @@ export interface EmailSendRequest {
32
32
  /** Provider-level categorization tags. */
33
33
  tags?: string[];
34
34
  metadata?: Record<string, any>;
35
+ /**
36
+ * The organization this email is sent on behalf of. Drives sender identity: the
37
+ * orchestrator resolves the organization's verified address per provider and
38
+ * falls back to the platform sender when there is none.
39
+ */
40
+ organizationId?: number;
35
41
  }
@@ -1,6 +1,7 @@
1
1
  import { NotificationChannel } from '../enums/notification-channel.enum';
2
2
  import { EmailProviderName } from '../enums/email-provider-name.enum';
3
3
  import { ProviderFailureReason } from '../enums/provider-failure-reason.enum';
4
+ import { NotificationSenderSource } from '../enums/notification-sender-source.enum';
4
5
  import { ProviderAttempt } from './provider-attempt';
5
6
  /**
6
7
  * Normalized result of an email send across the configured provider chain.
@@ -19,4 +20,10 @@ export interface EmailSendResult {
19
20
  failureReason?: ProviderFailureReason;
20
21
  /** Internal, safe-to-log error summary. */
21
22
  errorMessage?: string;
23
+ /** The organization the message was sent on behalf of, when known. */
24
+ organizationId?: number;
25
+ /** The identity the successful attempt sent from: an email address, or an SMS sender ID. */
26
+ sender?: string;
27
+ /** Whether that identity was the organization's own or the platform default. */
28
+ senderSource?: NotificationSenderSource;
22
29
  }
@@ -0,0 +1,163 @@
1
+ import { CountryCode } from '../../country/enums/country-code.enum';
2
+ import { EmailProviderName } from '../enums/email-provider-name.enum';
3
+ import { EmailSenderVerificationMethod, EmailSenderVerificationStatus } from '../enums/email-sender-verification.enum';
4
+ import { NotificationBrandingSource } from '../enums/notification-branding-source.enum';
5
+ import { NotificationSenderStatus } from '../enums/notification-sender-status.enum';
6
+ import { SmsProviderName } from '../enums/sms-provider-name.enum';
7
+ import { SmsSenderType } from '../enums/sms-sender-type.enum';
8
+ /**
9
+ * Organization notification settings.
10
+ *
11
+ * Clarion is multi-tenant, and what a customer sees in a notification - the logo
12
+ * and colours of an email, the address it came from, the name an SMS arrives
13
+ * under - belongs to the ORGANIZATION that serves them. These contracts describe
14
+ * that identity. `organizationId` is the single key; the legacy `appId` survives
15
+ * only as an alias that lets an event which still carries nothing but an app id
16
+ * find its organization.
17
+ *
18
+ * Owned by clarion-notification, proxied by the gateway, rendered by the admin.
19
+ * Nothing here is a secret: provider credentials stay in the notification
20
+ * service's own configuration and never appear in these shapes.
21
+ */
22
+ export interface NotificationSocialLinks {
23
+ facebook?: string | null;
24
+ x?: string | null;
25
+ instagram?: string | null;
26
+ linkedin?: string | null;
27
+ }
28
+ /** The values a notification template can brand itself with. */
29
+ export interface NotificationBrandingFields {
30
+ /** Legal/trading name shown in the footer, e.g. `G4S Kenya Ltd`. */
31
+ companyName: string;
32
+ /** Product name the customer knows, e.g. `G4S Kenya`. Used in subjects and sign-offs. */
33
+ appName: string;
34
+ /** HTTPS URL of the logo. Email clients will not load anything else. */
35
+ logoUrl: string;
36
+ /** `#RRGGBB`. Buttons, links and accents. */
37
+ primaryColour: string;
38
+ /** `#RRGGBB`. Hover/pressed shade; derived from the primary when not chosen. */
39
+ primaryColourDark: string;
40
+ /** `#RRGGBB`. Secondary highlight. */
41
+ accentColour: string;
42
+ physicalAddress: string;
43
+ phoneNumber: string;
44
+ /** General contact address printed in the footer. Not the address mail is sent FROM. */
45
+ contactEmail: string;
46
+ supportEmail: string;
47
+ websiteUrl: string;
48
+ /** Base URL that links in a notification point at (the organization's web client). */
49
+ clientBaseUrl: string;
50
+ social: NotificationSocialLinks;
51
+ }
52
+ /** What an organization has chosen to override. Every field is optional: gaps are resolved, not rejected. */
53
+ export interface OrganizationNotificationBranding extends Partial<NotificationBrandingFields> {
54
+ organizationId: number;
55
+ /**
56
+ * Legacy alias. An event that carries only an `appId` resolves to the
57
+ * organization whose profile claims it. At most one organization per app id.
58
+ */
59
+ appId?: string | null;
60
+ createdAt?: string;
61
+ updatedAt?: string;
62
+ updatedBy?: number | null;
63
+ }
64
+ /**
65
+ * Branding after resolution: complete, and honest about where each value came
66
+ * from so the admin can show "inherited from the organization record" instead of
67
+ * an empty field.
68
+ */
69
+ export interface ResolvedNotificationBranding extends NotificationBrandingFields {
70
+ organizationId: number | null;
71
+ sources: Record<keyof NotificationBrandingFields, NotificationBrandingSource>;
72
+ }
73
+ /** One provider's answer to "will you send mail from this address?". */
74
+ export interface EmailSenderProviderVerification {
75
+ provider: EmailProviderName;
76
+ status: EmailSenderVerificationStatus;
77
+ method?: EmailSenderVerificationMethod | null;
78
+ /** Operator-facing explanation, e.g. "Domain ke.g4s.com is not added to Mailgun". */
79
+ detail?: string | null;
80
+ checkedAt?: string | null;
81
+ }
82
+ export interface OrganizationEmailSender {
83
+ id: string;
84
+ organizationId: number;
85
+ /** The address mail is sent FROM, e.g. `notifications@ke.g4s.com`. */
86
+ fromEmail: string;
87
+ /** Display name. Falls back to the resolved company name. */
88
+ fromName?: string | null;
89
+ /** Falls back to `fromEmail`. */
90
+ replyTo?: string | null;
91
+ /** The sender used when a notification does not ask for a specific one. One per organization. */
92
+ isDefault: boolean;
93
+ active: boolean;
94
+ verifications: EmailSenderProviderVerification[];
95
+ /** True when at least one configured provider has VERIFIED the address. */
96
+ usable: boolean;
97
+ createdAt?: string;
98
+ updatedAt?: string;
99
+ }
100
+ export interface OrganizationSmsSender {
101
+ id: string;
102
+ organizationId: number;
103
+ /** The provider account this sender is registered with. */
104
+ provider: SmsProviderName;
105
+ /** The destination country it is registered for. Null = every country the provider serves. */
106
+ countryCode?: CountryCode | null;
107
+ senderType: SmsSenderType;
108
+ senderId: string;
109
+ status: NotificationSenderStatus;
110
+ /** Registration reference, telco ticket, anything the operator needs later. */
111
+ notes?: string | null;
112
+ reviewedBy?: number | null;
113
+ reviewedAt?: string | null;
114
+ createdAt?: string;
115
+ updatedAt?: string;
116
+ }
117
+ /** A sender type a provider accepts, with everything a form needs to collect it. */
118
+ export interface SmsProviderSenderTypeDescriptor {
119
+ type: SmsSenderType;
120
+ label: string;
121
+ placeholder?: string;
122
+ description?: string;
123
+ }
124
+ /**
125
+ * Self-description of an SMS provider, published by clarion-notification.
126
+ *
127
+ * Same idea as the tracking provider descriptor: the service that owns the
128
+ * adapter is the source of truth for what it supports, so adding a provider
129
+ * (Celcom, Africa's Talking, ...) changes no client code. Only providers with a
130
+ * registered adapter are described.
131
+ */
132
+ export interface SmsProviderDescriptor {
133
+ provider: SmsProviderName;
134
+ displayName: string;
135
+ description: string;
136
+ /** Countries the adapter can deliver to. */
137
+ supportedCountries: CountryCode[];
138
+ senderTypes: SmsProviderSenderTypeDescriptor[];
139
+ /** Whether the platform's account for this provider is configured and enabled right now. */
140
+ configured: boolean;
141
+ documentationUrl?: string;
142
+ }
143
+ /** The platform senders an organization falls back to. Display-only. */
144
+ export interface PlatformNotificationDefaults {
145
+ email: {
146
+ fromEmail: string | null;
147
+ fromName: string | null;
148
+ };
149
+ /** Per-country default SMS provider chain, e.g. `{ KE: ['twilio', 'uwazii'] }`. */
150
+ smsProviderChains: Partial<Record<CountryCode, SmsProviderName[]>>;
151
+ /** Email providers currently able to send, in order. */
152
+ emailProviders: EmailProviderName[];
153
+ }
154
+ /** Everything the settings page needs, in one read. */
155
+ export interface OrganizationNotificationSettings {
156
+ organizationId: number;
157
+ /** Null until the organization saves a profile. */
158
+ branding: OrganizationNotificationBranding | null;
159
+ effectiveBranding: ResolvedNotificationBranding;
160
+ emailSenders: OrganizationEmailSender[];
161
+ smsSenders: OrganizationSmsSender[];
162
+ platformDefaults: PlatformNotificationDefaults;
163
+ }
@@ -1,5 +1,6 @@
1
1
  import { NotificationChannel } from '../enums/notification-channel.enum';
2
2
  import { ProviderFailureReason } from '../enums/provider-failure-reason.enum';
3
+ import { NotificationSenderSource } from '../enums/notification-sender-source.enum';
3
4
  /**
4
5
  * Record of a single provider send attempt within a channel.
5
6
  * One channel may produce several attempts (primary + fallbacks).
@@ -22,4 +23,8 @@ export interface ProviderAttempt {
22
23
  statusCode?: number;
23
24
  startedAt?: string;
24
25
  durationMs?: number;
26
+ /** The identity this attempt sent from: an email address, or an SMS sender ID. */
27
+ sender?: string;
28
+ /** Whether that identity was the organization's own or the platform default. */
29
+ senderSource?: NotificationSenderSource;
25
30
  }
@@ -1,6 +1,7 @@
1
1
  import { NotificationChannel } from '../enums/notification-channel.enum';
2
2
  import { ProviderFailureReason } from '../enums/provider-failure-reason.enum';
3
3
  import { SmsProviderName } from '../enums/sms-provider-name.enum';
4
+ import { NotificationSenderSource } from '../enums/notification-sender-source.enum';
4
5
  import { ProviderAttempt } from './provider-attempt';
5
6
  /**
6
7
  * Normalized result of an SMS send across the configured provider chain.
@@ -19,4 +20,10 @@ export interface SmsSendResult {
19
20
  failureReason?: ProviderFailureReason;
20
21
  /** Internal, safe-to-log error summary. */
21
22
  errorMessage?: string;
23
+ /** The organization the message was sent on behalf of, when known. */
24
+ organizationId?: number;
25
+ /** The identity the successful attempt sent from: an email address, or an SMS sender ID. */
26
+ sender?: string;
27
+ /** Whether that identity was the organization's own or the platform default. */
28
+ senderSource?: NotificationSenderSource;
22
29
  }
@@ -0,0 +1,25 @@
1
+ import { SmsSenderType } from '../enums/sms-sender-type.enum';
2
+ /**
3
+ * Validates an SMS sender value against its declared type.
4
+ * Returns null when valid, otherwise a message fit to show an operator.
5
+ */
6
+ export declare function validateSmsSenderId(senderType: SmsSenderType, senderId: string): string | null;
7
+ /** The domain part of an email address, lower-cased. Null when there is none. */
8
+ export declare function emailDomainOf(address: string | null | undefined): string | null;
9
+ /**
10
+ * WCAG contrast ratio of a `#RRGGBB` colour against white, from 1 (white) to 21
11
+ * (black). The email templates put WHITE text on the primary colour (buttons) and
12
+ * on the accent colour (header banner, footer), so a pale brand colour produces
13
+ * an email nobody can read. Returns 0 for anything that is not a hex colour.
14
+ */
15
+ export declare function contrastRatioWithWhite(hex: string): number;
16
+ /** Large text and UI components (WCAG 1.4.11): buttons and links in the primary colour. */
17
+ export declare const MIN_PRIMARY_COLOUR_CONTRAST = 3;
18
+ /** Body-size white text sits on the accent colour (WCAG 1.4.3). */
19
+ export declare const MIN_ACCENT_COLOUR_CONTRAST = 4.5;
20
+ /**
21
+ * Darkens a `#RRGGBB` colour by a fraction (0-1). Used to derive the hover/pressed
22
+ * shade of a brand colour so an organization only has to choose one.
23
+ * Returns the input unchanged when it is not a valid hex colour.
24
+ */
25
+ export declare function darkenHexColour(hex: string, fraction?: number): string;
@@ -24,7 +24,23 @@ export declare enum PermissionActions {
24
24
  CHANGE_PRIORITY_SUPPORT_TICKET = "change-priority:support-ticket",
25
25
  CLOSE_SUPPORT_TICKET = "close:support-ticket",
26
26
  REOPEN_SUPPORT_TICKET = "reopen:support-ticket",
27
+ /** Rate the support received on a resolved ticket. A customer action. */
28
+ RATE_SUPPORT_TICKET = "rate:support-ticket",
29
+ /**
30
+ * One ticket's audit trail. Deliberately separate from reading the ticket:
31
+ * the trail names the agents who touched it and what they changed, which is
32
+ * a deeper grant than the conversation itself.
33
+ */
34
+ READ_SUPPORT_AUDIT = "read:support-audit",
35
+ /**
36
+ * Submit customer feedback. A CUSTOMER action, distinct from raising a
37
+ * ticket: feedback is not a request for help and never leaves Clarion for a
38
+ * helpdesk unless somebody promotes it.
39
+ */
40
+ CREATE_SUPPORT_FEEDBACK = "create:support-feedback",
27
41
  READ_SUPPORT_FEEDBACK = "read:support-feedback",
42
+ /** A customer answering in their OWN feedback thread, not an agent replying. */
43
+ REPLY_SUPPORT_FEEDBACK = "reply:support-feedback",
28
44
  REVIEW_SUPPORT_FEEDBACK = "review:support-feedback",
29
45
  RESPOND_SUPPORT_FEEDBACK = "respond:support-feedback",
30
46
  CONVERT_SUPPORT_FEEDBACK = "convert:support-feedback",
@@ -130,5 +146,8 @@ export declare enum PermissionActions {
130
146
  UPDATE_NEWSFEED_POST = "update:newsfeed-post",
131
147
  PUBLISH_NEWSFEED_POST = "publish:newsfeed-post",
132
148
  ARCHIVE_NEWSFEED_POST = "archive:newsfeed-post",
133
- DELETE_NEWSFEED_POST = "delete:newsfeed-post"
149
+ DELETE_NEWSFEED_POST = "delete:newsfeed-post",
150
+ READ_NOTIFICATION_SETTINGS = "read:notification-settings",
151
+ MANAGE_NOTIFICATION_SETTINGS = "manage:notification-settings",
152
+ APPROVE_NOTIFICATION_SENDER = "approve:notification-sender"
134
153
  }
@@ -10,5 +10,6 @@ export declare enum PermissionsModule {
10
10
  TRACKING = "Tracking",
11
11
  BILLING = "Billing",
12
12
  NEWSFEED = "Newsfeed",
13
- SUPPORT = "Support"
13
+ SUPPORT = "Support",
14
+ NOTIFICATION = "Notification"
14
15
  }
@@ -11,6 +11,12 @@ export declare enum Roles {
11
11
  * device bindings, tracking operations - across the whole organization.
12
12
  */
13
13
  ORGANIZATION_RESPONSE_UNITS_ADMIN = "Organization:Response-Units-Admin",
14
+ /**
15
+ * Runs the support desk for an organization: tickets, customer feedback and
16
+ * the desk's own configuration. Support and feedback are organization-level
17
+ * concerns, so this role is scoped there rather than to a control centre.
18
+ */
19
+ ORGANIZATION_SUPPORT_ADMIN = "Organization:Support-Admin",
14
20
  CONTROL_CENTRE_ADMIN = "Control-Centre:Admin",
15
21
  CONTROL_CENTRE_USER = "Control-Centre:User",
16
22
  /** The same job, confined to one control centre. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grm-shared-library",
3
- "version": "1.1.210",
3
+ "version": "1.1.212",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/types/index.d.ts",