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
+43
View File
@@ -0,0 +1,43 @@
import { Locator, Page } from '@playwright/test';
/** The signed-in chrome: sidebar navigation and the account bar. */
export class ShellPage {
readonly agencyName: Locator;
readonly agencySlug: Locator;
readonly accountName: Locator;
readonly accountMeta: Locator;
readonly signOut: Locator;
constructor(private readonly page: Page) {
this.agencyName = page.locator('.tenant-name');
this.agencySlug = page.locator('.tenant-slug');
this.accountName = page.locator('.account-name');
this.accountMeta = page.locator('.account-meta');
this.signOut = page.getByRole('button', { name: 'Sign out' });
}
/**
* Navigates by sidebar link. The href selector is deliberate: several screens
* also carry a "Search flights" call-to-action button, and matching by role
* and name alone would be ambiguous.
*/
async goToDashboard(): Promise<void> {
await this.page.locator('.nav-link[href="/dashboard"]').click();
await this.page.waitForURL('**/dashboard');
}
async goToSearch(): Promise<void> {
await this.page.locator('.nav-link[href="/search"]').click();
await this.page.waitForURL('**/search');
}
async goToBookings(): Promise<void> {
await this.page.locator('.nav-link[href="/bookings"]').click();
await this.page.waitForURL('**/bookings');
}
async signOutAndWait(): Promise<void> {
await this.signOut.click();
await this.page.waitForURL('**/login');
}
}