Project Structure
Top-level layout
Section titled “Top-level layout”shanvitravels/├── backend/ # Express API├── frontend/ # React + Vite app├── docs/ # This documentation (Astro Starlight)├── deploy.sh # Deployment helper script└── Aggrement.md # Business agreement docsBackend
Section titled “Backend”backend/├── index.js # App factory — middleware, routes, DB init├── server.js # Entry point for cPanel (binds the port)├── worker.js # Entry point for Cloudflare Workers (serverless-http)├── wrangler.toml # Cloudflare Workers config├── config/│ ├── db.js # ⭐ Dual-DB abstraction (MySQL ↔ D1)│ └── multer.js # File upload config (memory storage)├── middleware/│ ├── auth.js # JWT verification + role guards│ ├── errorHandler.js # Global error handler│ └── validate.js # Request validation helpers├── routes/│ ├── auth.js # Register, login, refresh, KYC│ ├── admin.js # User/role/agent-type management (ADMIN only)│ ├── agents.js # Agent-facing endpoints│ ├── submissions.js # Thai visa submission lifecycle│ ├── tickets.js # FD ticket CRUD + booking│ ├── travel.js # Airport & date management│ ├── documents.js # Document handling│ └── settings.js # App settings (visa fee, service fee, etc.)├── utils/│ ├── storage.js # File save/delete/URL (R2 ↔ local disk)│ ├── notifier.js # Email notifications (nodemailer)│ └── obfuscate.js # RC4-based ticket ID obfuscation└── data/ └── airports.json # Global IATA airport reference data (~7000 entries)Frontend
Section titled “Frontend”frontend/src/├── App.tsx # Router + layout wrappers + route definitions├── main.tsx # React entry point├── config/│ └── api.ts # API base URL (auto-switches localhost ↔ prod)├── contexts/│ └── AuthContext.tsx # Auth state (user, token, login, logout)├── pages/│ ├── Home.tsx # Public landing page│ ├── Login.tsx # Login + register│ ├── Dashboard.tsx # Admin/Agent dashboard shell│ ├── UserDashboard.tsx # Logged-in user view│ ├── ThaiSubmission.tsx # Public Thai visa submission form│ ├── SearchResults.tsx # Public flight search results│ ├── BookTicket.tsx # Authenticated booking flow│ ├── FonepayPayment.tsx # Payment page│ ├── VfsTrackingPublic.tsx # Public VFS status tracker│ └── ... # About, Destinations, Contact, etc.├── components/│ ├── Dashboard/ # All dashboard feature tabs│ │ ├── Overview/ # Stats + recent submissions table│ │ ├── Tickets/ # FD ticket management│ │ ├── VFS/ # VFS task tracking│ │ ├── Travel/ # Airport + date management│ │ ├── Users/ # User list + KYC review│ │ ├── Settings/ # App settings│ │ ├── Profile/ # User profile│ │ ├── Onboarding/ # KYC onboarding flow│ │ ├── Layout/ # Sidebar + Header│ │ └── Common/ # Shared modals + UI primitives│ └── ui/ # shadcn/ui generated components (don't hand-edit)├── types/│ ├── dashboard.ts # Shared TypeScript types for dashboard│ └── ticket.ts # Ticket-specific types└── utils/ └── exportUtils.ts # CSV/Excel export helpersKey conventions
Section titled “Key conventions”- Backend routes always start with
/api/(e.g.,/api/auth/login) - Protected routes use
authenticateTokenmiddleware + optional role guards (requireAdmin,requireAgent) - DB calls always go through the
dbwrapper inconfig/db.js— never importmysql2or D1 directly in routes - File operations always go through
utils/storage.js— never usefsdirectly in routes - Frontend API calls always use the
API_BASE_URLfromconfig/api.ts— never hardcode a URL