Skip to content

redstone-tdps/rent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rent Reservation Backend (Go)

HTTP backend for a competition track rent reservation system with:

  • Passwordless login (OTP + magic link via email sender)
  • SMTP email delivery with embedded templates (no external template files needed at runtime)
  • Configurable allowed email domains
  • VIP users with earlier reservation window and per-item VIP hourly pricing (total fee = hourly price × duration_hours)
  • Reservation model: start_time (Unix timestamp seconds, must be full hour) + duration_hours (whole hours)
  • Team-based reservation: user selects team_id on first reservation
  • Non-VIP users: max 2 reservation hours per team per day (summed)
  • Configurable timezone and weekly availability window (e.g. Mon-Fri 09-21, Sat/Sun 10-20)
  • QR-payment flow with user-submitted identification code
  • awaiting_payment reservations auto-cancel after 5 minutes
  • Admin payment verification and admin-editable runtime config
  • Configurable DB backend (sqlite implemented, d1 stubbed)
  • All API time values use Unix timestamps (seconds)

Tech

  • Go 1.26+
  • modernc.org/sqlite (pure Go SQLite)
  • net/http standard library router

Frontend Integration

  • API reference for frontend developers: docs/FRONTEND_API.md

CORS Configuration

  • Configure CORS via environment variables:
    • CORS_ALLOWED_ORIGINS (comma-separated origins, e.g. http://localhost:3000)
    • CORS_ALLOWED_METHODS (comma-separated methods)
    • CORS_ALLOWED_HEADERS (comma-separated request headers)
    • CORS_ALLOW_CREDENTIALS (true/false)
    • CORS_MAX_AGE_SECONDS (preflight cache duration)
  • For local dev with Vite/React, set CORS_ALLOWED_ORIGINS to your frontend URL.

Magic Link URL Configuration

  • Magic-link emails can point to frontend routes instead of backend routes.
  • Configure with:
    • FRONTEND_BASE_URL (for example http://localhost:5173)
    • MAGIC_LINK_FRONTEND_PATH (for example /verify-link)
  • Backend verification endpoint remains GET /auth/verify-link and is typically called by frontend after reading the token from URL.

Run

  1. Copy .env.example values to your environment.
  • The server auto-loads .env and .env.local at startup.
  1. Configure SMTP (SMTP_HOST, SMTP_FROM_EMAIL, and optionally auth fields) to send real email.
  • If SMTP is not configured, the service falls back to log sender (credentials are logged for dev/testing).
  1. Start server:
go run ./cmd/server
  1. Health check:
curl http://localhost:8080/health

Auth flow

  1. Request login credential:
curl -X POST http://localhost:8080/auth/request \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","method":"otp"}'

or magic link:

curl -X POST http://localhost:8080/auth/request \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","method":"magic_link"}'
  1. Verify OTP:
curl -X POST http://localhost:8080/auth/verify-otp \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","code":"123456"}'

or verify magic link token:

curl "http://localhost:8080/auth/verify-link?token=<token>"
  1. Use session_token as bearer token.

  2. Optional: set contact email (OTP/magic-link delivery target):

curl -X PUT http://localhost:8080/me/contact-email \
  -H "Authorization: Bearer <session_token>" \
  -H "Content-Type: application/json" \
  -d '{"contact_email":"notify@example.org"}'

Notes:

  • If contact email is set, OTP/magic-link will be sent to contact email instead of account email.

Reservation + payment flow

Get teams for selection:

curl -X GET http://localhost:8080/teams \
  -H "Authorization: Bearer <session_token>"

Get rentable items:

curl -X GET http://localhost:8080/items \
  -H "Authorization: Bearer <session_token>"

Get occupied slots (active reservations):

curl -X GET http://localhost:8080/reservations/occupied \
  -H "Authorization: Bearer <session_token>"

Get configured weekly availability and timezone:

curl -X GET http://localhost:8080/reservations/availability \
  -H "Authorization: Bearer <session_token>"

Create reservation:

curl -X POST http://localhost:8080/reservations \
  -H "Authorization: Bearer <session_token>" \
  -H "Content-Type: application/json" \
  -d '{"item_id":1,"start_time":1774058400,"duration_hours":2,"team_id":1}'

Admin list items:

curl -X GET http://localhost:8080/admin/items \
  -H "Authorization: Bearer <admin_session_token>"

Admin create item:

curl -X POST http://localhost:8080/admin/items \
  -H "Authorization: Bearer <admin_session_token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Camera A","image_url":"https://cdn.example.com/camera-a.jpg","normal_price_cents":15000,"vip_price_cents":12000,"slot_capacity":2,"is_active":true}'

Admin update item:

curl -X PUT http://localhost:8080/admin/items/1 \
  -H "Authorization: Bearer <admin_session_token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Camera A+","image_url":"https://cdn.example.com/camera-a-plus.jpg","normal_price_cents":16000,"vip_price_cents":13000,"slot_capacity":2,"is_active":true}'

Admin delete item:

curl -X DELETE http://localhost:8080/admin/items/1 \
  -H "Authorization: Bearer <admin_session_token>"

Get payment info (QR + identification code):

curl -X GET http://localhost:8080/reservations/<reservation_id>/payment-info \
  -H "Authorization: Bearer <session_token>"

Mark payment done (moves to pending_verification):

curl -X POST http://localhost:8080/reservations/<reservation_id>/payment-done \
  -H "Authorization: Bearer <session_token>" \
  -H "Content-Type: application/json" \
  -d '{"identification_code":"<generated_code>"}'

Admin APIs

List config:

curl -X GET http://localhost:8080/admin/config \
  -H "Authorization: Bearer <admin_session_token>"

Update config key:

curl -X PUT http://localhost:8080/admin/config/reservation.vip_lead_hours \
  -H "Authorization: Bearer <admin_session_token>" \
  -H "Content-Type: application/json" \
  -d '{"value":"72"}'

Set user VIP:

curl -X PUT http://localhost:8080/admin/users/2/vip \
  -H "Authorization: Bearer <admin_session_token>" \
  -H "Content-Type: application/json" \
  -d '{"vip":true}'

Verify payment:

curl -X POST http://localhost:8080/admin/reservations/res_xxx/verify \
  -H "Authorization: Bearer <admin_session_token>" \
  -H "Content-Type: application/json" \
  -d '{"approved":true,"note":"Matched incoming transfer"}'

Teams

  • Table teams is created by migration.
  • Teams are currently edited manually by admin (DB-level operation, no edit API yet).
  • Frontend can fetch active teams via GET /teams.

Config keys in DB (app_configs)

  • auth.allowed_domains (comma-separated)
  • reservation.normal_lead_hours
  • reservation.vip_lead_hours
  • reservation.timezone
  • reservation.weekly_availability_json (JSON by weekday with start_hour and end_hour)
  • payment.qr_by_price_json (JSON map: price -> QR payload)
  • auth.otp_ttl_minutes
  • auth.magic_link_ttl_minutes
  • auth.session_ttl_hours

SMTP templates (embedded)

  • Templates are embedded at build time via Go embed in internal/email/templates/*.tmpl.
  • Current templates:
    • OTP subject/body
    • Magic-link subject/body
  • This means the built executable includes the templates and does not require template files deployed beside the binary.

DB backend mode

  • DB_BACKEND=sqlite: fully implemented.
  • DB_BACKEND=d1: interface-compatible stub currently returns not implemented for storage operations.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages