███████╗████████╗ ██████╗ ██████╗██╗ ██╗███████╗██╗ ██████╗ ██╗ ██╗
██╔════╝╚══██╔══╝██╔═══██╗██╔════╝██║ ██╔╝██╔════╝██║ ██╔═══██╗██║ ██║
███████╗ ██║ ██║ ██║██║ █████╔╝ █████╗ ██║ ██║ ██║██║ █╗ ██║
╚════██║ ██║ ██║ ██║██║ ██╔═██╗ ██╔══╝ ██║ ██║ ██║██║███╗██║
███████║ ██║ ╚██████╔╝╚██████╗██║ ██╗██║ ███████╗╚██████╔╝╚███╔███╔╝
╚══════╝ ╚═╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝
Full-stack inventory & procurement management platform
🚧 Actively developed as a portfolio project targeting full-stack roles in Singapore.
StockFlow is a business-oriented inventory and procurement management platform built to feel like a real internal operations tool, not a tutorial clone. It helps teams manage products, suppliers, stock visibility, and the procurement workflows that connect them.
The project focuses on production-minded full-stack engineering:
- clean REST API design
- layered Spring Boot architecture
- relational data modeling with PostgreSQL
- typed frontend development with React + TypeScript
- reusable CRUD patterns across modules
- DTO-based API boundaries instead of exposing entities directly
- a polished internal-tool UI with modals, detail views, search, and summary cards
StockFlow currently supports product and supplier management across both backend and frontend.
- Product CRUD
- Supplier CRUD
- Product-to-supplier relationship
- Product create/edit form with supplier dropdown
- Supplier and product detail modals
- Frontend summary cards for products and suppliers
- Modal-based create/edit flows
- Delete flows with immediate UI updates
- Backend request/response DTOs for product and supplier APIs
- Mapper layer for converting entities to API responses
- Layered backend structure with controller/service/repository separation
- Supplier service interface + implementation structure
- Custom supplier not-found exception
- Global exception handling
- Product backend search endpoint
- Supplier backend search endpoint
- Frontend search UI for products and suppliers
- Wiring product page search fully to backend query search
- Pagination for product and supplier tables
- Better validation feedback in the frontend
- Purchase order domain modeling
- JWT authentication
- Role-based access control
- Purchase order workflow
- Stock updates and inventory history
- Dashboard analytics
- Audit logging
- Dockerized production deployment
- CI/CD pipeline
┌─────────────────────┐ ┌──────────────────────────┐ ┌─────────────┐
│ React Frontend │──HTTP──▶│ Spring Boot Backend │──JPA───▶│ PostgreSQL │
│ TypeScript/Tailwind│◀──JSON──│ REST API │ │ Database │
└─────────────────────┘ └──────────────────────────┘ └─────────────┘
Controller → Service → Repository → Entity → PostgreSQL
(HTTP/JSON) (Logic) (Data access) (DB map)
Page → Modal/Details → Service → API
(UI) (State/Form) (HTTP) (Backend)
This pattern is intentionally repeated across modules so new business entities can be added consistently.
| Layer | Technology |
|---|---|
| Frontend | React 19, TypeScript, Tailwind CSS, Vite, React Icons |
| Backend | Java 17, Spring Boot 3.5, Spring Data JPA, Spring Validation |
| Database | PostgreSQL 15 |
| API Client | Axios |
| Build | Maven, npm, Vite |
| DevOps | Docker Compose for local PostgreSQL |
| Testing | Spring Boot Test, Postman/manual API testing |
| Security | JWT + role-based access control planned |
| Module | Status |
|---|---|
| Product management CRUD | ✅ Done |
| Supplier management CRUD | ✅ Done |
| Product-supplier relationship | ✅ Done |
| Product detail modal | ✅ Done |
| Supplier detail modal | ✅ Done |
| Product search endpoint | ✅ Done |
| Supplier search endpoint | ✅ Done |
| Frontend search UI | ✅ Done |
| Pagination | 🔨 Next |
| Better validation feedback | 🔨 Next |
| JWT authentication | 📋 Planned |
| Role-based access | 📋 Planned |
| Purchase order workflow | 📋 Planned |
| Stock updates & inventory history | 📋 Planned |
| Dashboard analytics | 📋 Planned |
| Audit logs | 📋 Planned |
| Docker + CI/CD pipeline | 📋 Planned |
The Product module manages the inventory catalog and serves as the main template for full-stack feature development.
- Product entity mapped to the
productstable - Product request and response DTOs
- Product mapper
- Product repository with database search support
- Product service with supplier lookup logic
- Product controller with REST endpoints
- Product table on the frontend
- Add product modal
- Edit product modal with pre-filled values
- Supplier dropdown inside the product form
- Delete product flow
- Product detail modal
- Product summary cards for total, low-stock, and out-of-stock counts
- Search UI by product name, SKU, description, and supplier name
Products are connected to suppliers through a many-to-one relationship:
Supplier 1 ──▶ Product many
In database terms:
products.supplier_id → suppliers.id
The frontend sends a simple supplierId when creating or updating a product. The backend looks up the supplier entity and returns clean response fields such as supplierId and supplierName.
The Supplier module manages the procurement partners that provide products.
- Supplier entity mapped to the
supplierstable - Supplier repository with exact lookup methods and search support
- Supplier service interface
- Supplier service implementation
- Request/response DTOs
- Mapper layer
- Custom not-found exception
- Global exception handling
- Supplier table on the frontend
- Add supplier modal
- Edit supplier modal with pre-filled values
- Delete supplier flow
- Supplier detail modal
- Supplier summary cards for total suppliers, email contacts, and phone contacts
- Debounced supplier search from the frontend API service
- Name
- Contact person
- Phone
- Address
StockFlow supports backend search through optional query parameters.
GET /api/products?search=laptop
GET /api/suppliers?search=dellProduct search currently supports:
- name
- SKU
- description
Supplier search currently supports:
- name
- contact person
- phone
- address
Planned workflow:
DRAFT ──▶ SUBMITTED ──▶ APPROVED ──▶ RECEIVED
│
└──▶ REJECTED
This module will eventually connect suppliers, products, order lines, approval states, and stock updates.
Planned authorization model:
| Action | Admin | Manager | Staff |
|---|---|---|---|
| View products & suppliers | ✅ | ✅ | ✅ |
| Create / edit products | ✅ | ✅ | ❌ |
| Manage suppliers | ✅ | ✅ | ❌ |
| Create purchase orders | ✅ | ✅ | ✅ |
| Approve / reject orders | ✅ | ✅ | ❌ |
| View audit logs | ✅ | ❌ | ❌ |
| Manage users | ✅ | ❌ | ❌ |
StockFlow/
├── backend/
│ ├── src/main/java/com/stockflow/
│ │ ├── StockflowApplication.java
│ │ ├── common/
│ │ │ └── exception/
│ │ ├── product/
│ │ │ ├── controller/
│ │ │ ├── dto/
│ │ │ ├── entity/
│ │ │ ├── mapper/
│ │ │ ├── repository/
│ │ │ └── service/
│ │ └── supplier/
│ │ ├── controller/
│ │ ├── dto/
│ │ ├── entity/
│ │ ├── mapper/
│ │ ├── repository/
│ │ └── service/
│ │ └── impl/
│ └── pom.xml
│
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ │ ├── ProductDetailsModal.tsx
│ │ │ ├── ProductModal.tsx
│ │ │ ├── SupplierDetailsModal.tsx
│ │ │ └── SupplierModal.tsx
│ │ ├── pages/
│ │ │ ├── ProductsPage.tsx
│ │ │ └── SupplierPage.tsx
│ │ ├── services/
│ │ │ ├── api.ts
│ │ │ ├── productService.ts
│ │ │ └── supplierService.ts
│ │ ├── types/
│ │ │ ├── product.ts
│ │ │ └── supplier.ts
│ │ ├── App.tsx
│ │ └── main.tsx
│ └── package.json
│
├── database/
│ └── seed-test-products.sql
├── docs/
├── docker-compose.yml
└── README.md
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/products |
Get all products |
GET |
/api/products?search={term} |
Search products |
GET |
/api/products/{id} |
Get product by ID |
POST |
/api/products |
Create a product |
PUT |
/api/products/{id} |
Update a product |
DELETE |
/api/products/{id} |
Delete a product |
Example create/update payload:
{
"name": "Laptop",
"description": "Business laptop",
"sku": "LAP-001",
"price": 999.99,
"stockQuantity": 20,
"supplierId": 1
}Example response:
{
"id": 1,
"name": "Laptop",
"description": "Business laptop",
"sku": "LAP-001",
"price": 999.99,
"stockQuantity": 20,
"supplierId": 1,
"supplierName": "Dell Wholesale",
"createdAt": "2026-05-18T22:00:00",
"updatedAt": "2026-05-18T22:00:00"
}| Method | Endpoint | Description |
|---|---|---|
GET |
/api/suppliers |
Get all suppliers |
GET |
/api/suppliers?search={term} |
Search suppliers |
GET |
/api/suppliers/{id} |
Get supplier by ID |
POST |
/api/suppliers |
Create a supplier |
PUT |
/api/suppliers/{id} |
Update a supplier |
DELETE |
/api/suppliers/{id} |
Delete a supplier |
Example create/update payload:
{
"name": "Dell Wholesale",
"contactPerson": "Sarah Lee",
"email": "sarah@example.com",
"phone": "+65 1234 5678",
"address": "Singapore"
}- Java 17+
- Node.js 18+
- Maven
- Docker & Docker Compose
git clone https://github.com/YOUR_USERNAME/stockflow.git
cd stockflowdocker compose up -dPostgreSQL runs on port 5432 with the local database configured in docker-compose.yml.
cd backend
./mvnw spring-boot:runBackend runs at:
http://localhost:8080
cd frontend
npm install
npm run devFrontend runs at:
http://localhost:5173
- Products
- Suppliers
- Product-supplier relationship
- Search UI
- Backend product search endpoint
- Backend supplier search endpoint
- Wire product page search fully to backend query search
- Pagination
- Better validation feedback
- JWT login
- Route protection
- Role-based permissions
- Purchase orders
- Order line items
- Approval workflow
- Stock updates on receive
- Dashboard analytics
- Audit logs
- Dockerized deployment
- GitHub Actions pipeline
- README screenshots and demo polish
This project is being built as a portfolio-quality system to demonstrate the difference between knowing a framework and being able to design a real application with it.
It is intentionally structured to show:
- full-stack consistency
- scalable feature organization
- reusable CRUD patterns
- enterprise-leaning backend design
- relational database modeling
- thoughtful frontend state management
Built by YetAnotherFactsEnjoyer