4.9 KiB
4.9 KiB
Server Endpoint Verification
Implementation Status: ✅ COMPLETE
All four required endpoints have been implemented in server/index.mjs:
1. GET /api/questions ✅
Requirements: 1.1, 2.4
Implementation:
- Accepts
productSlugquery parameter - Queries Appwrite for active product by slug
- Returns 404 if product not found
- Queries questions collection with:
Query.equal('productId', product.$id)Query.equal('isActive', true)Query.orderAsc('step')Query.orderAsc('order')
- Returns ordered list of active questions
Validation:
- ✅ Uses correct Appwrite Query API (not deprecated listRows)
- ✅ Filters by productId and isActive
- ✅ Orders by step and order
- ✅ Error handling for missing product
- ✅ Error handling for database errors
2. POST /api/submissions ✅
Requirements: 2.2, 2.3
Implementation:
- Accepts
productSlugandanswersin request body - Looks up product by slug
- Creates submission document with:
- productId
- status: 'draft'
- customerEmail (from answers.email)
- customerName (from answers.name)
- finalSummaryJson (stringified answers)
- priceCents (from product)
- currency (from product)
- Creates answers document with:
- submissionId
- answersJson (stringified answers)
- Returns submissionId
Validation:
- ✅ Uses createDocument (not deprecated createRow)
- ✅ Creates both submission and answers records
- ✅ Stores all required data
- ✅ Returns submissionId for checkout
- ✅ Error handling for missing product
- ✅ Error handling for database errors
3. POST /api/checkout ✅
Requirements: 3.1, 3.2
Implementation:
- Accepts
submissionIdin request body - Validates submissionId is provided (400 if missing)
- Fetches submission from Appwrite
- Creates Stripe Checkout Session with:
- Payment method: card
- Line item with price from submission
- Success/cancel URLs
- Metadata containing submissionId
- Returns checkout URL
Validation:
- ✅ Validates submissionId presence
- ✅ Fetches submission data
- ✅ Creates Stripe session with correct parameters
- ✅ Includes submissionId in metadata for webhook
- ✅ Returns URL for redirect
- ✅ Error handling for missing submission
- ✅ Error handling for Stripe errors
4. POST /stripe/webhook ✅
Requirements: 3.3, 3.4
Implementation:
- Uses
express.raw()middleware for signature verification - Extracts Stripe signature from headers
- Validates webhook signature using
stripe.webhooks.constructEvent() - Returns 400 if signature invalid
- Handles
checkout.session.completedevent - Extracts submissionId from session metadata
- Updates submission status to 'paid'
- Creates order document with session data
- Returns success response
Validation:
- ✅ Signature validation (returns 400 on invalid signature)
- ✅ Handles checkout.session.completed event
- ✅ Updates submission status to 'paid'
- ✅ Creates order record
- ✅ Uses updateDocument (not deprecated updateRow)
- ✅ Error handling with proper status codes
Environment Variables Validation ✅
The server validates all required environment variables on startup:
- APPWRITE_ENDPOINT
- APPWRITE_PROJECT_ID
- APPWRITE_API_KEY
- APPWRITE_DATABASE_ID
- STRIPE_SECRET_KEY
- STRIPE_WEBHOOK_SECRET
If any are missing, the server exits with an error message.
Middleware Configuration ✅
- Static file serving for public directory
- JSON parsing for /api routes
- Raw body parsing for /stripe/webhook (required for signature verification)
All Requirements Met ✅
- ✅ Requirement 1.1: Questions loaded from Appwrite
- ✅ Requirement 2.2: Submission created
- ✅ Requirement 2.3: Answers saved
- ✅ Requirement 3.1: Stripe Checkout Session created
- ✅ Requirement 3.2: Customer redirected to Stripe (via URL)
- ✅ Requirement 3.3: Submission status updated to 'paid'
- ✅ Requirement 3.4: Webhook signature validated
Testing Notes
To test these endpoints manually:
-
Setup Environment:
cd server cp ../.env.example .env # Edit .env with real credentials npm run bootstrap -
Start Server:
npm start -
Test GET /api/questions:
curl "http://localhost:3000/api/questions?productSlug=email-sorter" -
Test POST /api/submissions:
curl -X POST http://localhost:3000/api/submissions \ -H "Content-Type: application/json" \ -d '{"productSlug":"email-sorter","answers":{"email":"test@example.com","name":"Test User"}}' -
Test POST /api/checkout:
curl -X POST http://localhost:3000/api/checkout \ -H "Content-Type: application/json" \ -d '{"submissionId":"<submission-id-from-step-4>"}' -
Test Stripe Webhook:
- Use Stripe CLI:
stripe listen --forward-to localhost:3000/stripe/webhook - Trigger test event:
stripe trigger checkout.session.completed
- Use Stripe CLI: