End-to-end documentation for the booking platform.
![]() |
![]() |
![]() |
![]() |
![]() |
This repository is split into two apps:
booking-backend- Go API, database, auth, booking, email verification, and admin check-in.booking-frontend/ganeshbooking- Next.js app for users and admins.
- User signup and signin.
- Email verification flow.
- Ticket booking with QR generation.
- Admin dashboard for verification and check-in.
- QR scanner for gate entry.
- Optional Cloudflare Turnstile CAPTCHA for auth endpoints.
- SMTP mail sending for verification and booking emails.
- Go 1.22 or newer.
- Node.js 20 or newer.
- PostgreSQL.
- SMTP credentials for Brevo or Gmail.
- Cloudflare Turnstile site key and secret key if CAPTCHA is enabled.
booking-backend/
cmd/main.go
models/
router/
scripts/
booking-frontend/ganeshbooking/
src/app/
src/components/
- Configure the backend environment variables.
- Start the Go API on port
8080. - Configure the frontend environment variables.
- Start the Next.js app on port
3000. - Open the frontend and use the booking or admin flows.
Use the following template:
PORT=8080
DB_URL=postgres://postgres:postgres@localhost:5432/kannada_booking?sslmode=disable
# or use DATABASE_URL instead of DB_URL
# DATABASE_URL=postgres://postgres:postgres@localhost:5432/kannada_booking?sslmode=disable
FRONTEND_URL=http://localhost:3000
JWT_SECRET=replace_with_a_long_random_secret
SESSION_SECRET=replace_with_a_long_random_secret
Adminname=admin
Adminpass=adminpassword
# Mail settings
Email=verified-sender@example.com
Emailuser=your_smtp_username
Emailpass=your_smtp_password
# CAPTCHA settings
CAPTCHA_ENABLED=false
CAPTCHA_SECRET_KEY=your_turnstile_secret_keycd booking-backend
go mod download
go run ./cmdThe API runs on http://localhost:8080 by default.
Open:
GET http://localhost:8080/health
Expected response:
{"status":"ok"}Use the following template:
NEXT_PUBLIC_API_URL=http://localhost:8080
NEXT_PUBLIC_USER_API_URL=http://localhost:8080/user
NEXT_PUBLIC_ADMIN_API_URL=http://localhost:8080/admin
NEXT_PUBLIC_CAPTCHA_SITE_KEY=temporary_dev_captcha_site_key
NEXT_PUBLIC_CAPTCHA_ENABLED=falsecd booking-frontend/ganeshbooking
npm install
npm run devThe frontend runs on http://localhost:3000.
The backend already includes:
GET /user/verify?token=...to verify a user account.scripts.EmailVerifymail(to, token)to send the verification email.FRONTEND_URLto build the redirect target after verification.
- Generate a verification token in your onboarding flow.
- Send the token through
scripts.EmailVerifymail(to, token). - The email contains a link like:
http://localhost:3000/auth/verified?query=<token-o>
- That page can forward the token to the backend verification endpoint.
- The backend marks the user as verified and redirects back to the frontend.
The helper and endpoint are already present, but if you want automatic email verification during signup, make sure your signup flow actually sends the email after creating the token.
The auth routes support optional Cloudflare Turnstile verification.
Set:
CAPTCHA_ENABLED=false
NEXT_PUBLIC_CAPTCHA_ENABLED=falseSet:
CAPTCHA_ENABLED=true
CAPTCHA_SECRET_KEY=your_turnstile_secret_key
NEXT_PUBLIC_CAPTCHA_ENABLED=true
NEXT_PUBLIC_CAPTCHA_SITE_KEY=your_turnstile_site_key- When CAPTCHA is enabled,
/user/signinand/user/signuprequire a valid Turnstile token. - When CAPTCHA is disabled, those endpoints skip verification.
- User signs in or signs up on the frontend.
- User opens the booking page.
- The booking form sends data to
POST /user/book. - The backend stores the booking and generates a QR ticket.
- The booking page displays the QR for the UTR value.
- Admin signs in with
AdminnameandAdminpass. - The admin dashboard is protected by the admin token.
- The dashboard shows bookings, verification status, and attendance.
- The scanner page at
/scanneris used for gate check-in. - If a booking is already marked present, the backend returns
Already enteredand does not update it again.
GET /user/POST /user/signinPOST /user/signupGET /user/verify?token=...GET /user/verifytokenGET /user/mybookingPOST /user/book
GET /admin/POST /admin/adminauthPOST /admin/verifyadmintokenPOST /admin/verifybookPOST /admin/enterPUT /admin/statuscount/:utr
GET /health
| Variable | Purpose | Required |
|---|---|---|
PORT |
Backend listen port | No |
DB_URL |
PostgreSQL connection string | Yes, or DATABASE_URL |
DATABASE_URL |
Alternate PostgreSQL connection string | Yes, or DB_URL |
FRONTEND_URL |
Frontend base URL for redirects and email links | Recommended |
JWT_SECRET |
Admin token signing secret | Yes |
SESSION_SECRET |
Session or app secret used by your broader app setup | Recommended |
Adminname |
Admin username | Yes |
Adminpass |
Admin password | Yes |
Email |
Verified sender address | Yes for email sending |
Emailuser |
SMTP login | Yes for email sending |
Emailpass |
SMTP password | Yes for email sending |
CAPTCHA_ENABLED |
Turns CAPTCHA verification on or off | No |
CAPTCHA_SECRET_KEY |
Cloudflare Turnstile secret key | Yes if CAPTCHA is enabled |
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_API_URL |
Base backend URL |
NEXT_PUBLIC_USER_API_URL |
User API base URL |
NEXT_PUBLIC_ADMIN_API_URL |
Admin API base URL |
NEXT_PUBLIC_CAPTCHA_SITE_KEY |
Turnstile site key |
NEXT_PUBLIC_CAPTCHA_ENABLED |
Enables CAPTCHA UI on the frontend |
- Add your production frontend URL to the backend CORS allowlist in
cmd/main.go. - Set
FRONTEND_URLto the deployed frontend domain. - Use a strong
JWT_SECRETandSESSION_SECRET. - Enable CAPTCHA in production if you want extra auth protection.
- Use a real SMTP provider and verified sender domain for email delivery.
- Check that
DB_URLorDATABASE_URLis set. - Check that PostgreSQL is running.
- Check the
.envfile is inbooking-backend/.
- Make sure
CAPTCHA_ENABLED=trueonly when both frontend and backend keys are set. - Keep CAPTCHA disabled for local development unless you have valid keys.
- Verify
FRONTEND_URLpoints to the correct frontend domain. - Check the SMTP credentials in
EmailuserandEmailpass. - Confirm the sender email in
Emailis allowed by your SMTP provider.
- Allow browser camera permission.
- Use HTTPS in production.
- Try the explicit
Allow camera accessbutton on the scanner page.
- User-side QR scanning is intentionally disabled.
- QR scanning is admin-only.
- The admin entry endpoint is idempotent, so scanning the same QR again returns
Already entered.




