Skip to content

Showcase: Lifegames Portal

A personal data aggregation backend built on Mantle. The Lifegames Portal platform consolidates health, location, bookshelf, focus, GitHub activity, and article tracking into a single TypeScript/AWS Lambda service. Data is synced from iOS devices and third-party webhooks, then exported as structured JSON to S3/CloudFront for downstream consumption. Originally split across two separate services (manage-apple-health and manage-apple-location), the Portal is now a single fully-migrated Mantle instance.

Architecture

iOS devices (HealthKit / CoreLocation / LifePortal app)


API Gateway (bearer auth)
  ├──► api/health/*          POST /health/sync, GET /health/ping
  ├──► api/locations/*       POST /locations/summary/sync, GET /locations/ping
  ├──► api/books/*           GET/POST/DELETE /books, POST /books/add, POST /books/update
  ├──► api/articles/*        POST /articles/saved, POST /articles/notes
  ├──► api/focus.post.ts     POST /focus
  └──► api/github/webhook    POST /github/webhook (HMAC-validated)

  EventBridge (lifegames-portal bus)
  ├──► ExportHealthData       → S3/CloudFront (JSON)
  ├──► ExportLocationData     → S3/CloudFront (JSON)
  ├──► ExportBooks            → S3/CloudFront (JSON)
  ├──► ExportArticles         → S3/CloudFront (JSON)
  ├──► ExportGitHubActivity   → S3/CloudFront (JSON)
  ├──► ExportStarredRepos     → S3/CloudFront (JSON)
  ├──► ExportTheatreReviews   → S3/CloudFront (JSON)
  ├──► OptimizeImages         → S3 (in-place)
  └──► SyncStarredRepos       → GitHub API → Aurora DSQL

  Scheduled
  └──► DailyHealthExport      → EventBridge trigger chain

  Standalone
  └──► MigrateDSQL            → Aurora DSQL schema migrations + permission grants

  Aurora DSQL (PostgreSQL-compatible, serverless)
  ◄── All Lambdas (Drizzle ORM, IAM auth via getDrizzleClient)

Mantle Features Used

FeatureHow it is used
defineApiHandlerAll 13 API routes — bearer auth, Zod schema validation, OpenAPI metadata
defineEventBridgeHandler9 EventBridge handlers triggered by named detail types
defineScheduledHandlerDailyHealthExport on a CloudWatch schedule
mantle buildSingle command bundles all 23 handlers with esbuild
mantle deploy --stageOpenTofu plan + apply across staging and production
mantle generate infraAuto-generates all .tf files, EventBridge rules, IAM policies
mantle generate permissionsAuto-generates DSQL IAM grants from @RequiresTable decorators
exportToS3 / emitEventS3 export + EventBridge follow-up events from @mantleframework/aws
getDrizzleClientAurora DSQL with Drizzle ORM for all entity access
@mantleframework/observabilityStructured logging, EMF metrics, X-Ray tracing (ADOT)

Key Numbers

  • 23 Lambda handlers across 4 trigger types (API, EventBridge, Scheduled, Standalone)
  • 13 database tables across 6 data domains (health, location, books, articles, focus, GitHub)
  • 33 HealthKit quantity types accepted by /health/sync
  • 9 EventBridge export handlers writing structured JSON to S3/CloudFront
  • 8 custom ESLint local rules in eslint-local-rules/
  • 258 tests across 30 test files (Vitest)

Repo

mantle-LifegamesPortal/ — symlinked at the monorepo root.