DocsIntegrations

Frame.io, Surfline, Resend, and APNs

Integrations

Surflink integrates with several external services for video management, surf conditions, email delivery, and push notifications.

Frame.io (Video Assets)

File: src/lib/frameio.js

Surflink integrates with Adobe Frame.io V4 to allow coaches to browse and import video assets from their Frame.io accounts directly into the platform.

OAuth Flow

Frame.io uses Adobe IMS (Identity Management System) for OAuth:

  1. Coach clicks "Connect Frame.io" in the upload page
  2. Redirected to Adobe IMS authorization URL with scopes for Frame.io access
  3. User authorizes the application
  4. Callback exchanges the authorization code for access + refresh tokens
  5. Tokens are stored in HTTP-only cookies (frameio_token, frameio_refresh_token)
  6. Token refresh is handled automatically when the access token expires

API Methods

MethodDescription
getMe()Get current user profile
getWorkspaces(accountId)List workspaces for an account
getProjects(workspaceId)List projects in a workspace
getFolderChildren(folderId)List files and folders
getFile(fileId)Get file metadata
downloadAssetBuffer(url)Download file content as buffer

Import Flow

  1. Coach browses their Frame.io account through the FrameIOBrowser component
  2. Selects video files for import (max 10 per batch)
  3. /api/frameio/import downloads each asset and creates session + clip records
  4. Each clip is sent to Modal for AI analysis
  5. Processing follows the standard video pipeline

Surfline (Surf Conditions)

File: src/lib/surfline.js

Surflink wraps the Surfline KBYG (Know Before You Go) API to provide real-time surf condition data.

Caching

All Surfline API responses are cached in-memory with:

  • 10-minute TTL per cache entry
  • 200-entry LRU eviction to prevent memory bloat
  • Cache keys are based on the full request URL

Available Data

Data TypeDescription
Wave ForecastHeight (min/max), period, direction, optimal score
WindSpeed, direction, gusts, optimal score
Surf Rating0-5 star rating with human-readable conditions
TidesHigh/low tide times and heights
Map ViewBounding-box based spot discovery

API Methods

MethodDescription
getWaveForecast(spotId, days)Wave data for a spot
getWindForecast(spotId, days)Wind data for a spot
getRating(spotId, days)Surf quality rating
getTides(spotId, days)Tide schedule
getConditions(spotId)Current conditions summary
getSpotForecast(spotId, days)Composite: wave + wind + rating + tides in parallel
getMapview(bounds)Spots within a bounding box

Integration Points

  • Dashboard widget -- Current conditions at the coach's home break
  • Surf forecast widget -- Multi-day outlook
  • Lesson scheduling -- Forecast data for the scheduled date and location
  • Journal entries -- Conditions at the time of the session

The default configuration focuses on Barbados surf spots with a pre-configured bounding box and spot database.


Resend (Email)

Package: resend

Used for transactional email delivery:

  • Student invitations -- Email with invite link when a coach adds a new student
  • Critical notifications -- Lesson reminders, achievement awards, and other important updates

Emails are sent through the /api/notifications/send and /api/invite endpoints.


Apple Push Notifications (APNs)

Package: jose (for JWT signing)

Push notifications are sent to registered iOS and watchOS devices:

Token Registration

Devices register their push tokens via the push_tokens table. Each token records the user ID, device token, platform (apns/fcm/web), and device name.

Sending Flow

  1. /api/notifications/send receives a notification request
  2. Creates a notification record in the database
  3. Queries push_tokens for the target user's registered devices
  4. Signs a JWT using the APNs private key (via jose)
  5. Sends the push payload to Apple's APNs HTTP/2 endpoint
  6. Handles token expiration and invalid token cleanup

Configuration

Requires these environment variables:

  • APNS_KEY_ID -- Key ID from Apple Developer portal
  • APNS_TEAM_ID -- Apple Developer Team ID
  • APNS_PRIVATE_KEY -- The .p8 private key content
  • APNS_BUNDLE_ID -- App bundle identifier
  • APNS_ENVIRONMENT -- development or production