@pax8-cta/core 0.1.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 (226) hide show
  1. package/LICENSE +198 -0
  2. package/dist/auth/device-code-login.d.ts +40 -0
  3. package/dist/auth/device-code-login.d.ts.map +1 -0
  4. package/dist/auth/device-code-login.js +59 -0
  5. package/dist/auth/device-code-login.js.map +1 -0
  6. package/dist/auth/gdap-client.d.ts +81 -0
  7. package/dist/auth/gdap-client.d.ts.map +1 -0
  8. package/dist/auth/gdap-client.js +128 -0
  9. package/dist/auth/gdap-client.js.map +1 -0
  10. package/dist/auth/index.d.ts +19 -0
  11. package/dist/auth/index.d.ts.map +1 -0
  12. package/dist/auth/index.js +19 -0
  13. package/dist/auth/index.js.map +1 -0
  14. package/dist/auth/token-manager.d.ts +54 -0
  15. package/dist/auth/token-manager.d.ts.map +1 -0
  16. package/dist/auth/token-manager.js +150 -0
  17. package/dist/auth/token-manager.js.map +1 -0
  18. package/dist/client.d.ts +27 -0
  19. package/dist/client.d.ts.map +1 -0
  20. package/dist/client.js +27 -0
  21. package/dist/client.js.map +1 -0
  22. package/dist/config/client.d.ts +24 -0
  23. package/dist/config/client.d.ts.map +1 -0
  24. package/dist/config/client.js +18 -0
  25. package/dist/config/client.js.map +1 -0
  26. package/dist/config/index.d.ts +18 -0
  27. package/dist/config/index.d.ts.map +1 -0
  28. package/dist/config/index.js +18 -0
  29. package/dist/config/index.js.map +1 -0
  30. package/dist/config/loader.d.ts +81 -0
  31. package/dist/config/loader.d.ts.map +1 -0
  32. package/dist/config/loader.js +271 -0
  33. package/dist/config/loader.js.map +1 -0
  34. package/dist/config/schema.d.ts +751 -0
  35. package/dist/config/schema.d.ts.map +1 -0
  36. package/dist/config/schema.js +556 -0
  37. package/dist/config/schema.js.map +1 -0
  38. package/dist/constants.d.ts +116 -0
  39. package/dist/constants.d.ts.map +1 -0
  40. package/dist/constants.js +170 -0
  41. package/dist/constants.js.map +1 -0
  42. package/dist/dataverse/agent-resolver.d.ts +98 -0
  43. package/dist/dataverse/agent-resolver.d.ts.map +1 -0
  44. package/dist/dataverse/agent-resolver.js +185 -0
  45. package/dist/dataverse/agent-resolver.js.map +1 -0
  46. package/dist/dataverse/client.d.ts +104 -0
  47. package/dist/dataverse/client.d.ts.map +1 -0
  48. package/dist/dataverse/client.js +272 -0
  49. package/dist/dataverse/client.js.map +1 -0
  50. package/dist/dataverse/connection-refs.d.ts +115 -0
  51. package/dist/dataverse/connection-refs.d.ts.map +1 -0
  52. package/dist/dataverse/connection-refs.js +203 -0
  53. package/dist/dataverse/connection-refs.js.map +1 -0
  54. package/dist/dataverse/index.d.ts +20 -0
  55. package/dist/dataverse/index.d.ts.map +1 -0
  56. package/dist/dataverse/index.js +20 -0
  57. package/dist/dataverse/index.js.map +1 -0
  58. package/dist/dataverse/solution-ops.d.ts +100 -0
  59. package/dist/dataverse/solution-ops.d.ts.map +1 -0
  60. package/dist/dataverse/solution-ops.js +288 -0
  61. package/dist/dataverse/solution-ops.js.map +1 -0
  62. package/dist/errors.d.ts +171 -0
  63. package/dist/errors.d.ts.map +1 -0
  64. package/dist/errors.js +178 -0
  65. package/dist/errors.js.map +1 -0
  66. package/dist/index.d.ts +27 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +40 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/mock/demo-data.d.ts +213 -0
  71. package/dist/mock/demo-data.d.ts.map +1 -0
  72. package/dist/mock/demo-data.js +1096 -0
  73. package/dist/mock/demo-data.js.map +1 -0
  74. package/dist/mock/demo-deployment-store.d.ts +77 -0
  75. package/dist/mock/demo-deployment-store.d.ts.map +1 -0
  76. package/dist/mock/demo-deployment-store.js +85 -0
  77. package/dist/mock/demo-deployment-store.js.map +1 -0
  78. package/dist/powerplatform/admin-client.d.ts +226 -0
  79. package/dist/powerplatform/admin-client.d.ts.map +1 -0
  80. package/dist/powerplatform/admin-client.js +315 -0
  81. package/dist/powerplatform/admin-client.js.map +1 -0
  82. package/dist/powerplatform/index.d.ts +18 -0
  83. package/dist/powerplatform/index.d.ts.map +1 -0
  84. package/dist/powerplatform/index.js +18 -0
  85. package/dist/powerplatform/index.js.map +1 -0
  86. package/dist/powerplatform/tenant-discovery.d.ts +100 -0
  87. package/dist/powerplatform/tenant-discovery.d.ts.map +1 -0
  88. package/dist/powerplatform/tenant-discovery.js +205 -0
  89. package/dist/powerplatform/tenant-discovery.js.map +1 -0
  90. package/dist/preconditions/check.d.ts +41 -0
  91. package/dist/preconditions/check.d.ts.map +1 -0
  92. package/dist/preconditions/check.js +173 -0
  93. package/dist/preconditions/check.js.map +1 -0
  94. package/dist/preconditions/index.d.ts +20 -0
  95. package/dist/preconditions/index.d.ts.map +1 -0
  96. package/dist/preconditions/index.js +20 -0
  97. package/dist/preconditions/index.js.map +1 -0
  98. package/dist/preconditions/loader.d.ts +33 -0
  99. package/dist/preconditions/loader.d.ts.map +1 -0
  100. package/dist/preconditions/loader.js +65 -0
  101. package/dist/preconditions/loader.js.map +1 -0
  102. package/dist/preconditions/schema.d.ts +103 -0
  103. package/dist/preconditions/schema.d.ts.map +1 -0
  104. package/dist/preconditions/schema.js +93 -0
  105. package/dist/preconditions/schema.js.map +1 -0
  106. package/dist/preconditions/types.d.ts +118 -0
  107. package/dist/preconditions/types.d.ts.map +1 -0
  108. package/dist/preconditions/types.js +17 -0
  109. package/dist/preconditions/types.js.map +1 -0
  110. package/dist/queue/index.d.ts +17 -0
  111. package/dist/queue/index.d.ts.map +1 -0
  112. package/dist/queue/index.js +17 -0
  113. package/dist/queue/index.js.map +1 -0
  114. package/dist/queue/memory-queue.d.ts +86 -0
  115. package/dist/queue/memory-queue.d.ts.map +1 -0
  116. package/dist/queue/memory-queue.js +221 -0
  117. package/dist/queue/memory-queue.js.map +1 -0
  118. package/dist/services/audit-log.d.ts +59 -0
  119. package/dist/services/audit-log.d.ts.map +1 -0
  120. package/dist/services/audit-log.js +193 -0
  121. package/dist/services/audit-log.js.map +1 -0
  122. package/dist/services/auth-error-parser.d.ts +36 -0
  123. package/dist/services/auth-error-parser.d.ts.map +1 -0
  124. package/dist/services/auth-error-parser.js +90 -0
  125. package/dist/services/auth-error-parser.js.map +1 -0
  126. package/dist/services/deployment-doctor.d.ts +109 -0
  127. package/dist/services/deployment-doctor.d.ts.map +1 -0
  128. package/dist/services/deployment-doctor.js +476 -0
  129. package/dist/services/deployment-doctor.js.map +1 -0
  130. package/dist/services/deployment-notifications.d.ts +41 -0
  131. package/dist/services/deployment-notifications.d.ts.map +1 -0
  132. package/dist/services/deployment-notifications.js +161 -0
  133. package/dist/services/deployment-notifications.js.map +1 -0
  134. package/dist/services/deployment-progress.d.ts +89 -0
  135. package/dist/services/deployment-progress.d.ts.map +1 -0
  136. package/dist/services/deployment-progress.js +244 -0
  137. package/dist/services/deployment-progress.js.map +1 -0
  138. package/dist/services/deployment-service.d.ts +97 -0
  139. package/dist/services/deployment-service.d.ts.map +1 -0
  140. package/dist/services/deployment-service.js +375 -0
  141. package/dist/services/deployment-service.js.map +1 -0
  142. package/dist/services/drift-analyzer.d.ts +86 -0
  143. package/dist/services/drift-analyzer.d.ts.map +1 -0
  144. package/dist/services/drift-analyzer.js +273 -0
  145. package/dist/services/drift-analyzer.js.map +1 -0
  146. package/dist/services/environment-setup.d.ts +97 -0
  147. package/dist/services/environment-setup.d.ts.map +1 -0
  148. package/dist/services/environment-setup.js +250 -0
  149. package/dist/services/environment-setup.js.map +1 -0
  150. package/dist/services/health-check.d.ts +168 -0
  151. package/dist/services/health-check.d.ts.map +1 -0
  152. package/dist/services/health-check.js +705 -0
  153. package/dist/services/health-check.js.map +1 -0
  154. package/dist/services/index.d.ts +39 -0
  155. package/dist/services/index.d.ts.map +1 -0
  156. package/dist/services/index.js +39 -0
  157. package/dist/services/index.js.map +1 -0
  158. package/dist/services/logger.d.ts +139 -0
  159. package/dist/services/logger.d.ts.map +1 -0
  160. package/dist/services/logger.js +268 -0
  161. package/dist/services/logger.js.map +1 -0
  162. package/dist/services/notification-service.d.ts +55 -0
  163. package/dist/services/notification-service.d.ts.map +1 -0
  164. package/dist/services/notification-service.js +184 -0
  165. package/dist/services/notification-service.js.map +1 -0
  166. package/dist/services/risk-analyzer.d.ts +252 -0
  167. package/dist/services/risk-analyzer.d.ts.map +1 -0
  168. package/dist/services/risk-analyzer.js +866 -0
  169. package/dist/services/risk-analyzer.js.map +1 -0
  170. package/dist/services/rollback.d.ts +57 -0
  171. package/dist/services/rollback.d.ts.map +1 -0
  172. package/dist/services/rollback.js +270 -0
  173. package/dist/services/rollback.js.map +1 -0
  174. package/dist/services/scheduler.d.ts +80 -0
  175. package/dist/services/scheduler.d.ts.map +1 -0
  176. package/dist/services/scheduler.js +350 -0
  177. package/dist/services/scheduler.js.map +1 -0
  178. package/dist/services/secrets.d.ts +31 -0
  179. package/dist/services/secrets.d.ts.map +1 -0
  180. package/dist/services/secrets.js +206 -0
  181. package/dist/services/secrets.js.map +1 -0
  182. package/dist/services/settings-service.d.ts +132 -0
  183. package/dist/services/settings-service.d.ts.map +1 -0
  184. package/dist/services/settings-service.js +378 -0
  185. package/dist/services/settings-service.js.map +1 -0
  186. package/dist/services/solution-diff.d.ts +127 -0
  187. package/dist/services/solution-diff.d.ts.map +1 -0
  188. package/dist/services/solution-diff.js +260 -0
  189. package/dist/services/solution-diff.js.map +1 -0
  190. package/dist/services/solution-mode-detector.d.ts +35 -0
  191. package/dist/services/solution-mode-detector.d.ts.map +1 -0
  192. package/dist/services/solution-mode-detector.js +84 -0
  193. package/dist/services/solution-mode-detector.js.map +1 -0
  194. package/dist/services/tenant-resolver.d.ts +55 -0
  195. package/dist/services/tenant-resolver.d.ts.map +1 -0
  196. package/dist/services/tenant-resolver.js +126 -0
  197. package/dist/services/tenant-resolver.js.map +1 -0
  198. package/dist/services/unmanaged-customizations.d.ts +104 -0
  199. package/dist/services/unmanaged-customizations.d.ts.map +1 -0
  200. package/dist/services/unmanaged-customizations.js +521 -0
  201. package/dist/services/unmanaged-customizations.js.map +1 -0
  202. package/dist/services/url-templater.d.ts +184 -0
  203. package/dist/services/url-templater.d.ts.map +1 -0
  204. package/dist/services/url-templater.js +327 -0
  205. package/dist/services/url-templater.js.map +1 -0
  206. package/dist/services/version-checker.d.ts +108 -0
  207. package/dist/services/version-checker.d.ts.map +1 -0
  208. package/dist/services/version-checker.js +403 -0
  209. package/dist/services/version-checker.js.map +1 -0
  210. package/dist/services/waves.d.ts +90 -0
  211. package/dist/services/waves.d.ts.map +1 -0
  212. package/dist/services/waves.js +222 -0
  213. package/dist/services/waves.js.map +1 -0
  214. package/dist/services/webhook.d.ts +95 -0
  215. package/dist/services/webhook.d.ts.map +1 -0
  216. package/dist/services/webhook.js +244 -0
  217. package/dist/services/webhook.js.map +1 -0
  218. package/dist/utils/deployment-tools.d.ts +110 -0
  219. package/dist/utils/deployment-tools.d.ts.map +1 -0
  220. package/dist/utils/deployment-tools.js +121 -0
  221. package/dist/utils/deployment-tools.js.map +1 -0
  222. package/dist/utils/index.d.ts +17 -0
  223. package/dist/utils/index.d.ts.map +1 -0
  224. package/dist/utils/index.js +18 -0
  225. package/dist/utils/index.js.map +1 -0
  226. package/package.json +49 -0
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Copyright 2024 Pax8, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { coreLogger } from "./logger.js";
17
+ import { getSettingsService } from "./settings-service.js";
18
+ const logger = coreLogger.child({ service: "notifications" });
19
+ /**
20
+ * Notification service for sending alerts via Slack, Teams, and Email
21
+ */
22
+ export class NotificationService {
23
+ /**
24
+ * Send notification to all enabled channels
25
+ */
26
+ async sendNotification(payload) {
27
+ const settingsService = getSettingsService();
28
+ const settings = await settingsService.getDecryptedAppSettings();
29
+ const promises = [];
30
+ if (settings.slackEnabled && settings.slackWebhookUrl) {
31
+ promises.push(this.sendSlackNotification(settings.slackWebhookUrl, payload));
32
+ }
33
+ if (settings.teamsEnabled && settings.teamsWebhookUrl) {
34
+ promises.push(this.sendTeamsNotification(settings.teamsWebhookUrl, payload));
35
+ }
36
+ if (settings.emailEnabled && settings.emailRecipients) {
37
+ promises.push(this.sendEmailNotification(settings.emailRecipients, payload));
38
+ }
39
+ // Send all notifications in parallel
40
+ const results = await Promise.allSettled(promises);
41
+ // Log any failures
42
+ results.forEach((result, index) => {
43
+ if (result.status === "rejected") {
44
+ const channel = index === 0 ? "Slack" : index === 1 ? "Teams" : "Email";
45
+ logger.warn(`Failed to send ${channel} notification`, { error: result.reason });
46
+ }
47
+ });
48
+ }
49
+ /**
50
+ * Send Slack notification
51
+ */
52
+ async sendSlackNotification(webhookUrl, payload) {
53
+ const colorMap = {
54
+ success: "#36a64f",
55
+ error: "#ff0000",
56
+ warning: "#ff9900",
57
+ info: "#2196F3",
58
+ };
59
+ const slackPayload = {
60
+ attachments: [
61
+ {
62
+ color: colorMap[payload.color || "info"],
63
+ title: payload.title,
64
+ text: payload.message,
65
+ title_link: payload.url,
66
+ footer: "Pax8 CTA",
67
+ footer_icon: "https://pax8-cta.app/logo.png",
68
+ ts: Math.floor(Date.now() / 1000),
69
+ },
70
+ ],
71
+ };
72
+ const response = await fetch(webhookUrl, {
73
+ method: "POST",
74
+ headers: { "Content-Type": "application/json" },
75
+ body: JSON.stringify(slackPayload),
76
+ });
77
+ if (!response.ok) {
78
+ throw new Error(`Slack webhook returned ${response.status}: ${await response.text()}`);
79
+ }
80
+ logger.info("Slack notification sent", { title: payload.title });
81
+ }
82
+ /**
83
+ * Send Microsoft Teams notification
84
+ */
85
+ async sendTeamsNotification(webhookUrl, payload) {
86
+ const colorMap = {
87
+ success: "00ff00",
88
+ error: "ff0000",
89
+ warning: "ff9900",
90
+ info: "2196F3",
91
+ };
92
+ const teamsPayload = {
93
+ "@type": "MessageCard",
94
+ "@context": "https://schema.org/extensions",
95
+ summary: payload.title,
96
+ themeColor: colorMap[payload.color || "info"],
97
+ title: payload.title,
98
+ text: payload.message,
99
+ potentialAction: payload.url
100
+ ? [
101
+ {
102
+ "@type": "OpenUri",
103
+ name: "View Details",
104
+ targets: [
105
+ {
106
+ os: "default",
107
+ uri: payload.url,
108
+ },
109
+ ],
110
+ },
111
+ ]
112
+ : undefined,
113
+ };
114
+ const response = await fetch(webhookUrl, {
115
+ method: "POST",
116
+ headers: { "Content-Type": "application/json" },
117
+ body: JSON.stringify(teamsPayload),
118
+ });
119
+ if (!response.ok) {
120
+ throw new Error(`Teams webhook returned ${response.status}: ${await response.text()}`);
121
+ }
122
+ logger.info("Teams notification sent", { title: payload.title });
123
+ }
124
+ /**
125
+ * Send email notification
126
+ *
127
+ * Email notifications are not yet implemented. Slack and Teams webhooks are
128
+ * fully supported. Email integration (SendGrid, AWS SES, etc.) is planned
129
+ * for a future release.
130
+ */
131
+ async sendEmailNotification(recipients, payload) {
132
+ logger.info("Email notification skipped (not yet implemented)", {
133
+ recipients,
134
+ title: payload.title,
135
+ message: "Use Slack or Teams webhooks for notifications",
136
+ });
137
+ }
138
+ /**
139
+ * Test a notification channel
140
+ */
141
+ async testNotification(channel, webhookUrl, recipients) {
142
+ try {
143
+ const testPayload = {
144
+ title: "Pax8 CTA Test Notification",
145
+ message: `This is a test notification from Pax8 CTA. If you see this, your ${channel} integration is working correctly!`,
146
+ color: "info",
147
+ };
148
+ switch (channel) {
149
+ case "slack":
150
+ if (!webhookUrl)
151
+ throw new Error("Slack webhook URL is required");
152
+ await this.sendSlackNotification(webhookUrl, testPayload);
153
+ break;
154
+ case "teams":
155
+ if (!webhookUrl)
156
+ throw new Error("Teams webhook URL is required");
157
+ await this.sendTeamsNotification(webhookUrl, testPayload);
158
+ break;
159
+ case "email":
160
+ if (!recipients)
161
+ throw new Error("Email recipients are required");
162
+ await this.sendEmailNotification(recipients, testPayload);
163
+ break;
164
+ }
165
+ return { success: true };
166
+ }
167
+ catch (error) {
168
+ logger.error(`Test notification failed for ${channel}`, error);
169
+ return {
170
+ success: false,
171
+ error: error instanceof Error ? error.message : "Unknown error",
172
+ };
173
+ }
174
+ }
175
+ }
176
+ // Singleton instance
177
+ let notificationInstance = null;
178
+ export function getNotificationService() {
179
+ if (!notificationInstance) {
180
+ notificationInstance = new NotificationService();
181
+ }
182
+ return notificationInstance;
183
+ }
184
+ //# sourceMappingURL=notification-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-service.js","sourceRoot":"","sources":["../../src/services/notification-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,252 @@
1
+ /**
2
+ * Copyright 2024 Pax8, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { type PreconditionFailure } from "../preconditions/index.js";
17
+ import type { WaveExecutionPlan } from "./waves.js";
18
+ export interface Tenant {
19
+ id: string;
20
+ name: string;
21
+ environmentUrl: string;
22
+ tags?: string[];
23
+ }
24
+ /**
25
+ * Confidence qualifier — coarse bucket suitable for both human-readable
26
+ * labels and machine-readable scripting. Gated on the numeric `confidence`
27
+ * field via `confidenceQualifier()`.
28
+ */
29
+ export type ConfidenceQualifier = "limited" | "moderate" | "high";
30
+ /**
31
+ * Per-tenant risk row surfaced in `RiskAnalysis.perTenantBreakdown`. Same
32
+ * dimensions as the aggregate analysis (issues are already attributed by
33
+ * `affectedTenants`), but rolled up per-tenant for scripting and display.
34
+ */
35
+ export interface TenantRiskRow {
36
+ tenantId: string;
37
+ tenantName: string;
38
+ /** Risk level computed from issues that affect this specific tenant. */
39
+ score: "low" | "medium" | "high" | "critical";
40
+ /** The single highest-severity issue that mentions this tenant. */
41
+ topFactor?: {
42
+ severity: RiskSeverity;
43
+ category: RiskCategory;
44
+ message: string;
45
+ };
46
+ }
47
+ export type RiskSeverity = "info" | "warning" | "error" | "critical";
48
+ export type RiskCategory = "permissions" | "dependencies" | "health" | "timing" | "history" | "connections" | "configuration" | "preconditions";
49
+ export interface RiskIssue {
50
+ severity: RiskSeverity;
51
+ category: RiskCategory;
52
+ message: string;
53
+ affectedTenants?: string[];
54
+ resolution?: string;
55
+ link?: string;
56
+ details?: Record<string, unknown>;
57
+ }
58
+ export interface RiskAnalysis {
59
+ score: "low" | "medium" | "high" | "critical";
60
+ confidence: number;
61
+ /**
62
+ * Coarse bucket for `confidence`: "limited" (< 70), "moderate" (70-90),
63
+ * "high" (>= 90). Surfaced separately so scripts/CI can branch without
64
+ * re-implementing the threshold logic.
65
+ */
66
+ confidenceQualifier: ConfidenceQualifier;
67
+ /** Snake-case alias of `confidenceQualifier` for JSON consumers. */
68
+ confidence_qualifier: ConfidenceQualifier;
69
+ estimatedDuration: {
70
+ min: number;
71
+ max: number;
72
+ };
73
+ successProbability: number;
74
+ issues: RiskIssue[];
75
+ recommendations: string[];
76
+ blockers: RiskIssue[];
77
+ canProceed: boolean;
78
+ requiresApproval: boolean;
79
+ /** Per-tenant risk rollup. Same dimensions, attributed per tenant. */
80
+ perTenantBreakdown: TenantRiskRow[];
81
+ /**
82
+ * Preflight (preconditions) results — the fifth analyze dimension. When
83
+ * no manifest was found for the solution, `manifestFound` is false and
84
+ * `failures` is empty. When the manifest validates and the diff engine
85
+ * runs, every failed (tenant × requirement) lands in `failures` here AND
86
+ * is mirrored into `issues` as a RiskIssue with category `preconditions`.
87
+ */
88
+ preconditions: {
89
+ manifestFound: boolean;
90
+ solution?: string;
91
+ manifestVersion?: string;
92
+ failures: PreconditionFailure[];
93
+ };
94
+ }
95
+ export interface DeploymentContext {
96
+ tenants: Tenant[];
97
+ solutionFile?: string;
98
+ solutionSize?: number;
99
+ isProduction: boolean;
100
+ scheduledTime?: Date;
101
+ deploymentHistory?: DeploymentHistoryEntry[];
102
+ /**
103
+ * Wave execution plan to model duration with parallelism. Built from
104
+ * `WaveService.createExecutionPlan(config, destinations)` by callers that
105
+ * have access to a Config (real-mode `analyze`). When omitted, the
106
+ * analyzer assumes a single wave with `maxParallel = DEFAULT_MAX_PARALLEL`.
107
+ */
108
+ waves?: WaveExecutionPlan;
109
+ /**
110
+ * Override for the single-wave default parallelism. Only consulted when
111
+ * `waves` is not provided. Defaults to `DEFAULT_MAX_PARALLEL` (5).
112
+ */
113
+ maxParallel?: number;
114
+ /**
115
+ * Directories to search for `<solution>.preconditions.yaml`. When omitted,
116
+ * defaults to `["./agent packages", process.cwd()]`. The fifth analyze
117
+ * dimension (preconditions) walks this list and skips silently if no
118
+ * manifest is found.
119
+ */
120
+ preconditionSearchDirs?: string[];
121
+ }
122
+ /**
123
+ * Default parallelism when no wave config is supplied. Five concurrent
124
+ * deploys is what `deploy --all` does in practice and matches the
125
+ * Dataverse `importSolutionAsync` rate-limit headroom we have observed.
126
+ */
127
+ export declare const DEFAULT_MAX_PARALLEL = 5;
128
+ /**
129
+ * Map a numeric confidence value to its coarse qualifier bucket.
130
+ * Boundaries: < 70 -> limited, 70..89 -> moderate, >= 90 -> high.
131
+ * Exposed (not just internal) so CLI rendering can render
132
+ * `Risk Score: LOW (limited data)` without re-implementing thresholds.
133
+ */
134
+ export declare function confidenceQualifier(confidence: number): ConfidenceQualifier;
135
+ /**
136
+ * Map a confidence qualifier to the human-readable suffix shown next to
137
+ * the risk score (e.g. `LOW (limited data)`).
138
+ */
139
+ export declare function confidenceQualifierLabel(qualifier: ConfidenceQualifier): string;
140
+ export interface DeploymentHistoryEntry {
141
+ tenantId: string;
142
+ status: "success" | "failure";
143
+ error?: string;
144
+ completedAt: string;
145
+ durationMinutes?: number;
146
+ }
147
+ /**
148
+ * Main risk analyzer class
149
+ */
150
+ export declare class DeploymentRiskAnalyzer {
151
+ /**
152
+ * Analyze deployment risk
153
+ */
154
+ analyze(context: DeploymentContext): Promise<RiskAnalysis>;
155
+ /**
156
+ * Check GDAP permissions for all tenants. Returns `dataAvailable=true`
157
+ * when at least one tenant produced a determination — used as a
158
+ * coverage signal for `calculateConfidence`.
159
+ */
160
+ private checkGDAPPermissions;
161
+ /**
162
+ * Check connection references. Returns `dataAvailable=true` when we had
163
+ * any signal (currently: demo metadata).
164
+ */
165
+ private checkConnections;
166
+ /**
167
+ * Check tenant health. `dataAvailable=true` when we had health-relevant
168
+ * input (deployment history with at least one failure-bearing entry, or
169
+ * demo metadata). Note: an empty deploymentHistory still counts as "we
170
+ * looked but found nothing," not "we couldn't check."
171
+ */
172
+ private checkTenantHealth;
173
+ /**
174
+ * Analyze deployment history. `dataAvailable=true` when we had real
175
+ * deploymentHistory entries or demo metadata to draw from.
176
+ */
177
+ private analyzeHistory;
178
+ /**
179
+ * Fifth dimension — tenant-config preflight. Loads a sibling YAML
180
+ * `<solution>.preconditions.yaml`, runs it against synthetic per-tenant
181
+ * state (Phase 1), and emits one `RiskIssue` per failed requirement plus a
182
+ * structured `failures[]` payload the CLI can render with deep-link / CLI
183
+ * / manual remediation steps.
184
+ *
185
+ * When no manifest is found we emit a single `info` issue ("preflight
186
+ * skipped") and return — deploy still proceeds.
187
+ *
188
+ * Phase 2 will replace `synthesizeTenantStateResolver` with a real
189
+ * Microsoft Graph TCM client; the manifest format and the diff engine
190
+ * stay the same.
191
+ */
192
+ private checkPreconditions;
193
+ /**
194
+ * Calculate overall risk score
195
+ */
196
+ private calculateRiskScore;
197
+ /**
198
+ * Calculate confidence in the risk assessment.
199
+ *
200
+ * Two inputs drive confidence:
201
+ * - **Coverage** — number of dimensions (GDAP / connections / health /
202
+ * history) that returned data. Each adds 10 points.
203
+ * - **Sample size** — median per-tenant deploy history count, log-scaled
204
+ * and capped at 40 points.
205
+ *
206
+ * Formula: `50 + 10 * coverage + min(40, ceil(log2(median_history + 1)) * 10)`.
207
+ * Clamped to [0, 100]. Lands in the 50–95% range for realistic inputs:
208
+ * - 0 coverage, 0 history -> 50
209
+ * - 4 coverage, 0 history -> 90
210
+ * - 4 coverage, 5 history -> 90 + log2(6)*10 ≈ 90, capped to 95 by
211
+ * the 40-cap fallback (40 + 50 = 90, plus +5 if median ≥ 16).
212
+ * - 4 coverage, 50+ history -> 50 + 40 + 40 = 100, clamped to 95.
213
+ */
214
+ private calculateConfidence;
215
+ /**
216
+ * Median per-tenant historical deploy count for the requested solution
217
+ * (best-effort — falls back to overall demo `totalDeploys` or to the
218
+ * supplied `deploymentHistory` length / tenant count).
219
+ */
220
+ private medianSampleSize;
221
+ /**
222
+ * Estimate deployment duration with wave-aware parallelism.
223
+ *
224
+ * Today's deploys are not sequential — `WaveService` runs up to
225
+ * `maxParallel` tenants concurrently per wave. The previous estimate
226
+ * (2 min × N tenants, sequential) overstated duration ~5×.
227
+ *
228
+ * Compute: `Σ_per_wave (ceil(wave.tenants / wave.maxParallel) ×
229
+ * PER_TENANT_MINUTES) + Σ wave.waitAfterCompletion`. When no wave plan
230
+ * is supplied, fall back to a single wave with `DEFAULT_MAX_PARALLEL`.
231
+ */
232
+ private estimateDuration;
233
+ /**
234
+ * Build per-tenant rollup. For each tenant, find issues that name them
235
+ * (or that have no `affectedTenants` field — those apply to the whole
236
+ * fleet) and pick the highest-severity one as the top factor.
237
+ */
238
+ private buildPerTenantBreakdown;
239
+ /**
240
+ * Calculate success probability
241
+ */
242
+ private calculateSuccessProbability;
243
+ /**
244
+ * Generate actionable recommendations
245
+ */
246
+ private generateRecommendations;
247
+ }
248
+ /**
249
+ * Singleton instance
250
+ */
251
+ export declare const riskAnalyzer: DeploymentRiskAnalyzer;
252
+ //# sourceMappingURL=risk-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"risk-analyzer.d.ts","sourceRoot":"","sources":["../../src/services/risk-analyzer.ts"],"names":[],"mappings":"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"}