Skip to content

Latest commit

 

History

History
832 lines (629 loc) · 20.2 KB

File metadata and controls

832 lines (629 loc) · 20.2 KB

DevLaunch

Monorepo Web API DB Auth Billing Status

Developer-first launch platform for validating product demand before GA.

Table of Contents

1. Project Summary

DevLaunch is a SaaS-style platform where creators can publish early product pages, collect signals from real users, and decide whether to invest more development into a product.

In short, DevLaunch answers one question:

  • "Is this product worth building further?"

Primary reference docs:

  • Architecture notes: docs/architecture.md
  • Prisma schema: packages/db/prisma/schema.prisma

2. Why This Project Exists

Many builders launch too late, after spending months on features without market proof. DevLaunch moves validation earlier by combining:

  • waitlist demand
  • qualitative feedback
  • lightweight voting
  • early-access checkout intent

Business value:

  • reduces product risk
  • improves roadmap quality
  • turns assumptions into measurable signals

3. Who Uses DevLaunch

Creator persona

  • Creates launch pages
  • Tracks engagement and demand
  • Reads feedback before investing in full build

Early adopter persona

  • Discovers new products
  • Joins waitlists
  • Leaves feedback
  • Purchases early access if convinced

Team/operator persona

  • Monitors notifications and analytics
  • Reviews project performance trends
  • Manages account and security settings

4. Core Features

  • Product launch page creation with slug handling
  • Discovery listing and ranking/trending behavior
  • Waitlist capture and feedback collection
  • Vote-based demand signaling
  • Early-access checkout flow
  • Dashboard summary and activity monitoring
  • Notification and session management

5. Widget Catalog

Discovery widgets

Widget Purpose UI/UX detail
Trending Project Cards Highlight hot products Rank badge, score chip, vote/waitlist metrics
Project Hero Summary Context at first glance Status, date, slug, metadata layout
Project Quick Actions Fast outbound actions Share, copy link, open website

Engagement widgets

Widget Purpose Interaction
Waitlist CTA Capture user interest Email input -> submit -> success feedback
Feedback Composer Collect qualitative insight Text input -> API submit -> feed update
Feedback Feed Show social proof Newest-first feedback list
Vote Action Low-friction support signal One-click vote with auth checks

Conversion widgets

Widget Purpose Flow detail
Checkout Modal Monetize early demand Email -> Review -> Checkout steps
Consent Gate Legal clarity Explicit agreement before payment action
Payment Fallback Dev flow continuity Mock checkout when provider is placeholder

Dashboard widgets

Widget Purpose Data source
Summary Cards Quick health check Revenue, waitlist, notifications, top projects
Mini Sparkline Trend visibility Weekly and 14-day analytics slices
Notification Center Actionable updates Read/unread and activity feed
Settings Panels Account control Profile, password, session revocation

6. End-to-End User Flows

Flow A: Creator launches a product

  1. User signs in.
  2. Opens launch form and enters product details.
  3. System validates input with shared Zod schemas.
  4. API writes project + media in database.
  5. Product appears on discovery and detail pages.

Flow B: Visitor validates demand

  1. Visitor opens project page.
  2. Visitor joins waitlist and/or votes.
  3. Visitor leaves feedback text.
  4. Creator sees updated engagement and dashboard changes.

Flow C: Early-access purchase

  1. Visitor starts checkout from project page.
  2. Email capture and review step complete.
  3. API requests provider checkout session.
  4. In dev invalid token scenarios, fallback route is used.
  5. Purchase intent is visible in creator metrics.

7. System Architecture

apps/
  web/            Next.js 16 app router frontend
  api/            Elysia.js API on Bun
packages/
  ui/             Reusable design system components
  db/             Prisma schema/client and query helpers
  validation/     Zod schemas shared by API and web
  types/          Shared TypeScript domain types
  config/         Environment parser/config helpers
docs/
  architecture.md

Layered architecture

  • Presentation layer:
    • apps/web handles routing, pages, client interactions, and theming.
  • Application/API layer:
    • apps/api handles auth, business rules, route orchestration, and service logic.
  • Domain/shared contracts:
    • packages/validation and packages/types define shared shapes.
  • Data/persistence layer:
    • packages/db defines Prisma models and database access patterns.

Request lifecycle (example: submit feedback)

  1. Web component sends POST /feedback.
  2. API route parses body and validates schema.
  3. Service applies business checks (project existence, ownership rules if needed).
  4. Prisma writes feedback row.
  5. API responds with normalized payload.
  6. Web refreshes feed and updates UI state.

Architectural goals

  • clear separation of concerns
  • typed contracts from edge to DB
  • reusable packages in monorepo
  • safe development fallbacks for external providers

8. Package Responsibilities

apps/web

  • Next.js App Router pages
  • Dashboard and project UI
  • Client-side API integration and error display

apps/api

  • Elysia route modules
  • Service-layer business logic
  • Third-party integrations (Polar, email)

packages/ui

  • Shared visual components
  • Reusable layout/navigation building blocks

packages/db

  • Prisma schema and generated client
  • Data query helpers and typed persistence access

packages/validation

  • Shared Zod input/output schemas
  • Unified payload validation for web and API

packages/types

  • Shared TypeScript domain models
  • DTO-like utility types

packages/config

  • Environment variable parsing
  • Runtime-safe configuration helpers

9. Data Model

Main entities:

  • User, Session, CreatorProfile
  • Project, ProjectMedia
  • Waitlist, Feedback, Vote
  • Purchase, Notification, AnalyticsEvent

Relationship summary:

  • User -> many Projects
  • Project -> many Waitlist entries, Feedback records, Votes
  • Project -> many AnalyticsEvent records
  • User -> many Notifications and Sessions

Data rules and constraints:

  • unique project slug
  • ownership checks on mutating endpoints
  • indexed read-heavy fields
  • denormalized counters/trending score for discovery speed

10. API Design

API groups

Auth:

  • POST /auth/register
  • POST /auth/login
  • GET /auth/session

Projects:

  • POST /projects
  • GET /projects
  • GET /projects/:slug
  • PUT /projects/:id
  • DELETE /projects/:id

Engagement:

  • POST /waitlist
  • POST /feedback
  • GET /feedback/project/:projectId
  • POST /votes

Analytics:

  • GET /analytics/project/:id

Payments:

  • POST /payments/create-checkout
  • POST /payments/webhook

Dashboard:

  • GET /dashboard/summary
  • GET /dashboard/project/:projectId/activity
  • GET /dashboard/notifications
  • PUT /dashboard/notifications/:id/read

Settings:

  • GET /settings/me
  • PUT /settings/profile
  • POST /settings/password
  • GET /settings/sessions
  • DELETE /settings/sessions/:id

Health:

  • GET /health

API principles

  • schema validation at route boundaries
  • consistent error messages for UX clarity
  • auth and ownership checks before writes
  • explicit fallback behavior in dev integrations

11. Mermaid Architecture Diagram

flowchart LR
  U[Visitor / Creator] --> W[Next.js Web App\napps/web]
  W -->|HTTP JSON| A[Elysia API\napps/api]
  A --> V[Zod Validation\npackages/validation]
  A --> D[(PostgreSQL)]
  A --> P[Prisma Client\npackages/db]
  A --> B[Better Auth]
  A --> R[Resend]
  A --> O[Polar Billing]
  W --> UI[Shared UI\npackages/ui]
  A --> T[Shared Types\npackages/types]
  A --> C[Config Helpers\npackages/config]
Loading

12. API Request/Response Examples

All examples below are sample payloads for local development. Secrets/tokens are intentionally redacted.

Example A: Register user

POST /auth/register

Request:

{
  "name": "Jane Doe",
  "email": "jane@example.com",
  "password": "StrongPass123!"
}

Success response (201):

{
  "user": {
    "id": "cm8abc123xyz",
    "name": "Jane Doe",
    "email": "jane@example.com"
  },
  "session": {
    "id": "sess_01hxyz",
    "expiresAt": "2026-04-11T12:00:00.000Z"
  }
}

Example B: Create project

POST /projects

Request:

{
  "name": "FocusDock",
  "slug": "focusdock",
  "tagline": "Minimal focus dashboard for makers",
  "description": "Track deep work, launch goals, and weekly output.",
  "websiteUrl": "https://focusdock.dev",
  "category": "Productivity"
}

Success response (201):

{
  "id": "cm8proj001abc",
  "name": "FocusDock",
  "slug": "focusdock",
  "status": "draft",
  "createdAt": "2026-03-12T10:15:00.000Z"
}

Conflict response (409):

{
  "error": {
    "code": "PROJECT_SLUG_EXISTS",
    "message": "Slug is already taken",
    "suggestedSlug": "focusdock-app"
  }
}

Example C: Submit feedback

POST /feedback

Request:

{
  "projectId": "cm8proj001abc",
  "message": "Looks clean. I'd love Notion sync and weekly report emails."
}

Success response (201):

{
  "id": "cm8fb001qwe",
  "projectId": "cm8proj001abc",
  "message": "Looks clean. I'd love Notion sync and weekly report emails.",
  "createdAt": "2026-03-12T10:20:00.000Z"
}

Example D: Create checkout session

POST /payments/create-checkout

Request:

{
  "projectId": "cm8proj001abc",
  "email": "buyer@example.com"
}

Success response (200):

{
  "checkoutUrl": "https://polar.sh/checkout/<redacted>",
  "provider": "polar"
}

Dev fallback response (200):

{
  "checkoutUrl": "/checkout/mock?projectId=cm8proj001abc",
  "provider": "mock"
}

Example E: Standard error shape

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request payload",
    "details": {
      "field": "email",
      "reason": "Must be a valid email address"
    }
  }
}

Quick curl smoke examples

Use these examples for local API checks.

Health check:

curl http://localhost:3001/health

Register user:

curl -X POST http://localhost:3001/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "name":"Jane Doe",
    "email":"jane@example.com",
    "password":"StrongPass123!"
  }'

Create project:

curl -X POST http://localhost:3001/projects \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "name":"FocusDock",
    "slug":"focusdock",
    "tagline":"Minimal focus dashboard for makers",
    "description":"Track deep work, launch goals, and weekly output.",
    "websiteUrl":"https://focusdock.dev",
    "category":"Productivity"
  }'

Submit feedback:

curl -X POST http://localhost:3001/feedback \
  -H "Content-Type: application/json" \
  -d '{
    "projectId":"cm8proj001abc",
    "message":"Looks clean. I'd love Notion sync and weekly report emails."
  }'

Start checkout:

curl -X POST http://localhost:3001/payments/create-checkout \
  -H "Content-Type: application/json" \
  -d '{
    "projectId":"cm8proj001abc",
    "email":"buyer@example.com"
  }'

13. Security and Secret Management

Required secret policy

  • Never commit .env.
  • Never publish real database URLs or provider tokens.
  • Never include secrets in README, screenshots, issues, or logs.
  • Rotate compromised credentials immediately.

Redacted environment template

DATABASE_URL="postgresql://<user>:<password>@<host>:5432/<database>"
BETTER_AUTH_SECRET="<strong-random-secret>"
BETTER_AUTH_URL="http://localhost:3000"
POLAR_ACCESS_TOKEN="<polar-access-token>"
POLAR_ORGANIZATION_ID="<polar-org-id>"
RESEND_API_KEY="<resend-api-key>"
UPLOADTHING_TOKEN="<uploadthing-token>"
NEXT_PUBLIC_API_URL="http://localhost:3001"

Public/private boundary

  • NEXT_PUBLIC_* variables can appear in browser bundles.
  • Non-public variables are server-only.
  • DB credentials and webhook secrets must stay private.

14. Environment Setup

Prerequisites

  • Bun >=1.2
  • PostgreSQL >=15

Install

bun install

Database setup

bun run db:generate
bun run db:migrate

Start apps

bun run dev

Optional single-app mode:

bun run --cwd apps/api dev
bun run --cwd apps/web dev

Default local URLs:

  • Web: http://localhost:3000
  • API: http://localhost:3001

15. Scripts and Developer Workflow

Root scripts:

  • bun run dev
  • bun run build
  • bun run typecheck
  • bun run lint
  • bun run db:generate
  • bun run db:migrate

Scoped scripts:

  • API: bun run --cwd apps/api dev | build | start | typecheck
  • Web: bun run --cwd apps/web dev | build | typecheck

Suggested daily workflow:

  1. Pull latest changes.
  2. Run bun install if lockfile changed.
  3. Run DB generate/migrate if schema changed.
  4. Start local apps.
  5. Typecheck before commit.

16. Production Deployment

Recommended production topology:

  • Web: Vercel (apps/web)
  • API: Vercel Project (apps/api)
  • DB: Managed PostgreSQL (Neon/Supabase/Vercel Postgres)

Step 1: Prepare production secrets

Create secure values for:

  • DATABASE_URL
  • BETTER_AUTH_SECRET
  • POLAR_ACCESS_TOKEN
  • POLAR_ORGANIZATION_ID
  • RESEND_API_KEY
  • UPLOADTHING_TOKEN

Do not reuse local placeholder values in production.

Step 2: Deploy API (Vercel)

Vercel API project settings:

  • Framework Preset: Other
  • Root Directory: apps/api
  • API entrypoint: api/[...route].ts
  • Rewrites: handled by apps/api/vercel.json

API environment variables:

NODE_ENV="production"
DATABASE_URL="postgresql://<user>:<password>@<host>:5432/<database>"
BETTER_AUTH_SECRET="<strong-random-secret>"
BETTER_AUTH_URL="https://<your-web-domain>"
CORS_ORIGIN="https://<your-web-domain>"
POLAR_ACCESS_TOKEN="<polar-access-token>"
POLAR_ORGANIZATION_ID="<polar-org-id>"
RESEND_API_KEY="<resend-api-key>"
UPLOADTHING_TOKEN="<uploadthing-token>"
NEXT_PUBLIC_API_URL="https://<your-api-domain>"

Health check URL:

  • https://<your-api-domain>/health

Step 3: Deploy Web (Vercel)

Vercel project settings:

  • Framework: Next.js
  • Root Directory: apps/web
  • Install Command: bun install --frozen-lockfile
  • Build Command: bun run build
  • Output: default Next.js output

Web environment variables:

NEXT_PUBLIC_API_URL="https://<your-api-domain>"

Step 4: Configure auth and CORS

  • Set API BETTER_AUTH_URL to the exact web production URL.
  • Set API CORS_ORIGIN to same web URL.
  • If you use multiple domains, separate by comma:
    • CORS_ORIGIN="https://app.example.com,https://www.example.com"

Step 5: Post-deploy smoke test

curl https://<your-api-domain>/health

Expected:

{"ok":true,"service":"devlaunch-api"}

Then verify in browser:

  • Web home opens correctly.
  • Register/login works.
  • Project creation works.
  • Feedback and checkout flows return expected responses.

17. Contributor Onboarding Checklist

Use this checklist when a new contributor joins the project.

Access and setup

  • Clone repository and install Bun.
  • Create local .env from .env.example.
  • Request required secrets from team vault (never from chat/email).
  • Verify DB access using redacted/local credentials only.

Local run verification

  • Run bun install.
  • Run bun run db:generate.
  • Run bun run db:migrate.
  • Start app with bun run dev or per-app dev commands.
  • Confirm web at http://localhost:3000.
  • Confirm API health at http://localhost:3001/health.

Code quality and contribution

  • Run API typecheck: bun run --cwd apps/api typecheck.
  • Run web typecheck: bun run --cwd apps/web typecheck.
  • Follow shared schema contracts from packages/validation.
  • Keep secrets out of commits, logs, screenshots, and PR text.

Pull request readiness

  • Add/adjust tests when behavior changes.
  • Include migration notes if schema changed.
  • Add screenshots for UI changes.
  • Document any new env variable in .env.example with placeholder value.

18. Budget and Cost Planning

Monthly infra budget (example: 1k-5k MAU)

Item Starter Growth Notes
PostgreSQL (managed) $25 $120 backups, storage, read scaling
App hosting (web + api) $20 $100 region and instance sizing
Media storage/CDN $10 $60 logos, screenshots, assets
Email provider (Resend) $10 $50 transactional volume
Observability/logging $0-$20 $60 logs, alerts, traces
Domain + SSL + edge extras $2 $10 DNS and edge services
Total $67-$87 $400 excludes payment processing fees

Payment budget notes

  • provider fees are transaction-based
  • keep mock checkout only in development
  • use production secrets in secure stores only

19. Observability and Reliability

Operational recommendations:

  • expose health route checks in uptime monitor
  • track API latency and error rates
  • track checkout conversion and fallback ratio
  • track waitlist conversion per project
  • alert on payment webhook failures

Reliability posture:

  • graceful fallbacks for non-critical external errors in dev
  • strict validation to avoid corrupted writes
  • route-level error messages for faster debugging

20. Troubleshooting Guide

409 Conflict during project creation

Cause:

  • slug already exists.

Behavior:

  • UI suggests alternative slug candidates.

API is unreachable

Checklist:

  • API is running on :3001
  • GET http://localhost:3001/health returns 200
  • NEXT_PUBLIC_API_URL matches runtime host
  • no host mismatch (localhost vs 127.0.0.1)

Polar checkout failed: 401

Cause:

  • invalid or placeholder credentials.

Behavior:

  • development fallback route is used safely.

21. Quality Gates

Before commit:

bun run --cwd apps/api typecheck
bun run --cwd apps/web typecheck

Optional smoke checks:

curl http://localhost:3001/health

22. Roadmap

  • richer dashboard widgets (funnel, retention)
  • feedback sorting/filtering and pagination
  • project update timeline widget
  • background job queue for fanout email/notifications
  • role-based admin moderation panel

23. Glossary

  • GA: General Availability release.
  • Demand signal: measurable interest, such as waitlist, vote, purchase intent.
  • Early access: paid or invite-based pre-release usage.
  • Fallback checkout: safe dev-mode route when payment setup is invalid.

License

Private workspace project.