@discover-cloud/shared 1.0.11 → 1.2.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 (42) hide show
  1. package/dist/authorization/permission-cache.service.d.ts +14 -1
  2. package/dist/authorization/permission-cache.service.js +84 -16
  3. package/dist/authorization/permissions.d.ts +19 -15
  4. package/dist/authorization/permissions.js +24 -21
  5. package/dist/dtos/auth-service.dto.d.ts +13 -0
  6. package/dist/dtos/cloud-service.dto.d.ts +25 -10
  7. package/dist/dtos/insights-service.dto.d.ts +24 -8
  8. package/dist/dtos/response.dto.d.ts +80 -10
  9. package/dist/dtos/response.dto.js +23 -4
  10. package/dist/dtos/user-service.dto.d.ts +7 -0
  11. package/dist/enums/domain.enums.d.ts +45 -14
  12. package/dist/enums/domain.enums.js +40 -6
  13. package/dist/enums/permissions.enums.d.ts +12 -52
  14. package/dist/enums/permissions.enums.js +55 -59
  15. package/dist/errors/app-error.d.ts +17 -14
  16. package/dist/errors/app-error.js +19 -15
  17. package/dist/errors/http-errors.d.ts +12 -5
  18. package/dist/errors/http-errors.js +27 -5
  19. package/dist/http/service-client.d.ts +37 -12
  20. package/dist/http/service-client.js +43 -17
  21. package/dist/jwt/internal-jwt-verifier.d.ts +9 -3
  22. package/dist/jwt/internal-jwt-verifier.js +49 -26
  23. package/dist/middleware/authorize.middleware.d.ts +38 -6
  24. package/dist/middleware/authorize.middleware.js +62 -37
  25. package/dist/middleware/error-handler.middleware.d.ts +21 -7
  26. package/dist/middleware/error-handler.middleware.js +42 -14
  27. package/dist/middleware/request-id.middleware.d.ts +12 -10
  28. package/dist/middleware/request-id.middleware.js +15 -15
  29. package/dist/middleware/validate.middleware.d.ts +22 -13
  30. package/dist/middleware/validate.middleware.js +25 -16
  31. package/dist/middleware/validated-merge.middleware.js +1 -2
  32. package/dist/types/express.types.d.ts +37 -32
  33. package/dist/types/express.types.js +13 -11
  34. package/dist/utils/date.utils.d.ts +18 -4
  35. package/dist/utils/date.utils.js +18 -4
  36. package/dist/utils/env.d.ts +46 -0
  37. package/dist/utils/env.js +61 -0
  38. package/dist/utils/logger.utils.d.ts +31 -16
  39. package/dist/utils/logger.utils.js +55 -20
  40. package/dist/utils/response.utils.d.ts +47 -5
  41. package/dist/utils/response.utils.js +50 -7
  42. package/package.json +1 -1
@@ -1,6 +1,25 @@
1
1
  "use strict";
2
- /* ====================================================================
3
- RESPONSE DTOs
4
- Shared HTTP response shapes used across all services.
5
- ==================================================================== */
2
+ /**
3
+ * RESPONSE DTOs (@discover-cloud/shared)
4
+ * ─────────────────────────────────────────
5
+ * Shared HTTP response shapes used across all services.
6
+ * Every response — success or error — is wrapped in the ApiSuccessResponse
7
+ * or ApiErrorResponse envelope so clients have a consistent shape to key on.
8
+ *
9
+ * Envelope shape:
10
+ * {
11
+ * success: true,
12
+ * data: T,
13
+ * meta: { requestId, timestamp }
14
+ * }
15
+ * or
16
+ * {
17
+ * success: false,
18
+ * error: { code, message, details? },
19
+ * meta: { requestId, timestamp }
20
+ * }
21
+ *
22
+ * The success() and failure() utils in shared/utils construct these
23
+ * envelopes — don't build them manually in controllers.
24
+ */
6
25
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,4 +1,11 @@
1
1
  import { OrganizationRole, MembershipStatus, OrganizationStatus, Theme, Currency } from "../enums";
2
+ /**
3
+ * USER SERVICE DTOs (@discover-cloud/shared)
4
+ * ─────────────────────────────────────────────
5
+ * Shapes returned by the user service over HTTP.
6
+ * All timestamps are ISO 8601 strings — JSON has no Date type.
7
+ * Domain models use Date internally; mappers convert at the boundary.
8
+ */
2
9
  export interface UserDto {
3
10
  id: string;
4
11
  email: string;
@@ -1,8 +1,11 @@
1
1
  /**
2
- * DOMAIN STATUS & CONFIGURATION ENUMS
3
- * ──────────────────────────────────────
2
+ * DOMAIN STATUS & CONFIGURATION ENUMS (@discover-cloud/shared)
3
+ * ───────────────────────────────────────────────────────────────
4
4
  * General-purpose enums for entity lifecycle, UI preferences, and
5
- * configuration. Permission-related enums live in permissions.types.ts.
5
+ * cloud provider configuration.
6
+ *
7
+ * Permission-related enums (AccountRole, GlobalPermission, OrganizationRole,
8
+ * OrgPermission) live in permissions.enums.ts, not here.
6
9
  */
7
10
  export declare enum AccountStatus {
8
11
  ACTIVE = "ACTIVE",
@@ -40,17 +43,45 @@ export declare enum CloudProvider {
40
43
  GCP = "GCP",
41
44
  AZURE = "AZURE"
42
45
  }
46
+ /**
47
+ * AWS auth methods.
48
+ *
49
+ * ACCESS_KEY — Long-lived Access Key ID + Secret Access Key.
50
+ * Simplest to set up; least preferred for production.
51
+ * IAM_ROLE — Cross-account role assumption via Role ARN + External ID.
52
+ * Recommended for production AWS integrations.
53
+ * IAM_IDENTITY_CENTER — AWS SSO / IAM Identity Center (formerly AWS SSO).
54
+ * Used in organisations with centralised identity.
55
+ * IAM_ROLES_ANYWHERE — Certificate-based role assumption for non-AWS workloads.
56
+ */
43
57
  export declare enum AwsAuthMethod {
44
- ACCESS_KEY = "ACCESS_KEY",// Access Key ID + Secret
45
- IAM_ROLE = "IAM_ROLE",// Role ARN + External ID
46
- IAM_IDENTITY_CENTER = "IAM_IDENTITY_CENTER",// SSO
58
+ ACCESS_KEY = "ACCESS_KEY",
59
+ IAM_ROLE = "IAM_ROLE",
60
+ IAM_IDENTITY_CENTER = "IAM_IDENTITY_CENTER",
47
61
  IAM_ROLES_ANYWHERE = "IAM_ROLES_ANYWHERE"
48
62
  }
63
+ /**
64
+ * GCP auth methods.
65
+ *
66
+ * SERVICE_ACCOUNT_KEY — JSON key file for a GCP service account.
67
+ * Simpler but requires secure key storage.
68
+ * WORKLOAD_IDENTITY — Keyless auth using Workload Identity Federation.
69
+ * Preferred for production.
70
+ * SERVICE_ACCOUNT_IMPERSONATION — Short-lived tokens via service account impersonation.
71
+ */
49
72
  export declare enum GcpAuthMethod {
50
73
  SERVICE_ACCOUNT_KEY = "SERVICE_ACCOUNT_KEY",
51
74
  WORKLOAD_IDENTITY = "WORKLOAD_IDENTITY",
52
75
  SERVICE_ACCOUNT_IMPERSONATION = "SERVICE_ACCOUNT_IMPERSONATION"
53
76
  }
77
+ /**
78
+ * Azure auth methods.
79
+ *
80
+ * SERVICE_PRINCIPAL_SECRET — Client ID + Client Secret for an app registration.
81
+ * SERVICE_PRINCIPAL_CERTIFICATE — Client ID + certificate (more secure than secret).
82
+ * MANAGED_IDENTITY_USER — User-assigned managed identity.
83
+ * MANAGED_IDENTITY_SYSTEM — System-assigned managed identity (tied to the resource).
84
+ */
54
85
  export declare enum AzureAuthMethod {
55
86
  SERVICE_PRINCIPAL_SECRET = "SERVICE_PRINCIPAL_SECRET",
56
87
  SERVICE_PRINCIPAL_CERTIFICATE = "SERVICE_PRINCIPAL_CERTIFICATE",
@@ -58,20 +89,20 @@ export declare enum AzureAuthMethod {
58
89
  MANAGED_IDENTITY_SYSTEM = "MANAGED_IDENTITY_SYSTEM"
59
90
  }
60
91
  export declare enum CloudAccountStatus {
61
- PENDING = "PENDING",// Connected, never synced
62
- ACTIVE = "ACTIVE",// Last sync succeeded
63
- ERROR = "ERROR",// Last sync failed
92
+ PENDING = "PENDING",// Connected but never successfully synced
93
+ ACTIVE = "ACTIVE",// Last sync completed successfully
94
+ ERROR = "ERROR",// Last sync failed — check lastErrorMsg
64
95
  INACTIVE = "INACTIVE"
65
96
  }
66
97
  export declare enum SyncStatus {
67
- PENDING = "PENDING",
68
- RUNNING = "RUNNING",
69
- SUCCESS = "SUCCESS",
70
- FAILED = "FAILED",
98
+ PENDING = "PENDING",// Queued, not yet picked up by the scheduler
99
+ RUNNING = "RUNNING",// Currently in progress
100
+ SUCCESS = "SUCCESS",// All fetches completed without error
101
+ FAILED = "FAILED",// All fetches failed; no data was written
71
102
  PARTIAL = "PARTIAL"
72
103
  }
73
104
  export declare enum SyncType {
74
- FULL = "FULL",// All data types
105
+ FULL = "FULL",// All data types in one job
75
106
  COSTS = "COSTS",// Cost records only
76
107
  RESOURCES = "RESOURCES",// Resource inventory only
77
108
  BUDGETS = "BUDGETS"
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
2
  /**
3
- * DOMAIN STATUS & CONFIGURATION ENUMS
4
- * ──────────────────────────────────────
3
+ * DOMAIN STATUS & CONFIGURATION ENUMS (@discover-cloud/shared)
4
+ * ───────────────────────────────────────────────────────────────
5
5
  * General-purpose enums for entity lifecycle, UI preferences, and
6
- * configuration. Permission-related enums live in permissions.types.ts.
6
+ * cloud provider configuration.
7
+ *
8
+ * Permission-related enums (AccountRole, GlobalPermission, OrganizationRole,
9
+ * OrgPermission) live in permissions.enums.ts, not here.
7
10
  */
8
11
  Object.defineProperty(exports, "__esModule", { value: true });
9
12
  exports.SyncType = exports.SyncStatus = exports.CloudAccountStatus = exports.AzureAuthMethod = exports.GcpAuthMethod = exports.AwsAuthMethod = exports.CloudProvider = exports.Currency = exports.Theme = exports.MembershipStatus = exports.OrganizationStatus = exports.AccountStatus = void 0;
@@ -54,8 +57,8 @@ var Currency;
54
57
  })(Currency || (exports.Currency = Currency = {}));
55
58
  /* ====================================================================
56
59
  CLOUD PROVIDERS
57
- Used by cloud-service for account connections and insights-service
58
- for storing normalized cost/resource data.
60
+ Used by cloud-service for account connections, and by insights-service
61
+ for normalising cost/resource data across providers.
59
62
  ==================================================================== */
60
63
  var CloudProvider;
61
64
  (function (CloudProvider) {
@@ -66,8 +69,20 @@ var CloudProvider;
66
69
  /* ====================================================================
67
70
  CLOUD ACCOUNT AUTH METHODS
68
71
  Discriminator for which credential shape is stored per provider.
69
- Each provider has its own enum — only one is set per CloudAccount.
72
+ Each provider has its own enum — exactly one is set per CloudAccount
73
+ and determines how the credential cipher stores + retrieves secrets.
70
74
  ==================================================================== */
75
+ /**
76
+ * AWS auth methods.
77
+ *
78
+ * ACCESS_KEY — Long-lived Access Key ID + Secret Access Key.
79
+ * Simplest to set up; least preferred for production.
80
+ * IAM_ROLE — Cross-account role assumption via Role ARN + External ID.
81
+ * Recommended for production AWS integrations.
82
+ * IAM_IDENTITY_CENTER — AWS SSO / IAM Identity Center (formerly AWS SSO).
83
+ * Used in organisations with centralised identity.
84
+ * IAM_ROLES_ANYWHERE — Certificate-based role assumption for non-AWS workloads.
85
+ */
71
86
  var AwsAuthMethod;
72
87
  (function (AwsAuthMethod) {
73
88
  AwsAuthMethod["ACCESS_KEY"] = "ACCESS_KEY";
@@ -75,12 +90,29 @@ var AwsAuthMethod;
75
90
  AwsAuthMethod["IAM_IDENTITY_CENTER"] = "IAM_IDENTITY_CENTER";
76
91
  AwsAuthMethod["IAM_ROLES_ANYWHERE"] = "IAM_ROLES_ANYWHERE";
77
92
  })(AwsAuthMethod || (exports.AwsAuthMethod = AwsAuthMethod = {}));
93
+ /**
94
+ * GCP auth methods.
95
+ *
96
+ * SERVICE_ACCOUNT_KEY — JSON key file for a GCP service account.
97
+ * Simpler but requires secure key storage.
98
+ * WORKLOAD_IDENTITY — Keyless auth using Workload Identity Federation.
99
+ * Preferred for production.
100
+ * SERVICE_ACCOUNT_IMPERSONATION — Short-lived tokens via service account impersonation.
101
+ */
78
102
  var GcpAuthMethod;
79
103
  (function (GcpAuthMethod) {
80
104
  GcpAuthMethod["SERVICE_ACCOUNT_KEY"] = "SERVICE_ACCOUNT_KEY";
81
105
  GcpAuthMethod["WORKLOAD_IDENTITY"] = "WORKLOAD_IDENTITY";
82
106
  GcpAuthMethod["SERVICE_ACCOUNT_IMPERSONATION"] = "SERVICE_ACCOUNT_IMPERSONATION";
83
107
  })(GcpAuthMethod || (exports.GcpAuthMethod = GcpAuthMethod = {}));
108
+ /**
109
+ * Azure auth methods.
110
+ *
111
+ * SERVICE_PRINCIPAL_SECRET — Client ID + Client Secret for an app registration.
112
+ * SERVICE_PRINCIPAL_CERTIFICATE — Client ID + certificate (more secure than secret).
113
+ * MANAGED_IDENTITY_USER — User-assigned managed identity.
114
+ * MANAGED_IDENTITY_SYSTEM — System-assigned managed identity (tied to the resource).
115
+ */
84
116
  var AzureAuthMethod;
85
117
  (function (AzureAuthMethod) {
86
118
  AzureAuthMethod["SERVICE_PRINCIPAL_SECRET"] = "SERVICE_PRINCIPAL_SECRET";
@@ -90,6 +122,7 @@ var AzureAuthMethod;
90
122
  })(AzureAuthMethod || (exports.AzureAuthMethod = AzureAuthMethod = {}));
91
123
  /* ====================================================================
92
124
  CLOUD ACCOUNT STATUS
125
+ Lifecycle state of a connected cloud account.
93
126
  ==================================================================== */
94
127
  var CloudAccountStatus;
95
128
  (function (CloudAccountStatus) {
@@ -100,6 +133,7 @@ var CloudAccountStatus;
100
133
  })(CloudAccountStatus || (exports.CloudAccountStatus = CloudAccountStatus = {}));
101
134
  /* ====================================================================
102
135
  SYNC JOB
136
+ Tracks the lifecycle and scope of a single sync run.
103
137
  ==================================================================== */
104
138
  var SyncStatus;
105
139
  (function (SyncStatus) {
@@ -1,9 +1,17 @@
1
1
  /**
2
- * ACCOUNT ROLES
3
- * ──────────────
4
- * Platform-level roles assigned to every account.
5
- * Ordered from highest to lowest privilege.
2
+ * PERMISSION ENUMS (@discover-cloud/shared)
3
+ * ────────────────────────────────────────────
4
+ * Platform-level roles and permissions. These are the single source of
5
+ * truth for the entire permission system — the Redis permission cache,
6
+ * JWT payloads, and route guards all derive from these definitions.
6
7
  *
8
+ * File layout:
9
+ * AccountRole — platform-level account roles (highest → lowest privilege)
10
+ * GlobalPermission — platform-wide permissions derived from AccountRole
11
+ * OrganizationRole — per-org roles (future)
12
+ * OrgPermission — per-org permissions checked by tenant middleware (future)
13
+ */
14
+ /**
7
15
  * SUPERADMIN — Full platform control. Internal engineering / founders only.
8
16
  * Can impersonate users, access all data, manage platform config.
9
17
  *
@@ -26,40 +34,6 @@ export declare enum AccountRole {
26
34
  MODERATOR = "MODERATOR",
27
35
  USER = "USER"
28
36
  }
29
- /**
30
- * GLOBAL PERMISSIONS
31
- * ───────────────────
32
- * Platform-wide permissions derived from AccountRole.
33
- * These are checked at the gateway / service middleware level.
34
- *
35
- * Naming convention: VERB_NOUN or VERB_SCOPE_NOUN
36
- *
37
- * Account management
38
- * MANAGE_ACCOUNTS — Create, update, suspend, delete any account
39
- * VIEW_ANY_ACCOUNT — Read any account's profile and metadata
40
- * IMPERSONATE_ACCOUNT — Act as another user (SUPERADMIN only — support tooling)
41
- * SUSPEND_ACCOUNT — Suspend / unsuspend an account without full delete
42
- * DELETE_ACCOUNT — Hard delete an account and all associated data
43
- *
44
- * Cloud cost data (platform-level, not per-org)
45
- * VIEW_ANY_COST_DATA — Read any user's cloud cost reports (support/admin use)
46
- * EXPORT_ANY_COST_DATA — Export cost data for any user (compliance, support)
47
- * MANAGE_COST_ALERTS — Create/edit/delete cost alert rules platform-wide
48
- *
49
- * Platform operations
50
- * VIEW_SYSTEM_LOGS — Access platform audit logs and system events
51
- * VIEW_SYSTEM_HEALTH — Read service health, metrics dashboards
52
- * MANAGE_PLATFORM_CONFIG — Modify platform-wide settings (limits, features)
53
- *
54
- * Support tooling
55
- * SUPPORT_VIEW — Read-only access to user data for support purposes
56
- * SUPPORT_WRITE — Ability to make support-sanctioned changes on behalf of users
57
- *
58
- * Future-proofing (define now, assign later)
59
- * MANAGE_BILLING — Access to subscription and billing management
60
- * MODERATE_CONTENT — Moderate user-generated content (alerts, comments, etc.)
61
- * MANAGE_INTEGRATIONS — Manage platform-level cloud provider integrations
62
- */
63
37
  export declare enum GlobalPermission {
64
38
  MANAGE_ACCOUNTS = "MANAGE_ACCOUNTS",
65
39
  VIEW_ANY_ACCOUNT = "VIEW_ANY_ACCOUNT",
@@ -79,11 +53,6 @@ export declare enum GlobalPermission {
79
53
  MANAGE_INTEGRATIONS = "MANAGE_INTEGRATIONS"
80
54
  }
81
55
  /**
82
- * ORGANIZATION ROLES (future work)
83
- * ────────────────────────────────────
84
- * Defined now so the type system is ready when org support ships.
85
- * No permissions are assigned yet — see orgRolePermissions below.
86
- *
87
56
  * OWNER — Created the org. Full control, including deletion and billing.
88
57
  * ADMIN — Manages members and org settings. Cannot delete the org.
89
58
  * EDITOR — Can create/edit cost reports and dashboards within the org.
@@ -97,15 +66,6 @@ export declare enum OrganizationRole {
97
66
  VIEWER = "VIEWER",
98
67
  BILLING = "BILLING"
99
68
  }
100
- /**
101
- * ORG PERMISSIONS (future work)
102
- * ────────────────────────────────
103
- * Granular org-scoped permissions. Checked by tenant middleware in each
104
- * service via DB lookup — NOT in the JWT (org membership changes too
105
- * frequently to embed reliably).
106
- *
107
- * Naming: VERB_RESOURCE
108
- */
109
69
  export declare enum OrgPermission {
110
70
  DELETE_ORG = "DELETE_ORG",
111
71
  MANAGE_ORG_SETTINGS = "MANAGE_ORG_SETTINGS",
@@ -1,12 +1,24 @@
1
1
  "use strict";
2
+ /**
3
+ * PERMISSION ENUMS (@discover-cloud/shared)
4
+ * ────────────────────────────────────────────
5
+ * Platform-level roles and permissions. These are the single source of
6
+ * truth for the entire permission system — the Redis permission cache,
7
+ * JWT payloads, and route guards all derive from these definitions.
8
+ *
9
+ * File layout:
10
+ * AccountRole — platform-level account roles (highest → lowest privilege)
11
+ * GlobalPermission — platform-wide permissions derived from AccountRole
12
+ * OrganizationRole — per-org roles (future)
13
+ * OrgPermission — per-org permissions checked by tenant middleware (future)
14
+ */
2
15
  Object.defineProperty(exports, "__esModule", { value: true });
3
16
  exports.OrgPermission = exports.OrganizationRole = exports.GlobalPermission = exports.AccountRole = void 0;
17
+ /* ====================================================================
18
+ ACCOUNT ROLES
19
+ Ordered from highest to lowest privilege.
20
+ ==================================================================== */
4
21
  /**
5
- * ACCOUNT ROLES
6
- * ──────────────
7
- * Platform-level roles assigned to every account.
8
- * Ordered from highest to lowest privilege.
9
- *
10
22
  * SUPERADMIN — Full platform control. Internal engineering / founders only.
11
23
  * Can impersonate users, access all data, manage platform config.
12
24
  *
@@ -30,70 +42,55 @@ var AccountRole;
30
42
  AccountRole["MODERATOR"] = "MODERATOR";
31
43
  AccountRole["USER"] = "USER";
32
44
  })(AccountRole || (exports.AccountRole = AccountRole = {}));
33
- /**
34
- * GLOBAL PERMISSIONS
35
- * ───────────────────
36
- * Platform-wide permissions derived from AccountRole.
37
- * These are checked at the gateway / service middleware level.
38
- *
39
- * Naming convention: VERB_NOUN or VERB_SCOPE_NOUN
40
- *
41
- * Account management
42
- * MANAGE_ACCOUNTS — Create, update, suspend, delete any account
43
- * VIEW_ANY_ACCOUNT — Read any account's profile and metadata
44
- * IMPERSONATE_ACCOUNT — Act as another user (SUPERADMIN only — support tooling)
45
- * SUSPEND_ACCOUNT — Suspend / unsuspend an account without full delete
46
- * DELETE_ACCOUNT — Hard delete an account and all associated data
47
- *
48
- * Cloud cost data (platform-level, not per-org)
49
- * VIEW_ANY_COST_DATA — Read any user's cloud cost reports (support/admin use)
50
- * EXPORT_ANY_COST_DATA — Export cost data for any user (compliance, support)
51
- * MANAGE_COST_ALERTS — Create/edit/delete cost alert rules platform-wide
52
- *
53
- * Platform operations
54
- * VIEW_SYSTEM_LOGS — Access platform audit logs and system events
55
- * VIEW_SYSTEM_HEALTH — Read service health, metrics dashboards
56
- * MANAGE_PLATFORM_CONFIG — Modify platform-wide settings (limits, features)
57
- *
58
- * Support tooling
59
- * SUPPORT_VIEW — Read-only access to user data for support purposes
60
- * SUPPORT_WRITE — Ability to make support-sanctioned changes on behalf of users
61
- *
62
- * Future-proofing (define now, assign later)
63
- * MANAGE_BILLING — Access to subscription and billing management
64
- * MODERATE_CONTENT — Moderate user-generated content (alerts, comments, etc.)
65
- * MANAGE_INTEGRATIONS — Manage platform-level cloud provider integrations
66
- */
45
+ /* ====================================================================
46
+ GLOBAL PERMISSIONS
47
+ Platform-wide permissions derived from AccountRole.
48
+ Checked at the gateway / service middleware level via Redis cache.
49
+
50
+ Naming convention: VERB_NOUN or VERB_SCOPE_NOUN
51
+ ==================================================================== */
67
52
  var GlobalPermission;
68
53
  (function (GlobalPermission) {
69
- // Account management
54
+ // ── Account management ────────────────────────────────────────────
55
+ // MANAGE_ACCOUNTS — Create, update, suspend, delete any account
56
+ // VIEW_ANY_ACCOUNT — Read any account's profile and metadata
57
+ // IMPERSONATE_ACCOUNT — Act as another user (SUPERADMIN only)
58
+ // SUSPEND_ACCOUNT — Suspend / unsuspend without full delete
59
+ // DELETE_ACCOUNT — Hard delete an account and all associated data
70
60
  GlobalPermission["MANAGE_ACCOUNTS"] = "MANAGE_ACCOUNTS";
71
61
  GlobalPermission["VIEW_ANY_ACCOUNT"] = "VIEW_ANY_ACCOUNT";
72
62
  GlobalPermission["IMPERSONATE_ACCOUNT"] = "IMPERSONATE_ACCOUNT";
73
63
  GlobalPermission["SUSPEND_ACCOUNT"] = "SUSPEND_ACCOUNT";
74
64
  GlobalPermission["DELETE_ACCOUNT"] = "DELETE_ACCOUNT";
75
- // Cloud cost data (platform-level)
65
+ // ── Cloud cost data (platform-level, not per-org) ─────────────────
66
+ // VIEW_ANY_COST_DATA — Read any user's cloud cost reports
67
+ // EXPORT_ANY_COST_DATA — Export cost data for any user (compliance)
68
+ // MANAGE_COST_ALERTS — Create/edit/delete alert rules platform-wide
76
69
  GlobalPermission["VIEW_ANY_COST_DATA"] = "VIEW_ANY_COST_DATA";
77
70
  GlobalPermission["EXPORT_ANY_COST_DATA"] = "EXPORT_ANY_COST_DATA";
78
71
  GlobalPermission["MANAGE_COST_ALERTS"] = "MANAGE_COST_ALERTS";
79
- // Platform operations
72
+ // ── Platform operations ───────────────────────────────────────────
73
+ // VIEW_SYSTEM_LOGS — Access platform audit logs and system events
74
+ // VIEW_SYSTEM_HEALTH — Read service health and metrics dashboards
75
+ // MANAGE_PLATFORM_CONFIG — Modify platform-wide settings (limits, features)
80
76
  GlobalPermission["VIEW_SYSTEM_LOGS"] = "VIEW_SYSTEM_LOGS";
81
77
  GlobalPermission["VIEW_SYSTEM_HEALTH"] = "VIEW_SYSTEM_HEALTH";
82
78
  GlobalPermission["MANAGE_PLATFORM_CONFIG"] = "MANAGE_PLATFORM_CONFIG";
83
- // Support tooling
79
+ // ── Support tooling ───────────────────────────────────────────────
80
+ // SUPPORT_VIEW — Read-only access to user data for support purposes
81
+ // SUPPORT_WRITE — Support-sanctioned changes on behalf of users
84
82
  GlobalPermission["SUPPORT_VIEW"] = "SUPPORT_VIEW";
85
83
  GlobalPermission["SUPPORT_WRITE"] = "SUPPORT_WRITE";
86
- // Future — define now so they exist in the type system before the features ship
84
+ // ── Future — defined now so they exist in the type system ─────────
87
85
  GlobalPermission["MANAGE_BILLING"] = "MANAGE_BILLING";
88
86
  GlobalPermission["MODERATE_CONTENT"] = "MODERATE_CONTENT";
89
87
  GlobalPermission["MANAGE_INTEGRATIONS"] = "MANAGE_INTEGRATIONS";
90
88
  })(GlobalPermission || (exports.GlobalPermission = GlobalPermission = {}));
89
+ /* ====================================================================
90
+ ORGANIZATION ROLES (future work)
91
+ Defined now so the type system is ready when org support ships.
92
+ ==================================================================== */
91
93
  /**
92
- * ORGANIZATION ROLES (future work)
93
- * ────────────────────────────────────
94
- * Defined now so the type system is ready when org support ships.
95
- * No permissions are assigned yet — see orgRolePermissions below.
96
- *
97
94
  * OWNER — Created the org. Full control, including deletion and billing.
98
95
  * ADMIN — Manages members and org settings. Cannot delete the org.
99
96
  * EDITOR — Can create/edit cost reports and dashboards within the org.
@@ -108,15 +105,14 @@ var OrganizationRole;
108
105
  OrganizationRole["VIEWER"] = "VIEWER";
109
106
  OrganizationRole["BILLING"] = "BILLING";
110
107
  })(OrganizationRole || (exports.OrganizationRole = OrganizationRole = {}));
111
- /**
112
- * ORG PERMISSIONS (future work)
113
- * ────────────────────────────────
114
- * Granular org-scoped permissions. Checked by tenant middleware in each
115
- * service via DB lookup — NOT in the JWT (org membership changes too
116
- * frequently to embed reliably).
117
- *
118
- * Naming: VERB_RESOURCE
119
- */
108
+ /* ====================================================================
109
+ ORG PERMISSIONS (future work)
110
+ Granular org-scoped permissions checked by tenant middleware in each
111
+ service via DB lookup NOT embedded in the JWT (org membership changes
112
+ too frequently to embed reliably).
113
+
114
+ Naming: VERB_RESOURCE
115
+ ==================================================================== */
120
116
  var OrgPermission;
121
117
  (function (OrgPermission) {
122
118
  // Org management
@@ -132,7 +128,7 @@ var OrgPermission;
132
128
  OrgPermission["EXPORT_COST_DATA"] = "EXPORT_COST_DATA";
133
129
  OrgPermission["MANAGE_COST_REPORTS"] = "MANAGE_COST_REPORTS";
134
130
  OrgPermission["MANAGE_ALERTS"] = "MANAGE_ALERTS";
135
- // Integrations within org
131
+ // Cloud account integrations within org
136
132
  OrgPermission["MANAGE_CLOUD_ACCOUNTS"] = "MANAGE_CLOUD_ACCOUNTS";
137
133
  OrgPermission["VIEW_CLOUD_ACCOUNTS"] = "VIEW_CLOUD_ACCOUNTS";
138
134
  // Billing within org
@@ -1,19 +1,22 @@
1
1
  /**
2
- * APP ERROR
3
- * ──────────
4
- * Base class for all known operational errors.
5
- * Subclasses map to specific HTTP status codes and error codes.
2
+ * APP ERROR (@discover-cloud/shared)
3
+ * ─────────────────────────────────────
4
+ * Base class for all known operational errors across every service.
5
+ * Subclasses (see http-errors.ts) map to specific HTTP status codes and
6
+ * error codes that the global error handler serialises into responses.
6
7
  *
7
- * GlobalErrorHandler catches instanceof AppError and maps it to a
8
- * structured error response — no duck-typing, no accidental matches.
9
- *
10
- * Changes vs original:
11
- * - details?: any details?: unknown
12
- * `any` disabled TypeScript's type checking on the most variable field.
13
- * Callers that need a specific details shape should cast after instanceof.
14
- * - Object.freeze(this) retained prevents accidental mutation of thrown errors.
15
- * Note: freeze is shallow. If details is an object, its contents are mutable.
16
- * This is acceptable — details is for logging/response context, not program logic.
8
+ * Design decisions:
9
+ * - GlobalErrorHandler catches `instanceof AppError` — no duck-typing,
10
+ * no accidental matches on arbitrary thrown objects.
11
+ * - details?: unknown (not any) — TypeScript's type checking is preserved
12
+ * on the most variable field. Callers that need a specific details shape
13
+ * should cast after an instanceof guard.
14
+ * - Object.freeze(this) prevents accidental post-construction mutation of
15
+ * a thrown error. Freeze is shallow: if details is an object, its contents
16
+ * remain mutable. This is acceptable details is for logging/response
17
+ * context, not program logic.
18
+ * - captureStackTrace — strips the AppError constructor frame from the stack
19
+ * so the trace points to the throw site, not the base class constructor.
17
20
  */
18
21
  export declare class AppError extends Error {
19
22
  readonly code: string;
@@ -2,21 +2,24 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AppError = void 0;
4
4
  /**
5
- * APP ERROR
6
- * ──────────
7
- * Base class for all known operational errors.
8
- * Subclasses map to specific HTTP status codes and error codes.
5
+ * APP ERROR (@discover-cloud/shared)
6
+ * ─────────────────────────────────────
7
+ * Base class for all known operational errors across every service.
8
+ * Subclasses (see http-errors.ts) map to specific HTTP status codes and
9
+ * error codes that the global error handler serialises into responses.
9
10
  *
10
- * GlobalErrorHandler catches instanceof AppError and maps it to a
11
- * structured error response — no duck-typing, no accidental matches.
12
- *
13
- * Changes vs original:
14
- * - details?: any details?: unknown
15
- * `any` disabled TypeScript's type checking on the most variable field.
16
- * Callers that need a specific details shape should cast after instanceof.
17
- * - Object.freeze(this) retained prevents accidental mutation of thrown errors.
18
- * Note: freeze is shallow. If details is an object, its contents are mutable.
19
- * This is acceptable — details is for logging/response context, not program logic.
11
+ * Design decisions:
12
+ * - GlobalErrorHandler catches `instanceof AppError` — no duck-typing,
13
+ * no accidental matches on arbitrary thrown objects.
14
+ * - details?: unknown (not any) — TypeScript's type checking is preserved
15
+ * on the most variable field. Callers that need a specific details shape
16
+ * should cast after an instanceof guard.
17
+ * - Object.freeze(this) prevents accidental post-construction mutation of
18
+ * a thrown error. Freeze is shallow: if details is an object, its contents
19
+ * remain mutable. This is acceptable details is for logging/response
20
+ * context, not program logic.
21
+ * - captureStackTrace — strips the AppError constructor frame from the stack
22
+ * so the trace points to the throw site, not the base class constructor.
20
23
  */
21
24
  class AppError extends Error {
22
25
  constructor(code, statusCode, message, details) {
@@ -24,7 +27,8 @@ class AppError extends Error {
24
27
  this.code = code;
25
28
  this.statusCode = statusCode;
26
29
  this.details = details;
27
- this.name = this.constructor.name;
30
+ this.name = this.constructor.name; // "NotFoundError", "ConflictError", etc.
31
+ // Available in V8 (Node.js / Chrome) — no-ops gracefully in other engines.
28
32
  if (typeof Error.captureStackTrace === "function") {
29
33
  Error.captureStackTrace(this, this.constructor);
30
34
  }
@@ -1,15 +1,22 @@
1
1
  import { AppError } from "./app-error";
2
2
  /**
3
- * HTTP ERRORS
4
- * ────────────
3
+ * HTTP ERRORS (@discover-cloud/shared)
4
+ * ───────────────────────────────────────
5
5
  * Typed subclasses of AppError for every common HTTP error status.
6
- * GlobalErrorHandler catches these via instanceof AppError and maps
7
- * statusCode + code directly to the response.
6
+ *
7
+ * GlobalErrorHandler catches these via `instanceof AppError` and maps
8
+ * statusCode + code directly to the response — no additional switch/if needed.
8
9
  *
9
10
  * Usage:
10
11
  * throw new NotFoundError("Account not found");
11
12
  * throw new ConflictError("Email already in use");
12
- * throw new BadRequestError("Invalid input", { field: "email" });
13
+ * throw new BadRequestError("Validation failed", { field: "email" });
14
+ *
15
+ * Adding a new error type:
16
+ * 1. Add a subclass here following the existing pattern.
17
+ * 2. Pick the correct HTTP status code.
18
+ * 3. Choose a SCREAMING_SNAKE_CASE code that is stable across versions
19
+ * (clients may key on it for error handling).
13
20
  */
14
21
  export declare class BadRequestError extends AppError {
15
22
  constructor(message?: string, details?: unknown);