@managemint-solutions/sdk 0.56.0 → 0.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +209 -7
  2. package/dist/audit/document-changes.d.ts +39 -0
  3. package/dist/audit/document-changes.js +332 -0
  4. package/dist/audit/index.d.ts +50 -2
  5. package/dist/audit/index.js +87 -44
  6. package/dist/client.d.ts +6 -0
  7. package/dist/client.js +9 -0
  8. package/dist/clients/dto.d.ts +18 -3
  9. package/dist/clients/dto.js +72 -2
  10. package/dist/clients/index.js +16 -0
  11. package/dist/configs/dto.js +4 -12
  12. package/dist/documents/content.d.ts +39 -0
  13. package/dist/documents/content.js +443 -0
  14. package/dist/documents/document-templates.d.ts +37 -0
  15. package/dist/documents/document-templates.js +143 -0
  16. package/dist/documents/documents.d.ts +154 -0
  17. package/dist/documents/documents.js +330 -0
  18. package/dist/documents/dto.d.ts +138 -0
  19. package/dist/documents/dto.js +594 -0
  20. package/dist/documents/index.d.ts +4 -0
  21. package/dist/documents/index.js +24 -0
  22. package/dist/documents/render/html.d.ts +64 -0
  23. package/dist/documents/render/html.js +413 -0
  24. package/dist/documents/render/index.d.ts +2 -0
  25. package/dist/documents/render/index.js +23 -0
  26. package/dist/documents/render/values.d.ts +86 -0
  27. package/dist/documents/render/values.js +142 -0
  28. package/dist/feature-requests/dto.js +4 -13
  29. package/dist/index.d.ts +8 -1
  30. package/dist/index.js +31 -3
  31. package/dist/leads/index.js +1 -3
  32. package/dist/notifications/index.d.ts +6 -0
  33. package/dist/notifications/index.js +16 -0
  34. package/dist/organization-payment-methods/dto.d.ts +10 -0
  35. package/dist/organization-payment-methods/dto.js +56 -0
  36. package/dist/organization-payment-methods/index.d.ts +8 -1
  37. package/dist/organization-payment-methods/index.js +23 -0
  38. package/dist/payments/index.d.ts +67 -0
  39. package/dist/payments/index.js +137 -0
  40. package/dist/permissions/dto.d.ts +4 -0
  41. package/dist/permissions/dto.js +20 -8
  42. package/dist/service-client/index.d.ts +44 -0
  43. package/dist/service-client/index.js +77 -0
  44. package/dist/staff-client.d.ts +3 -0
  45. package/dist/staff-client.js +5 -0
  46. package/dist/supporting-files/index.js +4 -6
  47. package/dist/supporting-files/paths.d.ts +2 -0
  48. package/dist/supporting-files/paths.js +3 -1
  49. package/dist/validators.d.ts +12 -0
  50. package/dist/validators.js +23 -1
  51. package/dist/visibility/dto.d.ts +15 -0
  52. package/dist/visibility/dto.js +68 -0
  53. package/dist/visibility/index.d.ts +59 -0
  54. package/dist/visibility/index.js +165 -0
  55. package/package.json +6 -2
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.systemValues = exports.johannesburgDate = exports.startingValues = exports.printsMoney = exports.documentTotals = exports.lineAmounts = exports.MONO_FONT = exports.formatDocumentDate = exports.money = exports.escapeHtml = exports.safeHref = exports.isObject = exports.SYSTEM_VARIABLES = exports.DOCUMENT_VARIABLE_PATTERN = void 0;
4
+ const enum_1 = require("@managemint-solutions/entities/documents/enum");
5
+ // The values a document prints that nobody types in: one line's amounts, the totals of every line
6
+ // items block, the system values, and how a value is escaped and formatted. Pure functions with
7
+ // no I/O, so the api (printing the PDF) and the portal (previewing it) work them out the same way.
8
+ /**
9
+ * A variable in plain text (field values, table cells, line descriptions, signer labels, header
10
+ * and footer text): `{{key}}`, spaces inside the braces allowed. The content rules check with it
11
+ * and the renderer replaces with it, so what is checked is exactly what prints. Global: use it
12
+ * with `matchAll` or `replace`, never `test`.
13
+ */
14
+ exports.DOCUMENT_VARIABLE_PATTERN = /\{\{\s*([^{}]*?)\s*\}\}/g;
15
+ /** How each system variable is labelled where it is missing, and the type it prints as. */
16
+ exports.SYSTEM_VARIABLES = {
17
+ [enum_1.DocumentSystemVariable.ORGANIZATION_NAME]: { label: 'Organization name', type: enum_1.DocumentVariableType.TEXT },
18
+ [enum_1.DocumentSystemVariable.ORGANIZATION_ADDRESS]: { label: 'Organization address', type: enum_1.DocumentVariableType.TEXT },
19
+ [enum_1.DocumentSystemVariable.CLIENT_NAME]: { label: 'Client name', type: enum_1.DocumentVariableType.TEXT },
20
+ [enum_1.DocumentSystemVariable.CLIENT_EMAIL]: { label: 'Client email', type: enum_1.DocumentVariableType.TEXT },
21
+ [enum_1.DocumentSystemVariable.CLIENT_PHONE]: { label: 'Client phone', type: enum_1.DocumentVariableType.TEXT },
22
+ [enum_1.DocumentSystemVariable.DOCUMENT_NUMBER]: { label: 'Document number', type: enum_1.DocumentVariableType.TEXT },
23
+ [enum_1.DocumentSystemVariable.ISSUE_DATE]: { label: 'Issue date', type: enum_1.DocumentVariableType.DATE },
24
+ [enum_1.DocumentSystemVariable.MONTH]: { label: 'Month', type: enum_1.DocumentVariableType.TEXT },
25
+ [enum_1.DocumentSystemVariable.YEAR]: { label: 'Year', type: enum_1.DocumentVariableType.TEXT },
26
+ // Never given a value: they print as page counters in the header and footer.
27
+ [enum_1.DocumentSystemVariable.PAGE_NUMBER]: { label: 'Page number', type: enum_1.DocumentVariableType.TEXT },
28
+ [enum_1.DocumentSystemVariable.PAGE_COUNT]: { label: 'Page count', type: enum_1.DocumentVariableType.TEXT },
29
+ [enum_1.DocumentSystemVariable.ORGANIZATION_REGISTRATION_NUMBER]: { label: 'Organization registration number', type: enum_1.DocumentVariableType.TEXT },
30
+ [enum_1.DocumentSystemVariable.ORGANIZATION_VAT_NUMBER]: { label: 'Organization VAT number', type: enum_1.DocumentVariableType.TEXT },
31
+ [enum_1.DocumentSystemVariable.ORGANIZATION_EMAIL]: { label: 'Organization email', type: enum_1.DocumentVariableType.TEXT },
32
+ [enum_1.DocumentSystemVariable.ORGANIZATION_PHONE]: { label: 'Organization phone', type: enum_1.DocumentVariableType.TEXT },
33
+ [enum_1.DocumentSystemVariable.CLIENT_ADDRESS]: { label: 'Client address', type: enum_1.DocumentVariableType.TEXT },
34
+ [enum_1.DocumentSystemVariable.CLIENT_REGISTRATION_NUMBER]: { label: 'Client registration number', type: enum_1.DocumentVariableType.TEXT },
35
+ [enum_1.DocumentSystemVariable.CLIENT_VAT_NUMBER]: { label: 'Client VAT number', type: enum_1.DocumentVariableType.TEXT },
36
+ };
37
+ const isObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
38
+ exports.isObject = isObject;
39
+ const LINK_PROTOCOLS = new Set(['http:', 'https:', 'mailto:']);
40
+ /**
41
+ * A link's href, or null unless it is http, https or mailto. The protocol is read as a browser
42
+ * reads it: the URL parser drops the tabs and newlines a plain prefix check would let hide a
43
+ * javascript: link. The content rules refuse what this refuses, and the renderer prints only what
44
+ * it passes.
45
+ */
46
+ const safeHref = (href) => typeof href === 'string' && URL.canParse(href) && LINK_PROTOCOLS.has(new URL(href).protocol) ? href : null;
47
+ exports.safeHref = safeHref;
48
+ const escapeHtml = (value) => value
49
+ .replaceAll('&', '&')
50
+ .replaceAll('<', '&lt;')
51
+ .replaceAll('>', '&gt;')
52
+ .replaceAll('"', '&quot;');
53
+ exports.escapeHtml = escapeHtml;
54
+ /** Integer cents in `currency`, the en-ZA way: `R 1 299,00`. Subscription invoices print with it too. */
55
+ const money = (amountMinor, currency) => new Intl.NumberFormat('en-ZA', { style: 'currency', currency }).format((amountMinor ?? 0) / 100);
56
+ exports.money = money;
57
+ /** `2026-11-01` -> `1 November 2026`. */
58
+ const formatDocumentDate = (date) => new Intl.DateTimeFormat('en-ZA', { day: 'numeric', month: 'long', year: 'numeric', timeZone: 'UTC' }).format(new Date(`${date}T00:00:00Z`));
59
+ exports.formatDocumentDate = formatDocumentDate;
60
+ /** The monospace stack for numbers - the design's JetBrains Mono, self-contained. */
61
+ exports.MONO_FONT = 'ui-monospace, \'Cascadia Mono\', \'Segoe UI Mono\', Consolas, monospace';
62
+ /** A line's quantity or unit price: the number written in, or its variable's value (0 while it has none). */
63
+ const amountOf = (amount, values) => {
64
+ if (typeof amount === 'number')
65
+ return amount;
66
+ const value = values[amount.variable];
67
+ return typeof value === 'number' ? value : 0;
68
+ };
69
+ /**
70
+ * One line's amounts in cents: gross = quantity x unit price, the discount a percentage of the
71
+ * gross, net = gross - discount, the tax a percentage of the net - each rounded to the cent.
72
+ */
73
+ const lineAmounts = (line, values) => {
74
+ const gross = Math.round(amountOf(line.quantity, values) * amountOf(line.unit_price_minor, values));
75
+ const discount = Math.round((gross * line.discount_percent) / 100);
76
+ const net = gross - discount;
77
+ const tax = Math.round((net * line.tax_rate) / 100);
78
+ return { gross, discount, net, tax };
79
+ };
80
+ exports.lineAmounts = lineAmounts;
81
+ /** The sums over every line of every line items block in `blocks`; all zero without one. */
82
+ const documentTotals = (blocks, values) => {
83
+ const totals = { subtotal_minor: 0, discount_minor: 0, tax_minor: 0, total_minor: 0 };
84
+ for (const block of blocks) {
85
+ if (block.type !== enum_1.DocumentBlockType.LINE_ITEMS)
86
+ continue;
87
+ for (const line of block.items) {
88
+ const { gross, discount, net, tax } = (0, exports.lineAmounts)(line, values);
89
+ totals.subtotal_minor += gross;
90
+ totals.discount_minor += discount;
91
+ totals.tax_minor += tax;
92
+ totals.total_minor += net + tax;
93
+ }
94
+ }
95
+ return totals;
96
+ };
97
+ exports.documentTotals = documentTotals;
98
+ /** Whether the content prints money - a line items block or a money variable - and so needs a currency. */
99
+ const printsMoney = (blocks, variables) => blocks.some((block) => block.type === enum_1.DocumentBlockType.LINE_ITEMS) ||
100
+ variables.some((variable) => variable.type === enum_1.DocumentVariableType.MONEY);
101
+ exports.printsMoney = printsMoney;
102
+ /** A new draft's values: each variable's default, overlaid by the values given. */
103
+ const startingValues = (variables, given = {}) => ({
104
+ ...Object.fromEntries(variables.flatMap((variable) => (variable.default_value === null ? [] : [[variable.key, variable.default_value]]))),
105
+ ...given,
106
+ });
107
+ exports.startingValues = startingValues;
108
+ /** The calendar date (`YYYY-MM-DD`) `now` falls on in Africa/Johannesburg - a draft's issue date. */
109
+ const johannesburgDate = (now) => new Intl.DateTimeFormat('en-CA', { timeZone: 'Africa/Johannesburg' }).format(now);
110
+ exports.johannesburgDate = johannesburgDate;
111
+ /**
112
+ * The values filled in for the system variables: the organization's name (its trading name
113
+ * first), address, registration and VAT numbers, email and phone; the client's name, email, phone,
114
+ * address, registration and VAT numbers; the document number; and the issue date with its month
115
+ * name and year. A value that is empty is left out, so it prints as missing. The
116
+ * page number and count are not values: they are counted page by page as the PDF prints.
117
+ */
118
+ const systemValues = ({ organization, client, number, issueDate }) => {
119
+ const text = (value) => (typeof value === 'string' ? value.trim() : '');
120
+ const address = (parts) => (parts ?? []).map(text).filter(Boolean).join(', ');
121
+ const [year, month] = issueDate.split('-');
122
+ const values = {
123
+ [enum_1.DocumentSystemVariable.ORGANIZATION_NAME]: text(organization.trading_name) || text(organization.name),
124
+ [enum_1.DocumentSystemVariable.ORGANIZATION_ADDRESS]: address(organization.address),
125
+ [enum_1.DocumentSystemVariable.ORGANIZATION_REGISTRATION_NUMBER]: text(organization.registration_number),
126
+ [enum_1.DocumentSystemVariable.ORGANIZATION_VAT_NUMBER]: text(organization.vat_number),
127
+ [enum_1.DocumentSystemVariable.ORGANIZATION_EMAIL]: text(organization.email),
128
+ [enum_1.DocumentSystemVariable.ORGANIZATION_PHONE]: text(organization.phone),
129
+ [enum_1.DocumentSystemVariable.CLIENT_NAME]: text(client?.name),
130
+ [enum_1.DocumentSystemVariable.CLIENT_EMAIL]: text(client?.email),
131
+ [enum_1.DocumentSystemVariable.CLIENT_PHONE]: text(client?.phone),
132
+ [enum_1.DocumentSystemVariable.CLIENT_ADDRESS]: address(client?.address),
133
+ [enum_1.DocumentSystemVariable.CLIENT_REGISTRATION_NUMBER]: text(client?.registration_number),
134
+ [enum_1.DocumentSystemVariable.CLIENT_VAT_NUMBER]: text(client?.vat_number),
135
+ [enum_1.DocumentSystemVariable.DOCUMENT_NUMBER]: number ?? '',
136
+ [enum_1.DocumentSystemVariable.ISSUE_DATE]: issueDate,
137
+ [enum_1.DocumentSystemVariable.MONTH]: new Intl.DateTimeFormat('en-ZA', { month: 'long', timeZone: 'UTC' }).format(new Date(Date.UTC(Number(year), Number(month) - 1, 1))),
138
+ [enum_1.DocumentSystemVariable.YEAR]: year,
139
+ };
140
+ return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== ''));
141
+ };
142
+ exports.systemValues = systemValues;
@@ -11,18 +11,9 @@ var __metadata = (this && this.__metadata) || function (k, v) {
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.CreateFeatureRequestDto = void 0;
13
13
  const class_validator_1 = require("class-validator");
14
- const class_transformer_1 = require("class-transformer");
15
14
  const validators_1 = require("../validators");
16
15
  // class-validator version of the shared DTO type from @managemint-solutions/entities, so the
17
16
  // wire contract cannot drift.
18
- /**
19
- * Whitespace on either side of a pasted value is not part of the answer. Trimming here rather
20
- * than in the api means the length rules below measure what will actually be stored - a name of
21
- * three spaces is empty, not three characters long.
22
- */
23
- const Trim = () => (0, class_transformer_1.Transform)(({ value }) => (typeof value === 'string' ? value.trim() : value), {
24
- toClassOnly: true,
25
- });
26
17
  class CreateFeatureRequestDto {
27
18
  name;
28
19
  // Markdown, and optional: a one-line request is a perfectly good request. `@Trim` sits above
@@ -44,7 +35,7 @@ class CreateFeatureRequestDto {
44
35
  }
45
36
  exports.CreateFeatureRequestDto = CreateFeatureRequestDto;
46
37
  __decorate([
47
- Trim(),
38
+ (0, validators_1.Trim)(),
48
39
  (0, class_validator_1.IsString)({ message: 'Invalid name' }),
49
40
  (0, class_validator_1.MinLength)(1, { message: 'Name cannot be empty' }),
50
41
  (0, class_validator_1.MaxLength)(200, { message: 'Name cannot exceed 200 characters' }),
@@ -52,7 +43,7 @@ __decorate([
52
43
  ], CreateFeatureRequestDto.prototype, "name", void 0);
53
44
  __decorate([
54
45
  (0, class_validator_1.IsOptional)(),
55
- Trim(),
46
+ (0, validators_1.Trim)(),
56
47
  (0, validators_1.EmptyToNull)(),
57
48
  (0, validators_1.IsNullable)(),
58
49
  (0, class_validator_1.ValidateIf)((o) => o.specification !== null && o.specification !== undefined),
@@ -61,14 +52,14 @@ __decorate([
61
52
  __metadata("design:type", Object)
62
53
  ], CreateFeatureRequestDto.prototype, "specification", void 0);
63
54
  __decorate([
64
- Trim(),
55
+ (0, validators_1.Trim)(),
65
56
  (0, class_validator_1.IsString)({ message: 'Invalid requester name' }),
66
57
  (0, class_validator_1.MinLength)(1, { message: 'Requester name cannot be empty' }),
67
58
  (0, class_validator_1.MaxLength)(200, { message: 'Requester name cannot exceed 200 characters' }),
68
59
  __metadata("design:type", String)
69
60
  ], CreateFeatureRequestDto.prototype, "requester_name", void 0);
70
61
  __decorate([
71
- Trim(),
62
+ (0, validators_1.Trim)(),
72
63
  (0, class_validator_1.IsEmail)({}, { message: 'Invalid email address' }),
73
64
  (0, class_validator_1.MaxLength)(320, { message: 'Email address cannot exceed 320 characters' }),
74
65
  __metadata("design:type", String)
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export type { SupabaseOrganizationScope, SupabaseServiceClientConfig } from './s
10
10
  export { SupabaseClientError } from './errors';
11
11
  export type { SupabaseClientErrorInit } from './errors';
12
12
  export { EmptyToNull, IsNullable } from './validators';
13
- export type { AuditActor, AuditChanges, AuditEntry, AuditErrorHandler, AuditGuard, AuditNameTable, AuditRow, AuditedTable, AuditedTableOptions, EntityAuditTrail, OrganizationTableFactory, } from './audit';
13
+ export type { AuditActor, AuditChanges, AuditDeleteGuard, AuditEntry, AuditErrorHandler, AuditGuard, AuditNameTable, AuditRow, AuditedTable, AuditedTableOptions, EntityAuditTrail, OrganizationTableFactory, } from './audit';
14
14
  export { GetAuditTrailDto, withAuditBatch } from './audit';
15
15
  export { CancelSubscriptionDto, GetPaymentsQueryDto, InitialPaymentDto, PaymentIdDto, PurchaseModuleDto, ReinstateSubscriptionDto, } from './billing';
16
16
  export { GetInvoicesQueryDto, InvoiceIdDto } from './billing/invoices';
@@ -26,6 +26,7 @@ export type { CreateNotificationInput, CreatedNotification, NotificationContentR
26
26
  export { GetNotificationsDto, NotificationIdDto } from './notifications';
27
27
  export type { OrganizationInvite } from './organization-invites';
28
28
  export type { OrganizationPaymentMethod, PaymentMethodLookupColumn, } from './organization-payment-methods';
29
+ export { UpdateOrganizationPayoutsDto } from './organization-payment-methods';
29
30
  export type { CreateOrganizationRow, OrganizationRow } from './organizations';
30
31
  export { CreateOrganizationDto, GetOrganizationsDto, OrganizationIdDto, UpdateOrganizationDto, } from './organizations';
31
32
  export { PermissionsResource } from './permissions';
@@ -40,6 +41,12 @@ export type { ClaimOutcome, WebhookEventRow, WebhookEventsTable } from './webhoo
40
41
  export { GetSupportingFilesDto, SupportingFileIdDto, SupportingFileNamesDto } from './supporting-files';
41
42
  export { ClientIdDto, CreateClientDto, GetClientsDto, StaffGetClientsDto, UpdateClientDto } from './clients';
42
43
  export { ConvertLeadDto, CreateLeadDto, GetLeadsDto, LeadIdDto, StaffGetLeadsDto, UpdateLeadDto } from './leads';
44
+ export type { CreateDocumentRow, DocumentListRecord, DocumentSendEvent, UpdateDocumentRow } from './documents';
45
+ export type { CreatePaymentRow, OpenPaymentRecord, PaymentRecord, SettlePaymentRow } from './payments';
46
+ export { CatalogueTemplateSlugDto, CopyCatalogueTemplateDto, CreateDocumentDto, CreateDocumentTemplateDto, DocumentIdDto, DocumentImageNameDto, DocumentImageUrlsDto, DocumentPayQueryDto, DocumentPayTokenDto, DocumentPaymentIdDto, DocumentTemplateIdDto, documentProblem, GetCatalogueTemplatesDto, GetDocumentsDto, GetDocumentTemplatesDto, PayDocumentDto, RecordDocumentPaymentDto, SendDocumentDto, UpdateDocumentDto, UpdateDocumentTemplateDto, VoidDocumentDto, ReassignPrivateDocumentsDto, } from './documents';
47
+ export type { DocumentRecord, DocumentTemplateRecord } from './documents';
48
+ export type { VisibilityRecord, VisibilityShareInput } from './visibility';
49
+ export { UpdateVisibilityDto } from './visibility';
43
50
  export { CreateProjectDto, GetProjectsDto, ProjectIdDto, StaffGetProjectsDto, UpdateProjectDto } from './projects';
44
51
  export { AddTaskLinkDto, CreateTaskDto, GetTasksDto, StaffGetTasksDto, TaskIdDto, TaskLinkIdDto, UpdateTaskDto, } from './tasks';
45
52
  export type { CreateLeaveEntitlementInput, CreateLeaveRequestRow, ReviewLeaveRequestRow, UpdateLeaveRequestRow, } from './leave';
package/dist/index.js CHANGED
@@ -7,9 +7,10 @@
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.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;
10
+ exports.UpdateOrganizationPayoutsDto = 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.SendDocumentDto = exports.RecordDocumentPaymentDto = exports.PayDocumentDto = exports.GetDocumentTemplatesDto = exports.GetDocumentsDto = exports.GetCatalogueTemplatesDto = exports.documentProblem = exports.DocumentTemplateIdDto = exports.DocumentPaymentIdDto = exports.DocumentPayTokenDto = exports.DocumentPayQueryDto = exports.DocumentImageUrlsDto = exports.DocumentImageNameDto = exports.DocumentIdDto = exports.CreateDocumentTemplateDto = exports.CreateDocumentDto = exports.CopyCatalogueTemplateDto = exports.CatalogueTemplateSlugDto = 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 = exports.CreateOrganizationDto = void 0;
12
+ 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 = 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.UpdateVisibilityDto = exports.ReassignPrivateDocumentsDto = exports.VoidDocumentDto = exports.UpdateDocumentTemplateDto = exports.UpdateDocumentDto = void 0;
13
+ exports.monthlyTotalMinor = exports.weekStartOf = exports.minutesBetween = void 0;
13
14
  var client_1 = require("./client");
14
15
  Object.defineProperty(exports, "SupabaseClient", { enumerable: true, get: function () { return client_1.SupabaseClient; } });
15
16
  Object.defineProperty(exports, "createSupabaseClient", { enumerable: true, get: function () { return client_1.createSupabaseClient; } });
@@ -77,6 +78,8 @@ Object.defineProperty(exports, "NoteIdDto", { enumerable: true, get: function ()
77
78
  var notifications_1 = require("./notifications");
78
79
  Object.defineProperty(exports, "GetNotificationsDto", { enumerable: true, get: function () { return notifications_1.GetNotificationsDto; } });
79
80
  Object.defineProperty(exports, "NotificationIdDto", { enumerable: true, get: function () { return notifications_1.NotificationIdDto; } });
81
+ var organization_payment_methods_1 = require("./organization-payment-methods");
82
+ Object.defineProperty(exports, "UpdateOrganizationPayoutsDto", { enumerable: true, get: function () { return organization_payment_methods_1.UpdateOrganizationPayoutsDto; } });
80
83
  var organizations_1 = require("./organizations");
81
84
  Object.defineProperty(exports, "CreateOrganizationDto", { enumerable: true, get: function () { return organizations_1.CreateOrganizationDto; } });
82
85
  Object.defineProperty(exports, "GetOrganizationsDto", { enumerable: true, get: function () { return organizations_1.GetOrganizationsDto; } });
@@ -120,6 +123,31 @@ Object.defineProperty(exports, "GetLeadsDto", { enumerable: true, get: function
120
123
  Object.defineProperty(exports, "LeadIdDto", { enumerable: true, get: function () { return leads_1.LeadIdDto; } });
121
124
  Object.defineProperty(exports, "StaffGetLeadsDto", { enumerable: true, get: function () { return leads_1.StaffGetLeadsDto; } });
122
125
  Object.defineProperty(exports, "UpdateLeadDto", { enumerable: true, get: function () { return leads_1.UpdateLeadDto; } });
126
+ var documents_1 = require("./documents");
127
+ Object.defineProperty(exports, "CatalogueTemplateSlugDto", { enumerable: true, get: function () { return documents_1.CatalogueTemplateSlugDto; } });
128
+ Object.defineProperty(exports, "CopyCatalogueTemplateDto", { enumerable: true, get: function () { return documents_1.CopyCatalogueTemplateDto; } });
129
+ Object.defineProperty(exports, "CreateDocumentDto", { enumerable: true, get: function () { return documents_1.CreateDocumentDto; } });
130
+ Object.defineProperty(exports, "CreateDocumentTemplateDto", { enumerable: true, get: function () { return documents_1.CreateDocumentTemplateDto; } });
131
+ Object.defineProperty(exports, "DocumentIdDto", { enumerable: true, get: function () { return documents_1.DocumentIdDto; } });
132
+ Object.defineProperty(exports, "DocumentImageNameDto", { enumerable: true, get: function () { return documents_1.DocumentImageNameDto; } });
133
+ Object.defineProperty(exports, "DocumentImageUrlsDto", { enumerable: true, get: function () { return documents_1.DocumentImageUrlsDto; } });
134
+ Object.defineProperty(exports, "DocumentPayQueryDto", { enumerable: true, get: function () { return documents_1.DocumentPayQueryDto; } });
135
+ Object.defineProperty(exports, "DocumentPayTokenDto", { enumerable: true, get: function () { return documents_1.DocumentPayTokenDto; } });
136
+ Object.defineProperty(exports, "DocumentPaymentIdDto", { enumerable: true, get: function () { return documents_1.DocumentPaymentIdDto; } });
137
+ Object.defineProperty(exports, "DocumentTemplateIdDto", { enumerable: true, get: function () { return documents_1.DocumentTemplateIdDto; } });
138
+ Object.defineProperty(exports, "documentProblem", { enumerable: true, get: function () { return documents_1.documentProblem; } });
139
+ Object.defineProperty(exports, "GetCatalogueTemplatesDto", { enumerable: true, get: function () { return documents_1.GetCatalogueTemplatesDto; } });
140
+ Object.defineProperty(exports, "GetDocumentsDto", { enumerable: true, get: function () { return documents_1.GetDocumentsDto; } });
141
+ Object.defineProperty(exports, "GetDocumentTemplatesDto", { enumerable: true, get: function () { return documents_1.GetDocumentTemplatesDto; } });
142
+ Object.defineProperty(exports, "PayDocumentDto", { enumerable: true, get: function () { return documents_1.PayDocumentDto; } });
143
+ Object.defineProperty(exports, "RecordDocumentPaymentDto", { enumerable: true, get: function () { return documents_1.RecordDocumentPaymentDto; } });
144
+ Object.defineProperty(exports, "SendDocumentDto", { enumerable: true, get: function () { return documents_1.SendDocumentDto; } });
145
+ Object.defineProperty(exports, "UpdateDocumentDto", { enumerable: true, get: function () { return documents_1.UpdateDocumentDto; } });
146
+ Object.defineProperty(exports, "UpdateDocumentTemplateDto", { enumerable: true, get: function () { return documents_1.UpdateDocumentTemplateDto; } });
147
+ Object.defineProperty(exports, "VoidDocumentDto", { enumerable: true, get: function () { return documents_1.VoidDocumentDto; } });
148
+ Object.defineProperty(exports, "ReassignPrivateDocumentsDto", { enumerable: true, get: function () { return documents_1.ReassignPrivateDocumentsDto; } });
149
+ var visibility_1 = require("./visibility");
150
+ Object.defineProperty(exports, "UpdateVisibilityDto", { enumerable: true, get: function () { return visibility_1.UpdateVisibilityDto; } });
123
151
  var projects_1 = require("./projects");
124
152
  Object.defineProperty(exports, "CreateProjectDto", { enumerable: true, get: function () { return projects_1.CreateProjectDto; } });
125
153
  Object.defineProperty(exports, "GetProjectsDto", { enumerable: true, get: function () { return projects_1.GetProjectsDto; } });
@@ -101,8 +101,6 @@ const LEAD_SOURCE_LABELS = {
101
101
  [enum_1.LeadSource.EXISTING_CLIENT]: 'Existing client',
102
102
  [enum_1.LeadSource.OTHER]: 'Other',
103
103
  };
104
- /** Storage bucket every supporting file lives in (as in SupportingFilesResource). */
105
- const SUPPORTING_FILES_BUCKET = 'supporting-files';
106
104
  const refuse = (status, message) => new errors_1.SupabaseClientError({ status, error: 'Database Error', message });
107
105
  class LeadsResource {
108
106
  supabase;
@@ -346,7 +344,7 @@ class LeadsResource {
346
344
  throw (0, errors_1.mapPostgrestError)(filesError);
347
345
  for (const file of files) {
348
346
  const { error: storageError } = await this.supabase.storage
349
- .from(SUPPORTING_FILES_BUCKET)
347
+ .from(paths_1.SUPPORTING_FILES_BUCKET)
350
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));
351
349
  if (storageError) {
352
350
  if (storageError.status === 404 || storageError.statusCode === '404')
@@ -91,6 +91,12 @@ export declare class NotificationsOutboxResource {
91
91
  private auditedFor;
92
92
  private rawUpdate;
93
93
  create(input: CreateNotificationInput): Promise<CreatedNotification>;
94
+ /**
95
+ * Whether `recipientId` has been sent a notification of `type` whose variables include every
96
+ * one of `variables` - how the documents cron tells a creator about one failure once, not every
97
+ * morning it retries.
98
+ */
99
+ existsFor(type: NotificationType, recipientId: string, variables: Record<string, string>): Promise<boolean>;
94
100
  /**
95
101
  * The outbox row behind a provider message id. The Resend webhook arrives knowing only that
96
102
  * id, and needs the organization before it can attribute anything.
@@ -239,6 +239,22 @@ class NotificationsOutboxResource {
239
239
  throw (0, errors_1.mapPostgrestError)(error);
240
240
  return data;
241
241
  }
242
+ /**
243
+ * Whether `recipientId` has been sent a notification of `type` whose variables include every
244
+ * one of `variables` - how the documents cron tells a creator about one failure once, not every
245
+ * morning it retries.
246
+ */
247
+ async existsFor(type, recipientId, variables) {
248
+ const { error, count } = await this.supabase
249
+ .from('notifications')
250
+ .select('mms_id', { count: 'exact', head: true })
251
+ .eq('type', type)
252
+ .eq('recipient_id', recipientId)
253
+ .contains('template_variables', variables);
254
+ if (error)
255
+ throw (0, errors_1.mapPostgrestError)(error);
256
+ return (count ?? 0) > 0;
257
+ }
242
258
  /**
243
259
  * The outbox row behind a provider message id. The Resend webhook arrives knowing only that
244
260
  * id, and needs the organization before it can attribute anything.
@@ -0,0 +1,10 @@
1
+ import type { UpdateOrganizationPayoutsDto as UpdateOrganizationPayoutsDtoType } from '@managemint-solutions/entities/organization/payouts/dto';
2
+ import { PayoutAccountType, PayoutDocumentType } from '@managemint-solutions/entities/organization/payouts/enum';
3
+ export declare class UpdateOrganizationPayoutsDto implements UpdateOrganizationPayoutsDtoType {
4
+ readonly business_name: string;
5
+ readonly account_type: PayoutAccountType;
6
+ readonly bank_code: string;
7
+ readonly account_number: string;
8
+ readonly document_type: PayoutDocumentType;
9
+ readonly document_number: string;
10
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.UpdateOrganizationPayoutsDto = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ const enum_1 = require("@managemint-solutions/entities/organization/payouts/enum");
15
+ // class-validator version of the shared DTO type from @managemint-solutions/entities. The account
16
+ // itself is checked by Paystack (POST /bank/validate) before anything is stored; these are only
17
+ // the shapes Paystack accepts. Each property's type check sits last (decorators run bottom-up).
18
+ class UpdateOrganizationPayoutsDto {
19
+ business_name;
20
+ account_type;
21
+ bank_code;
22
+ account_number;
23
+ document_type;
24
+ document_number;
25
+ }
26
+ exports.UpdateOrganizationPayoutsDto = UpdateOrganizationPayoutsDto;
27
+ __decorate([
28
+ (0, class_validator_1.MaxLength)(100, { message: 'Account holder cannot exceed 100 characters' }),
29
+ (0, class_validator_1.Matches)(/\S/, { message: 'Give the account holder\'s name' }),
30
+ (0, class_validator_1.IsString)({ message: 'Give the account holder\'s name' }),
31
+ __metadata("design:type", String)
32
+ ], UpdateOrganizationPayoutsDto.prototype, "business_name", void 0);
33
+ __decorate([
34
+ (0, class_validator_1.IsEnum)(enum_1.PayoutAccountType, { message: `Account type must be one of: ${Object.values(enum_1.PayoutAccountType).join(', ')}` }),
35
+ __metadata("design:type", String)
36
+ ], UpdateOrganizationPayoutsDto.prototype, "account_type", void 0);
37
+ __decorate([
38
+ (0, class_validator_1.Matches)(/^\d{3,10}$/, { message: 'Choose a bank from the list' }),
39
+ (0, class_validator_1.IsString)({ message: 'Choose a bank from the list' }),
40
+ __metadata("design:type", String)
41
+ ], UpdateOrganizationPayoutsDto.prototype, "bank_code", void 0);
42
+ __decorate([
43
+ (0, class_validator_1.Matches)(/^\d{6,16}$/, { message: 'Account number must be 6 to 16 digits' }),
44
+ (0, class_validator_1.IsString)({ message: 'Account number must be 6 to 16 digits' }),
45
+ __metadata("design:type", String)
46
+ ], UpdateOrganizationPayoutsDto.prototype, "account_number", void 0);
47
+ __decorate([
48
+ (0, class_validator_1.IsEnum)(enum_1.PayoutDocumentType, { message: `Document type must be one of: ${Object.values(enum_1.PayoutDocumentType).join(', ')}` }),
49
+ __metadata("design:type", String)
50
+ ], UpdateOrganizationPayoutsDto.prototype, "document_type", void 0);
51
+ __decorate([
52
+ (0, class_validator_1.MaxLength)(30, { message: 'Document number cannot exceed 30 characters' }),
53
+ (0, class_validator_1.MinLength)(1, { message: 'Give the document number' }),
54
+ (0, class_validator_1.IsString)({ message: 'Give the document number' }),
55
+ __metadata("design:type", String)
56
+ ], UpdateOrganizationPayoutsDto.prototype, "document_number", void 0);
@@ -1,5 +1,6 @@
1
1
  import type { AuditActor } from '../audit';
2
2
  import type { TypedSupabaseClient } from '../client';
3
+ export * from './dto';
3
4
  /**
4
5
  * Everything Paystack knows an organization by, plus the two secrets the billing service acts
5
6
  * with. One row per organization; every column is null until the step that creates it runs.
@@ -18,8 +19,14 @@ export type OrganizationPaymentMethod = {
18
19
  paystack_subscription_email_token: string | null;
19
20
  /** The saved card authorization every off-session charge is made against. */
20
21
  paystack_customer_authorization_code: string | null;
22
+ /** The subaccount every Pay now charge settles to; null while payouts are off. */
23
+ paystack_subaccount_code: string | null;
24
+ /** What the organization page shows of the payout account: the holder, the bank, the last four digits. */
25
+ payout_business_name: string | null;
26
+ payout_bank_name: string | null;
27
+ payout_account_last4: string | null;
21
28
  };
22
- export declare const PAYMENT_METHOD_COLUMNS: readonly ["paystack_customer_code", "paystack_customer_created_at", "paystack_plan_code", "paystack_plan_created_at", "paystack_subscription_code", "paystack_subscription_created_at", "paystack_subscription_email_token", "paystack_customer_authorization_code"];
29
+ export declare const PAYMENT_METHOD_COLUMNS: readonly ["paystack_customer_code", "paystack_customer_created_at", "paystack_plan_code", "paystack_plan_created_at", "paystack_subscription_code", "paystack_subscription_created_at", "paystack_subscription_email_token", "paystack_customer_authorization_code", "paystack_subaccount_code", "payout_business_name", "payout_bank_name", "payout_account_last4"];
23
30
  /** The payment-method columns a webhook may look an organization up by. */
24
31
  export type PaymentMethodLookupColumn = 'paystack_customer_code' | 'paystack_subscription_code';
25
32
  /**
@@ -1,7 +1,22 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  Object.defineProperty(exports, "__esModule", { value: true });
3
17
  exports.OrganizationPaymentMethodsResource = exports.PAYMENT_METHOD_COLUMNS = void 0;
4
18
  const errors_1 = require("../errors");
19
+ __exportStar(require("./dto"), exports);
5
20
  exports.PAYMENT_METHOD_COLUMNS = [
6
21
  'paystack_customer_code',
7
22
  'paystack_customer_created_at',
@@ -11,6 +26,10 @@ exports.PAYMENT_METHOD_COLUMNS = [
11
26
  'paystack_subscription_created_at',
12
27
  'paystack_subscription_email_token',
13
28
  'paystack_customer_authorization_code',
29
+ 'paystack_subaccount_code',
30
+ 'payout_business_name',
31
+ 'payout_bank_name',
32
+ 'payout_account_last4',
14
33
  ];
15
34
  const EMPTY = {
16
35
  paystack_customer_code: null,
@@ -21,6 +40,10 @@ const EMPTY = {
21
40
  paystack_subscription_created_at: null,
22
41
  paystack_subscription_email_token: null,
23
42
  paystack_customer_authorization_code: null,
43
+ paystack_subaccount_code: null,
44
+ payout_business_name: null,
45
+ payout_bank_name: null,
46
+ payout_account_last4: null,
24
47
  };
25
48
  /**
26
49
  * The `organization_payment_methods` table: the organization's Paystack identity in one row
@@ -0,0 +1,67 @@
1
+ import type { Payment } from '@managemint-solutions/entities/payments';
2
+ import { type PaymentEntityType } from '@managemint-solutions/entities/payments/enum';
3
+ import { type AuditResource, type ResourceActor } from '../audit';
4
+ import type { TypedSupabaseClient } from '../client';
5
+ /** A payment as the sdk reads it: the shared Payment. */
6
+ export type PaymentRecord = Payment;
7
+ /** An open checkout, with what reopening it needs: the provider's reference and access code. */
8
+ export type OpenPaymentRecord = PaymentRecord & {
9
+ access_code: string | null;
10
+ };
11
+ /**
12
+ * A payment as the api records it: an open checkout (no `paid_at`), or a settled charge nobody
13
+ * opened here (status paid, `paid_at` set).
14
+ */
15
+ export type CreatePaymentRow = Omit<Payment, 'mms_id' | 'created_at' | 'created_by' | 'paid_at'> & {
16
+ entity_type: PaymentEntityType;
17
+ entity_id: string;
18
+ access_code?: string | null;
19
+ /** ISO timestamp; null while open. */
20
+ paid_at: string | null;
21
+ };
22
+ /** What settling an open checkout fills in, from the charge Paystack confirmed. */
23
+ export type SettlePaymentRow = Pick<Payment, 'amount_minor' | 'currency' | 'payer_email'> & {
24
+ paid_at: string;
25
+ };
26
+ /**
27
+ * `public.payments`: money received for a record, keyed by `entity_type` + `entity_id` like the
28
+ * visibility table. Read on the caller's client (RLS shows a payment while its record is
29
+ * readable); written on the service client's organization scope alone - members hold only a
30
+ * SELECT grant. A checkout starts as an `open` row (one per record, by a partial unique index)
31
+ * and is settled to `paid`. Each write is audited and, through its `entity_type`/`entity_id`,
32
+ * filed under the record it pays for.
33
+ */
34
+ export declare class PaymentsResource {
35
+ private readonly supabase;
36
+ private readonly actor;
37
+ private readonly table;
38
+ constructor(supabase: TypedSupabaseClient, actor: ResourceActor, audit: AuditResource);
39
+ /** The money received for one record, oldest first - paid rows only. */
40
+ list(entityType: PaymentEntityType, entityId: string): Promise<PaymentRecord[]>;
41
+ /** How many paid payments each of `entityIds` has - one query for a page of a list. */
42
+ paidCounts(entityType: PaymentEntityType, entityIds: string[]): Promise<Record<string, number>>;
43
+ /**
44
+ * The ids of the organization's records of one kind with a settled payment, each once - the
45
+ * documents list's payment filter reads it before the page.
46
+ */
47
+ paidEntityIds(entityType: PaymentEntityType): Promise<string[]>;
48
+ /** The record's open checkout, if one is under way. */
49
+ findOpen(entityType: PaymentEntityType, entityId: string): Promise<OpenPaymentRecord | null>;
50
+ /** A payment by the provider's reference (unique), whatever its status. */
51
+ findByReference(reference: string): Promise<PaymentRecord | null>;
52
+ /**
53
+ * Records one payment, by the actor (null for the system). A Paystack reference recorded
54
+ * already, or a second open checkout for the record, is refused by a unique index - 409 with
55
+ * `code` 23505.
56
+ */
57
+ create(row: CreatePaymentRow): Promise<void>;
58
+ /**
59
+ * Removes a payment marked by hand (EFT) from the record it pays for. False when it is not one -
60
+ * a Paystack payment is money Paystack holds, refunded there, never removed here.
61
+ */
62
+ removeManual(paymentId: string, entityType: PaymentEntityType, entityId: string): Promise<boolean>;
63
+ /** Settles an open checkout. False when it is no longer open (settled or replaced first). */
64
+ settle(paymentId: string, row: SettlePaymentRow): Promise<boolean>;
65
+ /** Drops an open checkout Paystack says failed, so a new one can open. False when it moved on. */
66
+ removeOpen(paymentId: string): Promise<boolean>;
67
+ }