A minimal inventory management system tracking stores and the products they carry.
docker compose up --buildThen open http://localhost (port 80).
Note: The server uses better-sqlite3. On Windows you may need Visual Studio Build Tools. Use Docker otherwise.
# Terminal 1 - Backend
cd server && npm install && npm run dev
# Terminal 2 - Frontend
cd web && npm install && npm run dev- API: http://localhost:3001
- Web: http://localhost:5173 (proxies /api to backend)
| Method | Route | Description |
|---|---|---|
| GET | /api/stores |
List stores |
| GET | /api/stores/:id |
Get store |
| POST | /api/stores |
Create store |
| PUT | /api/stores/:id |
Update store |
| DELETE | /api/stores/:id |
Delete store |
| GET | /api/stores/:id/summary |
Non-trivial: total value, by-category breakdown, low-stock count |
| GET | /api/products?storeId=&category=&minPrice=&maxPrice=&inStock=&page=&limit= |
List products (filtered, paginated) |
| GET | /api/products/:id |
Get product |
| POST | /api/products |
Create product |
| PUT | /api/products/:id |
Update product |
| DELETE | /api/products/:id |
Delete product |
{ "error": "string", "details": {} }| Scenario | Status |
|---|---|
| Missing resource | 404 |
| Validation failure | 422 |
| Unexpected | 500 |
- Backend: Fastify + TypeScript — built-in schema validation, lean.
- Database: SQLite via Drizzle ORM — zero deps, migrations, type-safe queries.
- Frontend: Vite + React + TanStack Query + Tailwind — Query handles loading/error/stale; Tailwind for readable styles.
- Testing: Vitest + Supertest (server) + React Testing Library (frontend).
Flat: Store and Product (product has storeId, quantity). Category is a string enum (Produce, Dairy, Bakery) enforced at API. No separate Category table.
GET /stores/:id/summary returns:
- Total inventory value (
SUM(price × quantity)) - Per-category breakdown
- Low-stock count (quantity < 10)
Offset-based (page + limit). Cursor-based is better for large datasets; offset is simpler for this scope. All filters optional and composable.
- Backend: Thin routes, services hold logic, single error-handler middleware.
- Frontend:
api/(typed fetch),hooks/(TanStack Query wrappers). Pages use hooks only.
cd server && npm test
cd web && npm test| Layer | What's tested |
|---|---|
| API | Happy paths, 404, 422 via Supertest |
| Frontend | 100% line/statement coverage |
Run cd web && npm run test:ci for coverage report. E2E tests (Playwright) skipped at this scope.
- E2E tests — Playwright for create-store, add-product, view-summary flows.
- Optimistic updates — TanStack Query mutations with rollback on failure.
- Debounced filters — Reduce API calls while typing in product filters.