@managemint-solutions/sdk 0.3.0 → 0.5.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 CHANGED
@@ -13,7 +13,8 @@ npm install @managemint-solutions/sdk @supabase/supabase-js
13
13
  are peer dependencies — the request DTOs (`AddStatusDto`, `UpdateStatusDto`, `StatusIdDto`,
14
14
  `GetStatusesDto`, `AddAdditionalDetailsDto`, `UpdateAdditionalDetailsDto`,
15
15
  `AdditionalDetailsIdDto`, `GetAdditionalDetailsDto`, `AddNoteDto`, `NoteIdDto`,
16
- `GetNotesDto`) ship with their class-validator
16
+ `GetNotesDto`, `SupportingFileIdDto`, `GetSupportingFilesDto`, `GetClientsDto`, `ClientIdDto`,
17
+ `CreateClientDto`, `UpdateClientDto`) ship with their class-validator
17
18
  decorators so consumers validate against
18
19
  the same rules the SDK's input types describe. `@nestjs/common` (^11) is an optional peer
19
20
  dependency, needed only for the `@managemint-solutions/sdk/nest` subpath.
@@ -81,6 +82,48 @@ await supabase.notes.remove(note.mms_id);
81
82
  Each note carries its author as an embedded `user` (from the `user_profiles` view), and `list`
82
83
  returns newest first.
83
84
 
85
+ ```ts
86
+ import { SupportingFilesEntityTypes } from '@managemint-solutions/entities/supporting-files/enum';
87
+
88
+ // Supporting files hang off another entity, and cover Supabase Storage as well as the table.
89
+ const files = await supabase.supportingFiles.list(SupportingFilesEntityTypes.PROJECT, projectId);
90
+ await supabase.supportingFiles.upload(SupportingFilesEntityTypes.PROJECT, projectId, {
91
+ files: uploaded, // web `File`s — uploaded to the `supporting-files` bucket, then rowed up
92
+ });
93
+ const { url, ttl } = await supabase.supportingFiles.getPresignedUrl(files[0].mms_id); // 5 min
94
+ await supabase.supportingFiles.remove(files[0].mms_id); // deletes the row and the object
95
+ ```
96
+
97
+ Uploads run in batches of 5 and upsert, so re-uploading a file refreshes the object without
98
+ adding a second row; `upload` returns the entity's full file list.
99
+
100
+ ```ts
101
+ // Clients are paginated; the query DTO's page/page_size default to 1/10.
102
+ const page = await supabase.clients.list({ page: 1, page_size: 10, archive: false });
103
+ // → { results, page, per_page, count, total_pages, has_next_page, has_previous_page }
104
+ // `search` matches name/email, `created_after`/`created_before` bound created_at, and
105
+ // `status_id_in` filters by status.
106
+
107
+ const client = await supabase.clients.create({
108
+ name: 'Acme',
109
+ email: 'hello@acme.test',
110
+ phone: '0123456789',
111
+ status_id: statusId,
112
+ contract_client: true,
113
+ contracted_hours: 40,
114
+ });
115
+ await supabase.clients.getById(client.mms_id);
116
+ await supabase.clients.update(client.mms_id, { ...client, name: 'Acme Ltd' });
117
+ await supabase.clients.archive(client.mms_id); // archived + archived_at/by
118
+ await supabase.clients.unarchive(client.mms_id); // archived = false + unarchived_at/by
119
+ await supabase.clients.remove(client.mms_id); // soft delete — deleted + deleted_at/by
120
+ await supabase.clients.restore(client.mms_id); // deleted = false + restored_at/by
121
+ ```
122
+
123
+ `getById` on a soft-deleted client returns the audit trail with the details blanked (name,
124
+ email and phone empty, no status, `contract_client` false, `contracted_hours` 0). Every write
125
+ except `remove` re-reads and returns the full record afterwards.
126
+
84
127
  The client decodes `{ mms_id, organization_id }` from the JWT itself and scopes every query
85
128
  by `organization_id`. `supabase.supabase` is the raw typed `@supabase/supabase-js` client
86
129
  (`TypedSupabaseClient`) — the escape hatch for queries not yet covered by a resource.
@@ -90,7 +133,8 @@ by `organization_id`. `supabase.supabase` is the raw typed `@supabase/supabase-j
90
133
  Every error the SDK throws is a `SupabaseClientError` carrying the HTTP `status` to respond
91
134
  with and the client-facing body, `toResponse()` → `{ error, message }`. Postgrest/Postgres
92
135
  errors are translated by `mapPostgrestError` (Postgrest code → status, RLS permission and
93
- module denials → readable messages); JWT problems are `401 Authentication Error`. Consumers
136
+ module denials → readable messages), Storage errors by `mapStorageError` (the storage error's
137
+ own HTTP status, or 500 when it has none); JWT problems are `401 Authentication Error`. Consumers
94
138
  return these as-is instead of mapping database errors themselves.
95
139
 
96
140
  ## NestJS
package/dist/client.d.ts CHANGED
@@ -2,8 +2,10 @@ import { type SupabaseClient as SupabaseJsClient } from '@supabase/supabase-js';
2
2
  import type { Database } from './database.types';
3
3
  import { type AuthContext } from './auth';
4
4
  import { AdditionalDetailsResource } from './additional-details';
5
+ import { ClientsResource } from './clients';
5
6
  import { NotesResource } from './notes';
6
7
  import { StatusesResource } from './statuses';
8
+ import { SupportingFilesResource } from './supporting-files';
7
9
  export type TypedSupabaseClient = SupabaseJsClient<Database>;
8
10
  export type SupabaseClientConfig = {
9
11
  url: string;
@@ -16,6 +18,8 @@ export declare class SupabaseClient {
16
18
  readonly statuses: StatusesResource;
17
19
  readonly additionalDetails: AdditionalDetailsResource;
18
20
  readonly notes: NotesResource;
21
+ readonly supportingFiles: SupportingFilesResource;
22
+ readonly clients: ClientsResource;
19
23
  constructor(config: SupabaseClientConfig);
20
24
  }
21
25
  export declare const createSupabaseClient: (config: SupabaseClientConfig) => SupabaseClient;
package/dist/client.js CHANGED
@@ -4,14 +4,18 @@ exports.createSupabaseClient = exports.SupabaseClient = void 0;
4
4
  const supabase_js_1 = require("@supabase/supabase-js");
5
5
  const auth_1 = require("./auth");
6
6
  const additional_details_1 = require("./additional-details");
7
+ const clients_1 = require("./clients");
7
8
  const notes_1 = require("./notes");
8
9
  const statuses_1 = require("./statuses");
10
+ const supporting_files_1 = require("./supporting-files");
9
11
  class SupabaseClient {
10
12
  supabase; // escape hatch for not-yet-migrated queries
11
13
  auth;
12
14
  statuses;
13
15
  additionalDetails;
14
16
  notes;
17
+ supportingFiles;
18
+ clients;
15
19
  constructor(config) {
16
20
  this.auth = (0, auth_1.decodeAuthContext)(config.accessToken);
17
21
  this.supabase = (0, supabase_js_1.createClient)(config.url, config.key, {
@@ -21,6 +25,8 @@ class SupabaseClient {
21
25
  this.statuses = new statuses_1.StatusesResource(this.supabase, this.auth);
22
26
  this.additionalDetails = new additional_details_1.AdditionalDetailsResource(this.supabase, this.auth);
23
27
  this.notes = new notes_1.NotesResource(this.supabase, this.auth);
28
+ this.supportingFiles = new supporting_files_1.SupportingFilesResource(this.supabase, this.auth);
29
+ this.clients = new clients_1.ClientsResource(this.supabase, this.auth);
24
30
  }
25
31
  }
26
32
  exports.SupabaseClient = SupabaseClient;
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,uDAA8F;AAE9F,iCAA6D;AAC7D,6DAAiE;AACjE,mCAAwC;AACxC,yCAA8C;AAU9C,MAAa,cAAc;IAChB,QAAQ,CAAsB,CAAC,4CAA4C;IAC3E,IAAI,CAAc;IAClB,QAAQ,CAAmB;IAC3B,iBAAiB,CAA4B;IAC7C,KAAK,CAAgB;IAE9B,YAAY,MAA4B;QACtC,IAAI,CAAC,IAAI,GAAG,IAAA,wBAAiB,EAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAClD,IAAI,CAAC,QAAQ,GAAG,IAAA,0BAAY,EAAW,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE;YAC7D,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,CAAC,WAAW,EAAE,EAAE,EAAE;YACtE,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE;SACzD,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,GAAG,IAAI,2BAAgB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,IAAI,CAAC,iBAAiB,GAAG,IAAI,8CAAyB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACjF,IAAI,CAAC,KAAK,GAAG,IAAI,qBAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;CACF;AAjBD,wCAiBC;AAEM,MAAM,oBAAoB,GAAG,CAAC,MAA4B,EAAkB,EAAE,CACnF,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;AADhB,QAAA,oBAAoB,wBACJ"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,uDAA8F;AAE9F,iCAA6D;AAC7D,6DAAiE;AACjE,uCAA4C;AAC5C,mCAAwC;AACxC,yCAA8C;AAC9C,yDAA6D;AAU7D,MAAa,cAAc;IAChB,QAAQ,CAAsB,CAAC,4CAA4C;IAC3E,IAAI,CAAc;IAClB,QAAQ,CAAmB;IAC3B,iBAAiB,CAA4B;IAC7C,KAAK,CAAgB;IACrB,eAAe,CAA0B;IACzC,OAAO,CAAkB;IAElC,YAAY,MAA4B;QACtC,IAAI,CAAC,IAAI,GAAG,IAAA,wBAAiB,EAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAClD,IAAI,CAAC,QAAQ,GAAG,IAAA,0BAAY,EAAW,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE;YAC7D,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,CAAC,WAAW,EAAE,EAAE,EAAE;YACtE,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE;SACzD,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,GAAG,IAAI,2BAAgB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,IAAI,CAAC,iBAAiB,GAAG,IAAI,8CAAyB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACjF,IAAI,CAAC,KAAK,GAAG,IAAI,qBAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACzD,IAAI,CAAC,eAAe,GAAG,IAAI,0CAAuB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7E,IAAI,CAAC,OAAO,GAAG,IAAI,yBAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/D,CAAC;CACF;AArBD,wCAqBC;AAEM,MAAM,oBAAoB,GAAG,CAAC,MAA4B,EAAkB,EAAE,CACnF,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;AADhB,QAAA,oBAAoB,wBACJ"}
@@ -0,0 +1,30 @@
1
+ import type { UUID } from 'crypto';
2
+ import type { ClientIdDto as ClientIdDtoType, CreateClientDto as CreateClientDtoType, GetClientsDto as GetClientsDtoType, UpdateClientDto as UpdateClientDtoType } from '@managemint-solutions/entities/clients/dto';
3
+ export declare class GetClientsDto implements Omit<GetClientsDtoType, 'status_id_in'> {
4
+ readonly search?: string | null;
5
+ readonly page: number;
6
+ readonly page_size: number;
7
+ readonly created_after?: string | null;
8
+ readonly created_before?: string | null;
9
+ readonly status_id_in?: string[] | null;
10
+ readonly archive: boolean;
11
+ }
12
+ export declare class ClientIdDto implements ClientIdDtoType {
13
+ readonly clientId: string;
14
+ }
15
+ export declare class CreateClientDto implements CreateClientDtoType {
16
+ readonly name: string;
17
+ readonly email: string | null;
18
+ readonly phone: string | null;
19
+ readonly status_id: UUID | null;
20
+ readonly contract_client: boolean;
21
+ readonly contracted_hours: number | null;
22
+ }
23
+ export declare class UpdateClientDto implements UpdateClientDtoType {
24
+ readonly name: string;
25
+ readonly email: string | null;
26
+ readonly phone: string | null;
27
+ readonly status_id: UUID | null;
28
+ readonly contract_client: boolean;
29
+ readonly contracted_hours: number | null;
30
+ }
@@ -0,0 +1,181 @@
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.UpdateClientDto = exports.CreateClientDto = exports.ClientIdDto = exports.GetClientsDto = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ const class_transformer_1 = require("class-transformer");
15
+ const validators_1 = require("../validators");
16
+ // class-validator versions of the shared DTO types from @managemint-solutions/entities, so the
17
+ // wire contract cannot drift. `status_id` is typed as the entities' `UUID | null` for the same
18
+ // reason; class-validator only sees the runtime string.
19
+ // `status_id_in` is omitted from the implemented type on purpose: the entities type carries the
20
+ // CSV wire value (`string | null`), while this class carries the `@Transform`-parsed
21
+ // `string[] | null` the query builder feeds to `.in('status_id', ...)`.
22
+ class GetClientsDto {
23
+ search;
24
+ page = 1;
25
+ page_size = 10;
26
+ created_after;
27
+ created_before;
28
+ status_id_in;
29
+ archive = false;
30
+ }
31
+ exports.GetClientsDto = GetClientsDto;
32
+ __decorate([
33
+ (0, class_validator_1.IsOptional)(),
34
+ (0, validators_1.IsNullable)(),
35
+ (0, class_validator_1.IsString)({ message: 'Search query must be a string' }),
36
+ (0, class_validator_1.MinLength)(1, { message: 'Search query cannot be empty' }),
37
+ (0, class_validator_1.MaxLength)(255, { message: 'Search query cannot exceed 255 characters' }),
38
+ __metadata("design:type", Object)
39
+ ], GetClientsDto.prototype, "search", void 0);
40
+ __decorate([
41
+ (0, class_validator_1.IsOptional)(),
42
+ (0, class_transformer_1.Transform)(({ value }) => value ? Number(value) : 1, { toClassOnly: true }),
43
+ (0, class_validator_1.IsNumber)({}, { message: 'Page must be a number' }),
44
+ (0, class_validator_1.Min)(1, { message: 'Page must be at least 1' }),
45
+ __metadata("design:type", Number)
46
+ ], GetClientsDto.prototype, "page", void 0);
47
+ __decorate([
48
+ (0, class_validator_1.IsOptional)(),
49
+ (0, class_transformer_1.Transform)(({ value }) => value ? Number(value) : 10, { toClassOnly: true }),
50
+ (0, class_validator_1.IsNumber)({}, { message: 'Page size must be a number' }),
51
+ (0, class_validator_1.Min)(1, { message: 'Page size must be at least 1' }),
52
+ (0, class_validator_1.Max)(100, { message: 'Page size cannot exceed 100' }),
53
+ __metadata("design:type", Number)
54
+ ], GetClientsDto.prototype, "page_size", void 0);
55
+ __decorate([
56
+ (0, class_validator_1.IsOptional)(),
57
+ (0, validators_1.IsNullable)(),
58
+ (0, class_validator_1.IsDateString)({}, { message: 'Start date must be a valid ISO 8601 date string' }),
59
+ __metadata("design:type", Object)
60
+ ], GetClientsDto.prototype, "created_after", void 0);
61
+ __decorate([
62
+ (0, class_validator_1.IsOptional)(),
63
+ (0, validators_1.IsNullable)(),
64
+ (0, class_validator_1.IsDateString)({}, { message: 'End date must be a valid ISO 8601 date string' }),
65
+ __metadata("design:type", Object)
66
+ ], GetClientsDto.prototype, "created_before", void 0);
67
+ __decorate([
68
+ (0, class_validator_1.IsOptional)(),
69
+ (0, validators_1.IsNullable)(),
70
+ (0, class_transformer_1.Transform)(({ value }) => value ? value.split(',').map((id) => id.trim()) : null, { toClassOnly: true }),
71
+ (0, class_validator_1.IsUUID)('4', { each: true, message: 'Each status ID must be a valid UUID v4' }),
72
+ __metadata("design:type", Object)
73
+ ], GetClientsDto.prototype, "status_id_in", void 0);
74
+ __decorate([
75
+ (0, class_validator_1.IsOptional)(),
76
+ (0, validators_1.IsNullable)(),
77
+ (0, class_transformer_1.Transform)(({ value }) => value ? value === 'true' : false, { toClassOnly: true }),
78
+ (0, class_validator_1.IsBoolean)({ message: 'Include archived must be a boolean' }),
79
+ __metadata("design:type", Boolean)
80
+ ], GetClientsDto.prototype, "archive", void 0);
81
+ class ClientIdDto {
82
+ clientId;
83
+ }
84
+ exports.ClientIdDto = ClientIdDto;
85
+ __decorate([
86
+ (0, class_validator_1.IsUUID)('4', { message: 'Invalid client ID format' }),
87
+ __metadata("design:type", String)
88
+ ], ClientIdDto.prototype, "clientId", void 0);
89
+ class CreateClientDto {
90
+ name;
91
+ email;
92
+ phone;
93
+ status_id;
94
+ contract_client;
95
+ contracted_hours;
96
+ }
97
+ exports.CreateClientDto = CreateClientDto;
98
+ __decorate([
99
+ (0, class_validator_1.IsString)({ message: 'Invalid name' }),
100
+ (0, class_validator_1.MinLength)(1, { message: 'Name cannot be empty' }),
101
+ (0, class_validator_1.MaxLength)(100, { message: 'Name cannot exceed 100 characters' }),
102
+ __metadata("design:type", String)
103
+ ], CreateClientDto.prototype, "name", void 0);
104
+ __decorate([
105
+ (0, validators_1.IsNullable)(),
106
+ (0, class_transformer_1.Transform)(({ value }) => value !== undefined ? value : null, { toClassOnly: true }),
107
+ (0, class_validator_1.ValidateIf)((o) => o.email !== ''),
108
+ (0, class_validator_1.IsEmail)({}, { message: 'Invalid email address' }),
109
+ __metadata("design:type", Object)
110
+ ], CreateClientDto.prototype, "email", void 0);
111
+ __decorate([
112
+ (0, validators_1.IsNullable)(),
113
+ (0, class_transformer_1.Transform)(({ value }) => value !== undefined ? value : null, { toClassOnly: true }),
114
+ (0, class_validator_1.ValidateIf)((o) => o.phone !== ''),
115
+ (0, class_validator_1.IsString)({ message: 'Invalid phone number' }),
116
+ (0, class_validator_1.MinLength)(1, { message: 'Phone number cannot be empty' }),
117
+ __metadata("design:type", Object)
118
+ ], CreateClientDto.prototype, "phone", void 0);
119
+ __decorate([
120
+ (0, validators_1.IsNullable)(),
121
+ (0, class_validator_1.IsUUID)('4', { message: 'Invalid status ID format' }),
122
+ __metadata("design:type", Object)
123
+ ], CreateClientDto.prototype, "status_id", void 0);
124
+ __decorate([
125
+ (0, class_validator_1.IsBoolean)({ message: 'Contract client must be a boolean' }),
126
+ __metadata("design:type", Boolean)
127
+ ], CreateClientDto.prototype, "contract_client", void 0);
128
+ __decorate([
129
+ (0, validators_1.IsNullable)(),
130
+ (0, class_transformer_1.Transform)(({ value }) => value !== undefined ? Number(value) : null, { toClassOnly: true }),
131
+ (0, class_validator_1.IsNumber)({}, { message: 'Contracted hours must be a number' }),
132
+ (0, class_validator_1.Min)(0, { message: 'Contracted hours must be at least 0' }),
133
+ __metadata("design:type", Object)
134
+ ], CreateClientDto.prototype, "contracted_hours", void 0);
135
+ class UpdateClientDto {
136
+ name;
137
+ email;
138
+ phone;
139
+ status_id;
140
+ contract_client;
141
+ contracted_hours;
142
+ }
143
+ exports.UpdateClientDto = UpdateClientDto;
144
+ __decorate([
145
+ (0, class_validator_1.IsString)({ message: 'Invalid name' }),
146
+ (0, class_validator_1.MinLength)(1, { message: 'Name cannot be empty' }),
147
+ (0, class_validator_1.MaxLength)(100, { message: 'Name cannot exceed 100 characters' }),
148
+ __metadata("design:type", String)
149
+ ], UpdateClientDto.prototype, "name", void 0);
150
+ __decorate([
151
+ (0, validators_1.IsNullable)(),
152
+ (0, class_transformer_1.Transform)(({ value }) => value !== undefined ? value : null, { toClassOnly: true }),
153
+ (0, class_validator_1.ValidateIf)((o) => o.email !== ''),
154
+ (0, class_validator_1.IsEmail)({}, { message: 'Invalid email address' }),
155
+ __metadata("design:type", Object)
156
+ ], UpdateClientDto.prototype, "email", void 0);
157
+ __decorate([
158
+ (0, validators_1.IsNullable)(),
159
+ (0, class_transformer_1.Transform)(({ value }) => value !== undefined ? value : null, { toClassOnly: true }),
160
+ (0, class_validator_1.ValidateIf)((o) => o.phone !== ''),
161
+ (0, class_validator_1.IsString)({ message: 'Invalid phone number' }),
162
+ (0, class_validator_1.MinLength)(1, { message: 'Phone number cannot be empty' }),
163
+ __metadata("design:type", Object)
164
+ ], UpdateClientDto.prototype, "phone", void 0);
165
+ __decorate([
166
+ (0, validators_1.IsNullable)(),
167
+ (0, class_validator_1.IsUUID)('4', { message: 'Invalid status ID format' }),
168
+ __metadata("design:type", Object)
169
+ ], UpdateClientDto.prototype, "status_id", void 0);
170
+ __decorate([
171
+ (0, class_validator_1.IsBoolean)({ message: 'Contract client must be a boolean' }),
172
+ __metadata("design:type", Boolean)
173
+ ], UpdateClientDto.prototype, "contract_client", void 0);
174
+ __decorate([
175
+ (0, validators_1.IsNullable)(),
176
+ (0, class_transformer_1.Transform)(({ value }) => value !== undefined ? Number(value) : null, { toClassOnly: true }),
177
+ (0, class_validator_1.IsNumber)({}, { message: 'Contracted hours must be a number' }),
178
+ (0, class_validator_1.Min)(0, { message: 'Contracted hours must be at least 0' }),
179
+ __metadata("design:type", Object)
180
+ ], UpdateClientDto.prototype, "contracted_hours", void 0);
181
+ //# sourceMappingURL=dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dto.js","sourceRoot":"","sources":["../../src/clients/dto.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { ClientEntity, ClientSummary } from '@managemint-solutions/entities/clients';
2
+ import type { MmsList } from '@managemint-solutions/entities/common';
3
+ import type { AuthContext } from '../auth';
4
+ import type { TypedSupabaseClient } from '../client';
5
+ import type { CreateClientDto, GetClientsDto, UpdateClientDto } from './dto';
6
+ export * from './dto';
7
+ export declare class ClientsResource {
8
+ private readonly supabase;
9
+ private readonly auth;
10
+ constructor(supabase: TypedSupabaseClient, auth: AuthContext);
11
+ list(query: GetClientsDto): Promise<MmsList<ClientSummary>>;
12
+ getById(clientId: string): Promise<ClientEntity>;
13
+ create(input: CreateClientDto): Promise<ClientEntity>;
14
+ update(clientId: string, input: UpdateClientDto): Promise<ClientEntity>;
15
+ archive(clientId: string): Promise<ClientEntity>;
16
+ unarchive(clientId: string): Promise<ClientEntity>;
17
+ restore(clientId: string): Promise<ClientEntity>;
18
+ /** Soft delete — the row stays, flagged `deleted`, and `restore()` brings it back. */
19
+ remove(clientId: string): Promise<void>;
20
+ }
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.ClientsResource = void 0;
18
+ const errors_1 = require("../errors");
19
+ __exportStar(require("./dto"), exports);
20
+ // The queries are typed by the generated Database schema (so the select strings and the
21
+ // insert/update payloads are checked); the public contract is the shared ClientSummary /
22
+ // ClientEntity from @managemint-solutions/entities. The two shapes legitimately differ, hence
23
+ // `as unknown as`: the embedded user_profiles/statuses rows are all-nullable view rows where the
24
+ // entities declare UserIdentity/StatusEntity, and the timestamp columns are ISO strings where the
25
+ // entities declare Date.
26
+ const CLIENT_LIST_SELECT = `
27
+ mms_id,
28
+ created_at,
29
+ name,
30
+ email,
31
+ status:statuses!status_id (
32
+ mms_id,
33
+ colour,
34
+ label
35
+ ),
36
+ created_by:user_profiles!created_by (*)
37
+ `;
38
+ const CLIENT_DETAIL_SELECT = `
39
+ mms_id,
40
+ created_at,
41
+ name,
42
+ email,
43
+ phone,
44
+ status:statuses!status_id (
45
+ mms_id,
46
+ label,
47
+ colour
48
+ ),
49
+ contract_client,
50
+ contracted_hours,
51
+ updated_at,
52
+ last_updated_by:user_profiles!last_updated_by (
53
+ mms_id,
54
+ name,
55
+ surname,
56
+ email,
57
+ profile_image
58
+ ),
59
+ created_by:user_profiles!created_by (
60
+ mms_id,
61
+ name,
62
+ surname,
63
+ email,
64
+ profile_image
65
+ ),
66
+ archived,
67
+ archived_at,
68
+ archived_by:user_profiles!archived_by (
69
+ mms_id,
70
+ name,
71
+ surname,
72
+ email,
73
+ profile_image
74
+ ),
75
+ unarchived_at,
76
+ unarchived_by:user_profiles!unarchived_by (
77
+ mms_id,
78
+ name,
79
+ surname,
80
+ email,
81
+ profile_image
82
+ ),
83
+ deleted,
84
+ deleted_at,
85
+ deleted_by:user_profiles!deleted_by (
86
+ mms_id,
87
+ name,
88
+ surname,
89
+ email,
90
+ profile_image
91
+ ),
92
+ restored_at,
93
+ restored_by:user_profiles!restored_by (
94
+ mms_id,
95
+ name,
96
+ surname,
97
+ email,
98
+ profile_image
99
+ )
100
+ `;
101
+ class ClientsResource {
102
+ supabase;
103
+ auth;
104
+ constructor(supabase, auth) {
105
+ this.supabase = supabase;
106
+ this.auth = auth;
107
+ }
108
+ async list(query) {
109
+ const page = query.page;
110
+ const pageSize = query.page_size;
111
+ const offset = (page - 1) * pageSize;
112
+ const trimmedSearch = query.search?.trim();
113
+ // `order`/`range` return `this`, so the builder stays a filter builder and the conditional
114
+ // filters below can be reassigned onto it without a cast.
115
+ let clientsQuery = this.supabase
116
+ .from('clients')
117
+ .select(CLIENT_LIST_SELECT, { count: 'estimated' })
118
+ .eq('organization_id', this.auth.organization_id)
119
+ .eq('archived', query.archive)
120
+ .eq('deleted', false)
121
+ .order('created_at', { ascending: false })
122
+ .range(offset, offset + pageSize - 1);
123
+ if (trimmedSearch) {
124
+ const escapedSearch = trimmedSearch.replace(/,/g, '\\,');
125
+ clientsQuery = clientsQuery.or(`name.ilike.%${escapedSearch}%,email.ilike.%${escapedSearch}%`);
126
+ }
127
+ if (query.created_after) {
128
+ clientsQuery = clientsQuery.gte('created_at', query.created_after);
129
+ }
130
+ if (query.created_before) {
131
+ clientsQuery = clientsQuery.lte('created_at', query.created_before);
132
+ }
133
+ if (query.status_id_in && query.status_id_in.length > 0) {
134
+ clientsQuery = clientsQuery.in('status_id', query.status_id_in);
135
+ }
136
+ const { data, error, count } = await clientsQuery;
137
+ if (error)
138
+ throw (0, errors_1.mapPostgrestError)(error);
139
+ const totalEstimated = count ?? 0;
140
+ const totalPages = totalEstimated > 0 ? Math.ceil(totalEstimated / pageSize) : 0;
141
+ return {
142
+ results: (data ?? []),
143
+ page,
144
+ per_page: pageSize,
145
+ count: totalEstimated,
146
+ total_pages: totalPages,
147
+ has_next_page: page < totalPages,
148
+ has_previous_page: page > 1,
149
+ };
150
+ }
151
+ async getById(clientId) {
152
+ const { data, error } = await this.supabase
153
+ .from('clients')
154
+ .select(CLIENT_DETAIL_SELECT)
155
+ .eq('organization_id', this.auth.organization_id)
156
+ .eq('mms_id', clientId)
157
+ .single();
158
+ if (error)
159
+ throw (0, errors_1.mapPostgrestError)(error);
160
+ // A soft-deleted client keeps its audit trail but gives up its details.
161
+ if (data.deleted) {
162
+ return {
163
+ ...data,
164
+ name: '',
165
+ email: '',
166
+ phone: '',
167
+ status: null,
168
+ contract_client: false,
169
+ contracted_hours: 0,
170
+ };
171
+ }
172
+ return data;
173
+ }
174
+ async create(input) {
175
+ const { data, error } = await this.supabase
176
+ .from('clients')
177
+ .insert({
178
+ ...input,
179
+ organization_id: this.auth.organization_id,
180
+ created_by: this.auth.mms_id,
181
+ created_at: new Date().toISOString(),
182
+ })
183
+ .select('mms_id')
184
+ .single();
185
+ if (error)
186
+ throw (0, errors_1.mapPostgrestError)(error);
187
+ return this.getById(data.mms_id);
188
+ }
189
+ async update(clientId, input) {
190
+ const { data, error } = await this.supabase
191
+ .from('clients')
192
+ .update({
193
+ ...input,
194
+ last_updated_by: this.auth.mms_id,
195
+ updated_at: new Date().toISOString(),
196
+ })
197
+ .eq('organization_id', this.auth.organization_id)
198
+ .eq('mms_id', clientId)
199
+ .select('mms_id')
200
+ .single();
201
+ if (error)
202
+ throw (0, errors_1.mapPostgrestError)(error);
203
+ return this.getById(data.mms_id);
204
+ }
205
+ async archive(clientId) {
206
+ const { data, error } = await this.supabase
207
+ .from('clients')
208
+ .update({
209
+ archived: true,
210
+ archived_at: new Date().toISOString(),
211
+ archived_by: this.auth.mms_id,
212
+ })
213
+ .eq('organization_id', this.auth.organization_id)
214
+ .eq('mms_id', clientId)
215
+ .select('mms_id')
216
+ .single();
217
+ if (error)
218
+ throw (0, errors_1.mapPostgrestError)(error);
219
+ return this.getById(data.mms_id);
220
+ }
221
+ async unarchive(clientId) {
222
+ const { data, error } = await this.supabase
223
+ .from('clients')
224
+ .update({
225
+ archived: false,
226
+ unarchived_at: new Date().toISOString(),
227
+ unarchived_by: this.auth.mms_id,
228
+ })
229
+ .eq('organization_id', this.auth.organization_id)
230
+ .eq('mms_id', clientId)
231
+ .select('mms_id')
232
+ .single();
233
+ if (error)
234
+ throw (0, errors_1.mapPostgrestError)(error);
235
+ return this.getById(data.mms_id);
236
+ }
237
+ async restore(clientId) {
238
+ const { data, error } = await this.supabase
239
+ .from('clients')
240
+ .update({
241
+ deleted: false,
242
+ restored_at: new Date().toISOString(),
243
+ restored_by: this.auth.mms_id,
244
+ })
245
+ .eq('organization_id', this.auth.organization_id)
246
+ .eq('mms_id', clientId)
247
+ .select('mms_id')
248
+ .single();
249
+ if (error)
250
+ throw (0, errors_1.mapPostgrestError)(error);
251
+ return this.getById(data.mms_id);
252
+ }
253
+ /** Soft delete — the row stays, flagged `deleted`, and `restore()` brings it back. */
254
+ async remove(clientId) {
255
+ const { error } = await this.supabase
256
+ .from('clients')
257
+ .update({
258
+ deleted: true,
259
+ deleted_at: new Date().toISOString(),
260
+ deleted_by: this.auth.mms_id,
261
+ })
262
+ .eq('organization_id', this.auth.organization_id)
263
+ .eq('mms_id', clientId);
264
+ if (error)
265
+ throw (0, errors_1.mapPostgrestError)(error);
266
+ }
267
+ }
268
+ exports.ClientsResource = ClientsResource;
269
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/clients/index.ts"],"names":[],"mappings":"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"}
package/dist/errors.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { StorageError } from '@supabase/storage-js';
1
2
  import type { PostgrestError } from '@supabase/supabase-js';
2
3
  export type SupabaseClientErrorInit = {
3
4
  /** HTTP status the consumer should respond with. */
@@ -27,3 +28,9 @@ export declare class SupabaseClientError extends Error {
27
28
  }
28
29
  /** Converts a raw Postgrest error into the SupabaseClientError the SDK throws. */
29
30
  export declare const mapPostgrestError: (error: PostgrestError) => SupabaseClientError;
31
+ /**
32
+ * Converts a Supabase Storage error into the SupabaseClientError the SDK throws. `StorageError`
33
+ * carries the HTTP `status` only when it came back from the Storage API (`StorageApiError`);
34
+ * network/unknown failures have none, hence the 500 fallback.
35
+ */
36
+ export declare const mapStorageError: (error: StorageError, message?: string) => SupabaseClientError;
package/dist/errors.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mapPostgrestError = exports.SupabaseClientError = void 0;
3
+ exports.mapStorageError = exports.mapPostgrestError = exports.SupabaseClientError = void 0;
4
4
  /**
5
5
  * Every error the SDK throws. It already carries the HTTP status and the body the
6
6
  * consumer sends back to the client (`toResponse()`), so the api needs no mapping.
@@ -129,4 +129,15 @@ const mapPostgrestError = (error) => new SupabaseClientError({
129
129
  code: error.code,
130
130
  }, { cause: error });
131
131
  exports.mapPostgrestError = mapPostgrestError;
132
+ /**
133
+ * Converts a Supabase Storage error into the SupabaseClientError the SDK throws. `StorageError`
134
+ * carries the HTTP `status` only when it came back from the Storage API (`StorageApiError`);
135
+ * network/unknown failures have none, hence the 500 fallback.
136
+ */
137
+ const mapStorageError = (error, message = error.message) => new SupabaseClientError({
138
+ status: error.status ?? 500,
139
+ error: 'Storage Error',
140
+ message,
141
+ }, { cause: error });
142
+ exports.mapStorageError = mapStorageError;
132
143
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  export * from './client';
2
2
  export * from './auth';
3
3
  export * from './errors';
4
+ export * from './validators';
4
5
  export * from './statuses';
5
6
  export * from './additional-details';
6
7
  export * from './notes';
8
+ export * from './supporting-files';
9
+ export * from './clients';
7
10
  export type { Database, Tables, TablesInsert, TablesUpdate, Json } from './database.types';
package/dist/index.js CHANGED
@@ -17,7 +17,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./client"), exports);
18
18
  __exportStar(require("./auth"), exports);
19
19
  __exportStar(require("./errors"), exports);
20
+ __exportStar(require("./validators"), exports);
20
21
  __exportStar(require("./statuses"), exports);
21
22
  __exportStar(require("./additional-details"), exports);
22
23
  __exportStar(require("./notes"), exports);
24
+ __exportStar(require("./supporting-files"), exports);
25
+ __exportStar(require("./clients"), exports);
23
26
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,yCAAuB;AACvB,2CAAyB;AACzB,6CAA2B;AAC3B,uDAAqC;AACrC,0CAAwB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,yCAAuB;AACvB,2CAAyB;AACzB,+CAA6B;AAC7B,6CAA2B;AAC3B,uDAAqC;AACrC,0CAAwB;AACxB,qDAAmC;AACnC,4CAA0B"}
@@ -0,0 +1,9 @@
1
+ import type { GetSupportingFilesDto as GetSupportingFilesDtoType, SupportingFileIdDto as SupportingFileIdDtoType } from '@managemint-solutions/entities/supporting-files/dto';
2
+ import { SupportingFilesEntityTypes } from '@managemint-solutions/entities/supporting-files/enum';
3
+ export declare class SupportingFileIdDto implements SupportingFileIdDtoType {
4
+ readonly supportingFileId: string;
5
+ }
6
+ export declare class GetSupportingFilesDto implements GetSupportingFilesDtoType {
7
+ readonly entity: SupportingFilesEntityTypes;
8
+ readonly entityId: string;
9
+ }
@@ -0,0 +1,39 @@
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.GetSupportingFilesDto = exports.SupportingFileIdDto = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ const enum_1 = require("@managemint-solutions/entities/supporting-files/enum");
15
+ // class-validator versions of the shared DTO types from @managemint-solutions/entities.
16
+ // Each class `implements` its entities type so the wire contract cannot drift. There is no class
17
+ // for the upload payload — it arrives as multipart and is not validated by class-validator.
18
+ class SupportingFileIdDto {
19
+ supportingFileId;
20
+ }
21
+ exports.SupportingFileIdDto = SupportingFileIdDto;
22
+ __decorate([
23
+ (0, class_validator_1.IsUUID)('4', { message: 'Invalid supporting file ID format' }),
24
+ __metadata("design:type", String)
25
+ ], SupportingFileIdDto.prototype, "supportingFileId", void 0);
26
+ class GetSupportingFilesDto {
27
+ entity;
28
+ entityId;
29
+ }
30
+ exports.GetSupportingFilesDto = GetSupportingFilesDto;
31
+ __decorate([
32
+ (0, class_validator_1.IsEnum)(enum_1.SupportingFilesEntityTypes, { message: 'Invalid entity type' }),
33
+ __metadata("design:type", String)
34
+ ], GetSupportingFilesDto.prototype, "entity", void 0);
35
+ __decorate([
36
+ (0, class_validator_1.IsUUID)('4', { message: 'Invalid entity ID format' }),
37
+ __metadata("design:type", String)
38
+ ], GetSupportingFilesDto.prototype, "entityId", void 0);
39
+ //# sourceMappingURL=dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dto.js","sourceRoot":"","sources":["../../src/supporting-files/dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAiD;AAKjD,+EAAkG;AAElG,wFAAwF;AACxF,iGAAiG;AACjG,4FAA4F;AAE5F,MAAa,mBAAmB;IAErB,gBAAgB,CAAU;CACpC;AAHD,kDAGC;AADU;IADR,IAAA,wBAAM,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC;;6DAC3B;AAGrC,MAAa,qBAAqB;IAEvB,MAAM,CAA8B;IAGpC,QAAQ,CAAU;CAC5B;AAND,sDAMC;AAJU;IADR,IAAA,wBAAM,EAAC,iCAA0B,EAAE,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAC;;qDAC1B;AAGpC;IADR,IAAA,wBAAM,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC;;uDAC1B"}
@@ -0,0 +1,16 @@
1
+ import type { SupportingFileEntity, SupportingFilePresignedUrl } from '@managemint-solutions/entities/supporting-files';
2
+ import type { UploadSupportingFilesDto } from '@managemint-solutions/entities/supporting-files/dto';
3
+ import { SupportingFilesEntityTypes } from '@managemint-solutions/entities/supporting-files/enum';
4
+ import type { AuthContext } from '../auth';
5
+ import type { TypedSupabaseClient } from '../client';
6
+ export * from './dto';
7
+ export * from './paths';
8
+ export declare class SupportingFilesResource {
9
+ private readonly supabase;
10
+ private readonly auth;
11
+ constructor(supabase: TypedSupabaseClient, auth: AuthContext);
12
+ getPresignedUrl(supportingFileId: string): Promise<SupportingFilePresignedUrl>;
13
+ list(entity: SupportingFilesEntityTypes, entityId: string): Promise<SupportingFileEntity[]>;
14
+ upload(entity: SupportingFilesEntityTypes, entityId: string, input: UploadSupportingFilesDto): Promise<SupportingFileEntity[]>;
15
+ remove(supportingFileId: string): Promise<void>;
16
+ }
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.SupportingFilesResource = void 0;
18
+ const errors_1 = require("../errors");
19
+ const paths_1 = require("./paths");
20
+ __exportStar(require("./dto"), exports);
21
+ __exportStar(require("./paths"), exports);
22
+ /** Storage bucket every supporting file lives in. */
23
+ const BUCKET = 'supporting-files';
24
+ /** How long a presigned download URL stays valid. */
25
+ const SIGNED_URL_TTL_SECONDS = 300;
26
+ /** Uploads run concurrently in batches of this size. */
27
+ const UPLOAD_BATCH_SIZE = 5;
28
+ // The queries are typed by the generated Database schema; the public contract is the shared
29
+ // SupportingFileEntity from @managemint-solutions/entities. The row's `extension` is `text` where
30
+ // the entity declares SupportingFilesExtensions, hence the cast at the return.
31
+ class SupportingFilesResource {
32
+ supabase;
33
+ auth;
34
+ constructor(supabase, auth) {
35
+ this.supabase = supabase;
36
+ this.auth = auth;
37
+ }
38
+ async getPresignedUrl(supportingFileId) {
39
+ const { data, error } = await this.supabase
40
+ .from('supporting_files')
41
+ .select('name, extension, entity_type, entity_id')
42
+ .eq('mms_id', supportingFileId)
43
+ .eq('organization_id', this.auth.organization_id)
44
+ .single();
45
+ if (error)
46
+ throw (0, errors_1.mapPostgrestError)(error);
47
+ const { data: signed, error: signedError } = await this.supabase.storage
48
+ .from(BUCKET)
49
+ .createSignedUrl((0, paths_1.storagePath)(data.entity_type, data.entity_id, data.name, data.extension), SIGNED_URL_TTL_SECONDS);
50
+ if (signedError)
51
+ throw (0, errors_1.mapStorageError)(signedError);
52
+ return { url: signed.signedUrl, ttl: SIGNED_URL_TTL_SECONDS };
53
+ }
54
+ async list(entity, entityId) {
55
+ const { data, error } = await this.supabase
56
+ .from('supporting_files')
57
+ .select('mms_id, name, extension')
58
+ .eq('entity_type', entity)
59
+ .eq('entity_id', entityId)
60
+ .eq('organization_id', this.auth.organization_id)
61
+ .order('created_at', { ascending: false });
62
+ if (error)
63
+ throw (0, errors_1.mapPostgrestError)(error);
64
+ return data;
65
+ }
66
+ async upload(entity, entityId, input) {
67
+ const { data: existing, error: existingError } = await this.supabase
68
+ .from('supporting_files')
69
+ .select('name, extension')
70
+ .eq('entity_type', entity)
71
+ .eq('entity_id', entityId)
72
+ .eq('organization_id', this.auth.organization_id);
73
+ if (existingError)
74
+ throw (0, errors_1.mapPostgrestError)(existingError);
75
+ const existingFileNames = existing.map((file) => `${file.name}.${file.extension}`);
76
+ // Every file is written to the bucket, duplicates included — an upsert refreshes the object.
77
+ for (let index = 0; index < input.files.length; index += UPLOAD_BATCH_SIZE) {
78
+ await Promise.all(input.files.slice(index, index + UPLOAD_BATCH_SIZE).map(async (file) => {
79
+ const { error } = await this.supabase.storage
80
+ .from(BUCKET)
81
+ .upload(`${entity}/${entityId}/${file.name}`, file, {
82
+ cacheControl: '3600',
83
+ upsert: true,
84
+ });
85
+ if (error)
86
+ throw (0, errors_1.mapStorageError)(error, `Failed to upload file: ${file.name}`);
87
+ }));
88
+ }
89
+ // Only files without an existing row get one — the rest were refreshed in place above.
90
+ const newFiles = input.files.filter((file) => !existingFileNames.includes(file.name));
91
+ if (newFiles.length > 0) {
92
+ const { error } = await this.supabase.from('supporting_files').insert(newFiles.map((file) => ({
93
+ ...(0, paths_1.splitFileName)(file.name),
94
+ entity_type: entity,
95
+ entity_id: entityId,
96
+ organization_id: this.auth.organization_id,
97
+ created_at: new Date().toISOString(),
98
+ created_by: this.auth.mms_id,
99
+ })));
100
+ if (error)
101
+ throw (0, errors_1.mapPostgrestError)(error);
102
+ }
103
+ return this.list(entity, entityId);
104
+ }
105
+ async remove(supportingFileId) {
106
+ const { data, error } = await this.supabase
107
+ .from('supporting_files')
108
+ .select('entity_type, entity_id, name, extension')
109
+ .eq('mms_id', supportingFileId)
110
+ .eq('organization_id', this.auth.organization_id)
111
+ .single();
112
+ if (error)
113
+ throw (0, errors_1.mapPostgrestError)(error);
114
+ const { error: deleteError } = await this.supabase
115
+ .from('supporting_files')
116
+ .delete()
117
+ .eq('mms_id', supportingFileId)
118
+ .eq('organization_id', this.auth.organization_id);
119
+ if (deleteError)
120
+ throw (0, errors_1.mapPostgrestError)(deleteError);
121
+ const { error: storageError } = await this.supabase.storage
122
+ .from(BUCKET)
123
+ .remove([(0, paths_1.storagePath)(data.entity_type, data.entity_id, data.name, data.extension)]);
124
+ if (storageError) {
125
+ throw (0, errors_1.mapStorageError)(storageError, `Failed to delete file: ${data.name}.${data.extension}`);
126
+ }
127
+ }
128
+ }
129
+ exports.SupportingFilesResource = SupportingFilesResource;
130
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/supporting-files/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Splits an uploaded file name into the `name` / `extension` columns.
3
+ *
4
+ * This mirrors the api exactly, quirks included: only the segment before the *first* dot becomes
5
+ * the name, so `report.final.pdf` stores as name `report`, extension `pdf`.
6
+ */
7
+ export declare const splitFileName: (fileName: string) => {
8
+ name: string;
9
+ extension: string;
10
+ };
11
+ /** Where an object lives in the `supporting-files` bucket. */
12
+ export declare const storagePath: (entityType: string, entityId: string, name: string, extension: string) => string;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.storagePath = exports.splitFileName = void 0;
4
+ /**
5
+ * Splits an uploaded file name into the `name` / `extension` columns.
6
+ *
7
+ * This mirrors the api exactly, quirks included: only the segment before the *first* dot becomes
8
+ * the name, so `report.final.pdf` stores as name `report`, extension `pdf`.
9
+ */
10
+ const splitFileName = (fileName) => ({
11
+ name: fileName.split('.')[0],
12
+ extension: fileName.split('.').pop() ?? '',
13
+ });
14
+ exports.splitFileName = splitFileName;
15
+ /** Where an object lives in the `supporting-files` bucket. */
16
+ const storagePath = (entityType, entityId, name, extension) => `${entityType}/${entityId}/${name}.${extension}`;
17
+ exports.storagePath = storagePath;
18
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/supporting-files/paths.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACI,MAAM,aAAa,GAAG,CAAC,QAAgB,EAAuC,EAAE,CAAC,CAAC;IACvF,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC5B,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE;CAC3C,CAAC,CAAC;AAHU,QAAA,aAAa,iBAGvB;AAEH,8DAA8D;AACvD,MAAM,WAAW,GAAG,CACzB,UAAkB,EAClB,QAAgB,EAChB,IAAY,EACZ,SAAiB,EACT,EAAE,CAAC,GAAG,UAAU,IAAI,QAAQ,IAAI,IAAI,IAAI,SAAS,EAAE,CAAC;AALjD,QAAA,WAAW,eAKsC"}
@@ -0,0 +1,2 @@
1
+ import { ValidationOptions } from 'class-validator';
2
+ export declare function IsNullable(validationOptions?: ValidationOptions): PropertyDecorator;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IsNullable = IsNullable;
4
+ const class_validator_1 = require("class-validator");
5
+ function IsNullable(validationOptions) {
6
+ return (0, class_validator_1.ValidateIf)((_object, value) => value !== null, validationOptions);
7
+ }
8
+ //# sourceMappingURL=validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.js","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":";;AAEA,gCAEC;AAJD,qDAAgE;AAEhE,SAAgB,UAAU,CAAC,iBAAqC;IAC9D,OAAO,IAAA,4BAAU,EAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,EAAE,iBAAiB,CAAC,CAAC;AAC3E,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@managemint-solutions/sdk",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Typed Supabase data-access SDK for ManageMint Solutions",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Scott Bebington <scottbebington@gmail.com>",