@managemint-solutions/sdk 0.53.0 → 0.55.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/README.md +75 -3
- package/dist/additional-details/index.d.ts +2 -2
- package/dist/additional-details/index.js +6 -10
- package/dist/audit/index.d.ts +11 -5
- package/dist/audit/index.js +20 -12
- package/dist/auth-client/index.d.ts +2 -0
- package/dist/auth-client/index.js +12 -0
- package/dist/auth.d.ts +21 -0
- package/dist/auth.js +47 -3
- package/dist/clients/dto.d.ts +5 -1
- package/dist/clients/dto.js +12 -1
- package/dist/clients/index.d.ts +5 -3
- package/dist/clients/index.js +12 -10
- package/dist/emulation-handshakes/index.d.ts +16 -0
- package/dist/emulation-handshakes/index.js +39 -0
- package/dist/errors.js +2 -2
- package/dist/index.d.ts +13 -9
- package/dist/index.js +22 -4
- package/dist/leads/dto.d.ts +5 -1
- package/dist/leads/dto.js +12 -1
- package/dist/leads/index.d.ts +5 -3
- package/dist/leads/index.js +24 -21
- package/dist/nest/index.d.ts +26 -1
- package/dist/nest/index.js +58 -1
- package/dist/notifications/index.d.ts +1 -3
- package/dist/organizations/dto.d.ts +9 -1
- package/dist/organizations/dto.js +40 -1
- package/dist/organizations/index.d.ts +11 -3
- package/dist/organizations/index.js +30 -2
- package/dist/permissions/index.d.ts +6 -4
- package/dist/permissions/index.js +17 -12
- package/dist/projects/dto.d.ts +5 -1
- package/dist/projects/dto.js +12 -1
- package/dist/projects/index.d.ts +5 -3
- package/dist/projects/index.js +12 -10
- package/dist/service-client/index.d.ts +32 -1
- package/dist/service-client/index.js +54 -1
- package/dist/staff/dto.d.ts +14 -0
- package/dist/staff/dto.js +63 -0
- package/dist/staff/index.d.ts +50 -0
- package/dist/staff/index.js +139 -0
- package/dist/staff-client.d.ts +37 -0
- package/dist/staff-client.js +52 -0
- package/dist/tasks/dto.d.ts +5 -1
- package/dist/tasks/dto.js +12 -1
- package/dist/tasks/index.d.ts +5 -3
- package/dist/tasks/index.js +18 -19
- package/dist/tenancy.d.ts +13 -0
- package/dist/tenancy.js +25 -0
- package/dist/user-api-credentials/dto.d.ts +12 -0
- package/dist/user-api-credentials/dto.js +56 -0
- package/dist/user-api-credentials/index.d.ts +47 -0
- package/dist/user-api-credentials/index.js +101 -0
- package/dist/users/dto.d.ts +5 -1
- package/dist/users/dto.js +13 -2
- package/dist/users/index.d.ts +5 -3
- package/dist/users/index.js +13 -29
- package/dist/validators.d.ts +2 -0
- package/dist/validators.js +6 -1
- package/package.json +2 -2
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EmulationHandshakesResource = void 0;
|
|
4
|
+
const errors_1 = require("../errors");
|
|
5
|
+
/**
|
|
6
|
+
* `emulation_handshakes`, service client only: proof that a user's next sign-in is the admin
|
|
7
|
+
* api's own mint, which the custom access token hook spends to mark that token emulated.
|
|
8
|
+
*/
|
|
9
|
+
class EmulationHandshakesResource {
|
|
10
|
+
supabase;
|
|
11
|
+
constructor(supabase) {
|
|
12
|
+
this.supabase = supabase;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Opens a handshake for `userId`'s next sign-in, good for thirty seconds. Returns its id. The
|
|
16
|
+
* credential is the one a public mint presented; a staff member's own mint has none.
|
|
17
|
+
*/
|
|
18
|
+
async open(userId, credentialId) {
|
|
19
|
+
const { data, error } = await this.supabase
|
|
20
|
+
.from('emulation_handshakes')
|
|
21
|
+
.insert({
|
|
22
|
+
user_id: userId,
|
|
23
|
+
credential_id: credentialId,
|
|
24
|
+
expires_at: new Date(Date.now() + 30_000).toISOString(),
|
|
25
|
+
})
|
|
26
|
+
.select('id')
|
|
27
|
+
.single();
|
|
28
|
+
if (error)
|
|
29
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
30
|
+
return data.id;
|
|
31
|
+
}
|
|
32
|
+
/** Deletes the handshake, spent or not, once the mint is over. */
|
|
33
|
+
async close(id) {
|
|
34
|
+
const { error } = await this.supabase.from('emulation_handshakes').delete().eq('id', id);
|
|
35
|
+
if (error)
|
|
36
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.EmulationHandshakesResource = EmulationHandshakesResource;
|
package/dist/errors.js
CHANGED
|
@@ -90,7 +90,7 @@ exports.mapPostgrestError = mapPostgrestError;
|
|
|
90
90
|
* network/unknown failures have none, hence the 500 fallback.
|
|
91
91
|
*/
|
|
92
92
|
const mapStorageError = (error, message = error.message) => new SupabaseClientError({
|
|
93
|
-
status: error.status
|
|
93
|
+
status: error.status || 500,
|
|
94
94
|
error: 'Storage Error',
|
|
95
95
|
message,
|
|
96
96
|
}, { cause: error });
|
|
@@ -101,7 +101,7 @@ exports.mapStorageError = mapStorageError;
|
|
|
101
101
|
* status GoTrue answered with; network/unknown failures carry none, hence the 500 fallback.
|
|
102
102
|
*/
|
|
103
103
|
const mapAuthError = (error) => new SupabaseClientError({
|
|
104
|
-
status: error.status
|
|
104
|
+
status: error.status || 500,
|
|
105
105
|
error: 'Authentication Error',
|
|
106
106
|
message: error.message,
|
|
107
107
|
}, { cause: error });
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { SupabaseClient, createSupabaseClient } from './client';
|
|
2
2
|
export type { SupabaseClientConfig, TypedSupabaseClient } from './client';
|
|
3
|
-
export
|
|
3
|
+
export { SupabaseStaffClient, createSupabaseStaffClient } from './staff-client';
|
|
4
|
+
export type { AuthContext, StaffContext, VerifiedAuth, VerifiedOrganization, VerifiedStaff, VerifyAccessTokenConfig, } from './auth';
|
|
4
5
|
export { SupabaseAuthClient, createSupabaseAuthClient } from './auth-client';
|
|
5
6
|
export type { SupabaseAuthClientConfig } from './auth-client';
|
|
6
7
|
export { ExchangeRefreshTokenDto, ExchangeTokenHashDto, ResetPasswordDto, SendPasswordResetEmailDto, SignInDto, } from './auth-client';
|
|
@@ -9,7 +10,7 @@ export type { SupabaseOrganizationScope, SupabaseServiceClientConfig } from './s
|
|
|
9
10
|
export { SupabaseClientError } from './errors';
|
|
10
11
|
export type { SupabaseClientErrorInit } from './errors';
|
|
11
12
|
export { EmptyToNull, IsNullable } from './validators';
|
|
12
|
-
export type { AuditActor, AuditChanges, AuditEntry, AuditErrorHandler, AuditGuard, AuditNameTable, AuditRow, AuditedTable, AuditedTableOptions, EntityAuditTrail, } from './audit';
|
|
13
|
+
export type { AuditActor, AuditChanges, AuditEntry, AuditErrorHandler, AuditGuard, AuditNameTable, AuditRow, AuditedTable, AuditedTableOptions, EntityAuditTrail, OrganizationTableFactory, } from './audit';
|
|
13
14
|
export { GetAuditTrailDto, withAuditBatch } from './audit';
|
|
14
15
|
export { CancelSubscriptionDto, GetPaymentsQueryDto, InitialPaymentDto, PaymentIdDto, PurchaseModuleDto, ReinstateSubscriptionDto, } from './billing';
|
|
15
16
|
export { GetInvoicesQueryDto, InvoiceIdDto } from './billing/invoices';
|
|
@@ -21,23 +22,26 @@ export { AddStatusDto, GetStatusesDto, ReorderStatusesDto, StatusIdDto, UpdateSt
|
|
|
21
22
|
export { AddLabelDto, GetLabelsDto, LabelIdDto, UpdateLabelDto } from './labels';
|
|
22
23
|
export { AddAdditionalDetailsDto, AdditionalDetailsIdDto, GetAdditionalDetailsDto, IsAdditionalDetailsValueByType, UpdateAdditionalDetailsDto, } from './additional-details';
|
|
23
24
|
export { AddNoteDto, GetNotesDto, NoteIdDto } from './notes';
|
|
24
|
-
export type { CreateNotificationInput, CreatedNotification, NotificationContentRow,
|
|
25
|
+
export type { CreateNotificationInput, CreatedNotification, NotificationContentRow, QueuedNotification, } from './notifications';
|
|
25
26
|
export { GetNotificationsDto, NotificationIdDto } from './notifications';
|
|
26
27
|
export type { OrganizationInvite } from './organization-invites';
|
|
27
28
|
export type { OrganizationPaymentMethod, PaymentMethodLookupColumn, } from './organization-payment-methods';
|
|
28
29
|
export type { CreateOrganizationRow, OrganizationRow } from './organizations';
|
|
29
|
-
export { CreateOrganizationDto, UpdateOrganizationDto } from './organizations';
|
|
30
|
+
export { CreateOrganizationDto, GetOrganizationsDto, OrganizationIdDto, UpdateOrganizationDto, } from './organizations';
|
|
30
31
|
export { PermissionsResource } from './permissions';
|
|
31
32
|
export type { PermissionFlags } from './permissions';
|
|
32
33
|
export { UpdatePermissionsDto } from './permissions';
|
|
34
|
+
export { CreateStaffDto, StaffIdDto, UpdateStaffPermissionsDto } from './staff';
|
|
35
|
+
export type { CreateUserApiCredentialRow, UserApiCredentialRow } from './user-api-credentials';
|
|
36
|
+
export { CreateUserApiCredentialDto, MintEmulationTokenDto, UserApiCredentialIdDto, } from './user-api-credentials';
|
|
33
37
|
export type { UserEmploymentRow, UserRow } from './users';
|
|
34
|
-
export { AddUserDto, GetUsersQueryDto, UpdateMyProfileDto, UpdateUserDto, UserIdDto, } from './users';
|
|
38
|
+
export { AddUserDto, GetUsersQueryDto, StaffGetUsersDto, UpdateMyProfileDto, UpdateUserDto, UserIdDto, } from './users';
|
|
35
39
|
export type { ClaimOutcome, WebhookEventRow, WebhookEventsTable } from './webhook-events';
|
|
36
40
|
export { GetSupportingFilesDto, SupportingFileIdDto, SupportingFileNamesDto } from './supporting-files';
|
|
37
|
-
export { ClientIdDto, CreateClientDto, GetClientsDto, UpdateClientDto } from './clients';
|
|
38
|
-
export { ConvertLeadDto, CreateLeadDto, GetLeadsDto, LeadIdDto, UpdateLeadDto } from './leads';
|
|
39
|
-
export { CreateProjectDto, GetProjectsDto, ProjectIdDto, UpdateProjectDto } from './projects';
|
|
40
|
-
export { AddTaskLinkDto, CreateTaskDto, GetTasksDto, TaskIdDto, TaskLinkIdDto, UpdateTaskDto } from './tasks';
|
|
41
|
+
export { ClientIdDto, CreateClientDto, GetClientsDto, StaffGetClientsDto, UpdateClientDto } from './clients';
|
|
42
|
+
export { ConvertLeadDto, CreateLeadDto, GetLeadsDto, LeadIdDto, StaffGetLeadsDto, UpdateLeadDto } from './leads';
|
|
43
|
+
export { CreateProjectDto, GetProjectsDto, ProjectIdDto, StaffGetProjectsDto, UpdateProjectDto } from './projects';
|
|
44
|
+
export { AddTaskLinkDto, CreateTaskDto, GetTasksDto, StaffGetTasksDto, TaskIdDto, TaskLinkIdDto, UpdateTaskDto, } from './tasks';
|
|
41
45
|
export type { CreateLeaveEntitlementInput, CreateLeaveRequestRow, ReviewLeaveRequestRow, UpdateLeaveRequestRow, } from './leave';
|
|
42
46
|
export type { BalanceEntitlement, BalanceRequest, LeaveCycle } from './leave';
|
|
43
47
|
export { BulkCreateLeaveEntitlementsDto, CreateLeaveAdjustmentDto, CreateLeaveEntitlementDto, CreateLeaveRequestDto, CreateLeaveTypeDto, GetLeaveCalendarDto, GetLeaveEntitlementsDto, GetLeaveRequestsDto, GetLeaveTypesDto, LeaveEntitlementIdDto, LeaveRequestIdDto, LeaveTypeIdDto, ReviewLeaveRequestDto, UpdateLeaveEntitlementDto, UpdateLeaveRequestDto, UpdateLeaveTypeDto, } from './leave';
|
package/dist/index.js
CHANGED
|
@@ -3,16 +3,19 @@
|
|
|
3
3
|
// the audit diff, the row helpers, the select-string fragments, the error mappers - and stays
|
|
4
4
|
// reachable only from inside. The `./nest` entrypoint is listed separately, in src/nest/index.ts.
|
|
5
5
|
//
|
|
6
|
-
// Resources are reached through the
|
|
6
|
+
// Resources are reached through the clients (`supabase.tasks`, `scope.invoices`, ...), so
|
|
7
7
|
// their classes are not exported: a consumer never constructs one, and every export is a contract
|
|
8
8
|
// to keep. The row and input types they produce and accept are exported for annotations.
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.
|
|
11
|
-
exports.
|
|
12
|
-
exports.monthlyTotalMinor = exports.weekStartOf = exports.minutesBetween = exports.UpdateTimesheetEntryDto = exports.TimesheetIdDto = exports.TimesheetEntryIdDto = exports.ReviewTimesheetDto = exports.GetTimesheetsDto = exports.GetTimesheetReportDto = exports.CreateTimesheetEntryDto = exports.todayInJohannesburg = exports.shiftDays = exports.proRataDays = exports.isWithinPeriod = void 0;
|
|
10
|
+
exports.CreateOrganizationDto = exports.NotificationIdDto = exports.GetNotificationsDto = exports.NoteIdDto = exports.GetNotesDto = exports.AddNoteDto = exports.UpdateAdditionalDetailsDto = exports.IsAdditionalDetailsValueByType = exports.GetAdditionalDetailsDto = exports.AdditionalDetailsIdDto = exports.AddAdditionalDetailsDto = exports.UpdateLabelDto = exports.LabelIdDto = exports.GetLabelsDto = exports.AddLabelDto = exports.UpdateStatusDto = exports.StatusIdDto = exports.ReorderStatusesDto = exports.GetStatusesDto = exports.AddStatusDto = exports.CreateSupportRequestDto = exports.UpdateConfigDto = exports.CreateConfigDto = exports.CreateFeatureRequestDto = exports.InvoiceIdDto = exports.GetInvoicesQueryDto = exports.ReinstateSubscriptionDto = exports.PurchaseModuleDto = exports.PaymentIdDto = exports.InitialPaymentDto = exports.GetPaymentsQueryDto = exports.CancelSubscriptionDto = exports.withAuditBatch = exports.GetAuditTrailDto = exports.IsNullable = exports.EmptyToNull = exports.SupabaseClientError = exports.createSupabaseServiceClient = exports.SupabaseServiceClient = exports.SignInDto = exports.SendPasswordResetEmailDto = exports.ResetPasswordDto = exports.ExchangeTokenHashDto = exports.ExchangeRefreshTokenDto = exports.createSupabaseAuthClient = exports.SupabaseAuthClient = exports.createSupabaseStaffClient = exports.SupabaseStaffClient = exports.createSupabaseClient = exports.SupabaseClient = void 0;
|
|
11
|
+
exports.GetLeaveEntitlementsDto = exports.GetLeaveCalendarDto = exports.CreateLeaveTypeDto = exports.CreateLeaveRequestDto = exports.CreateLeaveEntitlementDto = exports.CreateLeaveAdjustmentDto = exports.BulkCreateLeaveEntitlementsDto = exports.UpdateTaskDto = exports.TaskLinkIdDto = exports.TaskIdDto = exports.StaffGetTasksDto = exports.GetTasksDto = exports.CreateTaskDto = exports.AddTaskLinkDto = exports.UpdateProjectDto = exports.StaffGetProjectsDto = exports.ProjectIdDto = exports.GetProjectsDto = exports.CreateProjectDto = exports.UpdateLeadDto = exports.StaffGetLeadsDto = exports.LeadIdDto = exports.GetLeadsDto = exports.CreateLeadDto = exports.ConvertLeadDto = exports.UpdateClientDto = exports.StaffGetClientsDto = exports.GetClientsDto = exports.CreateClientDto = exports.ClientIdDto = exports.SupportingFileNamesDto = exports.SupportingFileIdDto = exports.GetSupportingFilesDto = exports.UserIdDto = exports.UpdateUserDto = exports.UpdateMyProfileDto = exports.StaffGetUsersDto = exports.GetUsersQueryDto = exports.AddUserDto = exports.UserApiCredentialIdDto = exports.MintEmulationTokenDto = exports.CreateUserApiCredentialDto = exports.UpdateStaffPermissionsDto = exports.StaffIdDto = exports.CreateStaffDto = exports.UpdatePermissionsDto = exports.PermissionsResource = exports.UpdateOrganizationDto = exports.OrganizationIdDto = exports.GetOrganizationsDto = void 0;
|
|
12
|
+
exports.monthlyTotalMinor = exports.weekStartOf = exports.minutesBetween = exports.UpdateTimesheetEntryDto = exports.TimesheetIdDto = exports.TimesheetEntryIdDto = exports.ReviewTimesheetDto = exports.GetTimesheetsDto = exports.GetTimesheetReportDto = exports.CreateTimesheetEntryDto = exports.todayInJohannesburg = exports.shiftDays = exports.proRataDays = exports.isWithinPeriod = exports.initialUntil = exports.cyclePeriodFor = exports.countWorkingDays = exports.completedMonths = exports.addMonths = exports.GetPublicHolidaysDto = exports.UpdateLeaveTypeDto = exports.UpdateLeaveRequestDto = exports.UpdateLeaveEntitlementDto = exports.ReviewLeaveRequestDto = exports.LeaveTypeIdDto = exports.LeaveRequestIdDto = exports.LeaveEntitlementIdDto = exports.GetLeaveTypesDto = exports.GetLeaveRequestsDto = void 0;
|
|
13
13
|
var client_1 = require("./client");
|
|
14
14
|
Object.defineProperty(exports, "SupabaseClient", { enumerable: true, get: function () { return client_1.SupabaseClient; } });
|
|
15
15
|
Object.defineProperty(exports, "createSupabaseClient", { enumerable: true, get: function () { return client_1.createSupabaseClient; } });
|
|
16
|
+
var staff_client_1 = require("./staff-client");
|
|
17
|
+
Object.defineProperty(exports, "SupabaseStaffClient", { enumerable: true, get: function () { return staff_client_1.SupabaseStaffClient; } });
|
|
18
|
+
Object.defineProperty(exports, "createSupabaseStaffClient", { enumerable: true, get: function () { return staff_client_1.createSupabaseStaffClient; } });
|
|
16
19
|
var auth_client_1 = require("./auth-client");
|
|
17
20
|
Object.defineProperty(exports, "SupabaseAuthClient", { enumerable: true, get: function () { return auth_client_1.SupabaseAuthClient; } });
|
|
18
21
|
Object.defineProperty(exports, "createSupabaseAuthClient", { enumerable: true, get: function () { return auth_client_1.createSupabaseAuthClient; } });
|
|
@@ -76,6 +79,8 @@ Object.defineProperty(exports, "GetNotificationsDto", { enumerable: true, get: f
|
|
|
76
79
|
Object.defineProperty(exports, "NotificationIdDto", { enumerable: true, get: function () { return notifications_1.NotificationIdDto; } });
|
|
77
80
|
var organizations_1 = require("./organizations");
|
|
78
81
|
Object.defineProperty(exports, "CreateOrganizationDto", { enumerable: true, get: function () { return organizations_1.CreateOrganizationDto; } });
|
|
82
|
+
Object.defineProperty(exports, "GetOrganizationsDto", { enumerable: true, get: function () { return organizations_1.GetOrganizationsDto; } });
|
|
83
|
+
Object.defineProperty(exports, "OrganizationIdDto", { enumerable: true, get: function () { return organizations_1.OrganizationIdDto; } });
|
|
79
84
|
Object.defineProperty(exports, "UpdateOrganizationDto", { enumerable: true, get: function () { return organizations_1.UpdateOrganizationDto; } });
|
|
80
85
|
// The one resource class still exported: the api's permissions guard spec drives a real
|
|
81
86
|
// PermissionsResource over a stubbed client.
|
|
@@ -83,9 +88,18 @@ var permissions_1 = require("./permissions");
|
|
|
83
88
|
Object.defineProperty(exports, "PermissionsResource", { enumerable: true, get: function () { return permissions_1.PermissionsResource; } });
|
|
84
89
|
var permissions_2 = require("./permissions");
|
|
85
90
|
Object.defineProperty(exports, "UpdatePermissionsDto", { enumerable: true, get: function () { return permissions_2.UpdatePermissionsDto; } });
|
|
91
|
+
var staff_1 = require("./staff");
|
|
92
|
+
Object.defineProperty(exports, "CreateStaffDto", { enumerable: true, get: function () { return staff_1.CreateStaffDto; } });
|
|
93
|
+
Object.defineProperty(exports, "StaffIdDto", { enumerable: true, get: function () { return staff_1.StaffIdDto; } });
|
|
94
|
+
Object.defineProperty(exports, "UpdateStaffPermissionsDto", { enumerable: true, get: function () { return staff_1.UpdateStaffPermissionsDto; } });
|
|
95
|
+
var user_api_credentials_1 = require("./user-api-credentials");
|
|
96
|
+
Object.defineProperty(exports, "CreateUserApiCredentialDto", { enumerable: true, get: function () { return user_api_credentials_1.CreateUserApiCredentialDto; } });
|
|
97
|
+
Object.defineProperty(exports, "MintEmulationTokenDto", { enumerable: true, get: function () { return user_api_credentials_1.MintEmulationTokenDto; } });
|
|
98
|
+
Object.defineProperty(exports, "UserApiCredentialIdDto", { enumerable: true, get: function () { return user_api_credentials_1.UserApiCredentialIdDto; } });
|
|
86
99
|
var users_1 = require("./users");
|
|
87
100
|
Object.defineProperty(exports, "AddUserDto", { enumerable: true, get: function () { return users_1.AddUserDto; } });
|
|
88
101
|
Object.defineProperty(exports, "GetUsersQueryDto", { enumerable: true, get: function () { return users_1.GetUsersQueryDto; } });
|
|
102
|
+
Object.defineProperty(exports, "StaffGetUsersDto", { enumerable: true, get: function () { return users_1.StaffGetUsersDto; } });
|
|
89
103
|
Object.defineProperty(exports, "UpdateMyProfileDto", { enumerable: true, get: function () { return users_1.UpdateMyProfileDto; } });
|
|
90
104
|
Object.defineProperty(exports, "UpdateUserDto", { enumerable: true, get: function () { return users_1.UpdateUserDto; } });
|
|
91
105
|
Object.defineProperty(exports, "UserIdDto", { enumerable: true, get: function () { return users_1.UserIdDto; } });
|
|
@@ -97,22 +111,26 @@ var clients_1 = require("./clients");
|
|
|
97
111
|
Object.defineProperty(exports, "ClientIdDto", { enumerable: true, get: function () { return clients_1.ClientIdDto; } });
|
|
98
112
|
Object.defineProperty(exports, "CreateClientDto", { enumerable: true, get: function () { return clients_1.CreateClientDto; } });
|
|
99
113
|
Object.defineProperty(exports, "GetClientsDto", { enumerable: true, get: function () { return clients_1.GetClientsDto; } });
|
|
114
|
+
Object.defineProperty(exports, "StaffGetClientsDto", { enumerable: true, get: function () { return clients_1.StaffGetClientsDto; } });
|
|
100
115
|
Object.defineProperty(exports, "UpdateClientDto", { enumerable: true, get: function () { return clients_1.UpdateClientDto; } });
|
|
101
116
|
var leads_1 = require("./leads");
|
|
102
117
|
Object.defineProperty(exports, "ConvertLeadDto", { enumerable: true, get: function () { return leads_1.ConvertLeadDto; } });
|
|
103
118
|
Object.defineProperty(exports, "CreateLeadDto", { enumerable: true, get: function () { return leads_1.CreateLeadDto; } });
|
|
104
119
|
Object.defineProperty(exports, "GetLeadsDto", { enumerable: true, get: function () { return leads_1.GetLeadsDto; } });
|
|
105
120
|
Object.defineProperty(exports, "LeadIdDto", { enumerable: true, get: function () { return leads_1.LeadIdDto; } });
|
|
121
|
+
Object.defineProperty(exports, "StaffGetLeadsDto", { enumerable: true, get: function () { return leads_1.StaffGetLeadsDto; } });
|
|
106
122
|
Object.defineProperty(exports, "UpdateLeadDto", { enumerable: true, get: function () { return leads_1.UpdateLeadDto; } });
|
|
107
123
|
var projects_1 = require("./projects");
|
|
108
124
|
Object.defineProperty(exports, "CreateProjectDto", { enumerable: true, get: function () { return projects_1.CreateProjectDto; } });
|
|
109
125
|
Object.defineProperty(exports, "GetProjectsDto", { enumerable: true, get: function () { return projects_1.GetProjectsDto; } });
|
|
110
126
|
Object.defineProperty(exports, "ProjectIdDto", { enumerable: true, get: function () { return projects_1.ProjectIdDto; } });
|
|
127
|
+
Object.defineProperty(exports, "StaffGetProjectsDto", { enumerable: true, get: function () { return projects_1.StaffGetProjectsDto; } });
|
|
111
128
|
Object.defineProperty(exports, "UpdateProjectDto", { enumerable: true, get: function () { return projects_1.UpdateProjectDto; } });
|
|
112
129
|
var tasks_1 = require("./tasks");
|
|
113
130
|
Object.defineProperty(exports, "AddTaskLinkDto", { enumerable: true, get: function () { return tasks_1.AddTaskLinkDto; } });
|
|
114
131
|
Object.defineProperty(exports, "CreateTaskDto", { enumerable: true, get: function () { return tasks_1.CreateTaskDto; } });
|
|
115
132
|
Object.defineProperty(exports, "GetTasksDto", { enumerable: true, get: function () { return tasks_1.GetTasksDto; } });
|
|
133
|
+
Object.defineProperty(exports, "StaffGetTasksDto", { enumerable: true, get: function () { return tasks_1.StaffGetTasksDto; } });
|
|
116
134
|
Object.defineProperty(exports, "TaskIdDto", { enumerable: true, get: function () { return tasks_1.TaskIdDto; } });
|
|
117
135
|
Object.defineProperty(exports, "TaskLinkIdDto", { enumerable: true, get: function () { return tasks_1.TaskLinkIdDto; } });
|
|
118
136
|
Object.defineProperty(exports, "UpdateTaskDto", { enumerable: true, get: function () { return tasks_1.UpdateTaskDto; } });
|
package/dist/leads/dto.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { UUID } from 'crypto';
|
|
2
|
-
import type { ConvertLeadDto as ConvertLeadDtoType, CreateLeadDto as CreateLeadDtoType, GetLeadsDto as GetLeadsDtoType, LeadIdDto as LeadIdDtoType, UpdateLeadDto as UpdateLeadDtoType } from '@managemint-solutions/entities/leads/dto';
|
|
2
|
+
import type { ConvertLeadDto as ConvertLeadDtoType, CreateLeadDto as CreateLeadDtoType, GetLeadsDto as GetLeadsDtoType, StaffGetLeadsDto as StaffGetLeadsDtoType, LeadIdDto as LeadIdDtoType, UpdateLeadDto as UpdateLeadDtoType } from '@managemint-solutions/entities/leads/dto';
|
|
3
3
|
import { LeadSource } from '@managemint-solutions/entities/leads/enum';
|
|
4
4
|
export declare class GetLeadsDto implements Omit<GetLeadsDtoType, 'status_id_in'> {
|
|
5
5
|
readonly search?: string | null;
|
|
@@ -13,6 +13,10 @@ export declare class GetLeadsDto implements Omit<GetLeadsDtoType, 'status_id_in'
|
|
|
13
13
|
readonly completed?: boolean | null;
|
|
14
14
|
readonly archive: boolean;
|
|
15
15
|
}
|
|
16
|
+
/** A staff read across organizations, optionally narrowed to one of them. */
|
|
17
|
+
export declare class StaffGetLeadsDto extends GetLeadsDto implements Omit<StaffGetLeadsDtoType, 'status_id_in'> {
|
|
18
|
+
readonly organization_id?: string | null;
|
|
19
|
+
}
|
|
16
20
|
export declare class LeadIdDto implements LeadIdDtoType {
|
|
17
21
|
readonly leadId: string;
|
|
18
22
|
}
|
package/dist/leads/dto.js
CHANGED
|
@@ -9,7 +9,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.ConvertLeadDto = exports.UpdateLeadDto = exports.CreateLeadDto = exports.LeadIdDto = exports.GetLeadsDto = void 0;
|
|
12
|
+
exports.ConvertLeadDto = exports.UpdateLeadDto = exports.CreateLeadDto = exports.LeadIdDto = exports.StaffGetLeadsDto = exports.GetLeadsDto = void 0;
|
|
13
13
|
const class_validator_1 = require("class-validator");
|
|
14
14
|
const class_transformer_1 = require("class-transformer");
|
|
15
15
|
const enum_1 = require("@managemint-solutions/entities/leads/enum");
|
|
@@ -107,6 +107,17 @@ __decorate([
|
|
|
107
107
|
(0, class_validator_1.IsBoolean)({ message: 'Include archived must be a boolean' }),
|
|
108
108
|
__metadata("design:type", Boolean)
|
|
109
109
|
], GetLeadsDto.prototype, "archive", void 0);
|
|
110
|
+
/** A staff read across organizations, optionally narrowed to one of them. */
|
|
111
|
+
class StaffGetLeadsDto extends GetLeadsDto {
|
|
112
|
+
organization_id;
|
|
113
|
+
}
|
|
114
|
+
exports.StaffGetLeadsDto = StaffGetLeadsDto;
|
|
115
|
+
__decorate([
|
|
116
|
+
(0, class_validator_1.IsOptional)(),
|
|
117
|
+
(0, validators_1.IsNullable)(),
|
|
118
|
+
(0, class_validator_1.IsUUID)('7', { message: 'Invalid organization ID format' }),
|
|
119
|
+
__metadata("design:type", Object)
|
|
120
|
+
], StaffGetLeadsDto.prototype, "organization_id", void 0);
|
|
110
121
|
class LeadIdDto {
|
|
111
122
|
leadId;
|
|
112
123
|
}
|
package/dist/leads/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ClientEntity } from '@managemint-solutions/entities/clients';
|
|
2
2
|
import type { MmsList } from '@managemint-solutions/entities/common';
|
|
3
3
|
import type { LeadEntity, LeadSummary } from '@managemint-solutions/entities/leads';
|
|
4
|
-
import type {
|
|
4
|
+
import type { ClientContext } from '../auth';
|
|
5
5
|
import type { AdditionalDetailsResource } from '../additional-details';
|
|
6
6
|
import { EntityAuditTrail, type AuditResource } from '../audit';
|
|
7
7
|
import type { ClientsResource } from '../clients';
|
|
@@ -15,8 +15,10 @@ export declare class LeadsResource {
|
|
|
15
15
|
private readonly table;
|
|
16
16
|
/** This record's history - its own rows and the rows that hang off it. */
|
|
17
17
|
readonly audit: EntityAuditTrail;
|
|
18
|
-
constructor(supabase: TypedSupabaseClient, auth:
|
|
19
|
-
list(query: GetLeadsDto
|
|
18
|
+
constructor(supabase: TypedSupabaseClient, auth: ClientContext, audit: AuditResource, additionalDetails: AdditionalDetailsResource);
|
|
19
|
+
list(query: GetLeadsDto & {
|
|
20
|
+
organization_id?: string | null;
|
|
21
|
+
}): Promise<MmsList<LeadSummary>>;
|
|
20
22
|
getById(leadId: string): Promise<LeadEntity>;
|
|
21
23
|
create(input: CreateLeadDto): Promise<LeadEntity>;
|
|
22
24
|
update(leadId: string, input: UpdateLeadDto): Promise<LeadEntity>;
|
package/dist/leads/index.js
CHANGED
|
@@ -24,6 +24,7 @@ const enum_6 = require("@managemint-solutions/entities/audit-trail/enum");
|
|
|
24
24
|
const audit_1 = require("../audit");
|
|
25
25
|
const errors_1 = require("../errors");
|
|
26
26
|
const paths_1 = require("../supporting-files/paths");
|
|
27
|
+
const tenancy_1 = require("../tenancy");
|
|
27
28
|
const transforms_1 = require("../transforms");
|
|
28
29
|
const won_1 = require("./won");
|
|
29
30
|
__exportStar(require("./dto"), exports);
|
|
@@ -127,14 +128,16 @@ class LeadsResource {
|
|
|
127
128
|
const trimmedSearch = query.search?.trim();
|
|
128
129
|
// `order`/`range` return `this`, so the builder stays a filter builder and the conditional
|
|
129
130
|
// filters below can be reassigned onto it without a cast.
|
|
130
|
-
let leadsQuery = this.supabase
|
|
131
|
+
let leadsQuery = (0, tenancy_1.scopeToOrganization)(this.supabase
|
|
131
132
|
.from('leads')
|
|
132
|
-
.select(LEAD_LIST_SELECT, { count: 'estimated' })
|
|
133
|
-
.eq('organization_id', this.auth.organization_id)
|
|
133
|
+
.select((0, tenancy_1.withOrganization)(LEAD_LIST_SELECT, this.auth), { count: 'estimated' }), this.auth)
|
|
134
134
|
.eq('archived', query.archive)
|
|
135
135
|
.eq('deleted', false)
|
|
136
136
|
.order('created_at', { ascending: false })
|
|
137
137
|
.range(offset, offset + pageSize - 1);
|
|
138
|
+
if (query.organization_id) {
|
|
139
|
+
leadsQuery = leadsQuery.eq('organization_id', query.organization_id);
|
|
140
|
+
}
|
|
138
141
|
if (trimmedSearch) {
|
|
139
142
|
leadsQuery = leadsQuery.or((0, transforms_1.orIlike)(['name', 'contact_person', 'email'], trimmedSearch));
|
|
140
143
|
}
|
|
@@ -162,19 +165,18 @@ class LeadsResource {
|
|
|
162
165
|
return (0, transforms_1.toMmsList)(data, page, pageSize, count);
|
|
163
166
|
}
|
|
164
167
|
async getById(leadId) {
|
|
165
|
-
const { data, error } = await this.supabase
|
|
166
|
-
.from('leads')
|
|
167
|
-
.select(LEAD_DETAIL_SELECT)
|
|
168
|
-
.eq('organization_id', this.auth.organization_id)
|
|
168
|
+
const { data, error } = await (0, tenancy_1.scopeToOrganization)(this.supabase.from('leads').select((0, tenancy_1.withOrganization)(LEAD_DETAIL_SELECT, this.auth)), this.auth)
|
|
169
169
|
.eq('mms_id', leadId)
|
|
170
170
|
.single();
|
|
171
171
|
if (error)
|
|
172
172
|
throw (0, errors_1.mapPostgrestError)(error);
|
|
173
|
+
// The select carries the staff embed, so its row type is not inferred from the string.
|
|
174
|
+
const row = data;
|
|
173
175
|
// A soft-deleted lead keeps its audit trail but gives up its details. The client it became
|
|
174
176
|
// stays, so a converted lead can still point at it.
|
|
175
|
-
if (
|
|
177
|
+
if (row.deleted) {
|
|
176
178
|
return {
|
|
177
|
-
...
|
|
179
|
+
...row,
|
|
178
180
|
name: '',
|
|
179
181
|
contact_person: null,
|
|
180
182
|
email: '',
|
|
@@ -196,7 +198,7 @@ class LeadsResource {
|
|
|
196
198
|
// Omitted means the creator owns the lead; an explicit null leaves it unassigned.
|
|
197
199
|
assigned_to_id: input.assigned_to_id === undefined ? this.auth.mms_id : input.assigned_to_id,
|
|
198
200
|
lost_reason: lostReason,
|
|
199
|
-
organization_id: this.auth
|
|
201
|
+
organization_id: (0, tenancy_1.requireOrganization)(this.auth),
|
|
200
202
|
created_by: this.auth.mms_id,
|
|
201
203
|
created_at: new Date().toISOString(),
|
|
202
204
|
});
|
|
@@ -208,7 +210,7 @@ class LeadsResource {
|
|
|
208
210
|
const { data, error } = await this.supabase
|
|
209
211
|
.from('leads')
|
|
210
212
|
.select('status_id, converted_client_id')
|
|
211
|
-
.eq('organization_id', this.auth
|
|
213
|
+
.eq('organization_id', (0, tenancy_1.requireOrganization)(this.auth))
|
|
212
214
|
.eq('mms_id', leadId)
|
|
213
215
|
.single();
|
|
214
216
|
if (error)
|
|
@@ -228,12 +230,12 @@ class LeadsResource {
|
|
|
228
230
|
return this.getById(leadId);
|
|
229
231
|
}
|
|
230
232
|
async archive(leadId) {
|
|
231
|
-
await (0, won_1.refuseWonLead)(this.supabase, this.auth
|
|
233
|
+
await (0, won_1.refuseWonLead)(this.supabase, (0, tenancy_1.requireOrganization)(this.auth), leadId);
|
|
232
234
|
await this.table.transition(leadId, enum_6.AuditTrailAction.ARCHIVE, (0, transforms_1.archivedPatch)(this.auth.mms_id));
|
|
233
235
|
return this.getById(leadId);
|
|
234
236
|
}
|
|
235
237
|
async unarchive(leadId) {
|
|
236
|
-
await (0, won_1.refuseWonLead)(this.supabase, this.auth
|
|
238
|
+
await (0, won_1.refuseWonLead)(this.supabase, (0, tenancy_1.requireOrganization)(this.auth), leadId);
|
|
237
239
|
await this.table.transition(leadId, enum_6.AuditTrailAction.UNARCHIVE, (0, transforms_1.unarchivedPatch)(this.auth.mms_id));
|
|
238
240
|
return this.getById(leadId);
|
|
239
241
|
}
|
|
@@ -243,7 +245,7 @@ class LeadsResource {
|
|
|
243
245
|
}
|
|
244
246
|
/** Soft delete - the row stays, flagged `deleted`, and `restore()` brings it back. A Won lead cannot be deleted. */
|
|
245
247
|
async remove(leadId) {
|
|
246
|
-
await (0, won_1.refuseWonLead)(this.supabase, this.auth
|
|
248
|
+
await (0, won_1.refuseWonLead)(this.supabase, (0, tenancy_1.requireOrganization)(this.auth), leadId);
|
|
247
249
|
await this.table.transition(leadId, enum_6.AuditTrailAction.DELETE, (0, transforms_1.deletedPatch)(this.auth.mms_id));
|
|
248
250
|
}
|
|
249
251
|
/**
|
|
@@ -266,11 +268,12 @@ class LeadsResource {
|
|
|
266
268
|
* client is created, and read back, without the caller holding any clients permission.
|
|
267
269
|
*/
|
|
268
270
|
async convert(leadId, input, clients) {
|
|
271
|
+
const organizationId = (0, tenancy_1.requireOrganization)(this.auth);
|
|
269
272
|
// (a) The lead, in this organization, not deleted and not converted already.
|
|
270
273
|
const { data, error } = await this.supabase
|
|
271
274
|
.from('leads')
|
|
272
275
|
.select(LEAD_CONVERT_SELECT)
|
|
273
|
-
.eq('organization_id',
|
|
276
|
+
.eq('organization_id', organizationId)
|
|
274
277
|
.eq('mms_id', leadId)
|
|
275
278
|
.maybeSingle();
|
|
276
279
|
if (error)
|
|
@@ -324,7 +327,7 @@ class LeadsResource {
|
|
|
324
327
|
const { error: moveError } = await this.supabase
|
|
325
328
|
.from(table)
|
|
326
329
|
.update({ entity_type: toType, entity_id: clientId })
|
|
327
|
-
.eq('organization_id',
|
|
330
|
+
.eq('organization_id', organizationId)
|
|
328
331
|
.eq('entity_type', fromType)
|
|
329
332
|
.eq('entity_id', leadId);
|
|
330
333
|
if (moveError)
|
|
@@ -336,7 +339,7 @@ class LeadsResource {
|
|
|
336
339
|
const { data: files, error: filesError } = await this.supabase
|
|
337
340
|
.from('supporting_files')
|
|
338
341
|
.select('mms_id, name, extension')
|
|
339
|
-
.eq('organization_id',
|
|
342
|
+
.eq('organization_id', organizationId)
|
|
340
343
|
.eq('entity_type', enum_5.SupportingFilesEntityTypes.LEAD)
|
|
341
344
|
.eq('entity_id', leadId);
|
|
342
345
|
if (filesError)
|
|
@@ -344,7 +347,7 @@ class LeadsResource {
|
|
|
344
347
|
for (const file of files) {
|
|
345
348
|
const { error: storageError } = await this.supabase.storage
|
|
346
349
|
.from(SUPPORTING_FILES_BUCKET)
|
|
347
|
-
.move((0, paths_1.storagePath)(
|
|
350
|
+
.move((0, paths_1.storagePath)(organizationId, enum_5.SupportingFilesEntityTypes.LEAD, leadId, file.name, file.extension), (0, paths_1.storagePath)(organizationId, enum_5.SupportingFilesEntityTypes.CLIENT, clientId, file.name, file.extension));
|
|
348
351
|
if (storageError) {
|
|
349
352
|
if (storageError.status === 404 || storageError.statusCode === '404')
|
|
350
353
|
continue;
|
|
@@ -353,7 +356,7 @@ class LeadsResource {
|
|
|
353
356
|
const { error: rowError } = await this.supabase
|
|
354
357
|
.from('supporting_files')
|
|
355
358
|
.update({ entity_type: enum_5.SupportingFilesEntityTypes.CLIENT, entity_id: clientId })
|
|
356
|
-
.eq('organization_id',
|
|
359
|
+
.eq('organization_id', organizationId)
|
|
357
360
|
.eq('mms_id', file.mms_id);
|
|
358
361
|
if (rowError)
|
|
359
362
|
throw (0, errors_1.mapPostgrestError)(rowError);
|
|
@@ -363,7 +366,7 @@ class LeadsResource {
|
|
|
363
366
|
const { data: won, error: wonError } = await this.supabase
|
|
364
367
|
.from('statuses')
|
|
365
368
|
.select('mms_id')
|
|
366
|
-
.eq('organization_id',
|
|
369
|
+
.eq('organization_id', organizationId)
|
|
367
370
|
.eq('is_won', true)
|
|
368
371
|
.maybeSingle();
|
|
369
372
|
if (wonError)
|
|
@@ -390,7 +393,7 @@ class LeadsResource {
|
|
|
390
393
|
const { data, error } = await this.supabase
|
|
391
394
|
.from('statuses')
|
|
392
395
|
.select('is_fail, is_won')
|
|
393
|
-
.eq('organization_id', this.auth
|
|
396
|
+
.eq('organization_id', (0, tenancy_1.requireOrganization)(this.auth))
|
|
394
397
|
.eq('entity_type', enum_4.StatusEntityTypes.LEAD)
|
|
395
398
|
.eq('mms_id', statusId)
|
|
396
399
|
.maybeSingle();
|
package/dist/nest/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { HttpException } from '@nestjs/common';
|
|
2
2
|
import type { Request } from 'express';
|
|
3
3
|
import type { AuditErrorHandler } from '../audit';
|
|
4
|
-
import { type VerifiedAuth } from '../auth';
|
|
4
|
+
import { type VerifiedAuth, type VerifiedStaff } from '../auth';
|
|
5
5
|
import { type SupabaseClient } from '../client';
|
|
6
6
|
import { SupabaseClientError } from '../errors';
|
|
7
|
+
import { type SupabaseStaffClient as StaffClient } from '../staff-client';
|
|
7
8
|
import { type SupabaseServiceClient } from '../service-client';
|
|
8
9
|
/**
|
|
9
10
|
* The HttpException Nest should send for an SDK error: same status, and the body is
|
|
@@ -42,6 +43,30 @@ export declare const attachSupabaseRequestContext: (request: Request) => Promise
|
|
|
42
43
|
export declare const getSupabaseRequestContext: (request: Request) => SupabaseRequestContext;
|
|
43
44
|
/** The caller's data client, from the context the auth guard attached. */
|
|
44
45
|
export declare const SupabaseUserClient: (...dataOrPipes: unknown[]) => ParameterDecorator;
|
|
46
|
+
/** What the admin api's staff guard leaves on the request for the decorator to pick up. */
|
|
47
|
+
export type SupabaseStaffRequestContext = {
|
|
48
|
+
client: StaffClient;
|
|
49
|
+
staff: VerifiedStaff;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Where on the request the staff context is stored - `request[SUPABASE_STAFF_REQUEST_KEY]`. A key
|
|
53
|
+
* of its own, so a staff context is never found where a tenant one is expected.
|
|
54
|
+
*/
|
|
55
|
+
export declare const SUPABASE_STAFF_REQUEST_KEY = "supabaseStaff";
|
|
56
|
+
/**
|
|
57
|
+
* `attachSupabaseRequestContext` for a staff session: verifies the token as a staff one and builds
|
|
58
|
+
* the staff member's `SupabaseStaffClient`.
|
|
59
|
+
*
|
|
60
|
+
* Idempotent: a second call hands back the context the first one attached.
|
|
61
|
+
*/
|
|
62
|
+
export declare const attachSupabaseStaffRequestContext: (request: Request) => Promise<SupabaseStaffRequestContext>;
|
|
63
|
+
/**
|
|
64
|
+
* The context the staff guard attached. Throws when it is absent, which only happens when the
|
|
65
|
+
* route is missing the guard.
|
|
66
|
+
*/
|
|
67
|
+
export declare const getSupabaseStaffRequestContext: (request: Request) => SupabaseStaffRequestContext;
|
|
68
|
+
/** The staff member's data client, from the context the staff guard attached. */
|
|
69
|
+
export declare const SupabaseStaffClient: (...dataOrPipes: unknown[]) => ParameterDecorator;
|
|
45
70
|
/**
|
|
46
71
|
* A `SupabaseServiceClient` from the ambient env - the SDK-side replacement for the api's
|
|
47
72
|
* `createSupabaseAdminClient()`.
|
package/dist/nest/index.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SupabasePublicClient = exports.createSupabaseServiceClientFromEnv = exports.SupabaseUserClient = exports.getSupabaseRequestContext = exports.attachSupabaseRequestContext = exports.SUPABASE_REQUEST_KEY = exports.configureSupabaseUserClient = exports.toHttpException = void 0;
|
|
3
|
+
exports.SupabasePublicClient = exports.createSupabaseServiceClientFromEnv = exports.SupabaseStaffClient = exports.getSupabaseStaffRequestContext = exports.attachSupabaseStaffRequestContext = exports.SUPABASE_STAFF_REQUEST_KEY = exports.SupabaseUserClient = exports.getSupabaseRequestContext = exports.attachSupabaseRequestContext = exports.SUPABASE_REQUEST_KEY = exports.configureSupabaseUserClient = exports.toHttpException = void 0;
|
|
4
4
|
const common_1 = require("@nestjs/common");
|
|
5
5
|
const auth_1 = require("../auth");
|
|
6
6
|
const auth_client_1 = require("../auth-client");
|
|
7
7
|
const client_1 = require("../client");
|
|
8
8
|
const errors_1 = require("../errors");
|
|
9
|
+
// Aliased: the param decorator below takes the class's name.
|
|
10
|
+
const staff_client_1 = require("../staff-client");
|
|
9
11
|
const service_client_1 = require("../service-client");
|
|
10
12
|
/**
|
|
11
13
|
* The HttpException Nest should send for an SDK error: same status, and the body is
|
|
@@ -96,6 +98,61 @@ const getSupabaseRequestContext = (request) => {
|
|
|
96
98
|
exports.getSupabaseRequestContext = getSupabaseRequestContext;
|
|
97
99
|
/** The caller's data client, from the context the auth guard attached. */
|
|
98
100
|
exports.SupabaseUserClient = (0, common_1.createParamDecorator)((_, ctx) => (0, exports.getSupabaseRequestContext)(ctx.switchToHttp().getRequest()).client);
|
|
101
|
+
/**
|
|
102
|
+
* Where on the request the staff context is stored - `request[SUPABASE_STAFF_REQUEST_KEY]`. A key
|
|
103
|
+
* of its own, so a staff context is never found where a tenant one is expected.
|
|
104
|
+
*/
|
|
105
|
+
exports.SUPABASE_STAFF_REQUEST_KEY = 'supabaseStaff';
|
|
106
|
+
/**
|
|
107
|
+
* `attachSupabaseRequestContext` for a staff session: verifies the token as a staff one and builds
|
|
108
|
+
* the staff member's `SupabaseStaffClient`.
|
|
109
|
+
*
|
|
110
|
+
* Idempotent: a second call hands back the context the first one attached.
|
|
111
|
+
*/
|
|
112
|
+
const attachSupabaseStaffRequestContext = async (request) => {
|
|
113
|
+
const existing = request[exports.SUPABASE_STAFF_REQUEST_KEY];
|
|
114
|
+
if (existing)
|
|
115
|
+
return existing;
|
|
116
|
+
const accessToken = getBearerToken(request);
|
|
117
|
+
const url = getEnvOrThrow('SUPABASE_URL');
|
|
118
|
+
const key = getEnvOrThrow('SUPABASE_PUBLISHABLE_KEY');
|
|
119
|
+
const client = (0, auth_1.createRawClient)(url, key, accessToken);
|
|
120
|
+
try {
|
|
121
|
+
const staff = await (0, auth_1.verifyStaffAccessToken)({ url, key, accessToken, client });
|
|
122
|
+
const context = {
|
|
123
|
+
staff,
|
|
124
|
+
client: (0, staff_client_1.createSupabaseStaffClient)({
|
|
125
|
+
url,
|
|
126
|
+
key,
|
|
127
|
+
accessToken,
|
|
128
|
+
client,
|
|
129
|
+
auth: { mms_id: staff.mms_id, organization_id: null },
|
|
130
|
+
}),
|
|
131
|
+
};
|
|
132
|
+
request[exports.SUPABASE_STAFF_REQUEST_KEY] = context;
|
|
133
|
+
return context;
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
// Converted here for the same reason as the tenant attach: guards run outside the filters.
|
|
137
|
+
if (error instanceof errors_1.SupabaseClientError)
|
|
138
|
+
throw (0, exports.toHttpException)(error);
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
exports.attachSupabaseStaffRequestContext = attachSupabaseStaffRequestContext;
|
|
143
|
+
/**
|
|
144
|
+
* The context the staff guard attached. Throws when it is absent, which only happens when the
|
|
145
|
+
* route is missing the guard.
|
|
146
|
+
*/
|
|
147
|
+
const getSupabaseStaffRequestContext = (request) => {
|
|
148
|
+
const context = request[exports.SUPABASE_STAFF_REQUEST_KEY];
|
|
149
|
+
if (!context)
|
|
150
|
+
throw new common_1.UnauthorizedException('Request is not authenticated');
|
|
151
|
+
return context;
|
|
152
|
+
};
|
|
153
|
+
exports.getSupabaseStaffRequestContext = getSupabaseStaffRequestContext;
|
|
154
|
+
/** The staff member's data client, from the context the staff guard attached. */
|
|
155
|
+
exports.SupabaseStaffClient = (0, common_1.createParamDecorator)((_, ctx) => (0, exports.getSupabaseStaffRequestContext)(ctx.switchToHttp().getRequest()).client);
|
|
99
156
|
/**
|
|
100
157
|
* A `SupabaseServiceClient` from the ambient env - the SDK-side replacement for the api's
|
|
101
158
|
* `createSupabaseAdminClient()`.
|
|
@@ -2,7 +2,7 @@ import type { NotificationContent, NotificationEntity, NotificationSummary, Noti
|
|
|
2
2
|
import { NotificationChannel, NotificationStatus, type NotificationType } from '@managemint-solutions/entities/notifications/enum';
|
|
3
3
|
import type { MmsList } from '@managemint-solutions/entities/common';
|
|
4
4
|
import type { AuthContext } from '../auth';
|
|
5
|
-
import { type
|
|
5
|
+
import { type AuditResource, type OrganizationTableFactory } from '../audit';
|
|
6
6
|
import type { TypedSupabaseClient } from '../client';
|
|
7
7
|
import type { GetNotificationsDto } from './dto';
|
|
8
8
|
export * from './dto';
|
|
@@ -75,8 +75,6 @@ export declare class NotificationsResource {
|
|
|
75
75
|
/** Soft delete - the outbox row stays, flagged `deleted`, so the send record survives. */
|
|
76
76
|
remove(notificationId: string): Promise<void>;
|
|
77
77
|
}
|
|
78
|
-
/** How the outbox reaches an audited table once it knows which organization a row belongs to. */
|
|
79
|
-
export type OrganizationTableFactory = (organizationId: string) => AuditedTable;
|
|
80
78
|
/**
|
|
81
79
|
* The outbox and the queue worker's side of the table, on the service client: RLS reserves
|
|
82
80
|
* `notifications` INSERT and DELETE to the service role, and `authenticated` has no grant on
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CreateOrganizationDto as CreateOrganizationDtoType, UpdateOrganizationDto as UpdateOrganizationDtoType } from '@managemint-solutions/entities/organization/dto';
|
|
1
|
+
import type { CreateOrganizationDto as CreateOrganizationDtoType, GetOrganizationsDto as GetOrganizationsDtoType, OrganizationIdDto as OrganizationIdDtoType, UpdateOrganizationDto as UpdateOrganizationDtoType } from '@managemint-solutions/entities/organization/dto';
|
|
2
2
|
import { OrganizationTypes } from '@managemint-solutions/entities/organization/enum';
|
|
3
3
|
export declare class CreateOrganizationDto implements CreateOrganizationDtoType {
|
|
4
4
|
readonly org_type: OrganizationTypes;
|
|
@@ -61,3 +61,11 @@ export declare class UpdateOrganizationDto implements UpdateOrganizationDtoType
|
|
|
61
61
|
readonly currency?: string;
|
|
62
62
|
readonly leave_calendar_start_month?: number;
|
|
63
63
|
}
|
|
64
|
+
export declare class OrganizationIdDto implements OrganizationIdDtoType {
|
|
65
|
+
readonly organizationId: string;
|
|
66
|
+
}
|
|
67
|
+
export declare class GetOrganizationsDto implements GetOrganizationsDtoType {
|
|
68
|
+
readonly search?: string | null;
|
|
69
|
+
readonly page: number;
|
|
70
|
+
readonly page_size: number;
|
|
71
|
+
}
|