@ucptools/validator 1.0.1 → 1.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 (152) hide show
  1. package/dist/auth/config.d.ts +20 -0
  2. package/dist/auth/config.d.ts.map +1 -0
  3. package/dist/auth/config.js +114 -0
  4. package/dist/auth/config.js.map +1 -0
  5. package/dist/auth/index.d.ts +5 -0
  6. package/dist/auth/index.d.ts.map +1 -0
  7. package/dist/auth/index.js +17 -0
  8. package/dist/auth/index.js.map +1 -0
  9. package/dist/auth/middleware.d.ts +45 -0
  10. package/dist/auth/middleware.d.ts.map +1 -0
  11. package/dist/auth/middleware.js +170 -0
  12. package/dist/auth/middleware.js.map +1 -0
  13. package/dist/auth/service.d.ts +80 -0
  14. package/dist/auth/service.d.ts.map +1 -0
  15. package/dist/auth/service.js +298 -0
  16. package/dist/auth/service.js.map +1 -0
  17. package/dist/cli/index.js +96 -0
  18. package/dist/cli/index.js.map +1 -1
  19. package/dist/cli/mock-server.d.ts +20 -0
  20. package/dist/cli/mock-server.d.ts.map +1 -0
  21. package/dist/cli/mock-server.js +261 -0
  22. package/dist/cli/mock-server.js.map +1 -0
  23. package/dist/db/index.d.ts +8 -2
  24. package/dist/db/index.d.ts.map +1 -1
  25. package/dist/db/index.js +22 -5
  26. package/dist/db/index.js.map +1 -1
  27. package/dist/db/schema.d.ts +3570 -128
  28. package/dist/db/schema.d.ts.map +1 -1
  29. package/dist/db/schema.js +377 -17
  30. package/dist/db/schema.js.map +1 -1
  31. package/dist/db/utils.d.ts +252 -0
  32. package/dist/db/utils.d.ts.map +1 -0
  33. package/dist/db/utils.js +295 -0
  34. package/dist/db/utils.js.map +1 -0
  35. package/dist/feed-analyzer/feed-analyzer.d.ts.map +1 -1
  36. package/dist/feed-analyzer/feed-analyzer.js +218 -4
  37. package/dist/feed-analyzer/feed-analyzer.js.map +1 -1
  38. package/dist/feed-analyzer/types.d.ts +82 -1
  39. package/dist/feed-analyzer/types.d.ts.map +1 -1
  40. package/dist/feed-analyzer/types.js +13 -0
  41. package/dist/feed-analyzer/types.js.map +1 -1
  42. package/dist/lib/analytics.d.ts +337 -0
  43. package/dist/lib/analytics.d.ts.map +1 -0
  44. package/dist/lib/analytics.js +188 -0
  45. package/dist/lib/analytics.js.map +1 -0
  46. package/dist/security/security-scanner.d.ts.map +1 -1
  47. package/dist/security/security-scanner.js +130 -2
  48. package/dist/security/security-scanner.js.map +1 -1
  49. package/dist/security/types.d.ts +32 -0
  50. package/dist/security/types.d.ts.map +1 -1
  51. package/dist/security/types.js.map +1 -1
  52. package/dist/services/analytics.d.ts +114 -0
  53. package/dist/services/analytics.d.ts.map +1 -0
  54. package/dist/services/analytics.js +862 -0
  55. package/dist/services/analytics.js.map +1 -0
  56. package/dist/services/badge.d.ts +31 -0
  57. package/dist/services/badge.d.ts.map +1 -0
  58. package/dist/services/badge.js +152 -0
  59. package/dist/services/badge.js.map +1 -0
  60. package/dist/services/cron.d.ts +125 -0
  61. package/dist/services/cron.d.ts.map +1 -0
  62. package/dist/services/cron.js +613 -0
  63. package/dist/services/cron.js.map +1 -0
  64. package/dist/services/directory.d.ts +2 -0
  65. package/dist/services/directory.d.ts.map +1 -1
  66. package/dist/services/directory.js +45 -27
  67. package/dist/services/directory.js.map +1 -1
  68. package/dist/services/email.d.ts +112 -0
  69. package/dist/services/email.d.ts.map +1 -0
  70. package/dist/services/email.js +772 -0
  71. package/dist/services/email.js.map +1 -0
  72. package/dist/services/hosted-profiles.d.ts +77 -0
  73. package/dist/services/hosted-profiles.d.ts.map +1 -0
  74. package/dist/services/hosted-profiles.js +433 -0
  75. package/dist/services/hosted-profiles.js.map +1 -0
  76. package/dist/services/latency.d.ts +67 -0
  77. package/dist/services/latency.d.ts.map +1 -0
  78. package/dist/services/latency.js +274 -0
  79. package/dist/services/latency.js.map +1 -0
  80. package/dist/services/manifest-compliance.d.ts +64 -0
  81. package/dist/services/manifest-compliance.d.ts.map +1 -0
  82. package/dist/services/manifest-compliance.js +271 -0
  83. package/dist/services/manifest-compliance.js.map +1 -0
  84. package/dist/services/monitoring-diff.d.ts +31 -0
  85. package/dist/services/monitoring-diff.d.ts.map +1 -0
  86. package/dist/services/monitoring-diff.js +189 -0
  87. package/dist/services/monitoring-diff.js.map +1 -0
  88. package/dist/services/notifications.d.ts +46 -0
  89. package/dist/services/notifications.d.ts.map +1 -0
  90. package/dist/services/notifications.js +88 -0
  91. package/dist/services/notifications.js.map +1 -0
  92. package/dist/services/stripe.d.ts +93 -0
  93. package/dist/services/stripe.d.ts.map +1 -0
  94. package/dist/services/stripe.js +490 -0
  95. package/dist/services/stripe.js.map +1 -0
  96. package/dist/services/validation-history.d.ts +99 -0
  97. package/dist/services/validation-history.d.ts.map +1 -0
  98. package/dist/services/validation-history.js +344 -0
  99. package/dist/services/validation-history.js.map +1 -0
  100. package/dist/services/validation-logging.d.ts +103 -0
  101. package/dist/services/validation-logging.d.ts.map +1 -0
  102. package/dist/services/validation-logging.js +210 -0
  103. package/dist/services/validation-logging.js.map +1 -0
  104. package/dist/services/validation.d.ts +119 -0
  105. package/dist/services/validation.d.ts.map +1 -0
  106. package/dist/services/validation.js +1185 -0
  107. package/dist/services/validation.js.map +1 -0
  108. package/dist/simulator/agent-simulator.d.ts.map +1 -1
  109. package/dist/simulator/agent-simulator.js +229 -9
  110. package/dist/simulator/agent-simulator.js.map +1 -1
  111. package/dist/simulator/types.d.ts +26 -0
  112. package/dist/simulator/types.d.ts.map +1 -1
  113. package/dist/simulator/types.js.map +1 -1
  114. package/dist/types/acp-validation.d.ts +87 -0
  115. package/dist/types/acp-validation.d.ts.map +1 -0
  116. package/dist/types/acp-validation.js +40 -0
  117. package/dist/types/acp-validation.js.map +1 -0
  118. package/dist/types/analytics.d.ts +182 -0
  119. package/dist/types/analytics.d.ts.map +1 -0
  120. package/dist/types/analytics.js +7 -0
  121. package/dist/types/analytics.js.map +1 -0
  122. package/dist/types/ucp-profile.d.ts +10 -2
  123. package/dist/types/ucp-profile.d.ts.map +1 -1
  124. package/dist/types/ucp-profile.js.map +1 -1
  125. package/dist/types/validation.d.ts +8 -0
  126. package/dist/types/validation.d.ts.map +1 -1
  127. package/dist/types/validation.js +10 -0
  128. package/dist/types/validation.js.map +1 -1
  129. package/dist/validator/acp/index.d.ts +31 -0
  130. package/dist/validator/acp/index.d.ts.map +1 -0
  131. package/dist/validator/acp/index.js +574 -0
  132. package/dist/validator/acp/index.js.map +1 -0
  133. package/dist/validator/network-validator.d.ts.map +1 -1
  134. package/dist/validator/network-validator.js +4 -4
  135. package/dist/validator/network-validator.js.map +1 -1
  136. package/dist/validator/rules-validator.d.ts +8 -0
  137. package/dist/validator/rules-validator.d.ts.map +1 -1
  138. package/dist/validator/rules-validator.js +92 -43
  139. package/dist/validator/rules-validator.js.map +1 -1
  140. package/dist/validator/structural-validator.d.ts.map +1 -1
  141. package/dist/validator/structural-validator.js +187 -53
  142. package/dist/validator/structural-validator.js.map +1 -1
  143. package/dist/validator/utils.d.ts +51 -0
  144. package/dist/validator/utils.d.ts.map +1 -0
  145. package/dist/validator/utils.js +132 -0
  146. package/dist/validator/utils.js.map +1 -0
  147. package/package.json +44 -12
  148. package/.claude/settings.local.json +0 -60
  149. package/.vercel/README.txt +0 -11
  150. package/.vercel/project.json +0 -1
  151. package/publish-output.txt +0 -0
  152. package/tsconfig.json +0 -20
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Monitoring Diff Engine
3
+ *
4
+ * Compares two ValidationResult objects to detect changes between scans.
5
+ * Classifies changes by severity: broken, degraded, changed, stable.
6
+ */
7
+ import type { ValidationResult } from './validation.js';
8
+ export type MonitoringSeverity = 'broken' | 'degraded' | 'changed' | 'stable';
9
+ export interface ProfileChange {
10
+ field: string;
11
+ type: 'added' | 'removed' | 'changed';
12
+ oldValue?: string | number | boolean | null;
13
+ newValue?: string | number | boolean | null;
14
+ severity: 'error' | 'warn' | 'info';
15
+ }
16
+ export interface ProfileDiff {
17
+ severity: MonitoringSeverity;
18
+ changes: ProfileChange[];
19
+ summary: string;
20
+ scoreChange: number | null;
21
+ gradeChange: {
22
+ from: string;
23
+ to: string;
24
+ } | null;
25
+ ucpStatusChange: {
26
+ from: boolean;
27
+ to: boolean;
28
+ } | null;
29
+ }
30
+ export declare function diffValidationResults(previous: ValidationResult, current: ValidationResult, threshold?: number): ProfileDiff;
31
+ //# sourceMappingURL=monitoring-diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitoring-diff.d.ts","sourceRoot":"","sources":["../../src/services/monitoring-diff.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAmB,MAAM,iBAAiB,CAAC;AAIzE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9E,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IAC5C,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,eAAe,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CACxD;AAiCD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,gBAAgB,EACzB,SAAS,GAAE,MAAW,GACrB,WAAW,CAmHb"}
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ /**
3
+ * Monitoring Diff Engine
4
+ *
5
+ * Compares two ValidationResult objects to detect changes between scans.
6
+ * Classifies changes by severity: broken, degraded, changed, stable.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.diffValidationResults = diffValidationResults;
10
+ // ── Grade ordering (lower index = better) ────────────────────────────────────
11
+ const GRADE_ORDER = { A: 0, B: 1, C: 2, D: 3, F: 4 };
12
+ function gradeWorsened(from, to) {
13
+ return (GRADE_ORDER[to] ?? 99) > (GRADE_ORDER[from] ?? 99);
14
+ }
15
+ function gradeImproved(from, to) {
16
+ return (GRADE_ORDER[to] ?? 99) < (GRADE_ORDER[from] ?? 99);
17
+ }
18
+ function diffIssues(prev, curr) {
19
+ const prevCodes = new Set(prev.map(i => i.code));
20
+ const currCodes = new Set(curr.map(i => i.code));
21
+ return {
22
+ added: curr.filter(i => !prevCodes.has(i.code)),
23
+ removed: prev.filter(i => !currCodes.has(i.code)),
24
+ };
25
+ }
26
+ // ── Core diff function ───────────────────────────────────────────────────────
27
+ function diffValidationResults(previous, current, threshold = 10) {
28
+ const changes = [];
29
+ // 1. UCP presence
30
+ const ucpStatusChange = previous.ucp.found !== current.ucp.found
31
+ ? { from: previous.ucp.found, to: current.ucp.found }
32
+ : null;
33
+ if (ucpStatusChange) {
34
+ changes.push({
35
+ field: 'ucp.found',
36
+ type: 'changed',
37
+ oldValue: previous.ucp.found,
38
+ newValue: current.ucp.found,
39
+ severity: current.ucp.found ? 'info' : 'error',
40
+ });
41
+ }
42
+ // 2. Score
43
+ const prevScore = previous.ai_readiness.score;
44
+ const currScore = current.ai_readiness.score;
45
+ const scoreChange = currScore - prevScore;
46
+ if (scoreChange !== 0) {
47
+ changes.push({
48
+ field: 'ai_readiness.score',
49
+ type: 'changed',
50
+ oldValue: prevScore,
51
+ newValue: currScore,
52
+ severity: scoreChange < -threshold ? 'error' : scoreChange < 0 ? 'warn' : 'info',
53
+ });
54
+ }
55
+ // 3. Grade
56
+ const prevGrade = previous.ai_readiness.grade;
57
+ const currGrade = current.ai_readiness.grade;
58
+ const gradeChange = prevGrade !== currGrade
59
+ ? { from: prevGrade, to: currGrade }
60
+ : null;
61
+ if (gradeChange) {
62
+ changes.push({
63
+ field: 'ai_readiness.grade',
64
+ type: 'changed',
65
+ oldValue: prevGrade,
66
+ newValue: currGrade,
67
+ severity: gradeWorsened(prevGrade, currGrade) ? 'error' : 'info',
68
+ });
69
+ }
70
+ // 4. UCP issues
71
+ const ucpIssueDiff = diffIssues(previous.ucp.issues || [], current.ucp.issues || []);
72
+ for (const issue of ucpIssueDiff.added) {
73
+ changes.push({
74
+ field: `ucp.issues.${issue.code}`,
75
+ type: 'added',
76
+ newValue: issue.message,
77
+ severity: issue.severity === 'error' ? 'error' : 'warn',
78
+ });
79
+ }
80
+ for (const issue of ucpIssueDiff.removed) {
81
+ changes.push({
82
+ field: `ucp.issues.${issue.code}`,
83
+ type: 'removed',
84
+ oldValue: issue.message,
85
+ severity: 'info',
86
+ });
87
+ }
88
+ // 5. Schema issues
89
+ const schemaIssueDiff = diffIssues(previous.schema.issues || [], current.schema.issues || []);
90
+ for (const issue of schemaIssueDiff.added) {
91
+ changes.push({
92
+ field: `schema.issues.${issue.code}`,
93
+ type: 'added',
94
+ newValue: issue.message,
95
+ severity: issue.severity === 'error' ? 'error' : 'warn',
96
+ });
97
+ }
98
+ for (const issue of schemaIssueDiff.removed) {
99
+ changes.push({
100
+ field: `schema.issues.${issue.code}`,
101
+ type: 'removed',
102
+ oldValue: issue.message,
103
+ severity: 'info',
104
+ });
105
+ }
106
+ // 6. Performance grade
107
+ if (previous.performance?.performanceGrade !== current.performance?.performanceGrade) {
108
+ changes.push({
109
+ field: 'performance.performanceGrade',
110
+ type: 'changed',
111
+ oldValue: previous.performance?.performanceGrade ?? null,
112
+ newValue: current.performance?.performanceGrade ?? null,
113
+ severity: 'info',
114
+ });
115
+ }
116
+ // ── Classify severity ──────────────────────────────────────────────────────
117
+ const severity = classifySeverity(changes, ucpStatusChange, scoreChange, gradeChange, threshold);
118
+ // ── Generate summary ───────────────────────────────────────────────────────
119
+ const summary = generateSummary(severity, scoreChange, gradeChange, ucpStatusChange, changes);
120
+ return {
121
+ severity,
122
+ changes,
123
+ summary,
124
+ scoreChange: scoreChange !== 0 ? scoreChange : null,
125
+ gradeChange,
126
+ ucpStatusChange,
127
+ };
128
+ }
129
+ // ── Severity classification ──────────────────────────────────────────────────
130
+ function classifySeverity(changes, ucpStatusChange, scoreChange, gradeChange, threshold) {
131
+ // Broken: UCP profile disappeared or score dropped to 0
132
+ if (ucpStatusChange && ucpStatusChange.from === true && ucpStatusChange.to === false) {
133
+ return 'broken';
134
+ }
135
+ // Degraded: grade worsened, or score dropped >= threshold, or new error-severity issues
136
+ if (gradeChange && gradeWorsened(gradeChange.from, gradeChange.to)) {
137
+ return 'degraded';
138
+ }
139
+ if (scoreChange <= -threshold) {
140
+ return 'degraded';
141
+ }
142
+ const hasNewErrors = changes.some(c => c.type === 'added' && c.severity === 'error');
143
+ if (hasNewErrors) {
144
+ return 'degraded';
145
+ }
146
+ // Stable: no meaningful changes at all, or only a tiny score fluctuation
147
+ if (changes.length === 0) {
148
+ return 'stable';
149
+ }
150
+ const onlySmallScoreChange = changes.every(c => c.field === 'ai_readiness.score') && Math.abs(scoreChange) <= 2;
151
+ if (onlySmallScoreChange) {
152
+ return 'stable';
153
+ }
154
+ // Changed: anything else (improvements, informational changes)
155
+ return 'changed';
156
+ }
157
+ // ── Summary generation ───────────────────────────────────────────────────────
158
+ function generateSummary(severity, scoreChange, gradeChange, ucpStatusChange, changes) {
159
+ if (severity === 'stable') {
160
+ return 'No meaningful changes detected';
161
+ }
162
+ const parts = [];
163
+ if (ucpStatusChange) {
164
+ if (!ucpStatusChange.to) {
165
+ parts.push('UCP profile no longer found');
166
+ }
167
+ else {
168
+ parts.push('UCP profile restored');
169
+ }
170
+ }
171
+ if (scoreChange !== 0) {
172
+ const direction = scoreChange > 0 ? 'improved' : 'dropped';
173
+ parts.push(`Score ${direction} by ${Math.abs(scoreChange)} points`);
174
+ }
175
+ if (gradeChange) {
176
+ const direction = gradeImproved(gradeChange.from, gradeChange.to) ? 'improved' : 'dropped';
177
+ parts.push(`Grade ${direction} from ${gradeChange.from} to ${gradeChange.to}`);
178
+ }
179
+ const newErrors = changes.filter(c => c.type === 'added' && c.severity === 'error');
180
+ if (newErrors.length > 0) {
181
+ parts.push(`${newErrors.length} new error(s)`);
182
+ }
183
+ const resolvedIssues = changes.filter(c => c.type === 'removed');
184
+ if (resolvedIssues.length > 0) {
185
+ parts.push(`${resolvedIssues.length} issue(s) resolved`);
186
+ }
187
+ return parts.join('. ') || 'Profile changes detected';
188
+ }
189
+ //# sourceMappingURL=monitoring-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitoring-diff.js","sourceRoot":"","sources":["../../src/services/monitoring-diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Notification Service
3
+ *
4
+ * Handles outbound notifications via Slack webhooks.
5
+ * All notifications are fire-and-forget to avoid blocking main operations.
6
+ */
7
+ export interface NotificationUser {
8
+ id: string;
9
+ email: string;
10
+ name: string | null;
11
+ }
12
+ export interface NotificationSubscription {
13
+ tier: string;
14
+ status: string;
15
+ }
16
+ /**
17
+ * Send signup notification to Slack
18
+ */
19
+ export interface WebhookPayload {
20
+ event: 'profile_broken' | 'profile_degraded' | 'profile_changed';
21
+ domain: string;
22
+ severity: string;
23
+ oldScore: number | null;
24
+ newScore: number;
25
+ oldGrade: string | null;
26
+ newGrade: string;
27
+ changes: Array<{
28
+ field: string;
29
+ type: string;
30
+ oldValue?: string | number | boolean | null;
31
+ newValue?: string | number | boolean | null;
32
+ }>;
33
+ summary: string;
34
+ timestamp: string;
35
+ dashboardUrl: string;
36
+ }
37
+ /**
38
+ * Send webhook notification for domain monitoring changes.
39
+ * Fire-and-forget - logs errors but never throws.
40
+ */
41
+ export declare function sendDomainWebhook(webhookUrl: string, payload: WebhookPayload): Promise<boolean>;
42
+ /**
43
+ * Send signup notification to Slack
44
+ */
45
+ export declare function notifySignup(user: NotificationUser, subscription: NotificationSubscription): Promise<void>;
46
+ //# sourceMappingURL=notifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/services/notifications.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,gBAAgB,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;QAC5C,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;KAC7C,CAAC,CAAC;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,gBAAgB,EACtB,YAAY,EAAE,wBAAwB,GACrC,OAAO,CAAC,IAAI,CAAC,CA+Cf"}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ /**
3
+ * Notification Service
4
+ *
5
+ * Handles outbound notifications via Slack webhooks.
6
+ * All notifications are fire-and-forget to avoid blocking main operations.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.sendDomainWebhook = sendDomainWebhook;
10
+ exports.notifySignup = notifySignup;
11
+ /**
12
+ * Send webhook notification for domain monitoring changes.
13
+ * Fire-and-forget - logs errors but never throws.
14
+ */
15
+ async function sendDomainWebhook(webhookUrl, payload) {
16
+ try {
17
+ const response = await fetch(webhookUrl, {
18
+ method: 'POST',
19
+ headers: {
20
+ 'Content-Type': 'application/json',
21
+ 'User-Agent': 'UCPtools-Webhook/1.0',
22
+ },
23
+ body: JSON.stringify(payload),
24
+ signal: AbortSignal.timeout(10000), // 10s timeout
25
+ });
26
+ if (!response.ok) {
27
+ console.error(`[Webhook] Failed to send to ${webhookUrl}: ${response.status}`);
28
+ return false;
29
+ }
30
+ console.log(`[Webhook] Sent ${payload.event} notification for ${payload.domain}`);
31
+ return true;
32
+ }
33
+ catch (error) {
34
+ console.error(`[Webhook] Error sending to ${webhookUrl}:`, error instanceof Error ? error.message : error);
35
+ return false;
36
+ }
37
+ }
38
+ /**
39
+ * Send signup notification to Slack
40
+ */
41
+ async function notifySignup(user, subscription) {
42
+ const webhookUrl = process.env.SLACK_WEBHOOK_URL;
43
+ if (!webhookUrl) {
44
+ console.log('[Slack] No webhook URL configured, skipping notification');
45
+ return;
46
+ }
47
+ const message = {
48
+ blocks: [
49
+ {
50
+ type: 'header',
51
+ text: { type: 'plain_text', text: '🎉 New Customer Signup!' }
52
+ },
53
+ {
54
+ type: 'section',
55
+ fields: [
56
+ { type: 'mrkdwn', text: `*Email:*\n${user.email}` },
57
+ { type: 'mrkdwn', text: `*Name:*\n${user.name || 'Not provided'}` },
58
+ { type: 'mrkdwn', text: `*Tier:*\n${subscription.tier}` },
59
+ { type: 'mrkdwn', text: `*Status:*\n${subscription.status}` }
60
+ ]
61
+ },
62
+ {
63
+ type: 'context',
64
+ elements: [
65
+ { type: 'mrkdwn', text: `User ID: ${user.id} | ${new Date().toISOString()}` }
66
+ ]
67
+ }
68
+ ]
69
+ };
70
+ // Fire-and-forget - don't await, don't block
71
+ fetch(webhookUrl, {
72
+ method: 'POST',
73
+ headers: { 'Content-Type': 'application/json' },
74
+ body: JSON.stringify(message)
75
+ })
76
+ .then(response => {
77
+ if (!response.ok) {
78
+ console.error(`[Slack] Notification failed: ${response.status}`);
79
+ }
80
+ else {
81
+ console.log(`[Slack] Signup notification sent for ${user.email}`);
82
+ }
83
+ })
84
+ .catch(err => {
85
+ console.error('[Slack] Notification error:', err.message);
86
+ });
87
+ }
88
+ //# sourceMappingURL=notifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../src/services/notifications.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Stripe Service
3
+ * Handles all Stripe-related operations including:
4
+ * - Checkout session creation
5
+ * - Subscription management
6
+ * - Customer portal
7
+ * - Webhook events
8
+ * Production deployment ready
9
+ */
10
+ import Stripe from 'stripe';
11
+ type SubscriptionTier = 'free' | 'starter' | 'pro' | 'business';
12
+ /**
13
+ * Get the Stripe instance, throwing an error if not configured.
14
+ * This allows the app to start even without Stripe keys,
15
+ * failing only when Stripe features are actually used.
16
+ */
17
+ export declare function getStripe(): Stripe;
18
+ export declare const stripe: Stripe;
19
+ export declare const STRIPE_PRICE_IDS: {
20
+ starter_monthly: string;
21
+ starter_annual: string;
22
+ pro_monthly: string;
23
+ pro_annual: string;
24
+ business_monthly: string;
25
+ business_annual: string;
26
+ };
27
+ /**
28
+ * Map Stripe price ID to subscription tier
29
+ */
30
+ export declare function priceIdToTier(priceId: string): SubscriptionTier;
31
+ /**
32
+ * Create a Stripe checkout session for a new subscription
33
+ */
34
+ export declare function createCheckoutSession(params: {
35
+ userId: string;
36
+ userEmail: string;
37
+ priceId: string;
38
+ successUrl: string;
39
+ cancelUrl: string;
40
+ trialDays?: number;
41
+ }): Promise<Stripe.Checkout.Session>;
42
+ /**
43
+ * Create a customer portal session for managing subscription
44
+ */
45
+ export declare function createCustomerPortalSession(params: {
46
+ customerId: string;
47
+ returnUrl: string;
48
+ }): Promise<Stripe.BillingPortal.Session>;
49
+ /**
50
+ * Start a free trial without requiring a credit card
51
+ * Creates a Stripe customer for future conversion, and a local subscription record
52
+ *
53
+ * @param userId - The user's ID in our database
54
+ * @param userEmail - The user's email address
55
+ * @param userName - Optional user name
56
+ * @param trialDays - Number of trial days (default 7)
57
+ * @returns The created Stripe customer ID and trial end date
58
+ */
59
+ export declare function startTrialWithoutPayment(params: {
60
+ userId: string;
61
+ userEmail: string;
62
+ userName?: string;
63
+ trialDays?: number;
64
+ }): Promise<{
65
+ customerId: string;
66
+ trialEndsAt: Date;
67
+ }>;
68
+ /**
69
+ * Handle Stripe webhook events
70
+ */
71
+ export declare function handleWebhookEvent(event: Stripe.Event): Promise<void>;
72
+ /**
73
+ * Verify Stripe webhook signature
74
+ */
75
+ export declare function verifyWebhookSignature(payload: string | Buffer, signature: string, secret: string): Stripe.Event;
76
+ /**
77
+ * Get subscription details for a user
78
+ */
79
+ export declare function getSubscriptionDetails(stripeSubscriptionId: string): Promise<Stripe.Subscription | null>;
80
+ /**
81
+ * Cancel a subscription at period end
82
+ */
83
+ export declare function cancelSubscription(stripeSubscriptionId: string): Promise<Stripe.Subscription>;
84
+ /**
85
+ * Resume a canceled subscription
86
+ */
87
+ export declare function resumeSubscription(stripeSubscriptionId: string): Promise<Stripe.Subscription>;
88
+ /**
89
+ * Update subscription to a new price (upgrade/downgrade)
90
+ */
91
+ export declare function updateSubscription(stripeSubscriptionId: string, newPriceId: string): Promise<Stripe.Subscription>;
92
+ export {};
93
+ //# sourceMappingURL=stripe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripe.d.ts","sourceRoot":"","sources":["../../src/services/stripe.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAQ5B,KAAK,gBAAgB,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,UAAU,CAAC;AAgBhE;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAQlC;AAGD,eAAO,MAAM,MAAM,QAIjB,CAAC;AAKH,eAAO,MAAM,gBAAgB;;;;;;;CAsB5B,CAAC;AAUF;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CA6B/D;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAuDnC;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAAC,MAAM,EAAE;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAQxC;AAED;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,IAAI,CAAA;CAAE,CAAC,CAiDrD;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA2C3E;AAuLD;;GAEG;AACH,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACf,MAAM,CAAC,KAAK,CAEd;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9G;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAInG;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAInG;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACpC,oBAAoB,EAAE,MAAM,EAC5B,UAAU,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAY9B"}