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,383 @@
1
+ # 🎉 Ready to Test - Complete Stripe Connect System
2
+
3
+ ## ✅ System Status: READY
4
+
5
+ Your Stripe Connect payment system is fully configured and ready to test!
6
+
7
+ ### What's Configured ✅
8
+
9
+ - ✅ Stripe API Keys (Live mode)
10
+ - ✅ Stripe Webhook Secret
11
+ - ✅ Server running on http://localhost:54112
12
+ - ✅ All 11 payment endpoints responding
13
+ - ✅ Firebase connected
14
+ - ✅ Database schema ready
15
+
16
+ ---
17
+
18
+ ## Quick Start Testing
19
+
20
+ ### Method 1: Browser Console (Easiest)
21
+
22
+ 1. **Open Provider Dashboard**
23
+ ```
24
+ http://localhost:54112/app
25
+ ```
26
+
27
+ 2. **Sign In** with your existing provider account
28
+
29
+ 3. **Open Developer Console** (Press F12)
30
+
31
+ 4. **Copy/Paste These Commands** one at a time:
32
+
33
+ #### Step 1: Create Stripe Connect Account
34
+ ```javascript
35
+ firebase.auth().currentUser.getIdToken().then(token => {
36
+ fetch('http://localhost:54112/api/stripe/create-connect-account', {
37
+ method: 'POST',
38
+ headers: {
39
+ 'Authorization': `Bearer ${token}`,
40
+ 'Content-Type': 'application/json'
41
+ }
42
+ })
43
+ .then(r => r.json())
44
+ .then(data => {
45
+ console.log('✅ Connect Account:', data);
46
+ window.stripeAccountId = data.accountId;
47
+ })
48
+ .catch(err => console.error('❌ Error:', err));
49
+ });
50
+ ```
51
+
52
+ Expected output:
53
+ ```json
54
+ {
55
+ "accountId": "acct_...",
56
+ "onboardingStatus": "PENDING"
57
+ }
58
+ ```
59
+
60
+ #### Step 2: Get Onboarding Link
61
+ ```javascript
62
+ firebase.auth().currentUser.getIdToken().then(token => {
63
+ fetch('http://localhost:54112/api/stripe/create-account-link', {
64
+ method: 'POST',
65
+ headers: {
66
+ 'Authorization': `Bearer ${token}`,
67
+ 'Content-Type': 'application/json'
68
+ }
69
+ })
70
+ .then(r => r.json())
71
+ .then(data => {
72
+ console.log('✅ Onboarding URL:', data.url);
73
+ window.open(data.url, '_blank');
74
+ })
75
+ .catch(err => console.error('❌ Error:', err));
76
+ });
77
+ ```
78
+
79
+ This will open Stripe's onboarding page. Use test data:
80
+ - Business type: Individual
81
+ - Country: United States
82
+ - SSN: 000-00-0000 (test mode)
83
+ - Bank routing: 110000000
84
+ - Bank account: Any 10 digits
85
+
86
+ #### Step 3: Refresh Account Status (After Onboarding)
87
+ ```javascript
88
+ firebase.auth().currentUser.getIdToken().then(token => {
89
+ fetch('http://localhost:54112/api/stripe/refresh-account-status', {
90
+ method: 'POST',
91
+ headers: {
92
+ 'Authorization': `Bearer ${token}`,
93
+ 'Content-Type': 'application/json'
94
+ }
95
+ })
96
+ .then(r => r.json())
97
+ .then(data => {
98
+ console.log('✅ Account Status:', data);
99
+ })
100
+ .catch(err => console.error('❌ Error:', err));
101
+ });
102
+ ```
103
+
104
+ Expected: `chargesEnabled: true, payoutsEnabled: true`
105
+
106
+ #### Step 4: Set Pricing
107
+ ```javascript
108
+ firebase.auth().currentUser.getIdToken().then(token => {
109
+ fetch('http://localhost:54112/api/stripe/set-pricing', {
110
+ method: 'POST',
111
+ headers: {
112
+ 'Authorization': `Bearer ${token}`,
113
+ 'Content-Type': 'application/json'
114
+ },
115
+ body: JSON.stringify({
116
+ currency: 'usd',
117
+ prices: {
118
+ day: 5.00,
119
+ week: 20.00,
120
+ month: 50.00
121
+ }
122
+ })
123
+ })
124
+ .then(r => r.json())
125
+ .then(data => {
126
+ console.log('✅ Pricing Set:', data);
127
+ })
128
+ .catch(err => console.error('❌ Error:', err));
129
+ });
130
+ ```
131
+
132
+ #### Step 5: Get Provider Handle
133
+ ```javascript
134
+ firebase.auth().currentUser.getIdToken().then(token => {
135
+ fetch('http://localhost:54112/api/me', {
136
+ headers: { 'Authorization': `Bearer ${token}` }
137
+ })
138
+ .then(r => r.json())
139
+ .then(data => {
140
+ console.log('✅ Provider Handle:', data.handle);
141
+ window.providerHandle = data.handle;
142
+ })
143
+ .catch(err => console.error('❌ Error:', err));
144
+ });
145
+ ```
146
+
147
+ #### Step 6: Create Checkout Session (As Patient)
148
+ ```javascript
149
+ const patientSessionId = `test-patient-${Date.now()}`;
150
+ window.patientSessionId = patientSessionId;
151
+
152
+ fetch('http://localhost:54112/api/payment/create-checkout-session', {
153
+ method: 'POST',
154
+ headers: { 'Content-Type': 'application/json' },
155
+ body: JSON.stringify({
156
+ handle: window.providerHandle,
157
+ sessionId: patientSessionId,
158
+ interval: 'month'
159
+ })
160
+ })
161
+ .then(r => r.json())
162
+ .then(data => {
163
+ console.log('✅ Checkout Session:', data);
164
+ console.log('💳 Open this URL to pay:', data.url);
165
+ window.open(data.url, '_blank');
166
+ })
167
+ .catch(err => console.error('❌ Error:', err));
168
+ ```
169
+
170
+ #### Step 7: Complete Payment
171
+
172
+ Click the checkout URL that opens. Use test card:
173
+ - **Card**: 4242 4242 4242 4242
174
+ - **Expiry**: 12/34
175
+ - **CVC**: 123
176
+ - **ZIP**: 12345
177
+
178
+ #### Step 8: Check Access (After Payment)
179
+ ```javascript
180
+ fetch('http://localhost:54112/api/payment/check-access', {
181
+ method: 'POST',
182
+ headers: { 'Content-Type': 'application/json' },
183
+ body: JSON.stringify({
184
+ handle: window.providerHandle,
185
+ sessionId: window.patientSessionId
186
+ })
187
+ })
188
+ .then(r => r.json())
189
+ .then(data => {
190
+ console.log('✅ Access Status:', data);
191
+ // Should show: { hasAccess: true, type: 'subscription' }
192
+ })
193
+ .catch(err => console.error('❌ Error:', err));
194
+ ```
195
+
196
+ #### Step 9: Check Revenue
197
+ ```javascript
198
+ firebase.auth().currentUser.getIdToken().then(token => {
199
+ fetch('http://localhost:54112/api/payment/revenue', {
200
+ headers: { 'Authorization': `Bearer ${token}` }
201
+ })
202
+ .then(r => r.json())
203
+ .then(data => {
204
+ console.log('✅ Revenue:', data);
205
+ })
206
+ .catch(err => console.error('❌ Error:', err));
207
+ });
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Method 2: cURL Testing
213
+
214
+ If you prefer command line:
215
+
216
+ ```bash
217
+ # 1. Create checkout session (replace PROVIDER_HANDLE)
218
+ curl -X POST http://localhost:54112/api/payment/create-checkout-session \
219
+ -H "Content-Type: application/json" \
220
+ -d '{
221
+ "handle": "YOUR_PROVIDER_HANDLE",
222
+ "sessionId": "test-patient-123",
223
+ "interval": "month"
224
+ }'
225
+
226
+ # 2. Check access
227
+ curl -X POST http://localhost:54112/api/payment/check-access \
228
+ -H "Content-Type: application/json" \
229
+ -d '{
230
+ "handle": "YOUR_PROVIDER_HANDLE",
231
+ "sessionId": "test-patient-123"
232
+ }'
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Verify in Stripe Dashboard
238
+
239
+ 1. **Go to**: https://dashboard.stripe.com/test/connect/accounts
240
+ 2. **Check**: Provider's Connect account
241
+ 3. **Go to**: https://dashboard.stripe.com/test/subscriptions
242
+ 4. **Check**: Patient subscription with 25% application fee
243
+ 5. **Go to**: https://dashboard.stripe.com/test/balance
244
+ 6. **Check**: Your platform's 25% fee in balance
245
+
246
+ ---
247
+
248
+ ## Verify in Firestore
249
+
250
+ Check these collections in Firebase Console:
251
+
252
+ ### providers/{uid}
253
+ Should have:
254
+ ```json
255
+ {
256
+ "stripeAccountId": "acct_...",
257
+ "stripeOnboardingStatus": "COMPLETE",
258
+ "chargesEnabled": true,
259
+ "payoutsEnabled": true,
260
+ "stripeProductId": "prod_...",
261
+ "stripePriceIds": {
262
+ "day": "price_...",
263
+ "week": "price_...",
264
+ "month": "price_..."
265
+ }
266
+ }
267
+ ```
268
+
269
+ ### patients/{sessionId}
270
+ Should have:
271
+ ```json
272
+ {
273
+ "stripeCustomerId": "cus_...",
274
+ "createdAt": "...",
275
+ "updatedAt": "..."
276
+ }
277
+ ```
278
+
279
+ ### subscriptions (auto-generated doc ID)
280
+ Should have:
281
+ ```json
282
+ {
283
+ "providerId": "...",
284
+ "patientId": "test-patient-...",
285
+ "status": "active",
286
+ "stripeSubscriptionId": "sub_...",
287
+ "stripeCustomerId": "cus_...",
288
+ "stripePriceId": "price_..."
289
+ }
290
+ ```
291
+
292
+ ### access/{providerId}_{patientId}
293
+ Should have:
294
+ ```json
295
+ {
296
+ "providerId": "...",
297
+ "patientId": "test-patient-...",
298
+ "status": "ACTIVE",
299
+ "stripeSubscriptionId": "sub_..."
300
+ }
301
+ ```
302
+
303
+ ---
304
+
305
+ ## Expected Results
306
+
307
+ ✅ Provider creates Stripe Connect account (programmatic)
308
+ ✅ Provider completes onboarding in Stripe
309
+ ✅ Provider sets subscription prices
310
+ ✅ Patient creates checkout session
311
+ ✅ Patient pays with test card
312
+ ✅ Subscription created with 25% platform fee
313
+ ✅ Access granted automatically via webhook
314
+ ✅ Revenue appears in provider dashboard
315
+ ✅ Platform receives 25% in Stripe balance
316
+ ✅ Provider receives 75% in Connect account
317
+
318
+ ---
319
+
320
+ ## Troubleshooting
321
+
322
+ ### "Provider has not set up payments yet"
323
+ → Run Step 1 to create Connect account
324
+ → Complete Step 2 onboarding
325
+
326
+ ### "Provider payment account not yet approved"
327
+ → Complete all Stripe onboarding steps
328
+ → Run Step 3 to refresh status
329
+
330
+ ### "month subscription not available"
331
+ → Run Step 4 to set pricing
332
+ → Check Firestore for `stripePriceIds.month`
333
+
334
+ ### Access shows `hasAccess: false` after payment
335
+ → Wait 5-10 seconds for webhooks
336
+ → Check webhook secret is configured
337
+ → Check Firestore `access` collection manually
338
+
339
+ ### Firebase error in console
340
+ → Refresh the page
341
+ → Sign out and sign back in
342
+ → Clear browser cache
343
+
344
+ ---
345
+
346
+ ## What's Next?
347
+
348
+ Once testing is successful:
349
+
350
+ 1. **Production Deployment**
351
+ - Use live Stripe keys
352
+ - Update webhook URL to production
353
+ - Complete Stripe business verification
354
+
355
+ 2. **UI Enhancements** (Optional)
356
+ - Add onboarding button to dashboard
357
+ - Add subscription picker for patients
358
+ - Add revenue charts
359
+
360
+ 3. **Features** (Optional)
361
+ - Email notifications
362
+ - Subscription management
363
+ - Refunds
364
+ - Promo codes
365
+
366
+ ---
367
+
368
+ ## Files to Reference
369
+
370
+ - [STRIPE_CONNECT_SETUP.md](STRIPE_CONNECT_SETUP.md) - Complete technical docs
371
+ - [MANUAL_TEST_GUIDE.md](MANUAL_TEST_GUIDE.md) - Detailed testing guide
372
+ - [IMPLEMENTATION_COMPLETE.md](IMPLEMENTATION_COMPLETE.md) - System summary
373
+
374
+ ---
375
+
376
+ 🎉 **Your system is ready! Start testing now at http://localhost:54112/app**
377
+
378
+ **Webhook Secret**: ✅ Configured
379
+ **Server**: ✅ Running
380
+ **Endpoints**: ✅ All responding
381
+ **Documentation**: ✅ Complete
382
+
383
+ **Status**: READY TO TEST 🚀
package/docs/RUN.md ADDED
@@ -0,0 +1,237 @@
1
+ # How to Run EvalDoc
2
+
3
+ ## Simple Node.js App
4
+
5
+ This is now a **simple, unified Node.js Express application**. No Firebase CLI needed!
6
+
7
+ ## Prerequisites
8
+
9
+ 1. **Node.js 18+** installed
10
+ 2. **Firebase project credentials** (for database access)
11
+
12
+ ## Quick Start
13
+
14
+ ### 1. Install Dependencies
15
+
16
+ ```bash
17
+ npm install
18
+ ```
19
+
20
+
21
+ ### 2. Set up Firebase Credentials
22
+
23
+ You need Firebase Admin SDK credentials. Two options:
24
+
25
+ **Option A: Application Default Credentials (Easiest)**
26
+ ```bash
27
+ # Login to Google Cloud
28
+ gcloud auth application-default login
29
+ ```
30
+
31
+ **Option B: Service Account Key**
32
+ 1. Go to [Firebase Console](https://console.firebase.google.com/)
33
+ 2. Select project: **evaldocplatform**
34
+ 3. Go to Project Settings → Service Accounts
35
+ 4. Click "Generate New Private Key"
36
+ 5. Save as `serviceAccountKey.json` in project root
37
+
38
+ Then set environment variable:
39
+ ```bash
40
+ export GOOGLE_APPLICATION_CREDENTIALS="./serviceAccountKey.json"
41
+ ```
42
+
43
+ ### 3. Run the Server
44
+
45
+ ```bash
46
+ npm start
47
+ ```
48
+
49
+ Or for development with auto-reload:
50
+ ```bash
51
+ npm run dev
52
+ ```
53
+
54
+ ### 4. Open in Browser
55
+
56
+ The server will show you the URLs:
57
+
58
+ ```
59
+ 🏥 EvalDoc Server Running
60
+
61
+ Local: http://localhost:8080
62
+ Provider Console: http://localhost:8080/app
63
+ Health Check: http://localhost:8080/health
64
+ ```
65
+
66
+ Visit:
67
+ - **Provider Console**: http://localhost:8080/app
68
+ - **Health Check**: http://localhost:8080/health
69
+
70
+ ## Enable Firebase Authentication
71
+
72
+ Before you can create provider accounts:
73
+
74
+ 1. Go to [Firebase Console](https://console.firebase.google.com/)
75
+ 2. Select project: **evaldocplatform**
76
+ 3. Click **Authentication** → **Get Started**
77
+ 4. Enable **Email/Password** sign-in method
78
+
79
+ ## Testing the App
80
+
81
+ ### 1. Create a Provider Account
82
+ 1. Visit http://localhost:8080/app
83
+ 2. Click "Create account"
84
+ 3. Enter email/password
85
+ 4. Fill in provider details
86
+ 5. Choose a handle (e.g., "dr-smith")
87
+ 6. Select topics
88
+ 7. Change status to "Published"
89
+ 8. Click "Save settings"
90
+
91
+ ### 2. Test Patient Chat
92
+ 1. Visit http://localhost:8080/dr-smith (your handle)
93
+ 2. Select a topic
94
+ 3. Send a test message
95
+ 4. You'll get a response (currently stubbed)
96
+
97
+ ### 3. View Analytics
98
+ Go back to http://localhost:8080/app to see your conversation stats.
99
+
100
+ ## Architecture
101
+
102
+ ```
103
+ ┌────────────────────────────────────┐
104
+ │ Express Server (server.js) │
105
+ │ - Serves static files │
106
+ │ - Handles /api/* routes │
107
+ │ - Connects to Firestore │
108
+ └────────────────────────────────────┘
109
+ ↓ ↓
110
+ ┌────────┐ ┌──────────────┐
111
+ │ public/│ │ Firebase │
112
+ │ files │ │ Firestore DB │
113
+ └────────┘ └──────────────┘
114
+ ```
115
+
116
+ ## Project Structure
117
+
118
+ ```
119
+ evaldoc/
120
+ ├── server.js # Main Express server
121
+ ├── package.json # Dependencies
122
+ ├── public/ # Static frontend files
123
+ │ ├── index.html # Patient chat page
124
+ │ ├── app.js # Patient chat logic
125
+ │ ├── styles.css # Styles
126
+ │ └── app/ # Provider console
127
+ │ ├── index.html # Dashboard
128
+ │ ├── app.js # Dashboard logic
129
+ │ ├── app.css # Dashboard styles
130
+ │ └── config.js # Firebase config
131
+ └── functions/src/ # Business logic modules
132
+ ├── topics.js # Topic definitions
133
+ ├── safety.js # Safety checks
134
+ ├── llm.js # LLM integration (stub)
135
+ ├── analytics.js # Analytics
136
+ ├── limits.js # Rate limiting
137
+ └── auth.js # Authentication
138
+ ```
139
+
140
+ ## Environment Variables
141
+
142
+ ```bash
143
+ # Optional - defaults to evaldocplatform
144
+ export PROJECT_ID=evaldocplatform
145
+
146
+ # Optional - defaults to 8080
147
+ export PORT=8080
148
+
149
+ # Required - Path to service account key (if not using gcloud auth)
150
+ export GOOGLE_APPLICATION_CREDENTIALS=./serviceAccountKey.json
151
+ ```
152
+
153
+ ## Deployment Options
154
+
155
+ ### Option 1: Deploy to Firebase (Recommended)
156
+
157
+ ```bash
158
+ # Install Firebase CLI
159
+ npm install -g firebase-tools
160
+
161
+ # Login
162
+ firebase login
163
+
164
+ # Deploy
165
+ firebase deploy
166
+ ```
167
+
168
+ ### Option 2: Deploy to any Node.js host
169
+
170
+ This is a standard Node.js app. Deploy to:
171
+ - **Heroku**: `git push heroku main`
172
+ - **Railway**: Connect GitHub repo
173
+ - **Render**: Connect GitHub repo
174
+ - **Google Cloud Run**: `gcloud run deploy`
175
+ - **AWS/Azure**: Use their Node.js deployment methods
176
+
177
+ Just make sure to:
178
+ 1. Set environment variables (PROJECT_ID, credentials)
179
+ 2. Run `npm start`
180
+ 3. App runs on PORT environment variable
181
+
182
+ ## Troubleshooting
183
+
184
+ ### "Could not load credentials" error
185
+
186
+ You need Firebase credentials. Run:
187
+ ```bash
188
+ gcloud auth application-default login
189
+ ```
190
+
191
+ Or download service account key and set:
192
+ ```bash
193
+ export GOOGLE_APPLICATION_CREDENTIALS="./serviceAccountKey.json"
194
+ ```
195
+
196
+ ### "Provider not found" error
197
+
198
+ - Make sure provider status is "published" not "draft"
199
+ - Check the handle is correct
200
+ - Verify Firebase Authentication is enabled
201
+
202
+ ### Port already in use
203
+
204
+ Change the port:
205
+ ```bash
206
+ PORT=3000 npm start
207
+ ```
208
+
209
+ ## What's Next?
210
+
211
+ ### 🔴 Critical: Add Real LLM
212
+
213
+ The chat responses are currently stubbed. Edit `functions/src/llm.js` to integrate:
214
+ - OpenAI GPT-4
215
+ - Anthropic Claude
216
+ - Google Vertex AI
217
+
218
+ See [DEPLOYMENT.md](DEPLOYMENT.md) for integration examples.
219
+
220
+ ### Other Improvements
221
+
222
+ - Add logging (Winston, Bunyan)
223
+ - Add monitoring (Sentry, Datadog)
224
+ - Restrict CORS to specific domains
225
+ - Add input validation (message length limits)
226
+ - Implement QR code generation
227
+ - Add comprehensive tests
228
+
229
+ ## Support
230
+
231
+ - Check [README.md](README.md) for full documentation
232
+ - See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed deployment guide
233
+ - Review [SRS.md](SRS.md) for requirements
234
+
235
+ ---
236
+
237
+ **You now have a simple Node.js app that runs anywhere!** 🚀