Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 21 additions & 25 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
# Required
# --- Required ---
DATABASE_URL="postgresql://user:password@localhost:5432/amph_v2?schema=public"
JWT_SECRET="generate-with-openssl-rand-base64-32"

# Required for payments (PayMongo)
# Test keys start with sk_test_ / pk_test_; live keys start with sk_live_ / pk_live_
PAYMONGO_SECRET_KEY="sk_test_..."
PAYMONGO_PUBLIC_KEY="pk_test_..."
PAYMONGO_WEBHOOK_SECRET="whsec_..."
# Required for `pnpm prisma db seed` (creates the admin account)
ADMIN_EMAIL="you@example.com"
ADMIN_PASSWORD="ChangeMe123!"

# Required for email
RESEND_API_KEY="re_..."
RESEND_FROM_EMAIL="noreply@projectamazonph.com"
# Strongly recommended in production — used to build absolute URLs
# (account-claim links shown in /admin/enroll, certificate verification).
NEXT_PUBLIC_APP_URL="http://localhost:3000"

# Required for file storage
# --- Optional ---
# Required for file storage (used by the db-backup cron script only —
# no app code touches Vercel Blob in this stripped build)
BLOB_READ_WRITE_TOKEN="vercel_blob_..."

# Required for cron jobs (Vercel Cron sends this as `Authorization: Bearer <value>`)
# Used by /api/cron/expire-checkouts to authenticate scheduled invocations.
CRON_SECRET="generate-with-openssl-rand-base64-32"

# Required for error tracking
SENTRY_DSN="https://...@sentry.io/..."
NEXT_PUBLIC_SENTRY_DSN="https://...@sentry.io/..."

# Sprint 11 / STORY-048 — Sentry source-map upload (set in CI + deploy only)
SENTRY_AUTH_TOKEN="sntrys_..."
# Error tracking (Sentry no-ops when unset)
SENTRY_DSN=""
NEXT_PUBLIC_SENTRY_DSN=""
# Sentry source-map upload (CI/deploy only)
SENTRY_AUTH_TOKEN=""
SENTRY_ORG="projectamazonph"
SENTRY_PROJECT="amph-v2"
SENTRY_HOST="https://sentry.io" # self-hosted? override here

# Sprint 11 / STORY-052 — Sentry → Slack error alerting
# Sentry → Slack error alerting
# Required: API token with project:read scope; Slack Incoming Webhook URL
SENTRY_API_TOKEN="sntrys_..."
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/T.../B.../..."
Expand All @@ -41,7 +35,9 @@ WINDOW_MINUTES="60" # how many minutes back to aggregate
# to "true" to promote it to an enforcing Content-Security-Policy header.
CSP_ENFORCE="false"

# Optional
NEXT_PUBLIC_APP_URL="http://localhost:3000"
NODE_ENV="development"
LOG_LEVEL="debug"
LOG_LEVEL="debug"

# NOTE (stripped launch build): PayMongo and Resend were removed — payments
# are collected manually (GCash/bank transfer) and enrollments granted via
# /admin/enroll. See docs/LAUNCH-DEPLOY.md.
71 changes: 71 additions & 0 deletions docs/LAUNCH-DEPLOY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Launch deploy — stripped build (manual enrollments)

This branch is the **minimum-friction launch build**: PayMongo (payments) and
Resend (email) are stripped out entirely. You collect payments yourself
(GCash / bank transfer / Messenger) and grant course access from the admin
panel. Everything else — courses, lessons, the five practice tools,
gamification, certificates, live classes, admin — is intact.
Comment on lines +5 to +7

## What was removed

- **PayMongo**: checkout flow (`/pricing` buy buttons, `/checkout/complete`),
webhook route, refunds (student request flow + admin review pages),
receipts/invoice PDFs, the `paymongo` npm package.
- **Resend**: all email sending. `src/lib/email.ts` is now a no-op stub that
logs instead of sending; the `resend` npm package and webhook route are gone.
- Dashboard "Payments" page and nav entry.

The Prisma schema was **not** changed — `Payment`, `CheckoutSession`,
`RefundRequest` tables still exist (empty), so no migration surgery is needed
and the payment stack can be restored later from the main repo's history.

## What was added

- **`/admin/enroll`** — enter a student email + pricing tier; the student is
enrolled in every course on that tier.
- Existing account → access appears on their dashboard immediately.
- New email → a placeholder account is created and you get a **one-time
claim link** (shown once, expires in 7 days). Send it to the student
yourself (Messenger/email); they use it to set their password.
- Admin dashboard now shows recent enrollments instead of payments, with an
"Enroll Student" quick action. Each user's admin detail page links to a
pre-filled enroll form.
- `/pricing` keeps the tier cards but the CTA is now "create an account +
message us to pay" instead of a checkout button.

## Deploy steps (Vercel + hosted Postgres)

1. **Database**: create a Postgres instance (Neon, Supabase, or Vercel
Postgres). Copy the connection string.
2. **Env vars** (Vercel → Project → Settings → Environment Variables):
- `DATABASE_URL` — from step 1
- `JWT_SECRET` — `openssl rand -base64 32`
- `NEXT_PUBLIC_APP_URL` — your production URL (needed for correct claim
links from /admin/enroll)
- Optional: `SENTRY_DSN` / `NEXT_PUBLIC_SENTRY_DSN`
3. **Migrate + import + seed** (locally, pointing at the production DB) —
order matters: the curriculum import must run before the seed's
course-dependent steps (live classes) can complete:
```bash
DATABASE_URL="..." ADMIN_EMAIL="you@..." ADMIN_PASSWORD="..." ./scripts/setup-db.sh
```
or step by step:
```bash
DATABASE_URL="..." pnpm prisma:deploy # schema
DATABASE_URL="..." pnpm tsx scripts/import-amph-content.ts # courses/modules/lessons/quizzes
DATABASE_URL="..." ADMIN_EMAIL="you@..." ADMIN_PASSWORD="..." pnpm prisma db seed # admin, tiers, badges, live classes
```
4. **Deploy**: import the repo in Vercel, pick this branch, deploy. No other
configuration is required.
5. **Smoke test**: sign in at `/auth/signin` with the admin account →
`/admin/enroll` → enroll a test email → open the claim link in an
incognito window → set a password → dashboard shows the courses.

## Day-to-day enrollment workflow

1. Student pays you via GCash/bank transfer and messages you their email.
2. Admin → **Enroll Student** → paste email, pick tier, submit.
3. New student? Copy the claim link and send it to them. Existing student?
Tell them to refresh their dashboard.
4. Refunds/disputes: handle in chat; suspend the user or leave the
enrollment — there is no in-app refund flow in this build.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,10 @@
"jose": "^6.2.3",
"marked": "^18.0.6",
"next": "^16.0.0",
"paymongo": "^1.3.2",
"pg": "^8.22.0",
"pino": "^10.3.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"resend": "^6.17.2",
"server-only": "^0.0.1",
"zod": "^4.4.3"
},
Expand Down
Loading