evaldoc 1.0.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 (139) hide show
  1. package/.env.staging.example +19 -0
  2. package/.firebaserc +6 -0
  3. package/.github/workflows/auto-merge-to-main.yml +28 -0
  4. package/.github/workflows/ci.yml +27 -0
  5. package/.github/workflows/npxhub-publish.yml +170 -0
  6. package/.prettierignore +4 -0
  7. package/.prettierrc.json +7 -0
  8. package/README.md +142 -0
  9. package/SRS.md +448 -0
  10. package/apphosting.staging.yaml +48 -0
  11. package/apphosting.yaml +50 -0
  12. package/bin/evaldoc.cjs +105 -0
  13. package/cors.json +8 -0
  14. package/docs/ARCHITECTURE.md +769 -0
  15. package/docs/ARCHITECTURE_SUMMARY.md +323 -0
  16. package/docs/DEPLOYMENT.md +86 -0
  17. package/docs/DEPLOYMENT_STEPS.md +373 -0
  18. package/docs/DEPLOY_FIRESTORE_RULES.md +239 -0
  19. package/docs/DEPLOY_STORAGE_RULES.md +82 -0
  20. package/docs/DOCTOR_TUTORIAL.md +467 -0
  21. package/docs/FIREBASE_STORAGE_CORS_FIX.md +131 -0
  22. package/docs/FIXES_APPLIED.md +128 -0
  23. package/docs/IMPLEMENTATION.md +498 -0
  24. package/docs/IMPLEMENTATION_COMPLETE.md +317 -0
  25. package/docs/LLM-SETUP.md +216 -0
  26. package/docs/MANUAL_TEST_GUIDE.md +327 -0
  27. package/docs/PATIENT_GUIDE.md +451 -0
  28. package/docs/PLATFORM_OVERVIEW.md +194 -0
  29. package/docs/QUICKSTART.md +252 -0
  30. package/docs/QUICK_REFERENCE.md +222 -0
  31. package/docs/READY_TO_TEST.md +383 -0
  32. package/docs/RUN.md +237 -0
  33. package/docs/START_TESTING.md +130 -0
  34. package/docs/STRIPE_CONNECT_SETUP.md +454 -0
  35. package/docs/SYSTEM_READY.md +345 -0
  36. package/docs/THREADS_IMPLEMENTATION_COMPLETE.md +431 -0
  37. package/docs/THREAD_IMPLEMENTATION_GUIDE.md +345 -0
  38. package/docs/firebasefiles.md +21 -0
  39. package/docs/homepage.md +1208 -0
  40. package/docs/payments.md +159 -0
  41. package/eslint.config.js +76 -0
  42. package/firebase.json +27 -0
  43. package/firestore.indexes.json +88 -0
  44. package/firestore.rules +125 -0
  45. package/functions/package-lock.json +2884 -0
  46. package/functions/package.json +20 -0
  47. package/functions/src/analytics.js +101 -0
  48. package/functions/src/audit.js +28 -0
  49. package/functions/src/auth.js +19 -0
  50. package/functions/src/drafts.js +128 -0
  51. package/functions/src/feedback.js +164 -0
  52. package/functions/src/firebase-init.js +29 -0
  53. package/functions/src/i18n.js +134 -0
  54. package/functions/src/limits.js +27 -0
  55. package/functions/src/llm.js +271 -0
  56. package/functions/src/ner.js +162 -0
  57. package/functions/src/notifications.js +273 -0
  58. package/functions/src/orgs.js +127 -0
  59. package/functions/src/patient-api.js +545 -0
  60. package/functions/src/payment.js +830 -0
  61. package/functions/src/safety.js +188 -0
  62. package/functions/src/stripe-config.js +33 -0
  63. package/functions/src/topics.js +94 -0
  64. package/functions/src/triage.js +191 -0
  65. package/functions/src/utils.js +28 -0
  66. package/functions/src/validate.js +177 -0
  67. package/functions/test-firebase.js +36 -0
  68. package/jest.config.js +18 -0
  69. package/package.json +52 -0
  70. package/public/404.html +93 -0
  71. package/public/app/analytics.html +336 -0
  72. package/public/app/analytics.js +177 -0
  73. package/public/app/app.css +1400 -0
  74. package/public/app/app.js +1754 -0
  75. package/public/app/config.js +14 -0
  76. package/public/app/inbox-threads.js +843 -0
  77. package/public/app/inbox.html +598 -0
  78. package/public/app/inbox.js +397 -0
  79. package/public/app/index.html +612 -0
  80. package/public/assets/logo.jpg +0 -0
  81. package/public/chat.html +137 -0
  82. package/public/css/chat.css +870 -0
  83. package/public/css/landing-enhance.css +298 -0
  84. package/public/css/styles.css +1198 -0
  85. package/public/favicon.svg +5 -0
  86. package/public/find-doctor.html +220 -0
  87. package/public/index.html +399 -0
  88. package/public/js/chat-threads.js +513 -0
  89. package/public/js/chat.js +832 -0
  90. package/public/js/search.js +41 -0
  91. package/public/privacy.html +101 -0
  92. package/public/robots.txt +6 -0
  93. package/public/site.webmanifest +12 -0
  94. package/public/terms.html +110 -0
  95. package/scripts/create-test-provider.js +55 -0
  96. package/scripts/deploy-staging.sh +51 -0
  97. package/scripts/fix-provider.js +39 -0
  98. package/scripts/quick-test.sh +37 -0
  99. package/scripts/test-chat.sh +54 -0
  100. package/scripts/test-multi-turn.js +137 -0
  101. package/scripts/test-ner-simple.js +28 -0
  102. package/scripts/test-ner.js +60 -0
  103. package/scripts/test-stripe-connect.js +304 -0
  104. package/scripts/test-webhook-secret.sh +24 -0
  105. package/server.js +3864 -0
  106. package/storage.rules +22 -0
  107. package/test-api.json +1 -0
  108. package/tests/emulator/README.md +38 -0
  109. package/tests/emulator/counters.emulator.test.js +81 -0
  110. package/tests/integration/api-account-selfserve.test.js +312 -0
  111. package/tests/integration/api-admin-digest.test.js +202 -0
  112. package/tests/integration/api-chat-satisfaction.test.js +259 -0
  113. package/tests/integration/api-doctor-drafts.test.js +236 -0
  114. package/tests/integration/api-doctor-inbox.test.js +401 -0
  115. package/tests/integration/api-org.test.js +328 -0
  116. package/tests/integration/api-payment.test.js +664 -0
  117. package/tests/integration/api-provider-settings.test.js +475 -0
  118. package/tests/integration/api-qr.test.js +121 -0
  119. package/tests/integration/api-security.test.js +241 -0
  120. package/tests/integration/api-stripe-search.test.js +303 -0
  121. package/tests/integration/api-webhook-deletion.test.js +231 -0
  122. package/tests/mocks/firebase-admin.js +220 -0
  123. package/tests/unit/analytics.test.js +151 -0
  124. package/tests/unit/audit-bugs.test.js +203 -0
  125. package/tests/unit/chat-ui-logic.test.js +283 -0
  126. package/tests/unit/drafts.test.js +104 -0
  127. package/tests/unit/feedback.test.js +148 -0
  128. package/tests/unit/i18n.test.js +229 -0
  129. package/tests/unit/llm-retry.test.js +122 -0
  130. package/tests/unit/notifications.test.js +155 -0
  131. package/tests/unit/orgs.test.js +328 -0
  132. package/tests/unit/payment.test.js +889 -0
  133. package/tests/unit/safety-edge-cases.test.js +509 -0
  134. package/tests/unit/safety-srs-compliance.test.js +252 -0
  135. package/tests/unit/safety.test.js +291 -0
  136. package/tests/unit/server-helpers.test.js +774 -0
  137. package/tests/unit/topics-limits.test.js +158 -0
  138. package/tests/unit/triage.test.js +152 -0
  139. package/tests/unit/validate.test.js +408 -0
@@ -0,0 +1,327 @@
1
+ # Manual Testing Guide - Stripe Connect Payment System
2
+
3
+ ## Prerequisites
4
+
5
+ ✅ Server running: `http://localhost:54112`
6
+ ✅ Stripe keys configured in `.env`
7
+ ✅ Firebase project access
8
+
9
+ ## Test Flow
10
+
11
+ ### Part 1: Provider Setup (Using Existing Provider)
12
+
13
+ Since you already have providers in your system, let's use one for testing.
14
+
15
+ #### 1. Sign into Provider Dashboard
16
+
17
+ 1. Go to: http://localhost:54112/app
18
+ 2. Sign in with an existing provider account
19
+ 3. You should see the dashboard
20
+
21
+ #### 2. Enable Stripe Connect
22
+
23
+ Open your browser's Developer Console (F12) and run:
24
+
25
+ ```javascript
26
+ // Get your Firebase ID token
27
+ firebase.auth().currentUser.getIdToken().then(token => {
28
+ console.log('Token:', token);
29
+
30
+ // Create Connect account
31
+ fetch('http://localhost:54112/api/stripe/create-connect-account', {
32
+ method: 'POST',
33
+ headers: {
34
+ 'Authorization': `Bearer ${token}`,
35
+ 'Content-Type': 'application/json'
36
+ }
37
+ })
38
+ .then(r => r.json())
39
+ .then(data => {
40
+ console.log('✓ Connect Account Created:', data);
41
+ // Save account ID
42
+ window.stripeAccountId = data.accountId;
43
+ });
44
+ });
45
+ ```
46
+
47
+ #### 3. Get Onboarding Link
48
+
49
+ ```javascript
50
+ firebase.auth().currentUser.getIdToken().then(token => {
51
+ fetch('http://localhost:54112/api/stripe/create-account-link', {
52
+ method: 'POST',
53
+ headers: {
54
+ 'Authorization': `Bearer ${token}`,
55
+ 'Content-Type': 'application/json'
56
+ }
57
+ })
58
+ .then(r => r.json())
59
+ .then(data => {
60
+ console.log('✓ Onboarding Link:', data.url);
61
+ // Open in new tab
62
+ window.open(data.url, '_blank');
63
+ });
64
+ });
65
+ ```
66
+
67
+ #### 4. Complete Stripe Onboarding
68
+
69
+ 1. Click the onboarding link that opens
70
+ 2. **Use test mode details**:
71
+ - Business type: Individual
72
+ - Country: United States
73
+ - Name: Test Provider
74
+ - DOB: 01/01/1990
75
+ - SSN: 000-00-0000 (test mode)
76
+ - Address: Any valid US address
77
+ - Bank: Use test routing number `110000000`
78
+ - Account: Any 10-12 digits
79
+
80
+ 3. Complete all steps
81
+ 4. You'll be redirected back to `/app?onboarding=complete`
82
+
83
+ #### 5. Set Subscription Pricing
84
+
85
+ ```javascript
86
+ firebase.auth().currentUser.getIdToken().then(token => {
87
+ fetch('http://localhost:54112/api/stripe/set-pricing', {
88
+ method: 'POST',
89
+ headers: {
90
+ 'Authorization': `Bearer ${token}`,
91
+ 'Content-Type': 'application/json'
92
+ },
93
+ body: JSON.stringify({
94
+ currency: 'usd',
95
+ prices: {
96
+ day: 5.00,
97
+ week: 20.00,
98
+ month: 50.00
99
+ }
100
+ })
101
+ })
102
+ .then(r => r.json())
103
+ .then(data => {
104
+ console.log('✓ Pricing Set:', data);
105
+ });
106
+ });
107
+ ```
108
+
109
+ ### Part 2: Patient Subscription
110
+
111
+ #### 6. Get Provider Info
112
+
113
+ First, get the provider's handle. In the console:
114
+
115
+ ```javascript
116
+ // Get current provider data
117
+ fetch('http://localhost:54112/api/me', {
118
+ headers: {
119
+ 'Authorization': `Bearer ${await firebase.auth().currentUser.getIdToken()}`
120
+ }
121
+ })
122
+ .then(r => r.json())
123
+ .then(data => {
124
+ console.log('Provider Handle:', data.handle);
125
+ window.providerHandle = data.handle;
126
+ });
127
+ ```
128
+
129
+ #### 7. Create Checkout Session (as Patient)
130
+
131
+ ```javascript
132
+ // Simulate patient with session ID
133
+ const patientSessionId = `test-patient-${Date.now()}`;
134
+
135
+ fetch('http://localhost:54112/api/payment/create-checkout-session', {
136
+ method: 'POST',
137
+ headers: {
138
+ 'Content-Type': 'application/json'
139
+ },
140
+ body: JSON.stringify({
141
+ handle: window.providerHandle, // Use provider handle from step 6
142
+ sessionId: patientSessionId,
143
+ interval: 'month' // or 'week' or 'day'
144
+ })
145
+ })
146
+ .then(r => r.json())
147
+ .then(data => {
148
+ console.log('✓ Checkout Session:', data);
149
+ console.log('Open this URL:', data.url);
150
+ window.open(data.url, '_blank');
151
+ // Save for later
152
+ window.patientSessionId = patientSessionId;
153
+ });
154
+ ```
155
+
156
+ #### 8. Complete Payment
157
+
158
+ 1. Click the checkout URL that opens
159
+ 2. **Use test card**:
160
+ - Card number: `4242 4242 4242 4242`
161
+ - Expiry: Any future date (e.g., `12/34`)
162
+ - CVC: Any 3 digits (e.g., `123`)
163
+ - ZIP: Any 5 digits (e.g., `12345`)
164
+
165
+ 3. Complete payment
166
+ 4. You'll be redirected to `/payment-success?session_id=...`
167
+
168
+ #### 9. Check Access (After Payment)
169
+
170
+ ```javascript
171
+ fetch('http://localhost:54112/api/payment/check-access', {
172
+ method: 'POST',
173
+ headers: {
174
+ 'Content-Type': 'application/json'
175
+ },
176
+ body: JSON.stringify({
177
+ handle: window.providerHandle,
178
+ sessionId: window.patientSessionId
179
+ })
180
+ })
181
+ .then(r => r.json())
182
+ .then(data => {
183
+ console.log('✓ Access Status:', data);
184
+ // Should show: { hasAccess: true, type: 'subscription' }
185
+ });
186
+ ```
187
+
188
+ ### Part 3: Verify in Firestore
189
+
190
+ Check your Firestore database:
191
+
192
+ 1. **providers/{uid}** - Should have:
193
+ - `stripeAccountId`: "acct_..."
194
+ - `stripeOnboardingStatus`: "COMPLETE"
195
+ - `chargesEnabled`: true
196
+ - `payoutsEnabled`: true
197
+ - `stripePriceIds`: { day: "price_...", week: "price_...", month: "price_..." }
198
+
199
+ 2. **patients/{sessionId}** - Should have:
200
+ - `stripeCustomerId`: "cus_..."
201
+
202
+ 3. **subscriptions** - Should have a document with:
203
+ - `providerId`: provider UID
204
+ - `patientId`: session ID
205
+ - `status`: "active"
206
+ - `stripeSubscriptionId`: "sub_..."
207
+
208
+ 4. **access/{providerId}_{patientId}** - Should have:
209
+ - `status`: "ACTIVE"
210
+ - `stripeSubscriptionId`: "sub_..."
211
+
212
+ ### Part 4: Verify Revenue
213
+
214
+ #### 10. Check Revenue in Provider Dashboard
215
+
216
+ ```javascript
217
+ firebase.auth().currentUser.getIdToken().then(token => {
218
+ fetch('http://localhost:54112/api/payment/revenue', {
219
+ headers: {
220
+ 'Authorization': `Bearer ${token}`
221
+ }
222
+ })
223
+ .then(r => r.json())
224
+ .then(data => {
225
+ console.log('✓ Revenue Analytics:', data);
226
+ });
227
+ });
228
+ ```
229
+
230
+ #### 11. Check Transaction History
231
+
232
+ ```javascript
233
+ firebase.auth().currentUser.getIdToken().then(token => {
234
+ fetch('http://localhost:54112/api/payment/transactions', {
235
+ headers: {
236
+ 'Authorization': `Bearer ${token}`
237
+ }
238
+ })
239
+ .then(r => r.json())
240
+ .then(data => {
241
+ console.log('✓ Transactions:', data);
242
+ });
243
+ });
244
+ ```
245
+
246
+ ### Part 5: Verify in Stripe Dashboard
247
+
248
+ 1. Go to: https://dashboard.stripe.com/test/connect/accounts
249
+ 2. You should see the provider's Connect account
250
+ 3. Click on it to see details
251
+
252
+ 4. Go to: https://dashboard.stripe.com/test/subscriptions
253
+ 5. You should see the patient's subscription
254
+ 6. Note the **25% application fee** is listed
255
+
256
+ 7. Go to: https://dashboard.stripe.com/test/balance
257
+ 8. You should see your 25% platform fee in the balance
258
+
259
+ ## Expected Results
260
+
261
+ ✅ Provider has Stripe Connect account created
262
+ ✅ Provider completes onboarding
263
+ ✅ Provider sets subscription prices
264
+ ✅ Patient can create checkout session
265
+ ✅ Patient completes payment
266
+ ✅ Access is granted automatically
267
+ ✅ Revenue shows in provider dashboard
268
+ ✅ Platform receives 25% fee
269
+ ✅ Provider receives 75% in their Connect account
270
+
271
+ ## Troubleshooting
272
+
273
+ ### "Provider has not set up payments yet"
274
+ - Run step 2 to create Connect account
275
+ - Complete Stripe onboarding (step 4)
276
+
277
+ ### "Provider payment account not yet approved"
278
+ - Complete all Stripe onboarding steps
279
+ - Check `chargesEnabled` is true in Firestore
280
+
281
+ ### "month subscription not available"
282
+ - Run step 5 to set pricing
283
+ - Check `stripePriceIds.month` exists in Firestore
284
+
285
+ ### Access still shows `hasAccess: false`
286
+ - Wait for webhooks to process (usually instant)
287
+ - Check webhook secret is configured
288
+ - Manually check `access` collection in Firestore
289
+
290
+ ## Clean Up Test Data
291
+
292
+ ```javascript
293
+ // Cancel subscription
294
+ fetch('http://localhost:54112/api/payment/cancel-subscription', {
295
+ method: 'POST',
296
+ headers: {
297
+ 'Content-Type': 'application/json'
298
+ },
299
+ body: JSON.stringify({
300
+ subscriptionId: 'sub_...', // From Firestore or Stripe dashboard
301
+ cancelAtPeriodEnd: false // Cancel immediately
302
+ })
303
+ });
304
+ ```
305
+
306
+ ## Next Steps
307
+
308
+ Once testing is successful:
309
+
310
+ 1. **Set up webhooks properly**:
311
+ - Go to https://dashboard.stripe.com/test/webhooks
312
+ - Add endpoint: `https://your-domain.com/api/payment/webhook`
313
+ - Copy webhook secret to `.env`
314
+
315
+ 2. **Switch to live mode**:
316
+ - Use live API keys (`pk_live_...` and `sk_live_...`)
317
+ - Complete business verification
318
+ - Update webhook URL to production
319
+
320
+ 3. **Add UI components** (optional):
321
+ - Onboarding button in provider dashboard
322
+ - Subscription picker for patients
323
+ - Revenue charts
324
+
325
+ ---
326
+
327
+ **Note**: Since we don't have webhook secret yet, access control won't update automatically. You can manually update the `access` collection in Firestore for testing purposes.