84
85### **Service Layer** (External Integrations)
86- Handles external API calls (Notion, databases)
87- Manages data persistence
88- Returns structured results with success/error information
108- `GET /glimpse/login` - User-specific login redirect
109 - Requires user authentication (Google OAuth via LastLogin)
110 - Looks up authenticated user's email in `GLANCE_DEMOS_DB_ID` database
111 - If user found: Redirects to user's personal path (from Path property)
112 - If user not found: Creates new user record and redirects to `/glimpse/thanks`
113 - Shows detailed error information for debugging database structure issues
114
115- `GET /glimpse/thanks` - New user welcome page
213
2141. **Authentication**: User must be authenticated via Google OAuth (handled by LastLogin)
2152. **Database Lookup**: System queries `GLANCE_DEMOS_DB_ID` database for user's email
2163. **User Creation**: If not found, creates new user record with email address
2174. **Welcome Page**: Redirects to `/glimpse/thanks` with next steps information
2196. **User Return**: User can return to `/glimpse/login` once URL is configured
220
221### Database Requirements for Login
222
223The `GLANCE_DEMOS_DB_ID` database must contain:
224- **Email property**: Contains user's email address (exact match with authenticated email)
225- **Path property**: Contains user's redirect path in format `/glimpse/:id` (optional for new users)
231The login endpoint provides detailed error information for debugging:
232- Missing environment variables
233- Database query failures
234- User creation failures (falls back to access denied page)
235- Invalid or missing Path properties
2732. Retrieves page properties to extract Assigned and Viewing properties
2743. **Checks if Viewing property is true** - if not, skips assignment and logs result
2754. Queries `GLANCE_AGENTS_DB_ID` database for agents with matching Assigned property
2765. **STEP 1: Clear Current Demo Blob** - Immediately clears the agent blob for this demo
2776. **STEP 2: Find New Agents** - Queries agents database by Assigned property
2787. **STEP 3: Collect Agent Data** - Fetches complete agent information and validates
2798. **STEP 4: Clear Agents from Other Demo Blobs** - Removes agents from any other demo blobs to prevent double-assignment
283- **Immediate Updates**: Agent blob is updated immediately for fast frontend response
284- **Multi-Blob Clearing**: Ensures agents only appear in one demo blob at a time
285- **Eventual Consistency**: Cron jobs handle Notion database cleanup in the background
286- **No Manual Unassignment**: Assignments are cleared automatically when `Viewing = false`
287- **Reliable**: Blob operations are simpler and more reliable than complex relation management
325- Page must have a **Viewing property set to true** (assignment only occurs for actively viewed pages)
326- Page must have an Assigned property with assigned person
327- Agents database must have pages with Assigned properties matching the assigned person
328- Original page must have a "Glimpse agents" relation property
329- Agent pages must have a "Glimpse demos" relation property
394
395**Performance Benefits:**
396- **Fast Execution**: Blob scanning is faster than database queries
397- **Targeted Processing**: Only processes pages with empty agent arrays
398- **Resource Efficient**: Minimal API calls to Notion
433
434Configure these environment variables for full functionality:
435- `GLANCE_DEMOS_DB_ID` - Notion database ID for demos
436- `GLANCE_CONTENT_DB_ID` - Notion database ID for content
437- `GLANCE_INTERACTIONS_DB_ID` - Notion database ID for interactions
438- `GLANCE_AGENTS_DB_ID` - Notion database ID for agents
439- `NOTION_API_KEY` - Notion API key for database access
440- `NOTION_WEBHOOK_SECRET` - Secret key for webhook authentication
441
452### **Blob Storage + Notion Sync**
453- **Fast blob updates**: Page viewing status stored in Val Town blob storage for instant response (~100ms)
454- **Immediate Notion sync**: When users start viewing pages, Notion database is updated immediately
455- **Automatic cleanup**: Cron job runs every minute to mark stale sessions (>1 minute old) as not viewing
456
517- **Content**: Must exactly match the authenticated user's email address
518
519### **Notion Database Schema**
520Pages in your Notion databases should include these properties for viewing analytics:
521- **Email** (Email or Rich Text) - **Required** for authorization
522- **Session start** (Date) - **Primary viewing status**: Currently viewing + when session began