@doctorus/common 0.0.0 → 0.0.2

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
@@ -1 +1,391 @@
1
- # replace this
1
+ # @doctorus/common
2
+
3
+ Common TypeScript utilities for Doctorus - A shared library for managing operations, SSM parameters, and access control across infrastructure stacks and frontend applications.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@doctorus/common.svg)](https://www.npmjs.com/package/@doctorus/common)
6
+ [![License](https://img.shields.io/npm/l/@doctorus/common.svg)](https://github.com/DoctorusRepoOwner/common/blob/main/LICENSE)
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm install @doctorus/common
12
+ # or
13
+ pnpm add @doctorus/common
14
+ # or
15
+ yarn add @doctorus/common
16
+ ```
17
+
18
+ ## Features
19
+
20
+ - 🔐 **Operations Module** - Resource-Action pattern for access control and audit logging
21
+ - 🗄️ **SSM Parameters** - AWS SSM Parameter Store utilities with environment support
22
+ - 📋 **Type Safety** - Full TypeScript support with comprehensive type definitions
23
+ - 🏥 **Medical & Public Resources** - Separate categorization for HIPAA compliance
24
+ - ✅ **100% Test Coverage** - Thoroughly tested and production-ready
25
+
26
+ ## Modules
27
+
28
+ ### 1. Operations Module
29
+
30
+ Manage operations in `RESOURCE:ACTION` format for access control, audit logging, and permission management.
31
+
32
+ #### Basic Usage
33
+
34
+ ```typescript
35
+ import { Operation, Operations, Resource, Action } from '@doctorus/common';
36
+
37
+ // Use predefined operations
38
+ const operation = Operations.PATIENT_READ;
39
+ console.log(operation.toString()); // "PATIENT:READ"
40
+
41
+ // Create custom operations
42
+ const customOp = new Operation(Resource.PRESCRIPTION, Action.PRESCRIBE);
43
+ console.log(customOp.toString()); // "PRESCRIPTION:PRESCRIBE"
44
+
45
+ // Parse from string
46
+ const parsed = Operation.fromString("MEDICAL_SERVICE:SCHEDULE");
47
+ if (parsed) {
48
+ console.log(parsed.resource); // Resource.MEDICAL_SERVICE
49
+ console.log(parsed.action); // Action.SCHEDULE
50
+ }
51
+
52
+ // Compare operations
53
+ const op1 = Operations.PATIENT_READ;
54
+ const op2 = Operations.PATIENT_READ;
55
+ console.log(op1.equals(op2)); // true
56
+
57
+ // Convert to JSON
58
+ const json = operation.toJSON();
59
+ // { resource: "PATIENT", action: "READ", operation: "PATIENT:READ" }
60
+ ```
61
+
62
+ #### Resources
63
+
64
+ Resources are categorized as **Medical** (require special access control) or **Public** (standard access control):
65
+
66
+ **Medical Resources:**
67
+ - Patient: `PATIENT`, `PATIENT_MEDICAL_NOTES`, `PATIENT_MEDICAL_PROPERTIES`, `PATIENT_PAYMENT`
68
+ - Medical Services: `MEDICAL_SERVICE`, `MEDICAL_SERVICE_NOTE`, `MEDICAL_SERVICE_SCHEDULE`, `MEDICAL_SERVICE_FEES`, `MEDICAL_SERVICE_STATUS`
69
+ - Clinical: `MEDICAL_RECORD`, `MEDICAL_HISTORY`, `PRESCRIPTION`, `DIAGNOSIS`, `OBSERVATION`, `MEDICATION`, `ALLERGY`, `IMMUNIZATION`, `PROCEDURE`
70
+ - Measurements: `CLINICAL_NOTE`, `VITAL_SIGNS`, `MEASURE_MODEL`, `CALCULATED_MEASURE_MODEL`
71
+ - Diagnostics: `LAB_RESULT`, `IMAGING`
72
+
73
+ **Public Resources:**
74
+ - Account: `ACCOUNT`, `ACCOUNT_OWNERSHIP`, `ACCOUNT_PREFERENCES`
75
+ - User: `USER`, `CONTACT`
76
+ - Documents: `UPLOADED_DOCUMENT`, `DOCUMENT_LAYOUT`, `GENERATED_DOCUMENT`, `DOCUMENT_MODEL`, `SNIPPET`
77
+ - System: `NOTIFICATION`, `REPORT`, `AUDIT_LOG`, `SYSTEM`, `SETTINGS`, `MEMBERSHIP`, `LOCATION`, `TASK_TYPE`
78
+
79
+ #### Actions
80
+
81
+ ```typescript
82
+ // CRUD operations
83
+ Action.CREATE, Action.READ, Action.UPDATE, Action.DELETE, Action.PUT, Action.LIST
84
+
85
+ // General actions
86
+ Action.MANAGE, Action.VIEW, Action.SEARCH
87
+
88
+ // Medical-specific actions
89
+ Action.PRESCRIBE, Action.DIAGNOSE, Action.SIGN, Action.VERIFY,
90
+ Action.SCHEDULE, Action.CANCEL, Action.APPROVE, Action.REJECT
91
+
92
+ // Medical service actions
93
+ Action.SET_MEDICAL_SERVICE_STATUS, Action.SET_MEDICAL_SERVICE_FEES
94
+
95
+ // Patient-specific actions
96
+ Action.UPDATE_STATUS, Action.VIEW_PATIENTS,
97
+ Action.PUT_PATIENT_PAYMENT, Action.DELETE_PATIENT_PAYMENT
98
+
99
+ // Data operations
100
+ Action.EXPORT, Action.IMPORT, Action.ARCHIVE, Action.RESTORE,
101
+ Action.SHARE, Action.DOWNLOAD, Action.UPLOAD
102
+
103
+ // System operations
104
+ Action.LOGIN, Action.LOGOUT, Action.CONFIGURE, Action.AUDIT
105
+ ```
106
+
107
+ #### Helper Functions
108
+
109
+ ```typescript
110
+ import {
111
+ isMedicalResource,
112
+ isPublicResource,
113
+ getAllOperations,
114
+ getOperationsByResource,
115
+ getOperationsByAction
116
+ } from '@doctorus/common';
117
+
118
+ // Check resource type
119
+ if (isMedicalResource(Resource.PATIENT)) {
120
+ // Apply HIPAA-compliant access controls
121
+ }
122
+
123
+ if (isPublicResource(Resource.USER)) {
124
+ // Apply standard access controls
125
+ }
126
+
127
+ // Get all predefined operations
128
+ const allOps = getAllOperations();
129
+
130
+ // Filter operations by resource
131
+ const patientOps = getOperationsByResource(Resource.PATIENT);
132
+ // [PATIENT_CREATE, PATIENT_READ, PATIENT_UPDATE, ...]
133
+
134
+ // Filter operations by action
135
+ const createOps = getOperationsByAction(Action.CREATE);
136
+ // [PATIENT_CREATE, USER_CREATE, MEDICAL_RECORD_CREATE, ...]
137
+ ```
138
+
139
+ #### Predefined Operations
140
+
141
+ Commonly used operations are predefined for convenience:
142
+
143
+ ```typescript
144
+ // Account operations
145
+ Operations.ACCOUNT_CREATE, Operations.ACCOUNT_READ, Operations.ACCOUNT_UPDATE,
146
+ Operations.ACCOUNT_DELETE, Operations.ACCOUNT_MANAGE
147
+
148
+ // Patient operations
149
+ Operations.PATIENT_CREATE, Operations.PATIENT_READ, Operations.PATIENT_UPDATE,
150
+ Operations.PATIENT_DELETE, Operations.PATIENT_LIST, Operations.PATIENT_VIEW,
151
+ Operations.PATIENT_UPDATE_STATUS
152
+
153
+ // Medical service operations
154
+ Operations.MEDICAL_SERVICE_CREATE, Operations.MEDICAL_SERVICE_READ,
155
+ Operations.MEDICAL_SERVICE_UPDATE, Operations.MEDICAL_SERVICE_DELETE,
156
+ Operations.MEDICAL_SERVICE_MANAGE, Operations.MEDICAL_SERVICE_SCHEDULE,
157
+ Operations.MEDICAL_SERVICE_CANCEL, Operations.MEDICAL_SERVICE_SET_STATUS,
158
+ Operations.MEDICAL_SERVICE_SET_FEES
159
+
160
+ // Prescription operations
161
+ Operations.PRESCRIPTION_CREATE, Operations.PRESCRIPTION_READ,
162
+ Operations.PRESCRIPTION_UPDATE, Operations.PRESCRIPTION_SIGN,
163
+ Operations.PRESCRIPTION_PRESCRIBE
164
+
165
+ // User operations
166
+ Operations.USER_CREATE, Operations.USER_READ, Operations.USER_UPDATE,
167
+ Operations.USER_DELETE, Operations.USER_LOGIN, Operations.USER_LOGOUT
168
+
169
+ // ... and many more
170
+ ```
171
+
172
+ ### 2. SSM Parameters Module
173
+
174
+ Utilities for managing AWS SSM Parameter Store keys with environment support.
175
+
176
+ #### Basic Usage
177
+
178
+ ```typescript
179
+ import {
180
+ SSM_PARAM_KEY,
181
+ buildSSMPath,
182
+ buildSSMPathWithPrefix,
183
+ extractEnvFromPath,
184
+ extractKeyFromPath,
185
+ isEnvAgnostic
186
+ } from '@doctorus/common';
187
+
188
+ // Build environment-specific path
189
+ const path = buildSSMPath('prod', SSM_PARAM_KEY.COGNITO_USER_POOL_ID);
190
+ console.log(path); // "/prod/user-pool-id"
191
+
192
+ // Build environment-agnostic path (for shared/central account parameters)
193
+ const sharedPath = buildSSMPath(null, SSM_PARAM_KEY.DB_USER);
194
+ console.log(sharedPath); // "/db-user"
195
+
196
+ // Build path with custom prefix
197
+ const customPath = buildSSMPathWithPrefix(
198
+ '/myapp/prod',
199
+ SSM_PARAM_KEY.GRAPHQL_API_ID
200
+ );
201
+ console.log(customPath); // "/myapp/prod/graphql-api-id"
202
+
203
+ // Extract environment from path
204
+ const env = extractEnvFromPath('/prod/user-pool-id');
205
+ console.log(env); // "prod"
206
+
207
+ // Extract key from path
208
+ const key = extractKeyFromPath('/prod/user-pool-id');
209
+ console.log(key); // SSM_PARAM_KEY.COGNITO_USER_POOL_ID
210
+
211
+ // Check if path is environment-agnostic
212
+ console.log(isEnvAgnostic('/db-user')); // true
213
+ console.log(isEnvAgnostic('/prod/user-pool-id')); // false
214
+ ```
215
+
216
+ #### Available SSM Parameter Keys
217
+
218
+ ```typescript
219
+ SSM_PARAM_KEY.COGNITO_USER_POOL_ID
220
+ SSM_PARAM_KEY.COGNITO_USER_POOL_WEB_CLIENT_ID
221
+ SSM_PARAM_KEY.COGNITO_OAUTH_DOMAIN
222
+ SSM_PARAM_KEY.RUM_GUEST_ROLE_ARN
223
+ SSM_PARAM_KEY.RUM_IDENTITY_POOL_ID
224
+ SSM_PARAM_KEY.RUM_APP_ID
225
+ SSM_PARAM_KEY.GRAPHQL_HTTP_URL
226
+ SSM_PARAM_KEY.GRAPHQL_WS_URL
227
+ SSM_PARAM_KEY.GRAPHQL_HOST
228
+ SSM_PARAM_KEY.GRAPHQL_API_ID
229
+ SSM_PARAM_KEY.MEDICAL_ASSETS_AWS_CLOUDFRONT_PRIVATE_KEY
230
+ SSM_PARAM_KEY.MEDICAL_ASSETS_AWS_CLOUDFRONT_KEY_ID
231
+ SSM_PARAM_KEY.MEDICAL_ASSETS_BUCKET_NAME
232
+ SSM_PARAM_KEY.PUBLIC_ASSETS_BUCKET_NAME
233
+ SSM_PARAM_KEY.DB_USER
234
+ SSM_PARAM_KEY.DB_PASSWORD
235
+ SSM_PARAM_KEY.MEDICAL_ASSETS_DISTRIBUTION_DOMAIN_NAME
236
+ SSM_PARAM_KEY.BASE_HOST
237
+ SSM_PARAM_KEY.EMAIL_FROM_ADDRESS
238
+ SSM_PARAM_KEY.EVENT_API_REAL_TIME_DNS
239
+ SSM_PARAM_KEY.EVENT_API_HTTP_DNS
240
+ SSM_PARAM_KEY.NOTIFIED_EVENT_ACTIONS
241
+ ```
242
+
243
+ ## Use Cases
244
+
245
+ ### 1. Access Control
246
+
247
+ ```typescript
248
+ import { Operation, isMedicalResource } from '@doctorus/common';
249
+
250
+ function checkPermission(userPermissions: string[], operation: Operation): boolean {
251
+ // Check if user has permission for this operation
252
+ const hasPermission = userPermissions.includes(operation.toString());
253
+
254
+ // Apply additional checks for medical resources
255
+ if (isMedicalResource(operation.resource)) {
256
+ // Enforce HIPAA compliance, additional logging, etc.
257
+ return hasPermission && user.hasHIPAAAccess;
258
+ }
259
+
260
+ return hasPermission;
261
+ }
262
+
263
+ // Usage
264
+ const canRead = checkPermission(
265
+ userPermissions,
266
+ Operations.PATIENT_READ
267
+ );
268
+ ```
269
+
270
+ ### 2. Audit Logging
271
+
272
+ ```typescript
273
+ import { Operation, Operations } from '@doctorus/common';
274
+
275
+ interface AuditLog {
276
+ timestamp: Date;
277
+ userId: string;
278
+ operation: string;
279
+ resourceId: string;
280
+ success: boolean;
281
+ }
282
+
283
+ function logAudit(
284
+ userId: string,
285
+ operation: Operation,
286
+ resourceId: string,
287
+ success: boolean
288
+ ) {
289
+ const log: AuditLog = {
290
+ timestamp: new Date(),
291
+ userId,
292
+ operation: operation.toString(),
293
+ resourceId,
294
+ success
295
+ };
296
+
297
+ // Store in audit log database
298
+ auditLogService.create(log);
299
+ }
300
+
301
+ // Usage
302
+ logAudit('user123', Operations.PRESCRIPTION_PRESCRIBE, 'rx-456', true);
303
+ ```
304
+
305
+ ### 3. Infrastructure Configuration
306
+
307
+ ```typescript
308
+ import { buildSSMPath, SSM_PARAM_KEY } from '@doctorus/common';
309
+ import { StringParameter } from 'aws-cdk-lib/aws-ssm';
310
+
311
+ // In your CDK stack
312
+ const env = 'prod';
313
+
314
+ const userPoolId = StringParameter.valueFromLookup(
315
+ this,
316
+ buildSSMPath(env, SSM_PARAM_KEY.COGNITO_USER_POOL_ID)
317
+ );
318
+
319
+ const graphqlUrl = StringParameter.valueFromLookup(
320
+ this,
321
+ buildSSMPath(env, SSM_PARAM_KEY.GRAPHQL_HTTP_URL)
322
+ );
323
+ ```
324
+
325
+ ### 4. Frontend Configuration
326
+
327
+ ```typescript
328
+ import { buildSSMPath, SSM_PARAM_KEY } from '@doctorus/common';
329
+ import { SSM } from '@aws-sdk/client-ssm';
330
+
331
+ async function loadConfig(environment: string) {
332
+ const ssm = new SSM();
333
+
334
+ const params = [
335
+ SSM_PARAM_KEY.COGNITO_USER_POOL_ID,
336
+ SSM_PARAM_KEY.GRAPHQL_HTTP_URL,
337
+ SSM_PARAM_KEY.RUM_APP_ID
338
+ ];
339
+
340
+ const config: Record<string, string> = {};
341
+
342
+ for (const param of params) {
343
+ const path = buildSSMPath(environment, param);
344
+ const response = await ssm.getParameter({ Name: path });
345
+ config[param] = response.Parameter?.Value || '';
346
+ }
347
+
348
+ return config;
349
+ }
350
+ ```
351
+
352
+ ## Development
353
+
354
+ ```bash
355
+ # Install dependencies
356
+ pnpm install
357
+
358
+ # Run tests
359
+ pnpm test
360
+
361
+ # Build
362
+ pnpm build
363
+
364
+ # Run projen (regenerate configuration)
365
+ pnpm projen
366
+ ```
367
+
368
+ ## Testing
369
+
370
+ The library includes comprehensive tests with 100% coverage:
371
+
372
+ ```bash
373
+ pnpm test
374
+ ```
375
+
376
+ ## Contributing
377
+
378
+ Contributions are welcome! Please feel free to submit a Pull Request.
379
+
380
+ ## License
381
+
382
+ Apache-2.0
383
+
384
+ ## Related
385
+
386
+ - [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html)
387
+ - [AWS CDK](https://aws.amazon.com/cdk/)
388
+
389
+ ---
390
+
391
+ Built with ❤️ for Doctorus
package/lib/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- export declare class Hello {
2
- sayHello(): string;
3
- }
1
+ export * from "./ssm";
2
+ export * from "./operations";
package/lib/index.js CHANGED
@@ -1,10 +1,19 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Hello = void 0;
4
- class Hello {
5
- sayHello() {
6
- return "hello, world!";
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
7
  }
8
- }
9
- exports.Hello = Hello;
10
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsTUFBYSxLQUFLO0lBQ1QsUUFBUTtRQUNiLE9BQU8sZUFBZSxDQUFDO0lBQ3pCLENBQUM7Q0FDRjtBQUpELHNCQUlDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIEhlbGxvIHtcbiAgcHVibGljIHNheUhlbGxvKCkge1xuICAgIHJldHVybiBcImhlbGxvLCB3b3JsZCFcIjtcbiAgfVxufSJdfQ==
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
+ __exportStar(require("./ssm"), exports);
18
+ __exportStar(require("./operations"), exports);
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHdDQUFzQjtBQUN0QiwrQ0FBNkIiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tIFwiLi9zc21cIjtcbmV4cG9ydCAqIGZyb20gXCIuL29wZXJhdGlvbnNcIjtcbiJdfQ==
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Action types for operations
3
+ */
4
+ export declare enum Action {
5
+ CREATE = "CREATE",
6
+ READ = "READ",
7
+ UPDATE = "UPDATE",
8
+ DELETE = "DELETE",
9
+ PUT = "PUT",
10
+ LIST = "LIST",
11
+ MANAGE = "MANAGE",
12
+ VIEW = "VIEW",
13
+ SEARCH = "SEARCH",
14
+ GRANT = "GRANT",
15
+ REVOKE = "REVOKE",
16
+ PRESCRIBE = "PRESCRIBE",
17
+ DIAGNOSE = "DIAGNOSE",
18
+ SCHEDULE = "SCHEDULE",
19
+ CANCEL = "CANCEL",
20
+ APPROVE = "APPROVE",
21
+ REJECT = "REJECT",
22
+ SIGN = "SIGN",
23
+ VERIFY = "VERIFY",
24
+ SET_MEDICAL_SERVICE_STATUS = "SET_MEDICAL_SERVICE_STATUS",
25
+ SET_MEDICAL_SERVICE_FEES = "SET_MEDICAL_SERVICE_FEES",
26
+ UPDATE_STATUS = "UPDATE_STATUS",
27
+ VIEW_PATIENTS = "VIEW_PATIENTS",
28
+ PUT_PATIENT_PAYMENT = "PUT_PATIENT_PAYMENT",
29
+ DELETE_PATIENT_PAYMENT = "DELETE_PATIENT_PAYMENT",
30
+ EXPORT = "EXPORT",
31
+ IMPORT = "IMPORT",
32
+ ARCHIVE = "ARCHIVE",
33
+ RESTORE = "RESTORE",
34
+ SHARE = "SHARE",
35
+ DOWNLOAD = "DOWNLOAD",
36
+ UPLOAD = "UPLOAD",
37
+ LOGIN = "LOGIN",
38
+ LOGOUT = "LOGOUT",
39
+ CONFIGURE = "CONFIGURE",
40
+ AUDIT = "AUDIT"
41
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Action = void 0;
4
+ /**
5
+ * Action types for operations
6
+ */
7
+ var Action;
8
+ (function (Action) {
9
+ // CRUD operations
10
+ Action["CREATE"] = "CREATE";
11
+ Action["READ"] = "READ";
12
+ Action["UPDATE"] = "UPDATE";
13
+ Action["DELETE"] = "DELETE";
14
+ Action["PUT"] = "PUT";
15
+ Action["LIST"] = "LIST";
16
+ // General actions
17
+ Action["MANAGE"] = "MANAGE";
18
+ Action["VIEW"] = "VIEW";
19
+ Action["SEARCH"] = "SEARCH";
20
+ // Access control
21
+ Action["GRANT"] = "GRANT";
22
+ Action["REVOKE"] = "REVOKE";
23
+ // Medical specific
24
+ Action["PRESCRIBE"] = "PRESCRIBE";
25
+ Action["DIAGNOSE"] = "DIAGNOSE";
26
+ Action["SCHEDULE"] = "SCHEDULE";
27
+ Action["CANCEL"] = "CANCEL";
28
+ Action["APPROVE"] = "APPROVE";
29
+ Action["REJECT"] = "REJECT";
30
+ Action["SIGN"] = "SIGN";
31
+ Action["VERIFY"] = "VERIFY";
32
+ // Medical service specific
33
+ Action["SET_MEDICAL_SERVICE_STATUS"] = "SET_MEDICAL_SERVICE_STATUS";
34
+ Action["SET_MEDICAL_SERVICE_FEES"] = "SET_MEDICAL_SERVICE_FEES";
35
+ // Patient specific
36
+ Action["UPDATE_STATUS"] = "UPDATE_STATUS";
37
+ Action["VIEW_PATIENTS"] = "VIEW_PATIENTS";
38
+ Action["PUT_PATIENT_PAYMENT"] = "PUT_PATIENT_PAYMENT";
39
+ Action["DELETE_PATIENT_PAYMENT"] = "DELETE_PATIENT_PAYMENT";
40
+ // Data operations
41
+ Action["EXPORT"] = "EXPORT";
42
+ Action["IMPORT"] = "IMPORT";
43
+ Action["ARCHIVE"] = "ARCHIVE";
44
+ Action["RESTORE"] = "RESTORE";
45
+ Action["SHARE"] = "SHARE";
46
+ Action["DOWNLOAD"] = "DOWNLOAD";
47
+ Action["UPLOAD"] = "UPLOAD";
48
+ // System operations
49
+ Action["LOGIN"] = "LOGIN";
50
+ Action["LOGOUT"] = "LOGOUT";
51
+ Action["CONFIGURE"] = "CONFIGURE";
52
+ Action["AUDIT"] = "AUDIT";
53
+ })(Action || (exports.Action = Action = {}));
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcGVyYXRpb25zL2FjdGlvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUE7O0dBRUc7QUFDSCxJQUFZLE1Bb0RYO0FBcERELFdBQVksTUFBTTtJQUNoQixrQkFBa0I7SUFDbEIsMkJBQWlCLENBQUE7SUFDakIsdUJBQWEsQ0FBQTtJQUNiLDJCQUFpQixDQUFBO0lBQ2pCLDJCQUFpQixDQUFBO0lBQ2pCLHFCQUFXLENBQUE7SUFDWCx1QkFBYSxDQUFBO0lBRWIsa0JBQWtCO0lBQ2xCLDJCQUFpQixDQUFBO0lBQ2pCLHVCQUFhLENBQUE7SUFDYiwyQkFBaUIsQ0FBQTtJQUVqQixpQkFBaUI7SUFDakIseUJBQWUsQ0FBQTtJQUNmLDJCQUFpQixDQUFBO0lBRWpCLG1CQUFtQjtJQUNuQixpQ0FBdUIsQ0FBQTtJQUN2QiwrQkFBcUIsQ0FBQTtJQUNyQiwrQkFBcUIsQ0FBQTtJQUNyQiwyQkFBaUIsQ0FBQTtJQUNqQiw2QkFBbUIsQ0FBQTtJQUNuQiwyQkFBaUIsQ0FBQTtJQUNqQix1QkFBYSxDQUFBO0lBQ2IsMkJBQWlCLENBQUE7SUFFakIsMkJBQTJCO0lBQzNCLG1FQUF5RCxDQUFBO0lBQ3pELCtEQUFxRCxDQUFBO0lBRXJELG1CQUFtQjtJQUNuQix5Q0FBK0IsQ0FBQTtJQUMvQix5Q0FBK0IsQ0FBQTtJQUMvQixxREFBMkMsQ0FBQTtJQUMzQywyREFBaUQsQ0FBQTtJQUVqRCxrQkFBa0I7SUFDbEIsMkJBQWlCLENBQUE7SUFDakIsMkJBQWlCLENBQUE7SUFDakIsNkJBQW1CLENBQUE7SUFDbkIsNkJBQW1CLENBQUE7SUFDbkIseUJBQWUsQ0FBQTtJQUNmLCtCQUFxQixDQUFBO0lBQ3JCLDJCQUFpQixDQUFBO0lBRWpCLG9CQUFvQjtJQUNwQix5QkFBZSxDQUFBO0lBQ2YsMkJBQWlCLENBQUE7SUFDakIsaUNBQXVCLENBQUE7SUFDdkIseUJBQWUsQ0FBQTtBQUNqQixDQUFDLEVBcERXLE1BQU0sc0JBQU4sTUFBTSxRQW9EakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEFjdGlvbiB0eXBlcyBmb3Igb3BlcmF0aW9uc1xuICovXG5leHBvcnQgZW51bSBBY3Rpb24ge1xuICAvLyBDUlVEIG9wZXJhdGlvbnNcbiAgQ1JFQVRFID0gXCJDUkVBVEVcIixcbiAgUkVBRCA9IFwiUkVBRFwiLFxuICBVUERBVEUgPSBcIlVQREFURVwiLFxuICBERUxFVEUgPSBcIkRFTEVURVwiLFxuICBQVVQgPSBcIlBVVFwiLFxuICBMSVNUID0gXCJMSVNUXCIsXG5cbiAgLy8gR2VuZXJhbCBhY3Rpb25zXG4gIE1BTkFHRSA9IFwiTUFOQUdFXCIsXG4gIFZJRVcgPSBcIlZJRVdcIixcbiAgU0VBUkNIID0gXCJTRUFSQ0hcIixcblxuICAvLyBBY2Nlc3MgY29udHJvbFxuICBHUkFOVCA9IFwiR1JBTlRcIixcbiAgUkVWT0tFID0gXCJSRVZPS0VcIixcblxuICAvLyBNZWRpY2FsIHNwZWNpZmljXG4gIFBSRVNDUklCRSA9IFwiUFJFU0NSSUJFXCIsXG4gIERJQUdOT1NFID0gXCJESUFHTk9TRVwiLFxuICBTQ0hFRFVMRSA9IFwiU0NIRURVTEVcIixcbiAgQ0FOQ0VMID0gXCJDQU5DRUxcIixcbiAgQVBQUk9WRSA9IFwiQVBQUk9WRVwiLFxuICBSRUpFQ1QgPSBcIlJFSkVDVFwiLFxuICBTSUdOID0gXCJTSUdOXCIsXG4gIFZFUklGWSA9IFwiVkVSSUZZXCIsXG5cbiAgLy8gTWVkaWNhbCBzZXJ2aWNlIHNwZWNpZmljXG4gIFNFVF9NRURJQ0FMX1NFUlZJQ0VfU1RBVFVTID0gXCJTRVRfTUVESUNBTF9TRVJWSUNFX1NUQVRVU1wiLFxuICBTRVRfTUVESUNBTF9TRVJWSUNFX0ZFRVMgPSBcIlNFVF9NRURJQ0FMX1NFUlZJQ0VfRkVFU1wiLFxuXG4gIC8vIFBhdGllbnQgc3BlY2lmaWNcbiAgVVBEQVRFX1NUQVRVUyA9IFwiVVBEQVRFX1NUQVRVU1wiLFxuICBWSUVXX1BBVElFTlRTID0gXCJWSUVXX1BBVElFTlRTXCIsXG4gIFBVVF9QQVRJRU5UX1BBWU1FTlQgPSBcIlBVVF9QQVRJRU5UX1BBWU1FTlRcIixcbiAgREVMRVRFX1BBVElFTlRfUEFZTUVOVCA9IFwiREVMRVRFX1BBVElFTlRfUEFZTUVOVFwiLFxuXG4gIC8vIERhdGEgb3BlcmF0aW9uc1xuICBFWFBPUlQgPSBcIkVYUE9SVFwiLFxuICBJTVBPUlQgPSBcIklNUE9SVFwiLFxuICBBUkNISVZFID0gXCJBUkNISVZFXCIsXG4gIFJFU1RPUkUgPSBcIlJFU1RPUkVcIixcbiAgU0hBUkUgPSBcIlNIQVJFXCIsXG4gIERPV05MT0FEID0gXCJET1dOTE9BRFwiLFxuICBVUExPQUQgPSBcIlVQTE9BRFwiLFxuXG4gIC8vIFN5c3RlbSBvcGVyYXRpb25zXG4gIExPR0lOID0gXCJMT0dJTlwiLFxuICBMT0dPVVQgPSBcIkxPR09VVFwiLFxuICBDT05GSUdVUkUgPSBcIkNPTkZJR1VSRVwiLFxuICBBVURJVCA9IFwiQVVESVRcIixcbn1cbiJdfQ==
@@ -0,0 +1,4 @@
1
+ export { Resource, MEDICAL_RESOURCES, PUBLIC_RESOURCES, isMedicalResource, isPublicResource, } from "./resources";
2
+ export { Action } from "./actions";
3
+ export { Operation } from "./operation";
4
+ export { Operations, getAllOperations, getOperationsByResource, getOperationsByAction, } from "./predefined";
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getOperationsByAction = exports.getOperationsByResource = exports.getAllOperations = exports.Operations = exports.Operation = exports.Action = exports.isPublicResource = exports.isMedicalResource = exports.PUBLIC_RESOURCES = exports.MEDICAL_RESOURCES = exports.Resource = void 0;
4
+ var resources_1 = require("./resources");
5
+ Object.defineProperty(exports, "Resource", { enumerable: true, get: function () { return resources_1.Resource; } });
6
+ Object.defineProperty(exports, "MEDICAL_RESOURCES", { enumerable: true, get: function () { return resources_1.MEDICAL_RESOURCES; } });
7
+ Object.defineProperty(exports, "PUBLIC_RESOURCES", { enumerable: true, get: function () { return resources_1.PUBLIC_RESOURCES; } });
8
+ Object.defineProperty(exports, "isMedicalResource", { enumerable: true, get: function () { return resources_1.isMedicalResource; } });
9
+ Object.defineProperty(exports, "isPublicResource", { enumerable: true, get: function () { return resources_1.isPublicResource; } });
10
+ var actions_1 = require("./actions");
11
+ Object.defineProperty(exports, "Action", { enumerable: true, get: function () { return actions_1.Action; } });
12
+ var operation_1 = require("./operation");
13
+ Object.defineProperty(exports, "Operation", { enumerable: true, get: function () { return operation_1.Operation; } });
14
+ var predefined_1 = require("./predefined");
15
+ Object.defineProperty(exports, "Operations", { enumerable: true, get: function () { return predefined_1.Operations; } });
16
+ Object.defineProperty(exports, "getAllOperations", { enumerable: true, get: function () { return predefined_1.getAllOperations; } });
17
+ Object.defineProperty(exports, "getOperationsByResource", { enumerable: true, get: function () { return predefined_1.getOperationsByResource; } });
18
+ Object.defineProperty(exports, "getOperationsByAction", { enumerable: true, get: function () { return predefined_1.getOperationsByAction; } });
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3BlcmF0aW9ucy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5Q0FNcUI7QUFMbkIscUdBQUEsUUFBUSxPQUFBO0FBQ1IsOEdBQUEsaUJBQWlCLE9BQUE7QUFDakIsNkdBQUEsZ0JBQWdCLE9BQUE7QUFDaEIsOEdBQUEsaUJBQWlCLE9BQUE7QUFDakIsNkdBQUEsZ0JBQWdCLE9BQUE7QUFFbEIscUNBQW1DO0FBQTFCLGlHQUFBLE1BQU0sT0FBQTtBQUNmLHlDQUF3QztBQUEvQixzR0FBQSxTQUFTLE9BQUE7QUFDbEIsMkNBS3NCO0FBSnBCLHdHQUFBLFVBQVUsT0FBQTtBQUNWLDhHQUFBLGdCQUFnQixPQUFBO0FBQ2hCLHFIQUFBLHVCQUF1QixPQUFBO0FBQ3ZCLG1IQUFBLHFCQUFxQixPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHtcbiAgUmVzb3VyY2UsXG4gIE1FRElDQUxfUkVTT1VSQ0VTLFxuICBQVUJMSUNfUkVTT1VSQ0VTLFxuICBpc01lZGljYWxSZXNvdXJjZSxcbiAgaXNQdWJsaWNSZXNvdXJjZSxcbn0gZnJvbSBcIi4vcmVzb3VyY2VzXCI7XG5leHBvcnQgeyBBY3Rpb24gfSBmcm9tIFwiLi9hY3Rpb25zXCI7XG5leHBvcnQgeyBPcGVyYXRpb24gfSBmcm9tIFwiLi9vcGVyYXRpb25cIjtcbmV4cG9ydCB7XG4gIE9wZXJhdGlvbnMsXG4gIGdldEFsbE9wZXJhdGlvbnMsXG4gIGdldE9wZXJhdGlvbnNCeVJlc291cmNlLFxuICBnZXRPcGVyYXRpb25zQnlBY3Rpb24sXG59IGZyb20gXCIuL3ByZWRlZmluZWRcIjtcbiJdfQ==
@@ -0,0 +1,32 @@
1
+ import { Action } from "./actions";
2
+ import { Resource } from "./resources";
3
+ /**
4
+ * Operation in RESOURCE:ACTION format
5
+ */
6
+ export declare class Operation {
7
+ readonly resource: Resource;
8
+ readonly action: Action;
9
+ /**
10
+ * Create operation from string
11
+ * @param operationString - String in RESOURCE:ACTION format
12
+ * @returns Operation instance or null if invalid
13
+ */
14
+ static fromString(operationString: string): Operation | null;
15
+ constructor(resource: Resource, action: Action);
16
+ /**
17
+ * Get operation string in RESOURCE:ACTION format
18
+ */
19
+ toString(): string;
20
+ /**
21
+ * Check if two operations are equal
22
+ */
23
+ equals(other: Operation): boolean;
24
+ /**
25
+ * Convert to JSON representation
26
+ */
27
+ toJSON(): {
28
+ resource: Resource;
29
+ action: Action;
30
+ operation: string;
31
+ };
32
+ }
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Operation = void 0;
4
+ const actions_1 = require("./actions");
5
+ const resources_1 = require("./resources");
6
+ /**
7
+ * Operation in RESOURCE:ACTION format
8
+ */
9
+ class Operation {
10
+ resource;
11
+ action;
12
+ /**
13
+ * Create operation from string
14
+ * @param operationString - String in RESOURCE:ACTION format
15
+ * @returns Operation instance or null if invalid
16
+ */
17
+ static fromString(operationString) {
18
+ const parts = operationString.split(":");
19
+ if (parts.length !== 2) {
20
+ return null;
21
+ }
22
+ const [resourceStr, actionStr] = parts;
23
+ // Validate resource
24
+ if (!Object.values(resources_1.Resource).includes(resourceStr)) {
25
+ return null;
26
+ }
27
+ // Validate action
28
+ if (!Object.values(actions_1.Action).includes(actionStr)) {
29
+ return null;
30
+ }
31
+ return new Operation(resourceStr, actionStr);
32
+ }
33
+ constructor(resource, action) {
34
+ this.resource = resource;
35
+ this.action = action;
36
+ }
37
+ /**
38
+ * Get operation string in RESOURCE:ACTION format
39
+ */
40
+ toString() {
41
+ return `${this.resource}:${this.action}`;
42
+ }
43
+ /**
44
+ * Check if two operations are equal
45
+ */
46
+ equals(other) {
47
+ return this.resource === other.resource && this.action === other.action;
48
+ }
49
+ /**
50
+ * Convert to JSON representation
51
+ */
52
+ toJSON() {
53
+ return {
54
+ resource: this.resource,
55
+ action: this.action,
56
+ operation: this.toString(),
57
+ };
58
+ }
59
+ }
60
+ exports.Operation = Operation;
61
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlcmF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29wZXJhdGlvbnMvb3BlcmF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHVDQUFtQztBQUNuQywyQ0FBdUM7QUFFdkM7O0dBRUc7QUFDSCxNQUFhLFNBQVM7SUE0QkY7SUFDQTtJQTVCbEI7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxVQUFVLENBQUMsZUFBdUI7UUFDdkMsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdkIsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBRUQsTUFBTSxDQUFDLFdBQVcsRUFBRSxTQUFTLENBQUMsR0FBRyxLQUFLLENBQUM7UUFFdkMsb0JBQW9CO1FBQ3BCLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLG9CQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBdUIsQ0FBQyxFQUFFLENBQUM7WUFDL0QsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBRUQsa0JBQWtCO1FBQ2xCLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLGdCQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsU0FBbUIsQ0FBQyxFQUFFLENBQUM7WUFDekQsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBRUQsT0FBTyxJQUFJLFNBQVMsQ0FBQyxXQUF1QixFQUFFLFNBQW1CLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQsWUFDa0IsUUFBa0IsRUFDbEIsTUFBYztRQURkLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtJQUM3QixDQUFDO0lBRUo7O09BRUc7SUFDSCxRQUFRO1FBQ04sT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxLQUFnQjtRQUNyQixPQUFPLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSyxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDMUUsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTTtRQUNKLE9BQU87WUFDTCxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDdkIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLFNBQVMsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFO1NBQzNCLENBQUM7SUFDSixDQUFDO0NBQ0Y7QUF4REQsOEJBd0RDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWN0aW9uIH0gZnJvbSBcIi4vYWN0aW9uc1wiO1xuaW1wb3J0IHsgUmVzb3VyY2UgfSBmcm9tIFwiLi9yZXNvdXJjZXNcIjtcblxuLyoqXG4gKiBPcGVyYXRpb24gaW4gUkVTT1VSQ0U6QUNUSU9OIGZvcm1hdFxuICovXG5leHBvcnQgY2xhc3MgT3BlcmF0aW9uIHtcbiAgLyoqXG4gICAqIENyZWF0ZSBvcGVyYXRpb24gZnJvbSBzdHJpbmdcbiAgICogQHBhcmFtIG9wZXJhdGlvblN0cmluZyAtIFN0cmluZyBpbiBSRVNPVVJDRTpBQ1RJT04gZm9ybWF0XG4gICAqIEByZXR1cm5zIE9wZXJhdGlvbiBpbnN0YW5jZSBvciBudWxsIGlmIGludmFsaWRcbiAgICovXG4gIHN0YXRpYyBmcm9tU3RyaW5nKG9wZXJhdGlvblN0cmluZzogc3RyaW5nKTogT3BlcmF0aW9uIHwgbnVsbCB7XG4gICAgY29uc3QgcGFydHMgPSBvcGVyYXRpb25TdHJpbmcuc3BsaXQoXCI6XCIpO1xuICAgIGlmIChwYXJ0cy5sZW5ndGggIT09IDIpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IFtyZXNvdXJjZVN0ciwgYWN0aW9uU3RyXSA9IHBhcnRzO1xuXG4gICAgLy8gVmFsaWRhdGUgcmVzb3VyY2VcbiAgICBpZiAoIU9iamVjdC52YWx1ZXMoUmVzb3VyY2UpLmluY2x1ZGVzKHJlc291cmNlU3RyIGFzIFJlc291cmNlKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgYWN0aW9uXG4gICAgaWYgKCFPYmplY3QudmFsdWVzKEFjdGlvbikuaW5jbHVkZXMoYWN0aW9uU3RyIGFzIEFjdGlvbikpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgT3BlcmF0aW9uKHJlc291cmNlU3RyIGFzIFJlc291cmNlLCBhY3Rpb25TdHIgYXMgQWN0aW9uKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSByZXNvdXJjZTogUmVzb3VyY2UsXG4gICAgcHVibGljIHJlYWRvbmx5IGFjdGlvbjogQWN0aW9uLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIEdldCBvcGVyYXRpb24gc3RyaW5nIGluIFJFU09VUkNFOkFDVElPTiBmb3JtYXRcbiAgICovXG4gIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3RoaXMucmVzb3VyY2V9OiR7dGhpcy5hY3Rpb259YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0d28gb3BlcmF0aW9ucyBhcmUgZXF1YWxcbiAgICovXG4gIGVxdWFscyhvdGhlcjogT3BlcmF0aW9uKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2UgPT09IG90aGVyLnJlc291cmNlICYmIHRoaXMuYWN0aW9uID09PSBvdGhlci5hY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCB0byBKU09OIHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0b0pTT04oKTogeyByZXNvdXJjZTogUmVzb3VyY2U7IGFjdGlvbjogQWN0aW9uOyBvcGVyYXRpb246IHN0cmluZyB9IHtcbiAgICByZXR1cm4ge1xuICAgICAgcmVzb3VyY2U6IHRoaXMucmVzb3VyY2UsXG4gICAgICBhY3Rpb246IHRoaXMuYWN0aW9uLFxuICAgICAgb3BlcmF0aW9uOiB0aGlzLnRvU3RyaW5nKCksXG4gICAgfTtcbiAgfVxufVxuIl19