guideai-app 0.4.1 → 0.4.2-1

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 (39) hide show
  1. package/API_DATA_CONTRACTS.md +516 -0
  2. package/API_SESSIONID_TESTING.md +215 -0
  3. package/PII_HASHING_EPIC.md +886 -0
  4. package/PII_HASHING_STORIES_SUMMARY.md +275 -0
  5. package/SESSION_ID_VERIFICATION.md +122 -0
  6. package/VISIT_COUNT_TESTING.md +453 -0
  7. package/dist/GuideAI.js +1 -1
  8. package/dist/GuideAI.js.LICENSE.txt +20 -0
  9. package/dist/GuideAI.js.map +1 -1
  10. package/dist/components/TranscriptBox.d.ts +4 -0
  11. package/dist/index.d.ts +3 -0
  12. package/dist/metric/index.d.ts +0 -2
  13. package/dist/metric/metadata-tracker.d.ts +1 -2
  14. package/dist/styles/GuideAI.styles.d.ts +1 -1
  15. package/dist/types/GuideAI.types.d.ts +3 -1
  16. package/dist/types/metadata.types.d.ts +2 -0
  17. package/dist/utils/api.d.ts +5 -0
  18. package/dist/utils/elementInteractions.d.ts +92 -0
  19. package/dist/utils/gemini.d.ts +3 -0
  20. package/dist/utils/goToAElmLink.d.ts +1 -0
  21. package/dist/utils/highlightThenClick.d.ts +1 -0
  22. package/dist/utils/hoverThenClick.d.ts +1 -0
  23. package/dist/utils/logger.d.ts +1 -5
  24. package/dist/utils/session.d.ts +23 -0
  25. package/dist/utils/ui.d.ts +1 -1
  26. package/dist/visualContext/VisualContextScheduler.d.ts +43 -0
  27. package/dist/visualContext/VisualContextStore.d.ts +11 -0
  28. package/dist/visualContext/debug-overlay.d.ts +10 -0
  29. package/dist/visualContext/defaultProvider.d.ts +15 -0
  30. package/dist/visualContext/index.d.ts +5 -0
  31. package/dist/visualContext/types.d.ts +45 -0
  32. package/index.d.ts +5 -1
  33. package/jest.config.js +26 -0
  34. package/jest.setup.js +21 -0
  35. package/metadata-tracking-example.md +11 -11
  36. package/package.json +14 -3
  37. package/dist/metric/event-listner.d.ts +0 -141
  38. package/dist/utils/highlightAndClick.d.ts +0 -3
  39. package/dist/utils/hoverAndClick.d.ts +0 -4
@@ -0,0 +1,516 @@
1
+ # API Data Contracts
2
+
3
+ ## `/initialize-session` Endpoint
4
+
5
+ ### BEFORE Updates (Current/Legacy)
6
+
7
+ #### Request
8
+ ```typescript
9
+ POST /initialize-session
10
+
11
+ Headers:
12
+ Content-Type: application/json
13
+
14
+ Body:
15
+ {
16
+ organizationKey: string; // Required
17
+ userId: "anonymous"; // Always "anonymous" (hardcoded)
18
+ date: string; // ISO date (YYYY-MM-DD)
19
+ time: string; // Time (HH:MM:SS)
20
+ messages: any[]; // Array (usually empty)
21
+ workflowKey?: string; // Optional
22
+ }
23
+ ```
24
+
25
+ **Example:**
26
+ ```json
27
+ {
28
+ "organizationKey": "demo-org-demo",
29
+ "userId": "anonymous",
30
+ "date": "2025-10-14",
31
+ "time": "14:30:00",
32
+ "messages": []
33
+ }
34
+ ```
35
+
36
+ #### Response
37
+ ```typescript
38
+ {
39
+ id: string; // Conversation ID
40
+ ephemeralToken: string; // Temporary auth token
41
+ prompt: string; // AI prompt/instructions
42
+ workflows: Workflow[]; // Array of workflow objects
43
+ }
44
+
45
+ interface Workflow {
46
+ id: string;
47
+ name: string;
48
+ triggers: string[];
49
+ organizationKey: string;
50
+ prompt: string;
51
+ archived: boolean;
52
+ createdAt: string;
53
+ updatedAt: string;
54
+ }
55
+ ```
56
+
57
+ **Example:**
58
+ ```json
59
+ {
60
+ "id": "conv-123-456",
61
+ "ephemeralToken": "eyJhbGc...",
62
+ "prompt": "You are a helpful AI assistant...",
63
+ "workflows": [
64
+ {
65
+ "id": "workflow-1",
66
+ "name": "Customer Support",
67
+ "triggers": ["help", "support"],
68
+ "organizationKey": "demo-org-demo",
69
+ "prompt": "Help the user with...",
70
+ "archived": false,
71
+ "createdAt": "2025-01-01T00:00:00Z",
72
+ "updatedAt": "2025-01-01T00:00:00Z"
73
+ }
74
+ ]
75
+ }
76
+ ```
77
+
78
+ ---
79
+
80
+ ### AFTER Updates (New Implementation)
81
+
82
+ #### Request
83
+ ```typescript
84
+ POST /initialize-session
85
+
86
+ Headers:
87
+ Content-Type: application/json
88
+
89
+ Body:
90
+ {
91
+ organizationKey: string; // Required
92
+ userId: string; // NEW: Email if available, or "anonymous"
93
+ email?: string; // NEW: Explicit email field (undefined if not available)
94
+ date: string; // ISO date (YYYY-MM-DD)
95
+ time: string; // Time (HH:MM:SS)
96
+ messages: any[]; // Array (usually empty)
97
+ workflowKey?: string; // Optional
98
+ }
99
+ ```
100
+
101
+ **Example 1: Authenticated User**
102
+ ```json
103
+ {
104
+ "organizationKey": "demo-org-demo",
105
+ "userId": "csdemo@demo-org.com",
106
+ "email": "csdemo@demo-org.com",
107
+ "date": "2025-10-14",
108
+ "time": "14:30:00",
109
+ "messages": []
110
+ }
111
+ ```
112
+
113
+ **Example 2: Anonymous User**
114
+ ```json
115
+ {
116
+ "organizationKey": "demo-org-demo",
117
+ "userId": "anonymous",
118
+ "email": undefined, // Or omitted
119
+ "date": "2025-10-14",
120
+ "time": "14:30:00",
121
+ "messages": []
122
+ }
123
+ ```
124
+
125
+ #### Response
126
+ ```typescript
127
+ {
128
+ id: string; // Conversation ID
129
+ ephemeralToken: string; // Temporary auth token
130
+ prompt: string; // AI prompt/instructions
131
+ workflows: Workflow[]; // Array of workflow objects
132
+ userMetadata?: { // NEW: User metadata (optional)
133
+ visitCount: number; // Number of visits for this user
134
+ loginCount?: number; // Number of logins (optional)
135
+ email?: string; // User email (if available)
136
+ };
137
+ }
138
+ ```
139
+
140
+ **Example 1: Authenticated User Response**
141
+ ```json
142
+ {
143
+ "id": "conv-123-456",
144
+ "ephemeralToken": "eyJhbGc...",
145
+ "prompt": "You are a helpful AI assistant...",
146
+ "workflows": [...],
147
+ "userMetadata": {
148
+ "visitCount": 5,
149
+ "loginCount": 2,
150
+ "email": "csdemo@demo-org.com"
151
+ }
152
+ }
153
+ ```
154
+
155
+ **Example 2: Anonymous User Response**
156
+ ```json
157
+ {
158
+ "id": "conv-123-456",
159
+ "ephemeralToken": "eyJhbGc...",
160
+ "prompt": "You are a helpful AI assistant...",
161
+ "workflows": [...],
162
+ "userMetadata": {
163
+ "visitCount": 0
164
+ }
165
+ }
166
+ ```
167
+
168
+ ---
169
+
170
+ ## `/metadata-updates` Endpoint
171
+
172
+ ### Request (Already Implemented)
173
+
174
+ ```typescript
175
+ POST /metadata-updates
176
+
177
+ Headers:
178
+ Content-Type: application/json
179
+
180
+ Body:
181
+ {
182
+ organizationKey: string; // Required
183
+ updates: MetadataUpdate[]; // Array of metadata updates
184
+ batchTimestamp: number; // Timestamp when batch was created
185
+ updateCount: number; // Number of updates in batch
186
+ }
187
+
188
+ interface MetadataUpdate {
189
+ type: 'visit' | 'login' | 'user_info' | 'session' | 'custom';
190
+ timestamp: number; // Unix timestamp (milliseconds)
191
+ data: {
192
+ sessionId: string; // Current session ID
193
+ email?: string; // User email (if available) ← KEY FOR STORAGE
194
+ visitCount?: number; // Current visit count
195
+ loginCount?: number; // Current login count
196
+ firstVisit?: number; // First visit timestamp
197
+ lastVisit?: number; // Last visit timestamp
198
+ [key: string]: any; // Other custom fields
199
+ };
200
+ }
201
+ ```
202
+
203
+ ### Example Request
204
+
205
+ ```json
206
+ {
207
+ "organizationKey": "demo-org-demo",
208
+ "updates": [
209
+ {
210
+ "type": "visit",
211
+ "timestamp": 1697295600000,
212
+ "data": {
213
+ "sessionId": "550e8400-e29b-41d4-a716-446655440000",
214
+ "email": "csdemo@demo-org.com",
215
+ "firstVisit": 1697000000000,
216
+ "lastVisit": 1697295600000,
217
+ "visitCount": 5
218
+ }
219
+ },
220
+ {
221
+ "type": "login",
222
+ "timestamp": 1697295650000,
223
+ "data": {
224
+ "sessionId": "550e8400-e29b-41d4-a716-446655440000",
225
+ "email": "csdemo@demo-org.com",
226
+ "loginCount": 2,
227
+ "lastLogin": 1697295650000
228
+ }
229
+ }
230
+ ],
231
+ "batchTimestamp": 1697295600000,
232
+ "updateCount": 2
233
+ }
234
+ ```
235
+
236
+ ### Response
237
+
238
+ ```typescript
239
+ {
240
+ success: boolean; // Whether the update was successful
241
+ message?: string; // Optional message
242
+ }
243
+ ```
244
+
245
+ **Example:**
246
+ ```json
247
+ {
248
+ "success": true
249
+ }
250
+ ```
251
+
252
+ ---
253
+
254
+ ## Backend Implementation Notes
255
+
256
+ ### Key Changes Required
257
+
258
+ 1. **Accept email in `/initialize-session`**
259
+ - Read `email` from request body
260
+ - Use as user identifier (along with organizationKey)
261
+
262
+ 2. **Return userMetadata in `/initialize-session` response**
263
+ - Look up user by `organizationKey + email`
264
+ - Return their visitCount from database
265
+ - If not found or anonymous, return `visitCount: 0`
266
+
267
+ 3. **Store visitCount from `/metadata-updates`**
268
+ - Extract `email` from each update's data
269
+ - Store visitCount in database by `organizationKey + email`
270
+ - Update on each request (upsert operation)
271
+
272
+ ### Database Schema Suggestion
273
+
274
+ ```sql
275
+ -- User metadata table
276
+ CREATE TABLE user_metadata (
277
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
278
+ organization_key VARCHAR(255) NOT NULL,
279
+ email VARCHAR(255) NOT NULL,
280
+ visit_count INTEGER DEFAULT 0,
281
+ login_count INTEGER DEFAULT 0,
282
+ first_visit BIGINT, -- Unix timestamp (ms)
283
+ last_visit BIGINT, -- Unix timestamp (ms)
284
+ last_login BIGINT, -- Unix timestamp (ms)
285
+ created_at TIMESTAMP DEFAULT NOW(),
286
+ updated_at TIMESTAMP DEFAULT NOW(),
287
+ UNIQUE(organization_key, email)
288
+ );
289
+
290
+ -- Index for fast lookups
291
+ CREATE INDEX idx_user_metadata_lookup ON user_metadata(organization_key, email);
292
+ ```
293
+
294
+ ### Backend Logic Pseudocode
295
+
296
+ #### For `/initialize-session`:
297
+
298
+ ```python
299
+ def initialize_session(request):
300
+ org_key = request.organizationKey
301
+ email = request.email
302
+
303
+ # Look up user metadata
304
+ if email and email != 'anonymous':
305
+ user = db.query(
306
+ "SELECT * FROM user_metadata WHERE organization_key = ? AND email = ?",
307
+ org_key, email
308
+ )
309
+ visit_count = user.visit_count if user else 0
310
+ login_count = user.login_count if user else 0
311
+ else:
312
+ # Anonymous user
313
+ visit_count = 0
314
+ login_count = 0
315
+
316
+ # Return response with userMetadata
317
+ return {
318
+ "id": generate_conversation_id(),
319
+ "ephemeralToken": generate_token(),
320
+ "prompt": get_prompt(),
321
+ "workflows": get_workflows(org_key),
322
+ "userMetadata": {
323
+ "visitCount": visit_count,
324
+ "loginCount": login_count,
325
+ "email": email if email != 'anonymous' else None
326
+ }
327
+ }
328
+ ```
329
+
330
+ #### For `/metadata-updates`:
331
+
332
+ ```python
333
+ def metadata_updates(request):
334
+ org_key = request.organizationKey
335
+ updates = request.updates
336
+
337
+ for update in updates:
338
+ email = update.data.get('email')
339
+
340
+ if email and email != 'anonymous':
341
+ # Update or create user metadata
342
+ if update.type == 'visit':
343
+ db.upsert(
344
+ "user_metadata",
345
+ organization_key=org_key,
346
+ email=email,
347
+ visit_count=update.data.get('visitCount'),
348
+ first_visit=update.data.get('firstVisit'),
349
+ last_visit=update.data.get('lastVisit')
350
+ )
351
+
352
+ elif update.type == 'login':
353
+ db.upsert(
354
+ "user_metadata",
355
+ organization_key=org_key,
356
+ email=email,
357
+ login_count=update.data.get('loginCount'),
358
+ last_login=update.data.get('lastLogin')
359
+ )
360
+
361
+ return {"success": True}
362
+ ```
363
+
364
+ ---
365
+
366
+ ## Testing the Changes
367
+
368
+ ### Test 1: Authenticated User Flow
369
+
370
+ ```bash
371
+ # Step 1: Initialize session with email
372
+ curl -X POST https://your-api.com/initialize-session \
373
+ -H "Content-Type: application/json" \
374
+ -d '{
375
+ "organizationKey": "test-org",
376
+ "userId": "test@example.com",
377
+ "email": "test@example.com",
378
+ "date": "2025-10-14",
379
+ "time": "12:00:00",
380
+ "messages": []
381
+ }'
382
+
383
+ # Expected response:
384
+ # {
385
+ # "id": "conv-123",
386
+ # "ephemeralToken": "...",
387
+ # "prompt": "...",
388
+ # "workflows": [],
389
+ # "userMetadata": {
390
+ # "visitCount": 0, // First time
391
+ # "email": "test@example.com"
392
+ # }
393
+ # }
394
+
395
+ # Step 2: Send metadata update (simulate visit)
396
+ curl -X POST https://your-api.com/metadata-updates \
397
+ -H "Content-Type: application/json" \
398
+ -d '{
399
+ "organizationKey": "test-org",
400
+ "updates": [
401
+ {
402
+ "type": "visit",
403
+ "timestamp": 1697295600000,
404
+ "data": {
405
+ "sessionId": "session-123",
406
+ "email": "test@example.com",
407
+ "visitCount": 1,
408
+ "firstVisit": 1697295600000,
409
+ "lastVisit": 1697295600000
410
+ }
411
+ }
412
+ ],
413
+ "batchTimestamp": 1697295600000,
414
+ "updateCount": 1
415
+ }'
416
+
417
+ # Expected response:
418
+ # { "success": true }
419
+
420
+ # Step 3: Initialize session again (should return visitCount = 1)
421
+ curl -X POST https://your-api.com/initialize-session \
422
+ -H "Content-Type: application/json" \
423
+ -d '{
424
+ "organizationKey": "test-org",
425
+ "userId": "test@example.com",
426
+ "email": "test@example.com",
427
+ "date": "2025-10-14",
428
+ "time": "13:00:00",
429
+ "messages": []
430
+ }'
431
+
432
+ # Expected response:
433
+ # {
434
+ # "userMetadata": {
435
+ # "visitCount": 1 // ← Should return stored value
436
+ # }
437
+ # }
438
+ ```
439
+
440
+ ### Test 2: Anonymous User Flow
441
+
442
+ ```bash
443
+ # Initialize session without email
444
+ curl -X POST https://your-api.com/initialize-session \
445
+ -H "Content-Type: application/json" \
446
+ -d '{
447
+ "organizationKey": "test-org",
448
+ "userId": "anonymous",
449
+ "date": "2025-10-14",
450
+ "time": "12:00:00",
451
+ "messages": []
452
+ }'
453
+
454
+ # Expected response:
455
+ # {
456
+ # "userMetadata": {
457
+ # "visitCount": 0 // Always 0 for anonymous
458
+ # }
459
+ # }
460
+ ```
461
+
462
+ ---
463
+
464
+ ## Backward Compatibility
465
+
466
+ ### Will Old Clients Break?
467
+
468
+ **NO** - The implementation is backward compatible:
469
+
470
+ 1. **Old FE + New BE**: Works fine
471
+ - Old FE sends `userId: "anonymous"`
472
+ - New BE returns `userMetadata` (optional field)
473
+ - Old FE ignores the new field
474
+
475
+ 2. **New FE + Old BE**: Works fine
476
+ - New FE sends `email` field
477
+ - Old BE ignores unknown fields
478
+ - New FE handles missing `userMetadata` gracefully
479
+
480
+ 3. **New FE + New BE**: Full functionality
481
+ - Email-based user identification
482
+ - Cross-browser visitCount tracking
483
+ - Everything works as designed
484
+
485
+ ---
486
+
487
+ ## Summary
488
+
489
+ ### Changed Fields in `/initialize-session`
490
+
491
+ | Field | Before | After | Required |
492
+ |-------|--------|-------|----------|
493
+ | `userId` | Always "anonymous" | Email or "anonymous" | Yes |
494
+ | `email` | N/A | Email string | No (undefined if not available) |
495
+ | `userMetadata` (response) | N/A | Object with visitCount | No (optional) |
496
+
497
+ ### Key for Backend Team
498
+
499
+ ✅ **Must implement:**
500
+ 1. Read `email` from request
501
+ 2. Return `userMetadata.visitCount` in response
502
+ 3. Store visitCount from `/metadata-updates` by `organizationKey + email`
503
+
504
+ ✅ **Nice to have:**
505
+ 4. Store by sessionId for anonymous users (temporary tracking)
506
+ 5. Return loginCount in userMetadata
507
+ 6. Add database indexes for performance
508
+
509
+ ---
510
+
511
+ ## Questions?
512
+
513
+ Contact the development team or refer to:
514
+ - `src/utils/USER_IDENTIFICATION_NOTES.md` - Full documentation
515
+ - `IMPLEMENTATION_SUMMARY.md` - Implementation details
516
+