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,373 @@
1
+ # EvalDoc Thread System - Deployment Steps
2
+
3
+ ## ✅ What's Been Implemented
4
+
5
+ ### Frontend
6
+ - ✅ [public/chat.html](public/chat.html) - Updated with Google Sign-In modal and Firebase Auth scripts
7
+ - ✅ [public/js/chat-threads.js](public/js/chat-threads.js) - NEW: Thread-based chat system with Google authentication
8
+ - ✅ [public/app/inbox.html](public/app/inbox.html) - Updated with doctor reply styling
9
+ - ✅ [public/app/inbox-threads.js](public/app/inbox-threads.js) - NEW: Thread-based inbox with manual reply feature
10
+
11
+ ### Backend
12
+ - ✅ [functions/src/patient-api.js](functions/src/patient-api.js) - NEW: Patient API handlers
13
+ - ✅ [functions/src/index.js](functions/src/index.js) - Updated with patient and doctor thread endpoints
14
+
15
+ ### Security
16
+ - ✅ [firestore.rules](firestore.rules) - Updated with patients and threads collection rules
17
+
18
+ ### Documentation
19
+ - ✅ [THREAD_IMPLEMENTATION_GUIDE.md](THREAD_IMPLEMENTATION_GUIDE.md) - Complete implementation guide
20
+ - ✅ [ARCHITECTURE_SUMMARY.md](ARCHITECTURE_SUMMARY.md) - Architecture overview
21
+
22
+ ---
23
+
24
+ ## 🚀 Deployment Checklist
25
+
26
+ ### Step 1: Enable Google Sign-In (5 minutes)
27
+
28
+ 1. Go to [Firebase Console](https://console.firebase.google.com)
29
+ 2. Select your project
30
+ 3. Go to **Authentication** → **Sign-in method**
31
+ 4. Click **Google** and enable it
32
+ 5. Add authorized domains:
33
+ - `localhost` (for testing)
34
+ - Your production domain (e.g., `evaldoc.com`)
35
+ 6. Click **Save**
36
+
37
+ ---
38
+
39
+ ### Step 2: Deploy Firestore Rules (1 minute)
40
+
41
+ ```bash
42
+ # From your project root
43
+ firebase deploy --only firestore:rules
44
+ ```
45
+
46
+ **Expected output:**
47
+ ```
48
+ ✔ Deploy complete!
49
+ ✔ firestore: deployed database security rules
50
+ ```
51
+
52
+ ---
53
+
54
+ ### Step 3: Deploy Firebase Functions (5 minutes)
55
+
56
+ ```bash
57
+ # Make sure you're in the project root
58
+ cd functions
59
+ npm install # Install any new dependencies
60
+ cd ..
61
+
62
+ # Deploy functions
63
+ firebase deploy --only functions
64
+ ```
65
+
66
+ **Expected output:**
67
+ ```
68
+ ✔ Deploy complete!
69
+ ✔ functions[api]: Successful update operation
70
+ ```
71
+
72
+ **Note:** First deployment may take 5-10 minutes. Subsequent deploys are faster.
73
+
74
+ ---
75
+
76
+ ### Step 4: Deploy Hosting (1 minute)
77
+
78
+ ```bash
79
+ firebase deploy --only hosting
80
+ ```
81
+
82
+ **Expected output:**
83
+ ```
84
+ ✔ Deploy complete!
85
+ ✔ hosting: deployed new version
86
+ ```
87
+
88
+ ---
89
+
90
+ ### Step 5: Verify Deployment (2 minutes)
91
+
92
+ #### Test Patient Flow:
93
+
94
+ 1. Go to your deployed URL: `https://your-domain.com/dr-john-cardiology` (replace with actual doctor handle)
95
+ 2. Should see the chat interface
96
+ 3. Try sending a message
97
+ 4. Should see "Sign in to continue" modal
98
+ 5. Click "Continue with Google"
99
+ 6. Sign in with Google account
100
+ 7. Message should send successfully
101
+ 8. AI should respond
102
+ 9. **Refresh the page** - conversation should persist!
103
+
104
+ #### Test Doctor Inbox:
105
+
106
+ 1. Go to `https://your-domain.com/app`
107
+ 2. Sign in as doctor (provider account)
108
+ 3. Go to "Inbox" tab
109
+ 4. Should see threads instead of old conversations
110
+ 5. Click on a thread
111
+ 6. Should see patient name/email
112
+ 7. Type a reply and click "Send Reply"
113
+ 8. Message should appear in thread
114
+
115
+ ---
116
+
117
+ ## 🧪 Testing Scenarios
118
+
119
+ ### Scenario 1: New Patient
120
+ ```
121
+ 1. Clear browser data (to simulate new patient)
122
+ 2. Visit doctor link
123
+ 3. Send message → Should prompt for Google Sign-In
124
+ 4. Sign in with Google
125
+ 5. Message should send + AI responds
126
+ 6. Refresh page → Should see conversation history
127
+ 7. Send another message → Should continue thread
128
+ ```
129
+
130
+ ### Scenario 2: Returning Patient
131
+ ```
132
+ 1. Visit doctor link (already signed in)
133
+ 2. Should immediately see chat interface with history
134
+ 3. Send message → AI responds
135
+ 4. Conversation continues in same thread
136
+ ```
137
+
138
+ ### Scenario 3: Patient with Multiple Doctors
139
+ ```
140
+ 1. Patient chats with Dr. A
141
+ 2. Patient visits Dr. B's link
142
+ 3. New thread created for Dr. B
143
+ 4. Both conversations are separate
144
+ 5. Patient can switch between doctors
145
+ ```
146
+
147
+ ### Scenario 4: Doctor Manual Reply
148
+ ```
149
+ 1. Doctor logs into inbox
150
+ 2. Sees patient thread with unread indicator (green dot)
151
+ 3. Clicks on thread
152
+ 4. Types reply in text box
153
+ 5. Clicks "Send Reply"
154
+ 6. Message appears in thread
155
+ 7. Patient receives message (doctor's name shown)
156
+ ```
157
+
158
+ ### Scenario 5: Doctor Takes Over (Manual Mode)
159
+ ```
160
+ 1. Doctor clicks "👨‍⚕️ Take Over (Manual Mode)" button
161
+ 2. Thread marked as manual mode
162
+ 3. AI stops responding
163
+ 4. All messages from doctor are manual
164
+ 5. Doctor can toggle back to AI mode
165
+ ```
166
+
167
+ ---
168
+
169
+ ## 📋 Post-Deployment Verification
170
+
171
+ ### Check Firebase Console
172
+
173
+ 1. **Authentication:**
174
+ - Go to Authentication → Users
175
+ - Should see new users signing in via Google
176
+
177
+ 2. **Firestore:**
178
+ - Go to Firestore Database
179
+ - Should see new collections:
180
+ - `patients` - Patient profiles
181
+ - `threads` - Conversation threads
182
+ - Inside threads: `messages` subcollection
183
+
184
+ 3. **Functions:**
185
+ - Go to Functions → Dashboard
186
+ - Check `/api/patient/*` endpoints are deployed
187
+ - Check logs for any errors
188
+
189
+ ---
190
+
191
+ ## 🐛 Troubleshooting
192
+
193
+ ### Issue: "Unauthorized" error when sending message
194
+
195
+ **Fix:**
196
+ 1. Check Firebase Auth is enabled for Google
197
+ 2. Verify token is being sent: Open browser DevTools → Network → Check request headers for `Authorization: Bearer ...`
198
+ 3. Re-deploy Firestore rules: `firebase deploy --only firestore:rules`
199
+
200
+ ### Issue: "Thread not found" error
201
+
202
+ **Fix:**
203
+ 1. Check Firestore Database has `threads` collection
204
+ 2. Verify thread ID format: `thread_{patientId}_{doctorId}`
205
+ 3. Check Firebase console for error logs
206
+
207
+ ### Issue: Google Sign-In popup blocked
208
+
209
+ **Fix:**
210
+ 1. Check browser isn't blocking popups
211
+ 2. Add domain to Firebase Console → Authentication → Authorized domains
212
+ 3. Clear browser cache
213
+
214
+ ### Issue: Messages not showing in doctor inbox
215
+
216
+ **Fix:**
217
+ 1. Verify doctor is using [inbox-threads.js](public/app/inbox-threads.js) (not old inbox.js)
218
+ 2. Check API endpoint: `/api/doctor/threads` is working
219
+ 3. Check browser console for errors
220
+
221
+ ### Issue: Payment not working with threads
222
+
223
+ **Fix:**
224
+ 1. Thread-based payment integration is in [chat-threads.js](public/js/chat-threads.js)
225
+ 2. Verify Stripe keys are configured
226
+ 3. Check `thread.isPaid` status in Firestore
227
+
228
+ ---
229
+
230
+ ## 🔄 Rollback Plan (If Needed)
231
+
232
+ If something goes wrong, you can quickly rollback:
233
+
234
+ ### Rollback Frontend:
235
+ ```bash
236
+ # In public/chat.html, change:
237
+ <script src="/js/chat-threads.js?v=1"></script>
238
+ # Back to:
239
+ <script src="/js/chat.js?v=3"></script>
240
+
241
+ # In public/app/inbox.html, change:
242
+ <script src="/app/inbox-threads.js"></script>
243
+ # Back to:
244
+ <script src="/app/inbox.js"></script>
245
+
246
+ # Deploy:
247
+ firebase deploy --only hosting
248
+ ```
249
+
250
+ ### Rollback Functions:
251
+ ```bash
252
+ # Comment out patient API routes in functions/src/index.js:
253
+ // if (req.path.startsWith("/patient/")) {
254
+ // const user = await requireAuth(req, res);
255
+ // if (!user) return;
256
+ // await handlePatientAPI(req, res, user);
257
+ // return;
258
+ // }
259
+
260
+ firebase deploy --only functions
261
+ ```
262
+
263
+ **Note:** Old conversations in `conversations` collection are unaffected. They'll still work with old system.
264
+
265
+ ---
266
+
267
+ ## 📊 Monitoring & Analytics
268
+
269
+ ### Key Metrics to Watch:
270
+
271
+ 1. **Patient Sign-Ups:**
272
+ - Firebase Console → Authentication → Users
273
+ - Should see growth over time
274
+
275
+ 2. **Thread Creation Rate:**
276
+ - Firestore → `threads` collection
277
+ - Count of new documents
278
+
279
+ 3. **Message Volume:**
280
+ - Firestore → `threads/{id}/messages`
281
+ - Average messages per thread
282
+
283
+ 4. **Doctor Response Time:**
284
+ - Check `lastMessageAt` timestamps
285
+ - Time between patient message and doctor reply
286
+
287
+ 5. **API Performance:**
288
+ - Functions → Dashboard → Metrics
289
+ - Check latency and error rates
290
+
291
+ ---
292
+
293
+ ## 🎯 Success Criteria
294
+
295
+ You'll know deployment is successful when:
296
+
297
+ - ✅ Patients can sign in with Google
298
+ - ✅ Messages persist after browser refresh
299
+ - ✅ Doctor inbox shows patient names (not sessionIds)
300
+ - ✅ Doctor can send manual replies
301
+ - ✅ Manual mode (override AI) works
302
+ - ✅ No errors in Firebase Functions logs
303
+ - ✅ No errors in browser console
304
+ - ✅ Multiple patients can chat with same doctor
305
+ - ✅ Single patient can chat with multiple doctors
306
+
307
+ ---
308
+
309
+ ## 📞 Next Steps After Deployment
310
+
311
+ ### Phase 3: Web Push Notifications (Future)
312
+
313
+ Once everything is stable, implement push notifications:
314
+
315
+ 1. Add FCM (Firebase Cloud Messaging) to frontend
316
+ 2. Request notification permission from patients
317
+ 3. Save FCM token to patient profile
318
+ 4. Send push notification when doctor replies
319
+
320
+ See [THREAD_IMPLEMENTATION_GUIDE.md](THREAD_IMPLEMENTATION_GUIDE.md#phase-4-web-push-notifications) for details.
321
+
322
+ ---
323
+
324
+ ## 🔐 Security Reminders
325
+
326
+ - ✅ Patient data is private (only they can access)
327
+ - ✅ Doctors can only see their own threads
328
+ - ✅ All writes go through authenticated backend
329
+ - ✅ Firestore rules enforce access control
330
+ - ✅ Google Sign-In tokens are verified server-side
331
+
332
+ ---
333
+
334
+ ## 📝 Deployment Log Template
335
+
336
+ Use this to track your deployment:
337
+
338
+ ```
339
+ Date: _____________
340
+ Deployed by: _____________
341
+
342
+ Step 1: Google Sign-In Enabled ✅ / ❌
343
+ Step 2: Firestore Rules Deployed ✅ / ❌
344
+ Step 3: Functions Deployed ✅ / ❌
345
+ Step 4: Hosting Deployed ✅ / ❌
346
+ Step 5: Testing Complete ✅ / ❌
347
+
348
+ Test Results:
349
+ - New patient flow: ✅ / ❌
350
+ - Returning patient: ✅ / ❌
351
+ - Doctor inbox: ✅ / ❌
352
+ - Manual reply: ✅ / ❌
353
+
354
+ Issues Encountered:
355
+ __________________________________________
356
+ __________________________________________
357
+
358
+ Notes:
359
+ __________________________________________
360
+ __________________________________________
361
+ ```
362
+
363
+ ---
364
+
365
+ ## 🎉 You're Ready!
366
+
367
+ Follow the steps above and you'll have the thread-based system live in under 15 minutes!
368
+
369
+ **Need help?** Check:
370
+ 1. [THREAD_IMPLEMENTATION_GUIDE.md](THREAD_IMPLEMENTATION_GUIDE.md)
371
+ 2. [ARCHITECTURE_SUMMARY.md](ARCHITECTURE_SUMMARY.md)
372
+ 3. Firebase Console logs
373
+ 4. Browser developer console
@@ -0,0 +1,239 @@
1
+ # Deploy Firestore Security Rules Manually
2
+
3
+ ## The Issue
4
+ Firebase CLI is broken, so we need to deploy Firestore rules manually through the Firebase Console.
5
+
6
+ ## Quick Fix - Update Firestore Rules in Firebase Console
7
+
8
+ ### Step 1: Go to Firebase Console
9
+ 1. Open https://console.firebase.google.com/
10
+ 2. Select project: **evaldocplatform**
11
+ 3. Click **Firestore Database** in the left sidebar
12
+ 4. Click the **Rules** tab
13
+
14
+ ### Step 2: Copy and Paste These Rules
15
+
16
+ ```javascript
17
+ rules_version = '2';
18
+ service cloud.firestore {
19
+ match /databases/{database}/documents {
20
+ function isSignedIn() {
21
+ return request.auth != null;
22
+ }
23
+
24
+ function isOwner(ownerUid) {
25
+ return isSignedIn() && request.auth.uid == ownerUid;
26
+ }
27
+
28
+ // Provider documents
29
+ match /providers/{providerId} {
30
+ // Public: Anyone can read published providers
31
+ allow read: if resource.data.status == "published";
32
+
33
+ // Providers can only be created via backend API (Admin SDK)
34
+ allow create: if false;
35
+
36
+ // Providers can update their own profile
37
+ allow update: if isOwner(resource.data.ownerUid);
38
+
39
+ // Only backend can delete
40
+ allow delete: if false;
41
+
42
+ // Analytics subcollection
43
+ match /analyticsDaily/{dayId} {
44
+ allow read: if isOwner(providerId);
45
+ allow write: if false; // Only backend can write analytics
46
+ }
47
+ }
48
+
49
+ // Handle lookup (used to check if handle is taken)
50
+ match /handles/{handle} {
51
+ allow read: if true; // Anyone can check if handle exists
52
+ allow write: if false; // Only backend can manage handles
53
+ }
54
+
55
+ // Conversations (chat data)
56
+ match /conversations/{conversationId} {
57
+ // Only backend API can manage conversations
58
+ allow read, write: if false;
59
+
60
+ match /messages/{messageId} {
61
+ allow read, write: if false;
62
+ }
63
+ }
64
+
65
+ // Safety events (for monitoring)
66
+ match /safetyEvents/{eventId} {
67
+ allow read, write: if false; // Only backend
68
+ }
69
+
70
+ // Platform configuration
71
+ match /platformConfig/{docId} {
72
+ allow read: if true; // Public config can be read
73
+ allow write: if false; // Only backend can write
74
+ }
75
+
76
+ // Payment-related collections
77
+ match /subscriptions/{subscriptionId} {
78
+ allow read: if isSignedIn(); // Users can read their subscriptions
79
+ allow write: if false; // Only backend manages subscriptions
80
+ }
81
+
82
+ match /transactions/{transactionId} {
83
+ allow read: if isSignedIn(); // Users can read their transactions
84
+ allow write: if false; // Only backend manages transactions
85
+ }
86
+ }
87
+ }
88
+ ```
89
+
90
+ ### Step 3: Publish the Rules
91
+ 1. Click the **Publish** button in the Firebase Console
92
+ 2. Wait for confirmation that rules were published
93
+
94
+ ---
95
+
96
+ ## What These Rules Do
97
+
98
+ ### ✅ Provider Management
99
+ - **Read**: Anyone can read published providers (for patient search)
100
+ - **Create**: Blocked on client (must use backend API)
101
+ - **Update**: Providers can update their own profile
102
+ - **Delete**: Only backend can delete
103
+
104
+ ### ✅ Handles Collection
105
+ - **Read**: Public (to check if handle is available)
106
+ - **Write**: Backend only
107
+
108
+ ### ✅ Conversations & Messages
109
+ - **All access**: Backend only (sensitive medical data)
110
+
111
+ ### ✅ Payment Collections
112
+ - **Read**: Authenticated users can read their own data
113
+ - **Write**: Backend only (Stripe webhooks)
114
+
115
+ ---
116
+
117
+ ## Security Architecture
118
+
119
+ This is a **backend-first architecture**:
120
+
121
+ ```
122
+ Frontend → Backend API → Firebase Admin SDK → Firestore
123
+ ↓
124
+ (bypasses security rules)
125
+ ```
126
+
127
+ **Why this is secure:**
128
+ 1. ✅ All writes go through authenticated API endpoints
129
+ 2. ✅ API validates data before writing
130
+ 3. ✅ Admin SDK bypasses Firestore rules (backend has full access)
131
+ 4. ✅ Client-side direct writes are blocked
132
+ 5. ✅ Only necessary reads are allowed from client
133
+
134
+ **What the frontend can do directly:**
135
+ - ✅ Read published provider profiles
136
+ - ✅ Check if handles are available
137
+ - ✅ Read public platform config
138
+ - ✅ Read their own subscriptions/transactions
139
+
140
+ **What requires backend API:**
141
+ - ✅ Create provider profiles
142
+ - ✅ Update provider data
143
+ - ✅ Manage conversations
144
+ - ✅ Process payments
145
+ - ✅ Write analytics
146
+
147
+ ---
148
+
149
+ ## Testing After Deployment
150
+
151
+ ### Test 1: Public Provider Read
152
+ ```javascript
153
+ // In browser console at http://localhost:8080
154
+ firebase.firestore()
155
+ .collection('providers')
156
+ .where('status', '==', 'published')
157
+ .limit(1)
158
+ .get()
159
+ .then(snap => console.log('✅ Can read published providers'))
160
+ .catch(err => console.error('❌ Error:', err));
161
+ ```
162
+
163
+ ### Test 2: Handle Availability Check
164
+ ```javascript
165
+ // Check if handle is available
166
+ firebase.firestore()
167
+ .collection('handles')
168
+ .doc('test-doctor')
169
+ .get()
170
+ .then(doc => console.log('✅ Can check handles'))
171
+ .catch(err => console.error('❌ Error:', err));
172
+ ```
173
+
174
+ ### Test 3: Direct Create (Should Fail)
175
+ ```javascript
176
+ // This should be blocked
177
+ firebase.firestore()
178
+ .collection('providers')
179
+ .add({ test: true })
180
+ .then(() => console.error('❌ Security rules not working!'))
181
+ .catch(err => console.log('✅ Direct create blocked:', err.code));
182
+ // Expected: permission-denied
183
+ ```
184
+
185
+ ---
186
+
187
+ ## Common Issues
188
+
189
+ ### "Missing or insufficient permissions"
190
+ ✅ **This is expected** for operations that must go through the backend API
191
+ - Provider creation
192
+ - Conversation management
193
+ - Payment processing
194
+
195
+ Use the API endpoints instead:
196
+ - `POST /api/provider` - Create provider
197
+ - `POST /api/provider/update` - Update provider
198
+ - `POST /api/payment/update-pricing` - Update pricing
199
+
200
+ ### Rules not taking effect
201
+ 1. Clear browser cache
202
+ 2. Sign out and sign back in
203
+ 3. Wait 1-2 minutes for rules to propagate
204
+ 4. Check Firebase Console shows the new rules
205
+
206
+ ---
207
+
208
+ ## Verify Rules Are Active
209
+
210
+ After publishing, check the Firebase Console:
211
+ 1. Go to **Firestore Database** → **Rules**
212
+ 2. Verify the rules match what you pasted
213
+ 3. Check "Last updated" timestamp is recent
214
+
215
+ ---
216
+
217
+ ## Production Considerations
218
+
219
+ ### Current Rules (Development-Friendly)
220
+ ✅ Public can read published providers
221
+ ✅ Public can check handle availability
222
+ ✅ Authenticated users can read config
223
+
224
+ ### For Production Hardening
225
+ Consider adding:
226
+ - Rate limiting (via Firebase App Check)
227
+ - Geolocation restrictions
228
+ - More granular provider update rules
229
+ - Audit logging for sensitive operations
230
+
231
+ ---
232
+
233
+ ## Status
234
+
235
+ ✅ **Rules Created**: firestore.rules file updated
236
+ ⚠️ **Rules Deployed**: Manual deployment needed
237
+ 📋 **Next Step**: Copy rules to Firebase Console and publish
238
+
239
+ **Deploy now**: https://console.firebase.google.com/project/evaldocplatform/firestore/rules
@@ -0,0 +1,82 @@
1
+ # Deploy Firebase Storage Rules Manually
2
+
3
+ ## The Issue
4
+ Firebase CLI is broken, so we need to deploy storage rules manually through the Firebase Console.
5
+
6
+ ## Quick Fix - Update Storage Rules in Firebase Console
7
+
8
+ ### Step 1: Go to Firebase Console
9
+ 1. Open https://console.firebase.google.com/
10
+ 2. Select project: **evaldocplatform**
11
+ 3. Click **Storage** in the left sidebar
12
+ 4. Click the **Rules** tab
13
+
14
+ ### Step 2: Copy and Paste These Rules
15
+
16
+ ```javascript
17
+ rules_version = '2';
18
+ service firebase.storage {
19
+ match /b/{bucket}/o {
20
+
21
+ // Doctor certificates - allow authenticated users to upload their own
22
+ match /certificates/{userId}/{allPaths=**} {
23
+ // Users can only upload their own certificates
24
+ allow write: if request.auth != null
25
+ && request.auth.uid == userId
26
+ && request.resource.size < 10 * 1024 * 1024; // 10MB max
27
+
28
+ // Authenticated users can read (for admin verification)
29
+ allow read: if request.auth != null;
30
+ }
31
+
32
+ // Fallback for development - allow authenticated users
33
+ match /{allPaths=**} {
34
+ allow read, write: if request.auth != null;
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ ### Step 3: Publish the Rules
41
+ 1. Click the **Publish** button in the Firebase Console
42
+ 2. Wait for confirmation that rules were published
43
+
44
+ ### Step 4: Test Upload Again
45
+ 1. Go back to http://localhost:8080/app
46
+ 2. Try uploading a certificate again
47
+ 3. Should work now!
48
+
49
+ ## What These Rules Do
50
+
51
+ ✅ **Allow authenticated users to upload to their own folder**
52
+ - Path: `certificates/{userId}/filename.pdf`
53
+ - User can only write to their own `userId` folder
54
+ - Max file size: 10MB
55
+
56
+ ✅ **Allow authenticated users to read certificates**
57
+ - Needed for admin verification
58
+
59
+ ✅ **Development fallback**
60
+ - Any authenticated user can read/write anywhere
61
+ - This is permissive for development - tighten for production
62
+
63
+ ## Production Rules (Future)
64
+
65
+ For production, replace the fallback with explicit deny:
66
+
67
+ ```javascript
68
+ match /{allPaths=**} {
69
+ allow read, write: if false; // Deny all other access
70
+ }
71
+ ```
72
+
73
+ ## Verify Rules Are Active
74
+
75
+ After publishing, the upload error should change from:
76
+ - ❌ `storage/unauthorized` → ✅ Upload succeeds
77
+
78
+ If you still get permission errors:
79
+ 1. Make sure you're logged in (check Firebase Auth)
80
+ 2. Verify the userId in the path matches your auth.uid
81
+ 3. Check file size is under 10MB
82
+ 4. Clear browser cache and try again