A full-stack train schedule application built as a monorepo. The backend provides a REST API with JWT authentication and role-based access control; the frontend is a React Native mobile app (iOS & Android) built with Expo.
- NestJS — Node.js framework
- PostgreSQL + TypeORM — database and ORM
- JWT + Passport — authentication & authorization
- Swagger — auto-generated API documentation
- bcryptjs — password hashing
- React Native + Expo (SDK 54) — mobile app
- Expo Router — file-based navigation
- React Query — server state management
- Zustand — global UI state (filters, etc.)
- React Hook Form — form management & validation
- Unistyles — theming & styling (light / dark mode)
- Axios — HTTP client
train-schedule/
├── backend/ # NestJS REST API
│ └── src/
│ ├── auth/ # JWT auth, guards, strategies
│ ├── trains/ # Train CRUD module
│ ├── favorites/ # Favorites module
│ ├── users/ # User entity
│ └── seed.ts # Database seeder
└── frontend/ # Expo React Native app
└── src/
├── api/ # Axios API clients
├── app/ # Expo Router screens
│ ├── (auth)/ # Login, Register
│ └── (tabs)/ # Home, Favorites, Admin
├── components/ # Shared UI components
├── hooks/ # Custom React hooks
├── store/ # Zustand stores
└── types/ # TypeScript type definitions
- Node.js v20+
- Yarn v1 (classic)
- PostgreSQL 14+
- Xcode (for iOS simulator) or Android Studio (for Android emulator)
- Expo Go app on a physical device (optional)
cd backend
yarn installCopy the example file and fill in your values:
cp .env.example .env.env variables:
| Variable | Default | Description |
|---|---|---|
DB_HOST |
localhost |
PostgreSQL host |
DB_PORT |
5432 |
PostgreSQL port |
DB_USERNAME |
postgres |
PostgreSQL username |
DB_PASSWORD |
postgres |
PostgreSQL password |
DB_NAME |
train_schedule |
PostgreSQL database name |
PORT |
3000 |
HTTP port the API listens on |
JWT_SECRET |
secret |
Secret used to sign JWT tokens |
Important: Change
JWT_SECRETto a strong random value in any non-local environment.
psql -U postgres -c "CREATE DATABASE train_schedule;"Populates 5 sample trains and 2 test users:
yarn seedTest users created by the seeder:
| Password | Role | |
|---|---|---|
admin@example.com |
admin123 |
admin |
user@example.com |
user123 |
user |
yarn start:devThe API will be available at http://localhost:3000.
Swagger UI is available at http://localhost:3000/api.
cd frontend
yarn installCopy the example file and fill in your values:
cp .env.example .env.env variables:
| Variable | Default | Description |
|---|---|---|
EXPO_PUBLIC_API_URL |
http://localhost:3000 |
Base URL of the REST API |
- For a physical device, replace
localhostwith your machine's local IP (e.g.http://192.168.1.100:3000). - For an Android emulator, use
http://10.0.2.2:3000. - For an iOS simulator,
localhostworks as-is.
Before running on a simulator or device for the first time, generate the ios/ and android/ native folders:
npx expo prebuildRe-run this command whenever you add a new native dependency or change
app.jsonsettings that affect native code. Use--cleanto fully regenerate the folders from scratch.
# Expo development server
yarn start
# Run directly on iOS simulator
yarn ios
# Run directly on Android emulator
yarn android- Register and log in with email & password
- Browse and search the full train schedule
- Filter trains by status (On Time / Delayed / Cancelled)
- Save favourite trains and view them on a dedicated screen
- Toggle light / dark theme
- All user features
- Add, edit, and delete trains from the Admin dashboard
All endpoints are documented interactively via Swagger at http://localhost:3000/api.
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /auth/register |
Public | Register a new user, returns JWT |
| POST | /auth/login |
Public | Login, returns JWT |
| GET | /auth/profile |
JWT | Get current user profile |
| GET | /trains |
JWT | List trains (with filters) |
| POST | /trains |
JWT + Admin | Create a train |
| PATCH | /trains/:id |
JWT + Admin | Update a train |
| DELETE | /trains/:id |
JWT + Admin | Delete a train |
| GET | /favorites |
JWT | Get current user's favorites |
| POST | /favorites/:trainId |
JWT | Add train to favorites |
| DELETE | /favorites/:trainId |
JWT | Remove train from favorites |
| Command | Description |
|---|---|
yarn start:dev |
Start in watch mode (development) |
yarn start:prod |
Start the compiled production build |
yarn build |
Compile TypeScript to dist/ |
yarn seed |
Seed the database with sample data |
yarn test |
Run unit tests |
yarn test:e2e |
Run end-to-end tests |
yarn lint |
Lint & auto-fix source files |
| Command | Description |
|---|---|
yarn start |
Start the Expo development server |
yarn ios |
Run on iOS simulator |
yarn android |
Run on Android emulator |
yarn lint |
Lint & auto-fix source files |