qualia-framework 2.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 (261) hide show
  1. package/README.md +50 -0
  2. package/bin/cli.js +519 -0
  3. package/framework/agents/architecture-strategist.md +53 -0
  4. package/framework/agents/backend-agent.md +150 -0
  5. package/framework/agents/code-simplicity-reviewer.md +86 -0
  6. package/framework/agents/frontend-agent.md +111 -0
  7. package/framework/agents/kieran-typescript-reviewer.md +96 -0
  8. package/framework/agents/performance-oracle.md +111 -0
  9. package/framework/agents/qualia-codebase-mapper.md +760 -0
  10. package/framework/agents/qualia-debugger.md +1203 -0
  11. package/framework/agents/qualia-executor.md +881 -0
  12. package/framework/agents/qualia-integration-checker.md +423 -0
  13. package/framework/agents/qualia-phase-researcher.md +453 -0
  14. package/framework/agents/qualia-plan-checker.md +699 -0
  15. package/framework/agents/qualia-planner.md +1241 -0
  16. package/framework/agents/qualia-project-researcher.md +602 -0
  17. package/framework/agents/qualia-research-synthesizer.md +236 -0
  18. package/framework/agents/qualia-roadmapper.md +605 -0
  19. package/framework/agents/qualia-verifier.md +685 -0
  20. package/framework/agents/team-orchestrator.md +228 -0
  21. package/framework/agents/teams/full-stack-team.md +48 -0
  22. package/framework/agents/teams/optimize-team.md +53 -0
  23. package/framework/agents/teams/review-team.md +62 -0
  24. package/framework/agents/teams/ship-team.md +86 -0
  25. package/framework/agents/test-agent.md +182 -0
  26. package/framework/askpass.sh +2 -0
  27. package/framework/commands/design.md +53 -0
  28. package/framework/commands/quick-db.md +22 -0
  29. package/framework/config/retention.json +35 -0
  30. package/framework/core/PRINCIPLES.md +77 -0
  31. package/framework/hooks/auto-format.sh +45 -0
  32. package/framework/hooks/block-env-edit.sh +42 -0
  33. package/framework/hooks/branch-guard.sh +46 -0
  34. package/framework/hooks/confirm-delete.sh +56 -0
  35. package/framework/hooks/migration-validate.sh +68 -0
  36. package/framework/hooks/notification-speak.sh +15 -0
  37. package/framework/hooks/pre-commit.sh +80 -0
  38. package/framework/hooks/pre-compact.sh +55 -0
  39. package/framework/hooks/pre-deploy-gate.sh +151 -0
  40. package/framework/hooks/qualia-colors.sh +32 -0
  41. package/framework/hooks/retention-cleanup.sh +43 -0
  42. package/framework/hooks/save-session-state.sh +153 -0
  43. package/framework/hooks/session-context-loader.sh +28 -0
  44. package/framework/hooks/session-learn.sh +30 -0
  45. package/framework/knowledge/claudecode-bible.md +1384 -0
  46. package/framework/knowledge/client-prefs.md +22 -0
  47. package/framework/knowledge/common-fixes.md +25 -0
  48. package/framework/knowledge/deployment-map.md +35 -0
  49. package/framework/knowledge/email-signature.html +1 -0
  50. package/framework/knowledge/employees.md +8 -0
  51. package/framework/knowledge/learned-patterns.md +51 -0
  52. package/framework/knowledge/optimization-research-2026.md +137 -0
  53. package/framework/knowledge/qualia-context.md +67 -0
  54. package/framework/knowledge/supabase-patterns.md +50 -0
  55. package/framework/knowledge/voice-agent-patterns.md +46 -0
  56. package/framework/qualia-engine/VERSION +1 -0
  57. package/framework/qualia-engine/bin/qualia-tools.js +2160 -0
  58. package/framework/qualia-engine/bin/qualia-tools.test.js +1054 -0
  59. package/framework/qualia-engine/references/checkpoints.md +775 -0
  60. package/framework/qualia-engine/references/continuation-format.md +249 -0
  61. package/framework/qualia-engine/references/decimal-phase-calculation.md +65 -0
  62. package/framework/qualia-engine/references/design-quality.md +56 -0
  63. package/framework/qualia-engine/references/git-integration.md +254 -0
  64. package/framework/qualia-engine/references/git-planning-commit.md +50 -0
  65. package/framework/qualia-engine/references/model-profile-resolution.md +32 -0
  66. package/framework/qualia-engine/references/model-profiles.md +73 -0
  67. package/framework/qualia-engine/references/phase-argument-parsing.md +61 -0
  68. package/framework/qualia-engine/references/planning-config.md +195 -0
  69. package/framework/qualia-engine/references/questioning.md +141 -0
  70. package/framework/qualia-engine/references/tdd.md +263 -0
  71. package/framework/qualia-engine/references/ui-brand.md +160 -0
  72. package/framework/qualia-engine/references/verification-patterns.md +612 -0
  73. package/framework/qualia-engine/templates/DEBUG.md +159 -0
  74. package/framework/qualia-engine/templates/DESIGN.md +81 -0
  75. package/framework/qualia-engine/templates/UAT.md +247 -0
  76. package/framework/qualia-engine/templates/codebase/architecture.md +255 -0
  77. package/framework/qualia-engine/templates/codebase/concerns.md +310 -0
  78. package/framework/qualia-engine/templates/codebase/conventions.md +307 -0
  79. package/framework/qualia-engine/templates/codebase/integrations.md +280 -0
  80. package/framework/qualia-engine/templates/codebase/stack.md +186 -0
  81. package/framework/qualia-engine/templates/codebase/structure.md +285 -0
  82. package/framework/qualia-engine/templates/codebase/testing.md +480 -0
  83. package/framework/qualia-engine/templates/config.json +35 -0
  84. package/framework/qualia-engine/templates/context.md +283 -0
  85. package/framework/qualia-engine/templates/continue-here.md +78 -0
  86. package/framework/qualia-engine/templates/debug-subagent-prompt.md +91 -0
  87. package/framework/qualia-engine/templates/discovery.md +146 -0
  88. package/framework/qualia-engine/templates/milestone-archive.md +123 -0
  89. package/framework/qualia-engine/templates/milestone.md +115 -0
  90. package/framework/qualia-engine/templates/phase-prompt.md +567 -0
  91. package/framework/qualia-engine/templates/planner-subagent-prompt.md +117 -0
  92. package/framework/qualia-engine/templates/project.md +184 -0
  93. package/framework/qualia-engine/templates/projects/ai-agent.md +156 -0
  94. package/framework/qualia-engine/templates/projects/mobile-app.md +181 -0
  95. package/framework/qualia-engine/templates/projects/voice-agent.md +134 -0
  96. package/framework/qualia-engine/templates/projects/website.md +137 -0
  97. package/framework/qualia-engine/templates/requirements.md +231 -0
  98. package/framework/qualia-engine/templates/research-project/ARCHITECTURE.md +204 -0
  99. package/framework/qualia-engine/templates/research-project/FEATURES.md +147 -0
  100. package/framework/qualia-engine/templates/research-project/PITFALLS.md +200 -0
  101. package/framework/qualia-engine/templates/research-project/STACK.md +120 -0
  102. package/framework/qualia-engine/templates/research-project/SUMMARY.md +170 -0
  103. package/framework/qualia-engine/templates/research.md +552 -0
  104. package/framework/qualia-engine/templates/roadmap.md +202 -0
  105. package/framework/qualia-engine/templates/state.md +176 -0
  106. package/framework/qualia-engine/templates/summary-complex.md +59 -0
  107. package/framework/qualia-engine/templates/summary-minimal.md +41 -0
  108. package/framework/qualia-engine/templates/summary-standard.md +48 -0
  109. package/framework/qualia-engine/templates/summary.md +246 -0
  110. package/framework/qualia-engine/templates/user-setup.md +311 -0
  111. package/framework/qualia-engine/templates/verification-report.md +322 -0
  112. package/framework/qualia-engine/workflows/add-phase.md +179 -0
  113. package/framework/qualia-engine/workflows/add-todo.md +157 -0
  114. package/framework/qualia-engine/workflows/audit-milestone.md +241 -0
  115. package/framework/qualia-engine/workflows/check-todos.md +176 -0
  116. package/framework/qualia-engine/workflows/complete-milestone.md +858 -0
  117. package/framework/qualia-engine/workflows/diagnose-issues.md +219 -0
  118. package/framework/qualia-engine/workflows/discovery-phase.md +289 -0
  119. package/framework/qualia-engine/workflows/discuss-phase.md +534 -0
  120. package/framework/qualia-engine/workflows/execute-phase.md +559 -0
  121. package/framework/qualia-engine/workflows/execute-plan.md +438 -0
  122. package/framework/qualia-engine/workflows/help.md +470 -0
  123. package/framework/qualia-engine/workflows/insert-phase.md +220 -0
  124. package/framework/qualia-engine/workflows/list-phase-assumptions.md +178 -0
  125. package/framework/qualia-engine/workflows/map-codebase.md +327 -0
  126. package/framework/qualia-engine/workflows/new-milestone.md +363 -0
  127. package/framework/qualia-engine/workflows/new-project.md +1037 -0
  128. package/framework/qualia-engine/workflows/pause-work.md +122 -0
  129. package/framework/qualia-engine/workflows/plan-milestone-gaps.md +256 -0
  130. package/framework/qualia-engine/workflows/plan-phase.md +422 -0
  131. package/framework/qualia-engine/workflows/progress.md +354 -0
  132. package/framework/qualia-engine/workflows/quick.md +252 -0
  133. package/framework/qualia-engine/workflows/remove-phase.md +326 -0
  134. package/framework/qualia-engine/workflows/research-phase.md +74 -0
  135. package/framework/qualia-engine/workflows/resume-project.md +306 -0
  136. package/framework/qualia-engine/workflows/set-profile.md +80 -0
  137. package/framework/qualia-engine/workflows/settings.md +145 -0
  138. package/framework/qualia-engine/workflows/transition.md +556 -0
  139. package/framework/qualia-engine/workflows/update.md +197 -0
  140. package/framework/qualia-engine/workflows/verify-phase.md +195 -0
  141. package/framework/qualia-engine/workflows/verify-work.md +625 -0
  142. package/framework/rules/context7.md +11 -0
  143. package/framework/rules/deployment.md +29 -0
  144. package/framework/rules/frontend.md +33 -0
  145. package/framework/rules/security.md +12 -0
  146. package/framework/rules/speed.md +20 -0
  147. package/framework/scripts/__pycache__/say.cpython-314.pyc +0 -0
  148. package/framework/scripts/apply-retention.sh +120 -0
  149. package/framework/scripts/bootstrap-pop-os.sh +354 -0
  150. package/framework/scripts/claude-voice +13 -0
  151. package/framework/scripts/cleanup.sh +131 -0
  152. package/framework/scripts/cowork-mode.sh +141 -0
  153. package/framework/scripts/generate-project-claude-md.sh +153 -0
  154. package/framework/scripts/load-test-webhook.js +172 -0
  155. package/framework/scripts/say.py +236 -0
  156. package/framework/scripts/showcase-video-recorder/ffmpeg-builder.js +167 -0
  157. package/framework/scripts/showcase-video-recorder/playwright-helpers.js +216 -0
  158. package/framework/scripts/speak.py +55 -0
  159. package/framework/scripts/speak.sh +18 -0
  160. package/framework/scripts/status.sh +138 -0
  161. package/framework/scripts/sync-to-framework.sh +65 -0
  162. package/framework/scripts/voice-hotkey.py +227 -0
  163. package/framework/scripts/voice-input.sh +51 -0
  164. package/framework/skills/animate/SKILL.md +202 -0
  165. package/framework/skills/bolder/SKILL.md +144 -0
  166. package/framework/skills/browser-qa/SKILL.md +536 -0
  167. package/framework/skills/clarify/SKILL.md +179 -0
  168. package/framework/skills/colorize/SKILL.md +170 -0
  169. package/framework/skills/critique/SKILL.md +126 -0
  170. package/framework/skills/deep-research/SKILL.md +271 -0
  171. package/framework/skills/delight/SKILL.md +329 -0
  172. package/framework/skills/deploy/SKILL.md +261 -0
  173. package/framework/skills/deploy-verify/SKILL.md +377 -0
  174. package/framework/skills/deploy-verify/scripts/canary-check.sh +206 -0
  175. package/framework/skills/deploy-verify/scripts/check-console-errors.js +147 -0
  176. package/framework/skills/deploy-verify/scripts/check-cwv.js +139 -0
  177. package/framework/skills/deploy-verify/scripts/project-detect.sh +84 -0
  178. package/framework/skills/deploy-verify/scripts/verify.sh +548 -0
  179. package/framework/skills/design-quieter/SKILL.md +130 -0
  180. package/framework/skills/distill/SKILL.md +149 -0
  181. package/framework/skills/docs-lookup/SKILL.md +78 -0
  182. package/framework/skills/fcm-notifications/SKILL.md +125 -0
  183. package/framework/skills/financial-ledger/SKILL.md +1039 -0
  184. package/framework/skills/frontend-master/NOTICE.md +4 -0
  185. package/framework/skills/frontend-master/SKILL.md +127 -0
  186. package/framework/skills/frontend-master/reference/color-and-contrast.md +132 -0
  187. package/framework/skills/frontend-master/reference/interaction-design.md +123 -0
  188. package/framework/skills/frontend-master/reference/motion-design.md +99 -0
  189. package/framework/skills/frontend-master/reference/responsive-design.md +114 -0
  190. package/framework/skills/frontend-master/reference/spatial-design.md +100 -0
  191. package/framework/skills/frontend-master/reference/typography.md +131 -0
  192. package/framework/skills/frontend-master/reference/ux-writing.md +107 -0
  193. package/framework/skills/harden/SKILL.md +357 -0
  194. package/framework/skills/i18n-rtl/SKILL.md +752 -0
  195. package/framework/skills/learn/SKILL.md +71 -0
  196. package/framework/skills/memory/SKILL.md +50 -0
  197. package/framework/skills/mobile-expo/SKILL.md +864 -0
  198. package/framework/skills/mobile-expo/references/store-checklist.md +550 -0
  199. package/framework/skills/nestjs-backend/README.md +73 -0
  200. package/framework/skills/nestjs-backend/SKILL.md +446 -0
  201. package/framework/skills/nestjs-backend/references/templates.md +1173 -0
  202. package/framework/skills/normalize/SKILL.md +79 -0
  203. package/framework/skills/onboard/SKILL.md +242 -0
  204. package/framework/skills/polish/SKILL.md +209 -0
  205. package/framework/skills/pr/SKILL.md +66 -0
  206. package/framework/skills/qualia/SKILL.md +153 -0
  207. package/framework/skills/qualia-add-todo/SKILL.md +68 -0
  208. package/framework/skills/qualia-audit-milestone/SKILL.md +92 -0
  209. package/framework/skills/qualia-check-todos/SKILL.md +55 -0
  210. package/framework/skills/qualia-complete-milestone/SKILL.md +108 -0
  211. package/framework/skills/qualia-debug/SKILL.md +149 -0
  212. package/framework/skills/qualia-design/SKILL.md +203 -0
  213. package/framework/skills/qualia-discuss-phase/SKILL.md +72 -0
  214. package/framework/skills/qualia-execute-phase/SKILL.md +86 -0
  215. package/framework/skills/qualia-help/SKILL.md +67 -0
  216. package/framework/skills/qualia-idk/SKILL.md +352 -0
  217. package/framework/skills/qualia-list-phase-assumptions/SKILL.md +67 -0
  218. package/framework/skills/qualia-new-milestone/SKILL.md +72 -0
  219. package/framework/skills/qualia-new-project/SKILL.md +92 -0
  220. package/framework/skills/qualia-optimize/SKILL.md +417 -0
  221. package/framework/skills/qualia-pause-work/SKILL.md +96 -0
  222. package/framework/skills/qualia-plan-milestone-gaps/SKILL.md +57 -0
  223. package/framework/skills/qualia-plan-phase/SKILL.md +101 -0
  224. package/framework/skills/qualia-progress/SKILL.md +53 -0
  225. package/framework/skills/qualia-quick/SKILL.md +89 -0
  226. package/framework/skills/qualia-research-phase/SKILL.md +88 -0
  227. package/framework/skills/qualia-resume-work/SKILL.md +62 -0
  228. package/framework/skills/qualia-review/SKILL.md +263 -0
  229. package/framework/skills/qualia-start/SKILL.md +182 -0
  230. package/framework/skills/qualia-verify-work/SKILL.md +105 -0
  231. package/framework/skills/qualia-workflow/SKILL.md +130 -0
  232. package/framework/skills/rag/SKILL.md +750 -0
  233. package/framework/skills/responsive/SKILL.md +231 -0
  234. package/framework/skills/retro/SKILL.md +284 -0
  235. package/framework/skills/sakani-conventions/SKILL.md +136 -0
  236. package/framework/skills/sakani-conventions/evals/evals.json +23 -0
  237. package/framework/skills/sakani-conventions/references/entities.md +365 -0
  238. package/framework/skills/sakani-conventions/references/error-codes.md +95 -0
  239. package/framework/skills/seo-master/SKILL.md +490 -0
  240. package/framework/skills/seo-master/references/checklist.md +199 -0
  241. package/framework/skills/seo-master/references/structured-data.md +609 -0
  242. package/framework/skills/ship/SKILL.md +202 -0
  243. package/framework/skills/stack-researcher/SKILL.md +215 -0
  244. package/framework/skills/status/SKILL.md +154 -0
  245. package/framework/skills/status/scripts/health-check.sh +562 -0
  246. package/framework/skills/subscription-payments/SKILL.md +250 -0
  247. package/framework/skills/supabase/SKILL.md +973 -0
  248. package/framework/skills/supabase/references/templates.md +159 -0
  249. package/framework/skills/team/SKILL.md +67 -0
  250. package/framework/skills/test-runner/SKILL.md +202 -0
  251. package/framework/skills/voice-agent/SKILL.md +407 -0
  252. package/framework/skills/zoho-workflow/SKILL.md +51 -0
  253. package/framework/statusline-command.sh +117 -0
  254. package/package.json +24 -0
  255. package/profiles/fawzi.json +16 -0
  256. package/profiles/hasan.json +16 -0
  257. package/profiles/moayad.json +16 -0
  258. package/templates/CLAUDE-owner.md +52 -0
  259. package/templates/CLAUDE.md.hbs +58 -0
  260. package/templates/env.claude.template +12 -0
  261. package/templates/settings.json +141 -0
@@ -0,0 +1,250 @@
1
+ ---
2
+ name: subscription-payments
3
+ description: "Subscription billing and payment gateway integration — Stripe/HyperPay adapter pattern, checkout sessions, webhook ingestion with signature validation, promo codes, subscription lifecycle management, and provider abstraction. Use whenever implementing payment processing, subscription management, checkout flows, webhook handlers, promo/discount systems, or payment provider integrations. Triggers on: subscription, payment, Stripe, HyperPay, checkout, webhook, billing, promo code, discount, payment gateway, recurring payment."
4
+ tags: [payments, subscription, stripe, billing]
5
+ ---
6
+
7
+ ## Provider Adapter Pattern
8
+
9
+ Abstract payment providers behind a common interface:
10
+
11
+ ```typescript
12
+ interface PaymentProvider {
13
+ createCheckoutSession(params: CheckoutParams): Promise<CheckoutSession>;
14
+ verifyWebhookSignature(payload: string, signature: string): boolean;
15
+ cancelSubscription(providerSubscriptionId: string): Promise<void>;
16
+ getSubscriptionStatus(providerSubscriptionId: string): Promise<SubscriptionStatus>;
17
+ }
18
+
19
+ class StripeProvider implements PaymentProvider {
20
+ // Stripe-specific implementation
21
+ }
22
+
23
+ class HyperPayProvider implements PaymentProvider {
24
+ // HyperPay-specific implementation
25
+ }
26
+
27
+ class PaymentProviderFactory {
28
+ static create(provider: 'stripe' | 'hyperpay'): PaymentProvider {
29
+ switch (provider) {
30
+ case 'stripe':
31
+ return new StripeProvider();
32
+ case 'hyperpay':
33
+ return new HyperPayProvider();
34
+ default:
35
+ throw new Error(`Unknown provider: ${provider}`);
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ - StripeProvider implements PaymentProvider
42
+ - HyperPayProvider implements PaymentProvider
43
+ - Factory pattern selects provider based on config
44
+ - Provider-specific logic NEVER leaks outside adapter
45
+
46
+ ## Checkout Flow
47
+
48
+ 1. Client requests price quote (snapshot pricing inputs + expiry)
49
+ 2. Client applies promo code (optional — RESERVED state)
50
+ 3. Client creates checkout session (validates quote not expired/consumed)
51
+ 4. Redirect to provider-hosted checkout page
52
+ 5. Provider webhook confirms payment
53
+ 6. System activates subscription + consumes promo
54
+
55
+ ## Webhook Ingestion
56
+
57
+ Critical security component:
58
+
59
+ ```typescript
60
+ @Post('webhooks/:provider')
61
+ async handleWebhook(@Req() req, @Param('provider') provider: string) {
62
+ // 1. Verify signature (BEFORE parsing body)
63
+ const isValid = this.paymentService.verifySignature(
64
+ provider,
65
+ req.rawBody,
66
+ req.headers
67
+ );
68
+ if (!isValid) throw new UnauthorizedException('WEBHOOK_SIGNATURE_INVALID');
69
+
70
+ // 2. Parse to canonical event (provider-agnostic)
71
+ const event = this.paymentService.normalizeEvent(provider, req.body);
72
+
73
+ // 3. Idempotency check (provider_event_id is unique)
74
+ const existing = await this.findEvent(event.providerEventId);
75
+ if (existing) return { received: true }; // Already processed
76
+
77
+ // 4. Store raw event for audit
78
+ await this.storeEvent(event);
79
+
80
+ // 5. Handle canonical event
81
+ await this.processEvent(event);
82
+
83
+ return { received: true };
84
+ }
85
+ ```
86
+
87
+ - Always verify signature FIRST
88
+ - Always check idempotency (webhooks can be retried)
89
+ - Store raw payload for debugging
90
+ - Normalize to canonical events before processing
91
+
92
+ ## Canonical Event Types
93
+
94
+ Map provider-specific events to canonical types:
95
+
96
+ ```typescript
97
+ type CanonicalEventType =
98
+ | 'checkout.completed'
99
+ | 'subscription.activated'
100
+ | 'subscription.renewed'
101
+ | 'subscription.cancelled'
102
+ | 'subscription.payment_failed'
103
+ | 'refund.completed';
104
+
105
+ interface CanonicalEvent {
106
+ id: string;
107
+ providerEventId: string;
108
+ type: CanonicalEventType;
109
+ provider: 'stripe' | 'hyperpay';
110
+ timestamp: Date;
111
+ data: Record<string, any>;
112
+ }
113
+ ```
114
+
115
+ ## Subscription Lifecycle
116
+
117
+ TRIAL (30 days) → ACTIVE (payment confirmed) → INACTIVE (cancelled/expired/failed)
118
+
119
+ - Trial starts on building creation
120
+ - Trial expiry: background job checks daily
121
+ - Activation: webhook confirms first payment
122
+ - Renewal: webhook confirms recurring payment
123
+ - Cancellation: webhook or manual admin action
124
+ - Failed payment: grace period → INACTIVE
125
+
126
+ ```typescript
127
+ enum SubscriptionStatus {
128
+ TRIAL = 'trial',
129
+ ACTIVE = 'active',
130
+ INACTIVE = 'inactive',
131
+ CANCELLED = 'cancelled',
132
+ }
133
+
134
+ interface Subscription {
135
+ id: string;
136
+ buildingId: string;
137
+ status: SubscriptionStatus;
138
+ providerSubscriptionId: string;
139
+ currentPeriodStart: Date;
140
+ currentPeriodEnd: Date;
141
+ trialEndsAt: Date | null;
142
+ cancelledAt: Date | null;
143
+ }
144
+ ```
145
+
146
+ ## Promo Code System
147
+
148
+ - Codes have: discount_type (PERCENTAGE|FIXED), discount_value, max_redemptions, valid_from/until
149
+ - Redemption lifecycle: RESERVED (on checkout start) → CONSUMED (on payment success)
150
+ - Reservation is atomic (check-and-reserve in single query)
151
+ - If checkout abandoned, RESERVED codes expire after timeout
152
+ - If payment fails, RESERVED reverts to available
153
+
154
+ ```typescript
155
+ enum PromoCodeStatus {
156
+ AVAILABLE = 'available',
157
+ RESERVED = 'reserved',
158
+ CONSUMED = 'consumed',
159
+ EXPIRED = 'expired',
160
+ }
161
+
162
+ interface PromoCode {
163
+ code: string;
164
+ discountType: 'PERCENTAGE' | 'FIXED';
165
+ discountValue: number;
166
+ maxRedemptions: number;
167
+ currentRedemptions: number;
168
+ validFrom: Date;
169
+ validUntil: Date;
170
+ reservationExpiry: number; // minutes
171
+ }
172
+
173
+ interface PromoReservation {
174
+ promoCodeId: string;
175
+ checkoutSessionId: string;
176
+ reservedAt: Date;
177
+ expiresAt: Date;
178
+ }
179
+ ```
180
+
181
+ ## Price Quotes
182
+
183
+ - Quote snapshots pricing inputs (building_type, unit_count, plan) at creation time
184
+ - Quotes have expiry (prevents stale pricing)
185
+ - Quote is consumed when checkout session is created
186
+ - One quote → one checkout session (no reuse)
187
+
188
+ ```typescript
189
+ interface PriceQuote {
190
+ id: string;
191
+ buildingId: string;
192
+ buildingType: string;
193
+ unitCount: number;
194
+ plan: string;
195
+ basePrice: number;
196
+ promoCodeId?: string;
197
+ promoDiscount: number;
198
+ finalPrice: number;
199
+ currency: string;
200
+ expiresAt: Date;
201
+ consumed: boolean;
202
+ consumedAt?: Date;
203
+ }
204
+ ```
205
+
206
+ ## Reimbursement
207
+
208
+ When BM pays subscription on behalf of building:
209
+ - Create reimbursement_obligation on payment success
210
+ - Settlement methods: DUES_OFFSET (automatic) or MANUAL (staff-only)
211
+ - Idempotent creation (same checkout → same reimbursement)
212
+
213
+ ```typescript
214
+ enum SettlementMethod {
215
+ DUES_OFFSET = 'dues_offset',
216
+ MANUAL = 'manual',
217
+ }
218
+
219
+ interface ReimbursementObligation {
220
+ id: string;
221
+ checkoutSessionId: string;
222
+ subscriptionId: string;
223
+ buildingId: string;
224
+ amount: number;
225
+ currency: string;
226
+ settlementMethod: SettlementMethod;
227
+ settledAt?: Date;
228
+ createdAt: Date;
229
+ }
230
+ ```
231
+
232
+ ## Security
233
+
234
+ - Never log full card numbers or payment tokens
235
+ - Webhook endpoints have no auth (signature validation instead)
236
+ - Use provider's hosted checkout (never handle card data directly — PCI compliance)
237
+ - Store provider customer/subscription IDs, not payment methods
238
+ - Webhook signature verification is mandatory before any processing
239
+ - All webhook events stored for audit trail
240
+ - Idempotency keys prevent duplicate charges from retried webhooks
241
+
242
+ ## Testing
243
+
244
+ - Mock payment providers in tests (never hit real APIs)
245
+ - Test webhook signature validation with known test signatures
246
+ - Test idempotency (same webhook delivered twice)
247
+ - Test promo code edge cases (expired, exhausted, concurrent reservations)
248
+ - Test quote expiry and consumption
249
+ - Test subscription lifecycle state transitions
250
+ - Test reimbursement obligation creation idempotency