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:
@@ -0,0 +1,39 @@
|
||||
// Package repository holds every SQL statement in the service.
|
||||
//
|
||||
// Tenant isolation convention: any query touching a tenant-owned table
|
||||
// (users, flights, bookings, passengers) takes tenantID as its FIRST argument
|
||||
// and filters on it in the WHERE clause. Callers pass the id from the
|
||||
// authenticated identity, never from client input.
|
||||
package repository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
// ErrNotFound is returned when a lookup matches no row within the tenant.
|
||||
// Handlers map it to 404, which also means a caller probing for another
|
||||
// tenant's record sees a plain "not found" rather than a permission error.
|
||||
var ErrNotFound = errors.New("not found")
|
||||
|
||||
// ErrNoSeats is returned when a booking asks for more seats than remain.
|
||||
var ErrNoSeats = errors.New("not enough seats available")
|
||||
|
||||
// Repository is the data access layer over a pgx pool.
|
||||
type Repository struct {
|
||||
pool *pgxpool.Pool
|
||||
}
|
||||
|
||||
// New builds a Repository around an open pool.
|
||||
func New(pool *pgxpool.Pool) *Repository {
|
||||
return &Repository{pool: pool}
|
||||
}
|
||||
|
||||
// isUniqueViolation reports whether err is PostgreSQL's 23505, which lets
|
||||
// callers retry a generated value instead of failing the request.
|
||||
func isUniqueViolation(err error) bool {
|
||||
var pgErr *pgconn.PgError
|
||||
return errors.As(err, &pgErr) && pgErr.Code == "23505"
|
||||
}
|
||||
Reference in New Issue
Block a user