Four surfaces, one backend, zero data duplication.
A connected suite of four products — admin portal, mobile app, AI-driven Telegram bot, and a privacy policy site — sharing a single Supabase backend with carefully designed row-level-security policies for multi-admin data isolation.
- Role
- Full-Stack Developer + UI/UX (multi-product)
- Stack
- Next.js (Admin Portal)React Native + Expo SDK 54TelegrafOpenAIExpressSupabaseexpo-notificationsexpo-secure-store
- Tags
- Multi-platformMobileAI BotsMulti-tenant AuthPublic Sector / Advocacy
Context
Freedom Action Network needed three things at once: an admin portal for content publishing and analytics, a mobile app for the public to consume that content, and an AI-powered Telegram bot for campaign info and draft generation. Off-the-shelf tools couldn’t connect them; building three separate systems would’ve meant three separate sources of truth.
Approach
Designed a single Supabase backend as the source of truth, with explicit row-level-security policies on three tables (admins, posts, push_tokens) that handle three audiences correctly: admins can only edit their own posts (auth.uid() = author_id), the mobile app’s anon key only sees published = true rows, and the service-role key stays server-side for admin-wide operations. The Next.js admin portal handles content publishing, image uploads to Supabase Storage, and analytics — including a Twitter-source-tracking module and per-post analytics. The Expo SDK 54 mobile app consumes the same data through the public RLS-protected endpoints, with push notifications, secure token storage, and offline-friendly caching. The Telegram bot uses Telegraf and OpenAI to handle conversational queries and generate draft content from user context.
Outcome
Four surfaces, one backend, zero data duplication. Adding a new content type means writing one schema migration, not three. The RLS policies have held up under real adversarial testing — admins cannot leak each other’s drafts, anon clients cannot see unpublished content, and the boundary is enforced at the database layer where it cannot be bypassed by application bugs.
What it does
- 01Four production surfaces (admin portal, native mobile app on iOS + Android, Telegram bot, privacy policy site) sharing a single Supabase backend
- 02RLS policies on 3 tables enforcing three distinct access patterns (owner-scoped, public-published-only, service-role)
- 03Production across mobile (iOS + Android), web admin, and conversational surfaces with no shared-state drift between them
Tell us what you’re working on.
We’re happy to talk through what we learned on this project and whether we’re the right partner for yours.