Overview
TechCal uses client-side event tracking through Supabase RPC functions rather than a dedicated REST API endpoint. This approach provides real-time updates and integrates seamlessly with Row Level Security policies.
Event tracking operations are performed client-side using the UserEventService class, which calls Supabase RPC functions with automatic calendar sync.
Authentication
All tracking operations require an authenticated Supabase client session.
Tracking Methods
Toggle Bookmark
Add or remove an event from your bookmarks. Bookmarked events automatically sync to connected calendars.
Service Method:
import { UserEventService } from '@/services/userEventService' ;
const result = await UserEventService . toggleBookmark ( userId , eventId );
Parameters:
UUID of the authenticated user
UUID of the event to bookmark/unbookmark
Returns:
{
isBookmarked : boolean ; // New bookmark state
wasBookmarked : boolean ; // Previous state
autoBookmarked : boolean ; // Whether event was auto-bookmarked
}
Database RPC:
SELECT * FROM toggle_bookmark_v3(
p_user_id : = user_id,
p_event_id : = event_id
);
Set Attendance Status
Update your attendance status for an event.
Service Method:
const result = await UserEventService . setAttendanceStatus (
userId ,
eventId ,
'attending' // or 'attended', 'cancelled'
);
Parameters:
UUID of the authenticated user
Attendance status to set Options: attending, attended, cancelled
Returns:
{
success : boolean ;
status : 'attending' | 'attended' | 'cancelled' ;
}
Database RPC:
SELECT * FROM set_attendance_status(
p_user_id : = user_id,
p_event_id : = event_id,
p_status : = status
);
Legacy Track Event (Deprecated)
The original trackEvent method is deprecated in favor of decoupled bookmark and attendance operations.
Use toggleBookmark() and setAttendanceStatus() instead for better control and clearer semantics.
Calendar Sync Integration
When you bookmark an event, TechCal automatically syncs it to your connected Google Calendar if:
You’ve connected a Google Calendar account
Calendar sync is enabled in your preferences
The event has valid date/time information
Sync Endpoint:
See Calendar Sync API for details on calendar integration.
Database Schema
Event tracking uses the user_events table with Row Level Security:
CREATE TABLE user_events (
id UUID PRIMARY KEY ,
user_id UUID REFERENCES profiles(id),
event_id UUID REFERENCES events(id),
is_bookmarked BOOLEAN DEFAULT false,
bookmarked_at TIMESTAMPTZ ,
status TEXT CHECK ( status IN ( 'attending' , 'attended' , 'cancelled' )),
notes TEXT ,
created_at TIMESTAMPTZ DEFAULT NOW (),
UNIQUE (user_id, event_id)
);
Example Usage
React Component Example
'use client' ;
import { useState } from 'react' ;
import { UserEventService } from '@/services/userEventService' ;
import { useAuth } from '@/contexts/AuthContext' ;
export function BookmarkButton ({ eventId } : { eventId : string }) {
const { user } = useAuth ();
const [ isBookmarked , setIsBookmarked ] = useState ( false );
const [ loading , setLoading ] = useState ( false );
const handleToggle = async () => {
if ( ! user ) return ;
setLoading ( true );
try {
const result = await UserEventService . toggleBookmark ( user . id , eventId );
setIsBookmarked ( result . isBookmarked );
if ( result . isBookmarked ) {
// Event bookmarked, will auto-sync to calendar
console . log ( 'Event added to bookmarks' );
}
} catch ( error ) {
console . error ( 'Failed to toggle bookmark:' , error );
} finally {
setLoading ( false );
}
};
return (
< button onClick = { handleToggle } disabled = { loading } >
{ isBookmarked ? 'Remove Bookmark' : 'Bookmark Event' }
</ button >
);
}
Error Handling
Common errors when tracking events:
Ensure the Supabase client has a valid session before calling tracking methods. const { data : { session } } = await supabase . auth . getSession ();
if ( ! session ) {
throw new Error ( 'User must be authenticated' );
}
The event ID doesn’t exist or has been deleted. // Verify event exists before tracking
const { data : event } = await supabase
. from ( 'events' )
. select ( 'id' )
. eq ( 'id' , eventId )
. single ();
Calendar sync can fail if the calendar connection expired or was revoked. The bookmark will still be saved, but won’t sync to the external calendar. Check calendar connection status: GET / api / calendar / google / status
Calendar Sync Sync events to Google Calendar
Events API Query and filter events