https://github.com/saakeeb/hrinventory
https://github.com/saakeeb/hrinventory
Last synced: 15 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/saakeeb/hrinventory
- Owner: saakeeb
- License: apache-2.0
- Created: 2026-03-04T10:59:41.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-03-10T18:17:19.000Z (3 months ago)
- Last Synced: 2026-03-10T23:57:43.650Z (3 months ago)
- Language: TypeScript
- Size: 103 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# HR Inventory — Workforce System (Phase 1)
A full-stack monorepo scaffold for the **HR Inventory** workforce management system.
| Layer | Stack | Port |
|-----------|--------------------------------------------------------------|--------|
| Database | PostgreSQL 15 (via Docker) | `5432` |
| Backend | Express · TypeScript · `ts-node-dev` · JWT · WebSocket (`ws`) | `4000` |
| Frontend | Vite · React 18 · TypeScript · Tailwind CSS · React Query | `5173` |
---
## Table of Contents
- [Prerequisites](#prerequisites)
- [Project Structure](#project-structure)
- [Quick Start (Run Both Together)](#quick-start-run-both-together)
- [Step-by-Step Setup](#step-by-step-setup)
- [1. Clone & Install](#1-clone--install)
- [2. Configure Environment Variables](#2-configure-environment-variables)
- [3. Start the Database](#3-start-the-database)
- [4. Start the Backend](#4-start-the-backend)
- [5. Start the Frontend](#5-start-the-frontend)
- [Available Scripts](#available-scripts)
- [Environment Variables Reference](#environment-variables-reference)
- [Architecture Overview](#architecture-overview)
---
## Prerequisites
Make sure the following tools are installed on your machine before proceeding:
| Tool | Minimum Version | Check Command |
|---------------|-----------------|-----------------------|
| Node.js | 18+ | `node -v` |
| npm | 9+ | `npm -v` |
| Docker | 24+ | `docker -v` |
| Docker Compose| v2+ | `docker compose version` |
---
## Project Structure
```
hrinventory/
├── backend/ # Express + TypeScript API server
│ ├── src/
│ │ ├── config/ # App config (port, DB URL, JWT secret)
│ │ ├── database/ # DB connection utilities
│ │ ├── middleware/ # Request logger, error handler
│ │ ├── utils/ # Shared helpers
│ │ └── server.ts # Entry point
│ ├── modules/ # Feature modules (auth, users, attendance)
│ │ ├── auth/
│ │ ├── users/
│ │ └── attendance/
│ ├── database/
│ │ ├── migrations/ # SQL migration files
│ │ └── seed/ # Seed data scripts
│ ├── websocket/ # WebSocket server logic
│ ├── docker-compose.yml # PostgreSQL 15 service definition
│ ├── .env.example # Backend env template
│ └── package.json
│
├── frontend/ # Vite + React + Tailwind SPA
│ ├── src/
│ │ ├── App.tsx # Root component & routing shell
│ │ ├── router.tsx # React Router definitions
│ │ ├── AuthContext.tsx # Global auth state (JWT)
│ │ ├── axios.ts # Pre-configured Axios instance
│ │ ├── LoginPage.tsx
│ │ ├── ProfilePage.tsx
│ │ ├── ProfileForm.tsx
│ │ ├── Layout.tsx
│ │ ├── ProtectedRoute.tsx
│ │ ├── lib/ # Shared utilities / hooks
│ │ └── styles/ # Global CSS / Tailwind base
│ ├── .env.example # Frontend env template
│ ├── vite.config.ts
│ └── package.json
│
└── README.md
```
---
## Quick Start (Run Both Together)
> **Recommended approach**: open **three terminal tabs** — one for each service.
### Terminal 1 — Database (PostgreSQL via Docker)
```bash
cd backend
docker compose up -d
sudo systemctl stop postgresql (Optional: if postgresql already exist)
```
### Terminal 2 — Backend (Express API)
```bash
cd backend
npm install # first time only
cp .env.example .env # first time only — then edit .env
npm run dev
```
### Terminal 3 — Frontend (Vite Dev Server)
```bash
cd frontend
npm install # first time only
cp .env.example .env # first time only
npm run dev
```
Once all three services are running:
| Service | URL |
|----------|------------------------------|
| Frontend | http://localhost:5173 |
| Backend | http://localhost:4000 |
| API Health Check | http://localhost:4000/health |
---
## Step-by-Step Setup
### 1. Clone & Install
```bash
# Clone the repository
git clone hrinventory
cd hrinventory
# Install backend dependencies
cd backend && npm install && cd ..
# Install frontend dependencies
cd frontend && npm install && cd ..
```
---
### 2. Configure Environment Variables
#### Backend (`backend/.env`)
```bash
cd backend
cp .env.example .env
```
Open `backend/.env` and fill in the values:
```env
PORT=4000
NODE_ENV=development
# For local Docker Compose, use 'localhost' instead of 'db' for the host
DATABASE_URL=postgres://postgres:postgres@localhost:5432/hrinventory
JWT_SECRET=replace_this_with_a_strong_secret
# Optional OAuth providers (leave blank to skip)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
AUTH0_DOMAIN=
AUTH0_CLIENT_ID=
```
> **Important:** When running the backend **outside** Docker (i.e., directly with `npm run dev`), use `localhost` as the DB host instead of `db`.
#### Frontend (`frontend/.env`)
```bash
cd frontend
cp .env.example .env
```
`frontend/.env` only needs one variable — it should already be correct:
```env
VITE_API_URL=http://localhost:4000
```
---
### 3. Start the Database
The database runs as a Docker container. Start it from the `backend/` directory:
```bash
cd backend
docker compose up -d
```
Verify PostgreSQL is running:
```bash
docker compose ps
# You should see 'db' container with status: Up
```
To stop PostgreSQL:
```bash
docker compose down # stop containers (data preserved)
docker compose down -v # stop + destroy data volume
```
---
### 4. Start the Backend
```bash
cd backend
npm run dev
```
The backend starts with `ts-node-dev` (hot-reload on file changes). You should see:
```
Backend listening on http://localhost:4000
```
Verify it works:
```bash
curl http://localhost:4000/health
# → { "status": "ok" }
```
---
### 5. Start the Frontend
```bash
cd frontend
npm run dev
```
Vite will start the dev server and print:
```
VITE v5.x.x ready in Xms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
```
Open http://localhost:5173 in your browser.
---
## Available Scripts
### Backend (`cd backend`)
| Command | Description |
|------------------|---------------------------------------------|
| `npm run dev` | Start dev server with hot-reload (`ts-node-dev`) |
| `npm run build` | Compile TypeScript to `dist/` |
| `npm start` | Run compiled production build (`dist/server.js`) |
| `npm run lint` | Run ESLint on all `.ts` files |
| `npm run format` | Format codebase with Prettier |
### Frontend (`cd frontend`)
| Command | Description |
|-------------------|--------------------------------------------|
| `npm run dev` | Start Vite dev server (HMR enabled) |
| `npm run build` | Build production bundle to `dist/` |
| `npm run preview` | Serve the production build locally |
| `npm run lint` | Run ESLint on `.ts` / `.tsx` files |
| `npm run format` | Format codebase with Prettier |
### Docker (`cd backend`)
| Command | Description |
|-----------------------------|---------------------------------------------|
| `docker compose up -d` | Start PostgreSQL in background |
| `docker compose down` | Stop PostgreSQL (data preserved) |
| `docker compose down -v` | Stop PostgreSQL and destroy volume (wipe DB)|
| `docker compose logs -f db` | Follow PostgreSQL logs |
---
## Environment Variables Reference
### Backend
| Variable | Default | Required | Description |
|--------------------|------------------------------------------------------|----------|-------------------------------------|
| `PORT` | `4000` | No | Port the Express server listens on |
| `NODE_ENV` | `development` | No | Node environment |
| `DATABASE_URL` | — | **Yes** | PostgreSQL connection string |
| `JWT_SECRET` | `CHANGE_ME` | **Yes** | Secret for signing JWT tokens |
| `GOOGLE_CLIENT_ID` | — | No | Google OAuth client ID |
| `GOOGLE_CLIENT_SECRET` | — | No | Google OAuth client secret |
| `AUTH0_DOMAIN` | — | No | Auth0 domain |
| `AUTH0_CLIENT_ID` | — | No | Auth0 client ID |
### Frontend
| Variable | Default | Required | Description |
|----------------|----------------------------|----------|--------------------------------|
| `VITE_API_URL` | `http://localhost:4000` | **Yes** | Base URL of the backend API |
> All frontend env vars must be prefixed with `VITE_` to be accessible in the browser.
---
## Architecture Overview
```
Browser
│
▼
Vite Dev Server (localhost:5173)
│ HTTP/REST via Axios
│ (VITE_API_URL → localhost:4000)
▼
Express API (localhost:4000)
│ ├─ GET /health
│ ├─ /auth routes (JWT, Google OAuth, Auth0)
│ ├─ /users routes
│ ├─ /attendance routes
│ └─ WebSocket upgrade (ws)
│
▼
PostgreSQL 15 (localhost:5432)
└─ Docker volume: db_data
```
### Key Backend Files
| File/Dir | Role |
|----------------------------------|------------------------------------------------|
| `src/server.ts` | App bootstrap — Express setup, middleware, HTTP server |
| `src/config/index.ts` | Reads `.env` and exports typed config object |
| `src/middleware/request.logger` | Logs every incoming HTTP request |
| `src/middleware/error.middleware`| Centralized error handling |
| `modules/auth/` | Auth routes, JWT helpers, OAuth strategies |
| `modules/users/` | User CRUD |
| `modules/attendance/` | Attendance records |
| `websocket/` | WebSocket server for real-time features |
| `database/migrations/` | Raw SQL migration scripts |
| `database/seed/` | Seed data for development |
### Key Frontend Files
| File | Role |
|------------------------|---------------------------------------------------------|
| `src/main.tsx` | React entry point — mounts `` to the DOM |
| `src/App.tsx` | Root component with `QueryClientProvider` |
| `src/router.tsx` | All route definitions (React Router) |
| `src/AuthContext.tsx` | Global auth state (token storage, user info) |
| `src/axios.ts` | Axios instance pre-configured with `VITE_API_URL` |
| `src/ProtectedRoute.tsx` | HOC that redirects unauthenticated users to login |
| `src/LoginPage.tsx` | Login form UI |
| `src/ProfilePage.tsx` | User profile view |
---
## Troubleshooting
| Problem | Solution |
|---------|----------|
| `ECONNREFUSED` on backend startup | Database isn't running — run `docker compose up -d` first |
| `DATABASE_URL` host `db` not resolving | Change `db` → `localhost` in `backend/.env` when running outside Docker |
| Frontend shows blank page | Check `VITE_API_URL` in `frontend/.env` points to `http://localhost:4000` |
| Port `4000` already in use | Kill the conflicting process: `lsof -ti:4000 \| xargs kill` |
| Port `5173` already in use | Kill the conflicting process: `lsof -ti:5173 \| xargs kill` |
| `JWT_SECRET` default warning | Set a strong secret in `backend/.env` — never commit real secrets |