A full-stack SaaS task management application built with Next.js and Supabase, featuring AI-powered task labeling, image attachments, and Stripe subscriptions.
- Specific tutorial documents can be found in the
/tutorial
folder. - Project design and spec can be found at tutorial/PROJECT_DESIGN.md.
- Task management with automatic AI labeling
- Image attachments with cloud storage
- Google OAuth and email authentication
- Premium subscription with Stripe integration
- Usage limits and tracking
- Frontend: Next.js, React, TypeScript, Tailwind CSS
- Backend: Supabase (PostgreSQL, Auth, Storage, Edge Functions)
- AI: OpenAI
- Payments: Stripe
- Node.js and npm
- Supabase CLI
- Stripe CLI (optional)
- Account credentials for:
- Supabase
- OpenAI
- Stripe (test mode)
- Clone and install dependencies:
# From project root.
npm install
- Create environment files - update the values with your keys.
cp .env.example .env.local
cp .env.example .env.test.local
- Run development server:
npm run dev
# Visit http://localhost:3000
At this stage, it won't work well yet because we haven't set up the backend.
-
Create new Supabase project at supabase.com
-
Link project:
supabase init
supabase link --project-ref your-project-ref
- Deploy database and functions:
# Apply DB migrations
supabase db push
# Or you can use this command if you need to nuke the DB and reset it.
# supabase db reset --linked
# Deploy edge functions
supabase functions deploy create-task-with-ai
supabase functions deploy create-stripe-session
supabase functions deploy stripe-webhook
-
Disable
Enforce JWT Verification
( Edge Functions > stripe-webhook > Details > Enforce JWT Verification) for your Stripe webhook Edge Function. -
Disable email confirmation in Supabase Dashboard:
- Authentication > Providers > Email
- Uncheck "Confirm email"
- Get API key from platform.openai.com
- Set as Supabase secret:
supabase secrets set OPENAI_API_KEY=your-key
-
Create Stripe test account and get API keys
-
Create subscription product:
stripe prices create \
--currency=usd \
--unit-amount=1000 \
-d "recurring[interval]"=month \
-d "recurring[trial_period_days]"=14 \
-d "product_data[name]"="TaskMaster Premium"
- Configure customer portal:
stripe billing_portal configurations create \
-d "business_profile[privacy_policy_url]=https://your-site.com/privacy" \
-d "business_profile[terms_of_service_url]=https://your-site.com/terms" \
-d "default_return_url=http://localhost:3000/profile" \
-d "features[subscription_cancel][enabled]=true" \
-d "features[payment_method_update][enabled]=true"
-
Set up webhook in Stripe Dashboard:
- Endpoint:
https://[PROJECT_ID].supabase.co/functions/v1/stripe-webhook
- Events:
checkout.session.completed
,customer.subscription.deleted
,customer.subscription.updated
- Endpoint:
-
Set up Stripe secret in Supabase PostgresSQL vault. Go into your Supabase dashboard, to go SQL Editor then run this command (replacing your secret key):
insert into vault.secrets (name, secret)
select 'stripe', 'sk_test_xxx'
returning key_id;
Add to .env.local
and .env.test.local
:
# Add this to both:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
# Only .env.test.local needs these:
SUPABASE_SERVICE_KEY=your-service-key
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PRICE_ID=price_...
STRIPE_WEBHOOK_SECRET=whsec_...
Your Edge Functions will also need those environment variables. Set them like this:
supabase secrets set OPENAI_API_KEY="sk-xxx..."
supabase secrets set STRIPE_SECRET_KEY=sk_test_xxx
supabase secrets set STRIPE_PRICE_ID=price_xxx
supabase secrets set STRIPE_WEBHOOK_SECRET=whsec_xxx
# Run all tests
npm test
# Run specific test file
npm test tests/integration/2_auth.test.ts
# Run specific test case
npm test tests/integration/5_task_limits.test.ts -- -t "free user cannot exceed task limit"
Start development server and go to the local site for testing.
npm run dev
taskapp/
├── app/ # Next.js pages and layouts
├── components/ # React components
├── hooks/ # Application logic
│ ├── useAuth.ts # Authentication
│ ├── useTask.ts # Task management
│ └── useUser.ts # User profile/subscription
├── supabase/
│ ├── functions/ # Edge Functions
│ └── migrations/ # Database migrations
└── tests/
└── integration/ # Integration tests