Initial commit: TravelHub multi-tenant flight booking platform

Angular + Go + PostgreSQL sample with strict per-tenant isolation.

- Backend: Go API (basic auth, tenant-scoped repository layer, pgx pool)
- Frontend: Angular 22 SPA (search, checkout, bookings, dashboard)
- Database: schema, seed data and demo bookings migrations
- Tests: 311 across Go (integration), Angular (unit) and Playwright (e2e),
  plus a generated evidence report with PDF export
- Security: whitebox VAPT report under security/

Secrets (.env, tokens, DB credentials) are git-ignored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
nilesh.p
2026-09-13 11:38:01 +05:30
co-authored by Claude Opus 4.8
commit 4d3eb18a6c
129 changed files with 25424 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
// Package httpapi assembles the HTTP handler tree.
//
// It lives outside package main so tests can drive the exact same routing,
// middleware order and auth rules the server runs in production, rather than a
// hand-rolled approximation of them.
package httpapi
import (
"log/slog"
"net/http"
"github.com/travelswitch/travelhub/backend/internal/handlers"
"github.com/travelswitch/travelhub/backend/internal/middleware"
"github.com/travelswitch/travelhub/backend/internal/repository"
)
// New builds the full handler.
//
// Everything under /api/ requires Basic auth plus a tenant, except the two
// endpoints registered explicitly on the root mux: health, and the tenant list
// the sign-in screen needs before any credentials exist. More specific
// patterns win in Go's mux, so those two bypass the authenticated subtree.
func New(
h *handlers.Handler,
repo *repository.Repository,
logger *slog.Logger,
corsOrigins []string,
) http.Handler {
protected := http.NewServeMux()
protected.HandleFunc("GET /api/session", h.Session)
protected.HandleFunc("GET /api/flights", h.SearchFlights)
protected.HandleFunc("GET /api/flights/{id}", h.GetFlight)
protected.HandleFunc("GET /api/airports", h.ListAirports)
protected.HandleFunc("GET /api/airlines", h.ListAirlines)
protected.HandleFunc("GET /api/bookings", h.ListBookings)
protected.HandleFunc("POST /api/bookings", h.CreateBooking)
protected.HandleFunc("GET /api/bookings/{id}", h.GetBooking)
protected.HandleFunc("POST /api/bookings/{id}/cancel", h.CancelBooking)
protected.HandleFunc("GET /api/dashboard", h.Dashboard)
root := http.NewServeMux()
root.HandleFunc("GET /api/health", h.Health)
root.HandleFunc("GET /api/tenants", h.ListTenants)
root.Handle("/api/", middleware.BasicAuth(repo, logger)(protected))
return middleware.Chain(root,
middleware.Recoverer(logger),
middleware.Logger(logger),
middleware.CORS(corsOrigins),
)
}