Skip to content

ashgoren/registration

Repository files navigation

Contra Registration

Simple event registration / admissions sales site

Tech Stack

Front-end: Vite + React + Material-UI
Hosting: Firebase Hosting
Database: Firebase Firestore
Serverless functions: Firebase Functions
Logging: Google Cloud Logging
Secrets management: Doppler & Google Cloud Secret Manager
Address autocomplete: Google Places API
Email: Amazon SES
Payment: Stripe or PayPal
IaC: Terraform


Table of Contents

  1. Prerequisites
  2. Generate Repository
  3. Bootstrap Projects
  4. Spreadsheet Setup
  5. Email Setup
  6. Deploy Infrastructure
  7. Grant Spreadsheet Access
  8. Payment Setup
  9. Site Configuration
  10. Development
  11. Deployment
  12. Post-Deployment

1. Prerequisites

Important

Run commands from a Unix-compatible CLI (e.g. Terminal on Mac or Git Bash on Windows).

Required Accounts

GitHub - Code Repository
Firebase - Hosting, Database, Backend
Google Cloud - Infrastructure (billing required)
Doppler - Secrets Management
Amazon SES - Email Delivery
Stripe or PayPal - Payment Processing

Required CLI Tools

Tool Authentication
Node.js -
Terraform -
GitHub CLI gh auth login
Firebase CLI firebase login
Doppler CLI doppler login
Google Cloud CLI gcloud auth login + gcloud auth application-default login
Stripe CLI (optional) stripe login

2. Generate Repository

  1. Generate repository from template
  2. Clone: git clone <REPO_URL>
  3. Navigate to project: cd <your-repo-name>

3. Bootstrap Projects

Note

What this does: Creates production & staging Google Cloud projects linked to your billing account, enables APIs, initializes Terraform, generates .firebaserc file, creates Doppler projects (see scripts/bootstrap/README.md for details)

Tip

PROJECT_ID format: Use lowercase letters, numbers, hyphens. Must be globally unique.
Example: my-dance-event-2025 → Complimentary site will be at https://my-dance-event-2025.web.app

Tip

If the Google Cloud projects already exist (i.e. redeploying an existing site), add skip-project-creation as a second argument.

npm run bootstrap <PROJECT_ID> [skip-project-creation]

4. Spreadsheet Setup

  1. Create spreadsheet from template
  2. Rename spreadsheet to desired name
  3. Update columns as desired
  4. Add URL to terraform/shared.auto.tfvars:
   spreadsheet_url = "YOUR_SPREADSHEET_URL"

5. Email Setup

Step 5a: Verify Domain

Important

You must verify the domain of your email_from_address in Amazon SES.

  1. Go to SES Identities
  2. Create Identity → Domain → Enter your domain (e.g. yourdomain.com)
  3. Check "Use a custom MAIL FROM domain" → Enter amazonses (this is not visible to recipients but improves deliverability)
  4. Advanced DKIM settings → "Easy DKIM" with a 2048-bit key
  5. Uncheck "Publish DNS records to Route53" in both spots on the page (unless using Route53 for DNS)
  6. Leave "DKIM Signatures" checked
  7. Click "Create Identity"
  8. Publish the provided DNS records (likely 6 records total, from 3 sections - DKIM, MAIL FROM, and DMARC)
  9. Wait and check back until all 3 sections show as verified

Step 5b: Create SMTP Credentials

  1. Go to Amazon SES SMTP
  2. Add credentials to terraform/shared.auto.tfvars:
   email_amazonses_smtp_user = "YOUR_SMTP_USER"
   email_amazonses_smtp_password = "YOUR_SMTP_PASSWORD"

Step 5c: Configure Other Email Settings

Fill in email settings in terraform/shared.auto.tfvars:

email_from_name = "Example Dance Weekend"
email_from_address = "someone@yourdomain.com"
email_admin_notifications = "admin@yourdomain.com"

# Optional: if different from email_from_address
email_reply_to = ""

# Optional: domains to skip for email confirmation & data validation
email_test_domains = "example.com,test.com,testing.com"

# Required only if domain was verified in an aws region other than us-east-2
email_amazonses_email_endpoint = ""

6. Deploy Infrastructure

Important

Ensure all required values are set in terraform/shared.auto.tfvars

Tip

Leave frontend_domain blank if you don't plan to have a custom domain for your website

npm run terraform-stg # deploys staging infrastructure
npm run terraform-prd # deploys production infrastructure

7. Grant Spreadsheet Access

Share your spreadsheet (edit permissions) with:

  • sheets@<PROJECT_ID>.iam.gserviceaccount.com
  • sheets@<PROJECT_ID>-stg.iam.gserviceaccount.com

8. Payment Setup

Note

Staging & Dev mode webhooks are optional (only needed for testing webhook functionality)

Option A: Stripe

Step 8a: Configure Stripe Payment Methods

  • Disable all payment methods except: Cards, Apple Pay, Google Pay
  • Apple Pay requires Stripe domain verification

Step 8b: Create Stripe sandbox accounts

  • Create 2 sandbox accounts - dev & stg

Step 8c: Create Stripe Webhook Endpoints

Create webhooks for payment_intent.succeeded event only:

Environment Endpoint URL
Production https://<REGION>-<PROJECT_ID>.cloudfunctions.net/stripeWebhook
Stg (optional) https://<REGION>-<PROJECT_ID>-stg.cloudfunctions.net/stripeWebhook
Dev (optional) https://<localtunnel-url>/<PROJECT_ID>-stg/<REGION>/stripeWebhook (requires using localtunnel, e.g. lt -p 5001 -s <PROJECT_ID>)

Step 8d: Set Stripe Secrets

Run for each environment to set webhook secret and publishable + secret keys:

npm run set-payment-secrets <PROJECT_ID> stripe dev
npm run set-payment-secrets <PROJECT_ID> stripe stg
npm run set-payment-secrets <PROJECT_ID> stripe prd
Option B: PayPal

Step 8a: Configure PayPal Payment Methods

  • Don't want Venmo? Comment out the venmo line in configPaypal.jsx

Step 8b: Create PayPal sandbox accounts & REST API Apps

[!IMPORTANT] You must enable the "Transaction search" feature on each REST API app to facilitate the the payment matching script.

  • Create 2 sandbox business accounts - dev & stg
  • Create a REST API apps within each sandbox account
  • Enable "Transaction search" feature on each app
  • Also create production REST API app if it doesn't yet exist

Step 8c: Create PayPal Webhook Endpoints

Create webhooks for payment capture completed event only:

Environment Endpoint URL
Production https://<REGION>-<PROJECT_ID>.cloudfunctions.net/paypalWebhook
Stg (optional) https://<REGION>-<PROJECT_ID>-stg.cloudfunctions.net/paypalWebhook
Dev (optional) https://<localtunnel-url>/<PROJECT_ID>-stg/<REGION>/paypalWebhook (requires using localtunnel, e.g. lt -p 5001 -s <PROJECT_ID>)

Step 8d: Set PayPal Secrets

Run for each environment to set webhook id and client id + client secret:

npm run set-payment-secrets <PROJECT_ID> paypal dev
npm run set-payment-secrets <PROJECT_ID> paypal stg
npm run set-payment-secrets <PROJECT_ID> paypal prd

9. Site Configuration

File About
functions/config/userConfig.js Backend config
src/config/ Frontend config - event, fields, order-summary, theme
src/templates/ Email receipt templates
src/components/Static/ Static pages (e.g. Home, About, Contact)
src/components/IntroHeader.jsx Registration form header
src/components/layouts/Navbar.jsx Navbar
index.html Site title, metadata description, og:image
public/logo.png Optional Navbar logo (≤80px height recommended)
public/ favicon files - use a generator, e.g. favicon-generator

10. Development

First Time Setup

npm install && npm install --prefix functions
git checkout -b staging

Daily Development

npm run emulator # Start Firebase emulators
npm run dev # Start frontend dev server

Helper scripts

See scripts/README.md for database and payment processor query tools.


11. Deployment

Note

GitHub Actions automatically handles:

  • Frontend deployment to Firebase Hosting
  • Backend deployment to Firebase Functions
  • Doppler secrets sync to Google Cloud Secret Manager

Important

You must redeploy after any changes to Doppler secrets!

Deploy to Staging

git push origin staging

Deploy to Production

# 1. Ensure staging branch is up to date on GitHub
git push origin staging

# 2. Create and merge the pull request from staging to main
gh pr create --base main --head staging --fill --title "<SQUASH_COMMIT_MESSAGE>"
gh pr merge staging --auto --squash --delete-branch

# 3. Recreate staging branch from main
git checkout -b staging

12. Post-deployment

Configure Custom Domain (optional)

  • Add custom domain in Firebase Console

Go Live Checklist

  • Confirm Stripe/PayPal production secrets are set in Doppler
    • prd_frontend: VITE_STRIPE_PUBLISHABLE_KEY or VITE_PAYPAL_CLIENT_ID
    • prd_backend: STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET or PAYPAL_CLIENT_ID + PAYPAL_CLIENT_SECRET + PAYPAL_WEBHOOK_ID
  • Update registration link on homepage (if applicable)
  • Update robots.txt to allow indexing (if sharing direct link)
  • Set prd.live to true in configEvent.jsx
  • Clear spreadsheet data
  • Clear staging Firestore data
  • Clear production Firestore data if needed
  • Redeploy after any updates to Doppler secrets or source code

Waitlist Mode

  • Toggle registration.waitlist_mode flag in both src/config/configEvent and functions/config/userConfig.

Hibernation (optional)

For inactive projects:

npm run disable-apis   # npm run enable-apis to wake up

Shutdown (optional)

Important

This will run terraform destroy, delete firebase functions, and delete firestore database for both staging and production projects.
It will not delete the Google Cloud or Doppler projects themselves.

Sharing admin access

  • Necessary access for another developer to take over in a 'hit-by-the-bus' scenario: GitHub, Doppler, GCP, domain registration, spreadsheet
npm run shutdown <PROJECT_ID>

About

Template for Contra Registration apps

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors