All docs

Infrastructure

Infrastructure — Local / Staging / Production

Three environments (local Docker Supabase, staging cloud, production cloud) + admin portal on Vercel + Expo Go / EAS APK for mobile.

Implementation plan: See IMPLEMENTATION_PLAN.md for the full v0.2 rollout (admin portal, content catalog schema, chapters, i18n, SDLC). This page documents the resulting environment topology.

Environment map

Local Staging Production
Git branch feature/* staging main
Supabase supabase start (Docker, :54321) umikora-staging (cloud) umikora-production (cloud)
Admin portal npm run dev (:3000) Vercel preview (auto on staging) Vercel production (auto on main)
Mobile EXPO_PUBLIC_APP_ENV local staging production
Mobile target Expo Go on LAN Expo Go OR staging APK Production APK
Android package com.umikora.app.dev com.umikora.app.staging com.umikora.app
App display name Umikora (Dev) Umikora (Staging) Umikora
GitHub deploy n/a Supabase Integration + Vercel Supabase Integration + Vercel

Git workflow

feature/* → PR → staging → verify → PR → main
  • Push to staging triggers Supabase GitHub Integration (auto-deploys migrations + Edge Functions) and Vercel preview build of the admin portal.
  • Push to main triggers Supabase GitHub Integration and Vercel production deploy.
  • Mobile prod APK is built via eas build --profile production from main on release tags.

Supabase GitHub Integration

Supabase is connected directly to the GitHub repo via Integrations (Dashboard → Settings → Integrations → GitHub).

  • Staging project linked to staging branch — auto-deploys supabase/migrations/ + Edge Functions.
  • Production project linked to main branch — same.
  • PR preview databases are automatically created per PR.
  • No GitHub Actions secrets needed for Supabase (Integration handles auth).
  • CI tests still run via .github/workflows/test.yml.

Vercel project (admin portal)

Configured via Vercel dashboard (one project per environment, or one project with branch-based env vars):

Setting Value
Root directory apps/admin
Framework preset Next.js
Build command npm run build
Install command npm install (workspaces)
Preview branch staging → staging Supabase env vars
Production branch main → production Supabase env vars

Env vars per environment:

Var Where
NEXT_PUBLIC_SUPABASE_URL Vercel project env (preview / production)
NEXT_PUBLIC_SUPABASE_ANON_KEY Vercel project env (preview / production)

Supabase Dashboard (each project)

  1. Edge Functions → featured-feed → Secrets
    • APP_ENV = staging or production
  2. Confirm Settings → API Keys → Publishable key and Project URL for mobile / EAS.

Local development

The recommended path uses local Docker Supabase + auto-generated .env.local files. See SETUP.md for the cross-platform (macOS + Windows) walkthrough.

npm install
npm run supabase:start    # start local Supabase (Docker)
npm run setup:local       # writes apps/admin/.env.local and apps/mobile/.env.local
# admin portal
cd apps/admin && npm run dev      # http://localhost:3000
# mobile (in another terminal)
cd apps/mobile && npx expo start  # Expo Go on LAN

scripts/setup-local.mjs reads supabase status and writes:

  • apps/admin/.env.local:
    NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321
    NEXT_PUBLIC_SUPABASE_ANON_KEY=<local anon key>
    
  • apps/mobile/.env.local:
    EXPO_PUBLIC_APP_ENV=local
    EXPO_PUBLIC_SUPABASE_URL=http://<host LAN IP>:54321
    EXPO_PUBLIC_SUPABASE_ANON_KEY=<local anon key>
    

Targeting staging or production from a device

To run a physical-device build against cloud staging/production, override .env.local or use EAS build profiles (see EAS Build section below).

EXPO_PUBLIC_APP_ENV=staging
EXPO_PUBLIC_SUPABASE_URL=https://xxxx.supabase.co
EXPO_PUBLIC_SUPABASE_ANON_KEY=sb_publishable_...

Explore tab loads featured-feed Edge Function; offline falls back to mocks/featured.ts.

Manual Supabase CLI (optional)

supabase login
supabase link --project-ref <STAGING_REF>
supabase db push
supabase functions deploy featured-feed

EAS Build (Android APK)

Prerequisites: Expo account, eas-cli, project linked (eas init in apps/mobile).

Set Expo environment variables per build profile (staging / production):

  • EXPO_PUBLIC_SUPABASE_URL — Project URL
  • EXPO_PUBLIC_SUPABASE_ANON_KEY — Publishable key (sb_publishable_...)
cd apps/mobile
eas build --profile staging --platform android
eas build --profile production --platform android

Staging and production APKs can be installed side by side (different package IDs).

Verify staging

  1. GitHub Action green after push to staging.
  2. Supabase Table Editor: 8 rows in featured_items.
  3. Curl (replace URL + Publishable key):
curl -X POST "https://<PROJECT>.supabase.co/functions/v1/featured-feed" \
  -H "Authorization: Bearer <PUBLISHABLE_KEY>" \
  -H "Content-Type: application/json" \
  -d "{\"limit\":5,\"user_subject_tags\":[\"chemistry\"]}"
  1. Response items order should not match published_at only (editorial_boost affects rank).
  2. Mobile Explore → tap card → featured_events has click rows.

Content catalog (v0.2)

The content catalog (modules → chapters → cards, pathways, translations) lives entirely in Supabase. The admin portal is the only writer; the mobile app is a read-only consumer (syncs to its SQLite mirror for offline reads). See IMPLEMENTATION_PLAN.md §3 for the schema, §4 for RLS, and §6 for mobile sync.

RLS roles (set via auth.users.app_metadata.role)

Role Capabilities
anon SELECT on is_active=true content + all translations
reviewer + INSERT/UPDATE on translation tables
editor + Full CRUD on content tables
admin + user management, read audit trail

The admin portal Server Actions always use the user’s session JWT (not service_role), so RLS enforces every write.

Audit trail

Every change to content / translation tables writes a row to content_revisions (triggers in migration 20260608000001_content_catalog.sql). The admin Dashboard and System pages render this feed.

Repo layout

scripts/setup-local.mjs            One-shot local-env writer
apps/admin/                        Next.js admin portal (v0.2+)
apps/mobile/src/data/              SQLite mirror, repositories, supabaseContentClient
packages/shared/                   Types, SM-2, radar, featured scoring
supabase/migrations/               SQL schema + seed (content_catalog, featured_*)
supabase/functions/                Edge Functions (featured-feed, set-user-role)
.github/workflows/                 CI + deploy
docs/                              IMPLEMENTATION_PLAN.md, ARCHITECTURE.md, MOBILE.md, ...