@managemint-solutions/sdk 0.53.0 → 0.54.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 +8 -8
- package/dist/emulation-handshakes/index.d.ts +13 -0
- package/dist/emulation-handshakes/index.js +36 -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 +20 -19
- 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 +8 -8
- 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,36 @@
|
|
|
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
|
+
/** Opens a handshake for `userId`'s next sign-in, good for thirty seconds. Returns its id. */
|
|
15
|
+
async open(userId, credentialId) {
|
|
16
|
+
const { data, error } = await this.supabase
|
|
17
|
+
.from('emulation_handshakes')
|
|
18
|
+
.insert({
|
|
19
|
+
user_id: userId,
|
|
20
|
+
credential_id: credentialId,
|
|
21
|
+
expires_at: new Date(Date.now() + 30_000).toISOString(),
|
|
22
|
+
})
|
|
23
|
+
.select('id')
|
|
24
|
+
.single();
|
|
25
|
+
if (error)
|
|
26
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
27
|
+
return data.id;
|
|
28
|
+
}
|
|
29
|
+
/** Deletes the handshake, spent or not, once the mint is over. */
|
|
30
|
+
async close(id) {
|
|
31
|
+
const { error } = await this.supabase.from('emulation_handshakes').delete().eq('id', id);
|
|
32
|
+
if (error)
|
|
33
|
+
throw (0, errors_1.mapPostgrestError)(error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
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,10 +165,7 @@ 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(LEAD_DETAIL_SELECT), this.auth)
|
|
169
169
|
.eq('mms_id', leadId)
|
|
170
170
|
.single();
|
|
171
171
|
if (error)
|
|
@@ -196,7 +196,7 @@ class LeadsResource {
|
|
|
196
196
|
// Omitted means the creator owns the lead; an explicit null leaves it unassigned.
|
|
197
197
|
assigned_to_id: input.assigned_to_id === undefined ? this.auth.mms_id : input.assigned_to_id,
|
|
198
198
|
lost_reason: lostReason,
|
|
199
|
-
organization_id: this.auth
|
|
199
|
+
organization_id: (0, tenancy_1.requireOrganization)(this.auth),
|
|
200
200
|
created_by: this.auth.mms_id,
|
|
201
201
|
created_at: new Date().toISOString(),
|
|
202
202
|
});
|
|
@@ -208,7 +208,7 @@ class LeadsResource {
|
|
|
208
208
|
const { data, error } = await this.supabase
|
|
209
209
|
.from('leads')
|
|
210
210
|
.select('status_id, converted_client_id')
|
|
211
|
-
.eq('organization_id', this.auth
|
|
211
|
+
.eq('organization_id', (0, tenancy_1.requireOrganization)(this.auth))
|
|
212
212
|
.eq('mms_id', leadId)
|
|
213
213
|
.single();
|
|
214
214
|
if (error)
|
|
@@ -228,12 +228,12 @@ class LeadsResource {
|
|
|
228
228
|
return this.getById(leadId);
|
|
229
229
|
}
|
|
230
230
|
async archive(leadId) {
|
|
231
|
-
await (0, won_1.refuseWonLead)(this.supabase, this.auth
|
|
231
|
+
await (0, won_1.refuseWonLead)(this.supabase, (0, tenancy_1.requireOrganization)(this.auth), leadId);
|
|
232
232
|
await this.table.transition(leadId, enum_6.AuditTrailAction.ARCHIVE, (0, transforms_1.archivedPatch)(this.auth.mms_id));
|
|
233
233
|
return this.getById(leadId);
|
|
234
234
|
}
|
|
235
235
|
async unarchive(leadId) {
|
|
236
|
-
await (0, won_1.refuseWonLead)(this.supabase, this.auth
|
|
236
|
+
await (0, won_1.refuseWonLead)(this.supabase, (0, tenancy_1.requireOrganization)(this.auth), leadId);
|
|
237
237
|
await this.table.transition(leadId, enum_6.AuditTrailAction.UNARCHIVE, (0, transforms_1.unarchivedPatch)(this.auth.mms_id));
|
|
238
238
|
return this.getById(leadId);
|
|
239
239
|
}
|
|
@@ -243,7 +243,7 @@ class LeadsResource {
|
|
|
243
243
|
}
|
|
244
244
|
/** Soft delete - the row stays, flagged `deleted`, and `restore()` brings it back. A Won lead cannot be deleted. */
|
|
245
245
|
async remove(leadId) {
|
|
246
|
-
await (0, won_1.refuseWonLead)(this.supabase, this.auth
|
|
246
|
+
await (0, won_1.refuseWonLead)(this.supabase, (0, tenancy_1.requireOrganization)(this.auth), leadId);
|
|
247
247
|
await this.table.transition(leadId, enum_6.AuditTrailAction.DELETE, (0, transforms_1.deletedPatch)(this.auth.mms_id));
|
|
248
248
|
}
|
|
249
249
|
/**
|
|
@@ -266,11 +266,12 @@ class LeadsResource {
|
|
|
266
266
|
* client is created, and read back, without the caller holding any clients permission.
|
|
267
267
|
*/
|
|
268
268
|
async convert(leadId, input, clients) {
|
|
269
|
+
const organizationId = (0, tenancy_1.requireOrganization)(this.auth);
|
|
269
270
|
// (a) The lead, in this organization, not deleted and not converted already.
|
|
270
271
|
const { data, error } = await this.supabase
|
|
271
272
|
.from('leads')
|
|
272
273
|
.select(LEAD_CONVERT_SELECT)
|
|
273
|
-
.eq('organization_id',
|
|
274
|
+
.eq('organization_id', organizationId)
|
|
274
275
|
.eq('mms_id', leadId)
|
|
275
276
|
.maybeSingle();
|
|
276
277
|
if (error)
|
|
@@ -324,7 +325,7 @@ class LeadsResource {
|
|
|
324
325
|
const { error: moveError } = await this.supabase
|
|
325
326
|
.from(table)
|
|
326
327
|
.update({ entity_type: toType, entity_id: clientId })
|
|
327
|
-
.eq('organization_id',
|
|
328
|
+
.eq('organization_id', organizationId)
|
|
328
329
|
.eq('entity_type', fromType)
|
|
329
330
|
.eq('entity_id', leadId);
|
|
330
331
|
if (moveError)
|
|
@@ -336,7 +337,7 @@ class LeadsResource {
|
|
|
336
337
|
const { data: files, error: filesError } = await this.supabase
|
|
337
338
|
.from('supporting_files')
|
|
338
339
|
.select('mms_id, name, extension')
|
|
339
|
-
.eq('organization_id',
|
|
340
|
+
.eq('organization_id', organizationId)
|
|
340
341
|
.eq('entity_type', enum_5.SupportingFilesEntityTypes.LEAD)
|
|
341
342
|
.eq('entity_id', leadId);
|
|
342
343
|
if (filesError)
|
|
@@ -344,7 +345,7 @@ class LeadsResource {
|
|
|
344
345
|
for (const file of files) {
|
|
345
346
|
const { error: storageError } = await this.supabase.storage
|
|
346
347
|
.from(SUPPORTING_FILES_BUCKET)
|
|
347
|
-
.move((0, paths_1.storagePath)(
|
|
348
|
+
.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
349
|
if (storageError) {
|
|
349
350
|
if (storageError.status === 404 || storageError.statusCode === '404')
|
|
350
351
|
continue;
|
|
@@ -353,7 +354,7 @@ class LeadsResource {
|
|
|
353
354
|
const { error: rowError } = await this.supabase
|
|
354
355
|
.from('supporting_files')
|
|
355
356
|
.update({ entity_type: enum_5.SupportingFilesEntityTypes.CLIENT, entity_id: clientId })
|
|
356
|
-
.eq('organization_id',
|
|
357
|
+
.eq('organization_id', organizationId)
|
|
357
358
|
.eq('mms_id', file.mms_id);
|
|
358
359
|
if (rowError)
|
|
359
360
|
throw (0, errors_1.mapPostgrestError)(rowError);
|
|
@@ -363,7 +364,7 @@ class LeadsResource {
|
|
|
363
364
|
const { data: won, error: wonError } = await this.supabase
|
|
364
365
|
.from('statuses')
|
|
365
366
|
.select('mms_id')
|
|
366
|
-
.eq('organization_id',
|
|
367
|
+
.eq('organization_id', organizationId)
|
|
367
368
|
.eq('is_won', true)
|
|
368
369
|
.maybeSingle();
|
|
369
370
|
if (wonError)
|
|
@@ -390,7 +391,7 @@ class LeadsResource {
|
|
|
390
391
|
const { data, error } = await this.supabase
|
|
391
392
|
.from('statuses')
|
|
392
393
|
.select('is_fail, is_won')
|
|
393
|
-
.eq('organization_id', this.auth
|
|
394
|
+
.eq('organization_id', (0, tenancy_1.requireOrganization)(this.auth))
|
|
394
395
|
.eq('entity_type', enum_4.StatusEntityTypes.LEAD)
|
|
395
396
|
.eq('mms_id', statusId)
|
|
396
397
|
.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
|
+
}
|
|
@@ -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.UpdateOrganizationDto = exports.CreateOrganizationDto = void 0;
|
|
12
|
+
exports.GetOrganizationsDto = exports.OrganizationIdDto = exports.UpdateOrganizationDto = exports.CreateOrganizationDto = void 0;
|
|
13
13
|
const enum_1 = require("@managemint-solutions/entities/organization/enum");
|
|
14
14
|
const class_validator_1 = require("class-validator");
|
|
15
15
|
const validators_1 = require("../validators");
|
|
@@ -450,3 +450,42 @@ __decorate([
|
|
|
450
450
|
(0, class_validator_1.Max)(12, { message: 'Leave year start month must be between 1 and 12' }),
|
|
451
451
|
__metadata("design:type", Number)
|
|
452
452
|
], UpdateOrganizationDto.prototype, "leave_calendar_start_month", void 0);
|
|
453
|
+
// No tenant route takes one - a tenant only ever reaches their own organization - so this is the
|
|
454
|
+
// admin api's `/organizations/:organizationId`.
|
|
455
|
+
class OrganizationIdDto {
|
|
456
|
+
organizationId;
|
|
457
|
+
}
|
|
458
|
+
exports.OrganizationIdDto = OrganizationIdDto;
|
|
459
|
+
__decorate([
|
|
460
|
+
(0, class_validator_1.IsUUID)('7', { message: 'Invalid organization ID format' }),
|
|
461
|
+
__metadata("design:type", String)
|
|
462
|
+
], OrganizationIdDto.prototype, "organizationId", void 0);
|
|
463
|
+
class GetOrganizationsDto {
|
|
464
|
+
search;
|
|
465
|
+
page = 1;
|
|
466
|
+
page_size = 10;
|
|
467
|
+
}
|
|
468
|
+
exports.GetOrganizationsDto = GetOrganizationsDto;
|
|
469
|
+
__decorate([
|
|
470
|
+
(0, class_validator_1.IsOptional)(),
|
|
471
|
+
(0, validators_1.IsNullable)(),
|
|
472
|
+
(0, class_validator_1.IsString)({ message: 'Search query must be a string' }),
|
|
473
|
+
(0, class_validator_1.MinLength)(1, { message: 'Search query cannot be empty' }),
|
|
474
|
+
(0, class_validator_1.MaxLength)(255, { message: 'Search query cannot exceed 255 characters' }),
|
|
475
|
+
__metadata("design:type", Object)
|
|
476
|
+
], GetOrganizationsDto.prototype, "search", void 0);
|
|
477
|
+
__decorate([
|
|
478
|
+
(0, class_validator_1.IsOptional)(),
|
|
479
|
+
(0, class_transformer_1.Transform)(({ value }) => value ? Number(value) : 1, { toClassOnly: true }),
|
|
480
|
+
(0, class_validator_1.IsNumber)({}, { message: 'Page must be a number' }),
|
|
481
|
+
(0, class_validator_1.Min)(1, { message: 'Page must be at least 1' }),
|
|
482
|
+
__metadata("design:type", Number)
|
|
483
|
+
], GetOrganizationsDto.prototype, "page", void 0);
|
|
484
|
+
__decorate([
|
|
485
|
+
(0, class_validator_1.IsOptional)(),
|
|
486
|
+
(0, class_transformer_1.Transform)(({ value }) => value ? Number(value) : 10, { toClassOnly: true }),
|
|
487
|
+
(0, class_validator_1.IsNumber)({}, { message: 'Page size must be a number' }),
|
|
488
|
+
(0, class_validator_1.Min)(1, { message: 'Page size must be at least 1' }),
|
|
489
|
+
(0, class_validator_1.Max)(100, { message: 'Page size cannot exceed 100' }),
|
|
490
|
+
__metadata("design:type", Number)
|
|
491
|
+
], GetOrganizationsDto.prototype, "page_size", void 0);
|