@managemint-solutions/sdk 0.9.0 → 0.16.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.
- package/dist/audit/index.d.ts +15 -0
- package/dist/audit/index.js +37 -14
- package/dist/audit/index.js.map +1 -1
- package/dist/billing/dto.d.ts +33 -0
- package/dist/billing/dto.js +71 -0
- package/dist/billing/dto.js.map +1 -0
- package/dist/billing/index.d.ts +35 -0
- package/dist/billing/index.js +115 -0
- package/dist/billing/index.js.map +1 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.js +12 -0
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/nest/index.d.ts +11 -0
- package/dist/nest/index.js +17 -1
- package/dist/nest/index.js.map +1 -1
- package/dist/notifications/dto.d.ts +10 -0
- package/dist/notifications/dto.js +63 -0
- package/dist/notifications/dto.js.map +1 -0
- package/dist/notifications/index.d.ts +139 -0
- package/dist/notifications/index.js +354 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/organizations/dto.d.ts +62 -0
- package/dist/organizations/dto.js +445 -0
- package/dist/organizations/dto.js.map +1 -0
- package/dist/organizations/index.d.ts +72 -0
- package/dist/organizations/index.js +221 -0
- package/dist/organizations/index.js.map +1 -0
- package/dist/permissions/dto.d.ts +27 -0
- package/dist/permissions/dto.js +215 -0
- package/dist/permissions/dto.js.map +1 -0
- package/dist/permissions/index.d.ts +36 -0
- package/dist/permissions/index.js +110 -0
- package/dist/permissions/index.js.map +1 -0
- package/dist/service-client/index.d.ts +72 -0
- package/dist/service-client/index.js +119 -0
- package/dist/service-client/index.js.map +1 -0
- package/dist/users/dto.d.ts +48 -0
- package/dist/users/dto.js +267 -0
- package/dist/users/dto.js.map +1 -0
- package/dist/users/index.d.ts +38 -0
- package/dist/users/index.js +144 -0
- package/dist/users/index.js.map +1 -0
- package/dist/webhook-events/index.d.ts +65 -0
- package/dist/webhook-events/index.js +109 -0
- package/dist/webhook-events/index.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.GetNotificationsDto = exports.NotificationIdDto = void 0;
|
|
13
|
+
const class_validator_1 = require("class-validator");
|
|
14
|
+
const class_transformer_1 = require("class-transformer");
|
|
15
|
+
const validators_1 = require("../validators");
|
|
16
|
+
// class-validator versions of the shared DTO types from @managemint-solutions/entities.
|
|
17
|
+
// Each class `implements` its entities type so the wire contract cannot drift.
|
|
18
|
+
class NotificationIdDto {
|
|
19
|
+
notificationId;
|
|
20
|
+
}
|
|
21
|
+
exports.NotificationIdDto = NotificationIdDto;
|
|
22
|
+
__decorate([
|
|
23
|
+
(0, class_validator_1.IsUUID)('4', { message: 'Invalid notification ID format' }),
|
|
24
|
+
__metadata("design:type", String)
|
|
25
|
+
], NotificationIdDto.prototype, "notificationId", void 0);
|
|
26
|
+
class GetNotificationsDto {
|
|
27
|
+
search;
|
|
28
|
+
page = 1;
|
|
29
|
+
page_size = 10;
|
|
30
|
+
unread;
|
|
31
|
+
}
|
|
32
|
+
exports.GetNotificationsDto = GetNotificationsDto;
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, class_validator_1.IsOptional)(),
|
|
35
|
+
(0, validators_1.IsNullable)(),
|
|
36
|
+
(0, class_validator_1.IsString)({ message: 'Search query must be a string' }),
|
|
37
|
+
(0, class_validator_1.MinLength)(1, { message: 'Search query cannot be empty' }),
|
|
38
|
+
(0, class_validator_1.MaxLength)(255, { message: 'Search query cannot exceed 255 characters' }),
|
|
39
|
+
__metadata("design:type", Object)
|
|
40
|
+
], GetNotificationsDto.prototype, "search", void 0);
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, class_validator_1.IsOptional)(),
|
|
43
|
+
(0, class_transformer_1.Transform)(({ value }) => (value ? Number(value) : 1), { toClassOnly: true }),
|
|
44
|
+
(0, class_validator_1.IsNumber)({}, { message: 'Page must be a number' }),
|
|
45
|
+
(0, class_validator_1.Min)(1, { message: 'Page must be at least 1' }),
|
|
46
|
+
__metadata("design:type", Number)
|
|
47
|
+
], GetNotificationsDto.prototype, "page", void 0);
|
|
48
|
+
__decorate([
|
|
49
|
+
(0, class_validator_1.IsOptional)(),
|
|
50
|
+
(0, class_transformer_1.Transform)(({ value }) => (value ? Number(value) : 10), { toClassOnly: true }),
|
|
51
|
+
(0, class_validator_1.IsNumber)({}, { message: 'Page size must be a number' }),
|
|
52
|
+
(0, class_validator_1.Min)(1, { message: 'Page size must be at least 1' }),
|
|
53
|
+
(0, class_validator_1.Max)(100, { message: 'Page size cannot exceed 100' }),
|
|
54
|
+
__metadata("design:type", Number)
|
|
55
|
+
], GetNotificationsDto.prototype, "page_size", void 0);
|
|
56
|
+
__decorate([
|
|
57
|
+
(0, class_validator_1.IsOptional)(),
|
|
58
|
+
(0, validators_1.IsNullable)(),
|
|
59
|
+
(0, class_transformer_1.Transform)(({ value }) => (value ? value === 'true' : false), { toClassOnly: true }),
|
|
60
|
+
(0, class_validator_1.IsBoolean)({ message: 'Unread only must be a boolean' }),
|
|
61
|
+
__metadata("design:type", Boolean)
|
|
62
|
+
], GetNotificationsDto.prototype, "unread", void 0);
|
|
63
|
+
//# sourceMappingURL=dto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dto.js","sourceRoot":"","sources":["../../src/notifications/dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAoH;AACpH,yDAA8C;AAK9C,8CAA2C;AAE3C,wFAAwF;AACxF,+EAA+E;AAE/E,MAAa,iBAAiB;IAEnB,cAAc,CAAU;CAClC;AAHD,8CAGC;AADU;IADR,IAAA,wBAAM,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,gCAAgC,EAAE,CAAC;;yDAC1B;AAGnC,MAAa,mBAAmB;IAMrB,MAAM,CAAiB;IAMvB,IAAI,GAAW,CAAC,CAAC;IAOjB,SAAS,GAAW,EAAE,CAAC;IAMvB,MAAM,CAAW;CAC3B;AA1BD,kDA0BC;AApBU;IALR,IAAA,4BAAU,GAAE;IACZ,IAAA,uBAAU,GAAE;IACZ,IAAA,0BAAQ,EAAC,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;IACtD,IAAA,2BAAS,EAAC,CAAC,EAAE,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;IACzD,IAAA,2BAAS,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,2CAA2C,EAAE,CAAC;;mDACzC;AAMvB;IAJR,IAAA,4BAAU,GAAE;IACZ,IAAA,6BAAS,EAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC5E,IAAA,0BAAQ,EAAC,EAAE,EAAE,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC;IAClD,IAAA,qBAAG,EAAC,CAAC,EAAE,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC;;iDACrB;AAOjB;IALR,IAAA,4BAAU,GAAE;IACZ,IAAA,6BAAS,EAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC7E,IAAA,0BAAQ,EAAC,EAAE,EAAE,EAAE,OAAO,EAAE,4BAA4B,EAAE,CAAC;IACvD,IAAA,qBAAG,EAAC,CAAC,EAAE,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;IACnD,IAAA,qBAAG,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAAC;;sDACrB;AAMvB;IAJR,IAAA,4BAAU,GAAE;IACZ,IAAA,uBAAU,GAAE;IACZ,IAAA,6BAAS,EAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACnF,IAAA,2BAAS,EAAC,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;;mDAC9B"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { NotificationContent, NotificationEntity, NotificationSummary, NotificationUnreadCount } from '@managemint-solutions/entities/notifications';
|
|
2
|
+
import { NotificationChannel, NotificationStatus, type NotificationType } from '@managemint-solutions/entities/notifications/enum';
|
|
3
|
+
import type { MmsList } from '@managemint-solutions/entities/common';
|
|
4
|
+
import type { AuthContext } from '../auth';
|
|
5
|
+
import { type AuditedTable, type AuditResource } from '../audit';
|
|
6
|
+
import type { TypedSupabaseClient } from '../client';
|
|
7
|
+
import type { GetNotificationsDto } from './dto';
|
|
8
|
+
export * from './dto';
|
|
9
|
+
/** The outbox row a caller writes. `organization_id` is absent for auth mail, which precedes any tenant. */
|
|
10
|
+
export type CreateNotificationInput = {
|
|
11
|
+
created_by?: string | null;
|
|
12
|
+
organization_id?: string;
|
|
13
|
+
type: NotificationType;
|
|
14
|
+
channel: NotificationChannel;
|
|
15
|
+
template_id: string;
|
|
16
|
+
template_variables: Record<string, string>;
|
|
17
|
+
recipient_id?: string;
|
|
18
|
+
recipient_email?: string;
|
|
19
|
+
recipient_phone?: string;
|
|
20
|
+
};
|
|
21
|
+
export type CreatedNotification = NotificationEntity & {
|
|
22
|
+
organization_id: string | null;
|
|
23
|
+
provider_message_id: string | null;
|
|
24
|
+
};
|
|
25
|
+
/** The columns the queue worker needs to decide whether and how to send. */
|
|
26
|
+
export type QueuedNotification = {
|
|
27
|
+
mms_id: string;
|
|
28
|
+
organization_id: string | null;
|
|
29
|
+
status: NotificationStatus;
|
|
30
|
+
channel: NotificationChannel;
|
|
31
|
+
template_id: string | null;
|
|
32
|
+
template_variables: Record<string, string>;
|
|
33
|
+
recipient_email: string | null;
|
|
34
|
+
attempts: number;
|
|
35
|
+
sent_at: string | null;
|
|
36
|
+
deleted: boolean;
|
|
37
|
+
};
|
|
38
|
+
export type NotificationContentRow = {
|
|
39
|
+
mms_id: string;
|
|
40
|
+
organization_id: string | null;
|
|
41
|
+
channel: NotificationChannel;
|
|
42
|
+
provider_message_id: string | null;
|
|
43
|
+
rendered_content: Omit<NotificationContent, 'channel'> | null;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* The recipient's own inbox. Every method is scoped to the caller by `recipient_id`, matching
|
|
47
|
+
* the RLS policies (`auth.uid() = recipient_id`) rather than by organization — a notification
|
|
48
|
+
* belongs to a person, not a tenant.
|
|
49
|
+
*/
|
|
50
|
+
export declare class NotificationsResource {
|
|
51
|
+
private readonly supabase;
|
|
52
|
+
private readonly auth;
|
|
53
|
+
private readonly table;
|
|
54
|
+
constructor(supabase: TypedSupabaseClient, auth: AuthContext, audit: AuditResource);
|
|
55
|
+
list(query: GetNotificationsDto): Promise<MmsList<NotificationSummary>>;
|
|
56
|
+
getById(notificationId: string): Promise<NotificationEntity>;
|
|
57
|
+
unreadCount(): Promise<NotificationUnreadCount>;
|
|
58
|
+
/** Idempotent: re-reading an already read notification matches nothing and changes nothing. */
|
|
59
|
+
markRead(notificationId: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Deliberately one statement and unaudited. It is a bulk update with no single row to key on,
|
|
62
|
+
* so auditing it would mean a select-then-loop and one audit row per unread notification —
|
|
63
|
+
* for the reader's own UI state, not an entity change.
|
|
64
|
+
*/
|
|
65
|
+
markAllRead(): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* The ownership-checked read behind `GET /:id/content`. The caller decides whether to fall
|
|
68
|
+
* back to the provider; caching the result needs the service client's grant on
|
|
69
|
+
* `rendered_content`.
|
|
70
|
+
*/
|
|
71
|
+
contentRow(notificationId: string): Promise<NotificationContentRow>;
|
|
72
|
+
/** Soft delete — the outbox row stays, flagged `deleted`, so the send record survives. */
|
|
73
|
+
remove(notificationId: string): Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
/** How the outbox reaches an audited table once it knows which organization a row belongs to. */
|
|
76
|
+
export type OrganizationTableFactory = (organizationId: string) => AuditedTable;
|
|
77
|
+
/**
|
|
78
|
+
* The outbox and the queue worker's side of the table, on the service client: RLS reserves
|
|
79
|
+
* `notifications` INSERT and DELETE to the service role, and `authenticated` has no grant on
|
|
80
|
+
* `rendered_content`.
|
|
81
|
+
*
|
|
82
|
+
* Writes are audited against the row's own organization. Auth mail (signup confirmation,
|
|
83
|
+
* password recovery) has none — it precedes any tenant — and `audit_logs.organization_id` is
|
|
84
|
+
* not nullable, so those rows are written unaudited. Their lifecycle columns are the record.
|
|
85
|
+
*/
|
|
86
|
+
export declare class NotificationsOutboxResource {
|
|
87
|
+
private readonly supabase;
|
|
88
|
+
private readonly tableFor;
|
|
89
|
+
constructor(supabase: TypedSupabaseClient, tableFor: OrganizationTableFactory);
|
|
90
|
+
private auditedFor;
|
|
91
|
+
private rawUpdate;
|
|
92
|
+
create(input: CreateNotificationInput): Promise<CreatedNotification>;
|
|
93
|
+
/**
|
|
94
|
+
* The outbox row behind a provider message id. The Resend webhook arrives knowing only that
|
|
95
|
+
* id, and needs the organization before it can attribute anything.
|
|
96
|
+
*/
|
|
97
|
+
findByProviderMessageId(providerMessageId: string): Promise<Pick<NotificationContentRow, 'mms_id' | 'organization_id'> | null>;
|
|
98
|
+
/**
|
|
99
|
+
* Stamps a delivery rollup on first occurrence only. A provider that reports `delivered`
|
|
100
|
+
* twice must not move the timestamp, so the guard is the column still being null.
|
|
101
|
+
*
|
|
102
|
+
* Only the rollup columns are ever touched here — `status` belongs to the send lifecycle,
|
|
103
|
+
* not to what the provider reports afterwards.
|
|
104
|
+
*/
|
|
105
|
+
stampRollup(notification: Pick<NotificationContentRow, 'mms_id' | 'organization_id'>, column: 'delivered_at' | 'delivery_failure_reason', value: string): Promise<void>;
|
|
106
|
+
/** The worker's load. Returns null when the row is gone rather than throwing — see `processQueuedNotification`. */
|
|
107
|
+
loadForDelivery(notificationId: string): Promise<QueuedNotification | null>;
|
|
108
|
+
/**
|
|
109
|
+
* Stamps a successful send. Guarded on `sent_at is null` so a duplicate delivery of the same
|
|
110
|
+
* queue message changes nothing instead of double-stamping — the email has already gone.
|
|
111
|
+
*/
|
|
112
|
+
stampSent(notification: QueuedNotification, patch: {
|
|
113
|
+
providerMessageId: string | null;
|
|
114
|
+
attempts: number;
|
|
115
|
+
at: string;
|
|
116
|
+
}): Promise<void>;
|
|
117
|
+
/** Records an attempt, retiring the row when the caller says this was the last delivery. */
|
|
118
|
+
stampAttempt(notification: QueuedNotification, patch: {
|
|
119
|
+
attempts: number;
|
|
120
|
+
at: string;
|
|
121
|
+
failureReason: string;
|
|
122
|
+
terminal: boolean;
|
|
123
|
+
}): Promise<void>;
|
|
124
|
+
/** Retires a row nothing can rescue — an unknown template, no address, an unsupported channel. */
|
|
125
|
+
stampFailed(notification: QueuedNotification, patch: {
|
|
126
|
+
attempts: number;
|
|
127
|
+
at: string;
|
|
128
|
+
failureReason: string;
|
|
129
|
+
}): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Caches the provider's rendered email on the row. Guarded on `rendered_content is null` so
|
|
132
|
+
* concurrent first-opens settle on one write.
|
|
133
|
+
*/
|
|
134
|
+
cacheContent(notification: Pick<NotificationContentRow, 'mms_id' | 'organization_id'>, content: {
|
|
135
|
+
subject: string | null;
|
|
136
|
+
html: string | null;
|
|
137
|
+
}): Promise<void>;
|
|
138
|
+
}
|
|
139
|
+
export { NotificationChannel, NotificationStatus };
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.NotificationStatus = exports.NotificationChannel = exports.NotificationsOutboxResource = exports.NotificationsResource = void 0;
|
|
18
|
+
const enum_1 = require("@managemint-solutions/entities/notifications/enum");
|
|
19
|
+
Object.defineProperty(exports, "NotificationChannel", { enumerable: true, get: function () { return enum_1.NotificationChannel; } });
|
|
20
|
+
Object.defineProperty(exports, "NotificationStatus", { enumerable: true, get: function () { return enum_1.NotificationStatus; } });
|
|
21
|
+
const enum_2 = require("@managemint-solutions/entities/audit-trail/enum");
|
|
22
|
+
const audit_1 = require("../audit");
|
|
23
|
+
const errors_1 = require("../errors");
|
|
24
|
+
__exportStar(require("./dto"), exports);
|
|
25
|
+
// The public contract is the shared entities types; the casts at the returns declare the shape
|
|
26
|
+
// these select strings produce (the columns are defined in the api's supabase/migrations).
|
|
27
|
+
const NOTIFICATION_LIST_SELECT = `
|
|
28
|
+
mms_id,
|
|
29
|
+
created_at,
|
|
30
|
+
type,
|
|
31
|
+
channel,
|
|
32
|
+
status,
|
|
33
|
+
template_id,
|
|
34
|
+
recipient_email,
|
|
35
|
+
sent_at,
|
|
36
|
+
failed_at,
|
|
37
|
+
delivered_at,
|
|
38
|
+
read_at
|
|
39
|
+
`;
|
|
40
|
+
const NOTIFICATION_DETAIL_SELECT = `
|
|
41
|
+
mms_id,
|
|
42
|
+
created_at,
|
|
43
|
+
type,
|
|
44
|
+
channel,
|
|
45
|
+
status,
|
|
46
|
+
template_id,
|
|
47
|
+
template_variables,
|
|
48
|
+
recipient_email,
|
|
49
|
+
sent_at,
|
|
50
|
+
failed_at,
|
|
51
|
+
failure_reason,
|
|
52
|
+
provider,
|
|
53
|
+
delivered_at,
|
|
54
|
+
delivery_failure_reason,
|
|
55
|
+
read_at
|
|
56
|
+
`;
|
|
57
|
+
// What `create` hands back to the caller, which then publishes it to the queue.
|
|
58
|
+
const NOTIFICATION_CREATED_SELECT = `
|
|
59
|
+
mms_id,
|
|
60
|
+
organization_id,
|
|
61
|
+
created_at,
|
|
62
|
+
type,
|
|
63
|
+
channel,
|
|
64
|
+
status,
|
|
65
|
+
template_id,
|
|
66
|
+
template_variables,
|
|
67
|
+
recipient_email,
|
|
68
|
+
sent_at,
|
|
69
|
+
failed_at,
|
|
70
|
+
failure_reason,
|
|
71
|
+
provider,
|
|
72
|
+
provider_message_id,
|
|
73
|
+
delivered_at
|
|
74
|
+
`;
|
|
75
|
+
const NOTIFICATIONS_TABLE = {
|
|
76
|
+
table: 'notifications',
|
|
77
|
+
entityType: enum_2.AuditTrailEntityType.NOTIFICATION,
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* The recipient's own inbox. Every method is scoped to the caller by `recipient_id`, matching
|
|
81
|
+
* the RLS policies (`auth.uid() = recipient_id`) rather than by organization — a notification
|
|
82
|
+
* belongs to a person, not a tenant.
|
|
83
|
+
*/
|
|
84
|
+
class NotificationsResource {
|
|
85
|
+
supabase;
|
|
86
|
+
auth;
|
|
87
|
+
table;
|
|
88
|
+
constructor(supabase, auth, audit) {
|
|
89
|
+
this.supabase = supabase;
|
|
90
|
+
this.auth = auth;
|
|
91
|
+
this.table = (0, audit_1.auditedTable)(supabase, auth, audit, NOTIFICATIONS_TABLE);
|
|
92
|
+
}
|
|
93
|
+
async list(query) {
|
|
94
|
+
const page = query.page;
|
|
95
|
+
const pageSize = query.page_size;
|
|
96
|
+
const offset = (page - 1) * pageSize;
|
|
97
|
+
const trimmedSearch = query.search?.trim();
|
|
98
|
+
// `order`/`range` return `this`, so the builder stays a filter builder and the conditional
|
|
99
|
+
// filters below can be reassigned onto it without a cast.
|
|
100
|
+
let notificationsQuery = this.supabase
|
|
101
|
+
.from('notifications')
|
|
102
|
+
.select(NOTIFICATION_LIST_SELECT, { count: 'estimated' })
|
|
103
|
+
.eq('recipient_id', this.auth.mms_id)
|
|
104
|
+
.eq('deleted', false)
|
|
105
|
+
.order('created_at', { ascending: false })
|
|
106
|
+
.range(offset, offset + pageSize - 1);
|
|
107
|
+
if (query.unread) {
|
|
108
|
+
notificationsQuery = notificationsQuery.is('read_at', null);
|
|
109
|
+
}
|
|
110
|
+
if (trimmedSearch) {
|
|
111
|
+
const escapedSearch = trimmedSearch.replace(/,/g, '\\,');
|
|
112
|
+
notificationsQuery = notificationsQuery.or(`template_id.ilike.%${escapedSearch}%,type.ilike.%${escapedSearch}%`);
|
|
113
|
+
}
|
|
114
|
+
const { data, error, count } = await notificationsQuery;
|
|
115
|
+
if (error)
|
|
116
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
117
|
+
const totalEstimated = count ?? 0;
|
|
118
|
+
const totalPages = totalEstimated > 0 ? Math.ceil(totalEstimated / pageSize) : 0;
|
|
119
|
+
return {
|
|
120
|
+
results: (data ?? []),
|
|
121
|
+
page,
|
|
122
|
+
per_page: pageSize,
|
|
123
|
+
count: totalEstimated,
|
|
124
|
+
total_pages: totalPages,
|
|
125
|
+
has_next_page: page < totalPages,
|
|
126
|
+
has_previous_page: page > 1,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
async getById(notificationId) {
|
|
130
|
+
const { data, error } = await this.supabase
|
|
131
|
+
.from('notifications')
|
|
132
|
+
.select(NOTIFICATION_DETAIL_SELECT)
|
|
133
|
+
.eq('mms_id', notificationId)
|
|
134
|
+
.eq('recipient_id', this.auth.mms_id)
|
|
135
|
+
.eq('deleted', false)
|
|
136
|
+
.single();
|
|
137
|
+
if (error)
|
|
138
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
139
|
+
return data;
|
|
140
|
+
}
|
|
141
|
+
async unreadCount() {
|
|
142
|
+
const { count, error } = await this.supabase
|
|
143
|
+
.from('notifications')
|
|
144
|
+
.select('mms_id', { count: 'estimated', head: true })
|
|
145
|
+
.eq('recipient_id', this.auth.mms_id)
|
|
146
|
+
.eq('deleted', false)
|
|
147
|
+
.is('read_at', null);
|
|
148
|
+
if (error)
|
|
149
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
150
|
+
return { count: count ?? 0 };
|
|
151
|
+
}
|
|
152
|
+
/** Idempotent: re-reading an already read notification matches nothing and changes nothing. */
|
|
153
|
+
async markRead(notificationId) {
|
|
154
|
+
await this.table.updateWhere(notificationId, (query) => query.is('read_at', null), { read_at: new Date().toISOString() });
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Deliberately one statement and unaudited. It is a bulk update with no single row to key on,
|
|
158
|
+
* so auditing it would mean a select-then-loop and one audit row per unread notification —
|
|
159
|
+
* for the reader's own UI state, not an entity change.
|
|
160
|
+
*/
|
|
161
|
+
async markAllRead() {
|
|
162
|
+
const { error } = await this.supabase
|
|
163
|
+
.from('notifications')
|
|
164
|
+
.update({ read_at: new Date().toISOString() })
|
|
165
|
+
.eq('recipient_id', this.auth.mms_id)
|
|
166
|
+
.eq('deleted', false)
|
|
167
|
+
.is('read_at', null);
|
|
168
|
+
if (error)
|
|
169
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* The ownership-checked read behind `GET /:id/content`. The caller decides whether to fall
|
|
173
|
+
* back to the provider; caching the result needs the service client's grant on
|
|
174
|
+
* `rendered_content`.
|
|
175
|
+
*/
|
|
176
|
+
async contentRow(notificationId) {
|
|
177
|
+
const { data, error } = await this.supabase
|
|
178
|
+
.from('notifications')
|
|
179
|
+
.select('mms_id, organization_id, channel, provider_message_id, rendered_content')
|
|
180
|
+
.eq('mms_id', notificationId)
|
|
181
|
+
.eq('recipient_id', this.auth.mms_id)
|
|
182
|
+
.eq('deleted', false)
|
|
183
|
+
.single();
|
|
184
|
+
if (error)
|
|
185
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
186
|
+
return data;
|
|
187
|
+
}
|
|
188
|
+
/** Soft delete — the outbox row stays, flagged `deleted`, so the send record survives. */
|
|
189
|
+
async remove(notificationId) {
|
|
190
|
+
await this.table.transition(notificationId, enum_2.AuditTrailAction.DELETE, {
|
|
191
|
+
deleted: true,
|
|
192
|
+
deleted_at: new Date().toISOString(),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
exports.NotificationsResource = NotificationsResource;
|
|
197
|
+
/**
|
|
198
|
+
* The outbox and the queue worker's side of the table, on the service client: RLS reserves
|
|
199
|
+
* `notifications` INSERT and DELETE to the service role, and `authenticated` has no grant on
|
|
200
|
+
* `rendered_content`.
|
|
201
|
+
*
|
|
202
|
+
* Writes are audited against the row's own organization. Auth mail (signup confirmation,
|
|
203
|
+
* password recovery) has none — it precedes any tenant — and `audit_logs.organization_id` is
|
|
204
|
+
* not nullable, so those rows are written unaudited. Their lifecycle columns are the record.
|
|
205
|
+
*/
|
|
206
|
+
class NotificationsOutboxResource {
|
|
207
|
+
supabase;
|
|
208
|
+
tableFor;
|
|
209
|
+
constructor(supabase, tableFor) {
|
|
210
|
+
this.supabase = supabase;
|
|
211
|
+
this.tableFor = tableFor;
|
|
212
|
+
}
|
|
213
|
+
auditedFor(organizationId) {
|
|
214
|
+
return organizationId ? this.tableFor(organizationId) : null;
|
|
215
|
+
}
|
|
216
|
+
async rawUpdate(notificationId, payload) {
|
|
217
|
+
const { error } = await this.supabase
|
|
218
|
+
.from('notifications')
|
|
219
|
+
.update(payload)
|
|
220
|
+
.eq('mms_id', notificationId);
|
|
221
|
+
if (error)
|
|
222
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
223
|
+
}
|
|
224
|
+
async create(input) {
|
|
225
|
+
const payload = { ...input, created_by: input.created_by ?? null };
|
|
226
|
+
const audited = this.auditedFor(input.organization_id);
|
|
227
|
+
if (audited) {
|
|
228
|
+
const row = await audited.insert(payload);
|
|
229
|
+
return row;
|
|
230
|
+
}
|
|
231
|
+
const { data, error } = await this.supabase
|
|
232
|
+
.from('notifications')
|
|
233
|
+
.insert([payload])
|
|
234
|
+
.select(NOTIFICATION_CREATED_SELECT)
|
|
235
|
+
.single();
|
|
236
|
+
if (error)
|
|
237
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
238
|
+
return data;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* The outbox row behind a provider message id. The Resend webhook arrives knowing only that
|
|
242
|
+
* id, and needs the organization before it can attribute anything.
|
|
243
|
+
*/
|
|
244
|
+
async findByProviderMessageId(providerMessageId) {
|
|
245
|
+
const { data, error } = await this.supabase
|
|
246
|
+
.from('notifications')
|
|
247
|
+
.select('mms_id, organization_id')
|
|
248
|
+
.eq('provider_message_id', providerMessageId)
|
|
249
|
+
.maybeSingle();
|
|
250
|
+
if (error)
|
|
251
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
252
|
+
return (data ?? null);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Stamps a delivery rollup on first occurrence only. A provider that reports `delivered`
|
|
256
|
+
* twice must not move the timestamp, so the guard is the column still being null.
|
|
257
|
+
*
|
|
258
|
+
* Only the rollup columns are ever touched here — `status` belongs to the send lifecycle,
|
|
259
|
+
* not to what the provider reports afterwards.
|
|
260
|
+
*/
|
|
261
|
+
async stampRollup(notification, column, value) {
|
|
262
|
+
const audited = this.auditedFor(notification.organization_id);
|
|
263
|
+
if (audited) {
|
|
264
|
+
await audited.updateWhere(notification.mms_id, (query) => query.is(column, null), { [column]: value });
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const { error } = await this.supabase
|
|
268
|
+
.from('notifications')
|
|
269
|
+
.update({ [column]: value })
|
|
270
|
+
.eq('mms_id', notification.mms_id)
|
|
271
|
+
.is(column, null);
|
|
272
|
+
if (error)
|
|
273
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
274
|
+
}
|
|
275
|
+
/** The worker's load. Returns null when the row is gone rather than throwing — see `processQueuedNotification`. */
|
|
276
|
+
async loadForDelivery(notificationId) {
|
|
277
|
+
const { data, error } = await this.supabase
|
|
278
|
+
.from('notifications')
|
|
279
|
+
.select('mms_id, organization_id, status, channel, template_id, template_variables, recipient_email, attempts, sent_at, deleted')
|
|
280
|
+
.eq('mms_id', notificationId)
|
|
281
|
+
.maybeSingle();
|
|
282
|
+
if (error)
|
|
283
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
284
|
+
return (data ?? null);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Stamps a successful send. Guarded on `sent_at is null` so a duplicate delivery of the same
|
|
288
|
+
* queue message changes nothing instead of double-stamping — the email has already gone.
|
|
289
|
+
*/
|
|
290
|
+
async stampSent(notification, patch) {
|
|
291
|
+
const payload = {
|
|
292
|
+
status: enum_1.NotificationStatus.SENT,
|
|
293
|
+
sent_at: patch.at,
|
|
294
|
+
provider: 'resend',
|
|
295
|
+
provider_message_id: patch.providerMessageId,
|
|
296
|
+
attempts: patch.attempts,
|
|
297
|
+
last_attempted_at: patch.at,
|
|
298
|
+
};
|
|
299
|
+
const audited = this.auditedFor(notification.organization_id);
|
|
300
|
+
if (audited) {
|
|
301
|
+
await audited.updateWhere(notification.mms_id, (query) => query.is('sent_at', null), payload);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const { error } = await this.supabase
|
|
305
|
+
.from('notifications')
|
|
306
|
+
.update(payload)
|
|
307
|
+
.eq('mms_id', notification.mms_id)
|
|
308
|
+
.is('sent_at', null);
|
|
309
|
+
if (error)
|
|
310
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
311
|
+
}
|
|
312
|
+
/** Records an attempt, retiring the row when the caller says this was the last delivery. */
|
|
313
|
+
async stampAttempt(notification, patch) {
|
|
314
|
+
const payload = {
|
|
315
|
+
attempts: patch.attempts,
|
|
316
|
+
last_attempted_at: patch.at,
|
|
317
|
+
failure_reason: patch.failureReason,
|
|
318
|
+
...(patch.terminal
|
|
319
|
+
? { status: enum_1.NotificationStatus.FAILED, failed_at: patch.at }
|
|
320
|
+
: {}),
|
|
321
|
+
};
|
|
322
|
+
const audited = this.auditedFor(notification.organization_id);
|
|
323
|
+
if (audited) {
|
|
324
|
+
await audited.update(notification.mms_id, payload);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
await this.rawUpdate(notification.mms_id, payload);
|
|
328
|
+
}
|
|
329
|
+
/** Retires a row nothing can rescue — an unknown template, no address, an unsupported channel. */
|
|
330
|
+
async stampFailed(notification, patch) {
|
|
331
|
+
await this.stampAttempt(notification, { ...patch, terminal: true });
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Caches the provider's rendered email on the row. Guarded on `rendered_content is null` so
|
|
335
|
+
* concurrent first-opens settle on one write.
|
|
336
|
+
*/
|
|
337
|
+
async cacheContent(notification, content) {
|
|
338
|
+
const payload = { rendered_content: content };
|
|
339
|
+
const audited = this.auditedFor(notification.organization_id);
|
|
340
|
+
if (audited) {
|
|
341
|
+
await audited.updateWhere(notification.mms_id, (query) => query.is('rendered_content', null), payload);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const { error } = await this.supabase
|
|
345
|
+
.from('notifications')
|
|
346
|
+
.update(payload)
|
|
347
|
+
.eq('mms_id', notification.mms_id)
|
|
348
|
+
.is('rendered_content', null);
|
|
349
|
+
if (error)
|
|
350
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
exports.NotificationsOutboxResource = NotificationsOutboxResource;
|
|
354
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { CreateOrganizationDto as CreateOrganizationDtoType, UpdateOrganizationDto as UpdateOrganizationDtoType } from '@managemint-solutions/entities/organization/dto';
|
|
2
|
+
import { OrganizationTypes } from '@managemint-solutions/entities/organization/enum';
|
|
3
|
+
export declare class CreateOrganizationDto implements CreateOrganizationDtoType {
|
|
4
|
+
readonly org_type: OrganizationTypes;
|
|
5
|
+
readonly org_name: string;
|
|
6
|
+
readonly org_trading_name?: string | null;
|
|
7
|
+
readonly org_vat_number?: string | null;
|
|
8
|
+
readonly org_registration_number?: string | null;
|
|
9
|
+
readonly org_email: string;
|
|
10
|
+
readonly org_website?: string | null;
|
|
11
|
+
readonly org_phone?: string | null;
|
|
12
|
+
readonly org_address_line_1?: string | null;
|
|
13
|
+
readonly org_address_line_2?: string | null;
|
|
14
|
+
readonly org_city?: string | null;
|
|
15
|
+
readonly org_state?: string | null;
|
|
16
|
+
readonly org_postal_code?: string | null;
|
|
17
|
+
readonly org_country?: string | null;
|
|
18
|
+
readonly use_address_for_billing: boolean;
|
|
19
|
+
readonly org_billing_address_line_1?: string | null;
|
|
20
|
+
readonly org_billing_address_line_2?: string | null;
|
|
21
|
+
readonly org_billing_city?: string | null;
|
|
22
|
+
readonly org_billing_state?: string | null;
|
|
23
|
+
readonly org_billing_postal_code?: string | null;
|
|
24
|
+
readonly org_billing_country?: string | null;
|
|
25
|
+
readonly org_consent_given: true;
|
|
26
|
+
readonly org_industry?: string | null;
|
|
27
|
+
readonly org_marketting_consent_given: boolean;
|
|
28
|
+
readonly org_currency: string;
|
|
29
|
+
readonly owner_first_name: string;
|
|
30
|
+
readonly owner_last_name: string;
|
|
31
|
+
readonly owner_email: string;
|
|
32
|
+
readonly owner_country_code: string;
|
|
33
|
+
readonly owner_phone: string;
|
|
34
|
+
readonly owner_profile_image?: string | null;
|
|
35
|
+
readonly module_ids: string[];
|
|
36
|
+
}
|
|
37
|
+
export declare class UpdateOrganizationDto implements UpdateOrganizationDtoType {
|
|
38
|
+
readonly type?: OrganizationTypes;
|
|
39
|
+
readonly name?: string;
|
|
40
|
+
readonly trading_name?: string | null;
|
|
41
|
+
readonly vat_number?: string | null;
|
|
42
|
+
readonly registration_number?: string | null;
|
|
43
|
+
readonly email?: string;
|
|
44
|
+
readonly website?: string | null;
|
|
45
|
+
readonly phone?: string | null;
|
|
46
|
+
readonly address_line_1?: string | null;
|
|
47
|
+
readonly address_line_2?: string | null;
|
|
48
|
+
readonly city?: string | null;
|
|
49
|
+
readonly state?: string | null;
|
|
50
|
+
readonly post_code?: string | null;
|
|
51
|
+
readonly country?: string | null;
|
|
52
|
+
readonly use_address_for_billing?: boolean;
|
|
53
|
+
readonly billing_address_line_1?: string | null;
|
|
54
|
+
readonly billing_address_line_2?: string | null;
|
|
55
|
+
readonly billing_city?: string | null;
|
|
56
|
+
readonly billing_state?: string | null;
|
|
57
|
+
readonly billing_post_code?: string | null;
|
|
58
|
+
readonly billing_country?: string | null;
|
|
59
|
+
readonly industry?: string | null;
|
|
60
|
+
readonly marketing_consent?: boolean;
|
|
61
|
+
readonly currency?: string;
|
|
62
|
+
}
|