Arc is an AI-powered content strategy system built for startup founders. It turns weekly check-ins — 6 questions about what happened in your startup that week — into platform-native content plans with scripts, captions, and hashtags for Instagram, TikTok, and LinkedIn. Every plan is tailored to the founder's archetype, narrative phase, and historical performance data.
| Layer | Technology |
|---|---|
| Framework | Next.js 14 (App Router) |
| Database | Supabase (Postgres + Auth + Storage) |
| AI generation | OpenAI GPT-4o / Anthropic Claude (fallback) |
| Background jobs | Inngest |
| Payments | Stripe |
| Resend + React Email | |
| Rate limiting | Upstash Redis |
| Analytics | PostHog |
| Error tracking | Sentry |
| Testing | Vitest + Playwright |
| Deployment | Vercel |
- Node.js 20+
- npm
- Supabase CLI —
brew install supabase/tap/supabase - Active accounts: Supabase, OpenAI, Stripe, Resend, Upstash, Inngest, PostHog, Sentry
# 1. Clone and install dependencies
git clone https://github.com/MaitreyeeDeshmukh/arc.git
cd arc
npm install
# 2. Start Supabase locally
supabase start # starts local Postgres + Auth + Storage
supabase db push # applies migrations from supabase/migrations/
# 3. Configure environment variables
cp .env.example .env.local
# Edit .env.local — see the Environment Variables section below
# 4. Run the dev server
npm run devOpen http://localhost:3000.
For E2E tests a separate Supabase project is recommended:
export PLAYWRIGHT_BASE_URL=http://localhost:3000
export NEXT_PUBLIC_SUPABASE_URL=https://your-test-project.supabase.co
# ... fill remaining test env vars
npm run test:e2eCopy .env.example to .env.local and fill in each value.
| Variable | Where to find it |
|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Supabase dashboard → Settings → API → Project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Supabase dashboard → Settings → API → anon key |
SUPABASE_SERVICE_ROLE_KEY |
Supabase dashboard → Settings → API → service_role key — never expose in browser |
| Variable | Where to find it |
|---|---|
OPENAI_API_KEY |
platform.openai.com → API Keys |
ANTHROPIC_API_KEY |
console.anthropic.com → API Keys — used as GPT-4o fallback |
| Variable | Where to find it |
|---|---|
STRIPE_SECRET_KEY |
Stripe dashboard → Developers → API keys → Secret key |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY |
Stripe dashboard → Developers → API keys → Publishable key |
STRIPE_WEBHOOK_SECRET |
Stripe dashboard → Webhooks → your endpoint → Signing secret |
STRIPE_PRO_PRICE_ID |
Stripe dashboard → Products → your Pro product → price ID (starts with price_) |
STRIPE_FOUNDER_PRICE_ID |
Stripe dashboard → Products → your Founder product → price ID |
| Variable | Where to find it |
|---|---|
RESEND_API_KEY |
resend.com → API Keys |
| Variable | Where to find it |
|---|---|
UPSTASH_REDIS_REST_URL |
upstash.com → your database → REST API |
UPSTASH_REDIS_REST_TOKEN |
upstash.com → your database → REST API |
| Variable | Where to find it |
|---|---|
INNGEST_EVENT_KEY |
inngest.com → your app → Manage → Event Keys |
INNGEST_SIGNING_KEY |
inngest.com → your app → Manage → Signing Key |
| Variable | Description |
|---|---|
ENCRYPTION_KEY |
64-character hex string (32 random bytes). Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" |
| Variable | Where to find it |
|---|---|
NEXT_PUBLIC_POSTHOG_KEY |
posthog.com → your project → Settings → Project API Key |
NEXT_PUBLIC_POSTHOG_HOST |
https://app.posthog.com (EU: https://eu.posthog.com) |
SENTRY_DSN |
sentry.io → your project → Settings → Client Keys (DSN) |
NEXT_PUBLIC_SENTRY_DSN |
Same value as SENTRY_DSN — safe to expose publicly |
-
Import your GitHub repository at vercel.com/new.
-
Set all environment variables in the Vercel dashboard (Settings → Environment Variables). Copy every key from
.env.example. -
Supabase: In Supabase dashboard → Authentication → URL Configuration:
- Site URL:
https://your-domain.vercel.app - Redirect URLs:
https://your-domain.vercel.app/auth/callback
- Site URL:
-
Deploy — Vercel auto-deploys on every push to
main. -
After first deployment, register the Stripe webhook and connect Inngest (see sections below).
After deploying to Vercel:
- Stripe dashboard → Developers → Webhooks → Add endpoint
- Endpoint URL:
https://your-domain.vercel.app/api/webhooks/stripe - Events to listen for:
checkout.session.completedinvoice.payment_succeededinvoice.payment_failedcustomer.subscription.deletedcustomer.subscription.updated
- Click Add endpoint, then reveal the Signing secret
- Copy it to the
STRIPE_WEBHOOK_SECRETenvironment variable in Vercel and redeploy
Local testing: Use the Stripe CLI:
stripe listen --forward-to localhost:3000/api/webhooks/stripe- Create a free account at inngest.com
- Create a new app — copy Event Key →
INNGEST_EVENT_KEYand Signing Key →INNGEST_SIGNING_KEY - In Vercel, add both keys as environment variables and redeploy
- In the Inngest dashboard → Apps → Sync app → enter your Vercel URL
- Inngest will call
https://your-domain.vercel.app/api/inngestto register functions
Local development: Run the Inngest Dev Server:
npx inngest-cli@latest devThen open http://localhost:8288 to trigger and inspect background jobs.
Registered functions:
generate-content-plan— triggered bycheckin/submittedcompute-performance-summary— cron every night at 02:00 UTCweekly-reminder— cron every Monday at 08:00 UTC
npm run dev # Start development server
npm run build # Build for production
npm run test # Run unit + integration tests (Vitest)
npm run test:watch # Watch mode
npm run test:coverage # Coverage report
npm run test:e2e # End-to-end tests (Playwright)Before going live, verify each item:
- All 19 environment variables set in Vercel dashboard
- Supabase Site URL and Redirect URLs updated to production domain
- Supabase email templates customised (Auth → Email Templates)
- Stripe webhook endpoint registered with correct events and signing secret
- Stripe products created with
STRIPE_PRO_PRICE_IDandSTRIPE_FOUNDER_PRICE_ID - Stripe billing portal configured (dashboard.stripe.com/settings/billing/portal)
- Inngest app synced to production URL
- Resend domain verified with DNS (SPF + DKIM records at resend.com/domains)
- PostHog project created, key + host set in Vercel env
- Sentry project created, DSN set in Vercel env
- Google OAuth redirect URI added:
https://your-domain.vercel.app/auth/callback(Google Cloud Console) - ENCRYPTION_KEY set in Vercel env (generate fresh key, do not reuse dev key)
-
npm run testpasses (CI blocks merge on failure) - Run through full user flow: signup → onboarding → check-in → plan → view → log performance
- Auth: Supabase Auth with cookie-based sessions via
@supabase/ssr - Middleware: protects
/dashboard,/checkin,/plans,/settings; redirects incomplete onboarding to/onboarding/3 - AI Pipeline: GPT-4o → extract story → generate plan → scripts → captions → eval; Claude fallback for extraction step
- Free tier: 1 content plan per month, 2 posts per plan (enforced in API + pipeline)
- Prompt injection protection: check-in answers sanitised before AI injection via
lib/sanitize.ts