A cloud-native backend system for managing products, inventory, customer orders, and automatic invoice generation.
The system consists of two services:
- Java Spring Boot Core Service - Handles all business logic, database writes, and order processing
- Node.js Orchestrator Service - Handles API gateway, PDF generation, S3 uploads, and email delivery
Client
│
▼
Node.js API Gateway (Express)
│
▼
Java Spring Boot Core Service
│
▼
PostgreSQL (AWS RDS)
Java ──► Node (order completed callback)
Node ──► S3 (PDF invoices)
Node ──► SES (email)
- Core Backend: Java 17 + Spring Boot 3.2.0
- Orchestration: Node.js 18 + Express
- Database: PostgreSQL 15
- Storage: AWS S3
- Email: AWS SES
- Containers: Docker
- Docker and Docker Compose
- Java 17+ (for local development)
- Node.js 18+ (for local development)
- Maven 3.9+ (for local development)
- AWS Account with S3 and SES configured (for production)
- Clone the repository:
git clone <repository-url>
cd Inventory- Set environment variables (optional, for AWS):
export S3_BUCKET=your-invoice-bucket
export AWS_REGION=us-east-1
export AWS_ACCESS_KEY_ID=your-access-key
export AWS_SECRET_ACCESS_KEY=your-secret-key
export FROM_EMAIL=your-verified-ses-email- Start all services:
docker-compose up --buildThis will start:
- PostgreSQL on port 5432
- Java service on port 8080
- Node.js service on port 3000
cd java-service
mvn clean install
mvn spring-boot:runThe service will run on http://localhost:8080
cd node-service
npm install
npm startThe service will run on http://localhost:3000
Ensure PostgreSQL is running and create the database:
createdb inventory_dbFlyway will automatically run migrations on startup.
Endpoint: POST /api/orders
Request:
{
"customerId": 1,
"items": [
{ "productId": 1, "quantity": 2 }
]
}Response:
{
"id": 1,
"orderId": "ORD-2026-000001",
"customerId": 1,
"customerName": "John Doe",
"customerEmail": "john@example.com",
"items": [
{
"productId": 1,
"productName": "Product Name",
"quantity": 2,
"unitPrice": 19.99,
"totalPrice": 39.98
}
],
"subtotal": 39.98,
"tax": 4.00,
"total": 43.98,
"status": "COMPLETED",
"createdAt": "2026-01-15T10:30:00"
}Endpoint: GET /orders/{orderId}
Response: Same as create order response
- customers: Customer information
- products: Product catalog with inventory
- orders: Order headers
- order_items: Order line items
- All monetary values stored as cents (BIGINT) - no floating-point
- Inventory quantity cannot go negative
- Foreign keys enforce referential integrity
- Row-level locking prevents inventory race conditions
- Client creates order via Node.js API gateway
- Node.js forwards request to Java service
- Java service validates inventory, processes order transactionally
- After transaction commit, Java calls Node.js callback endpoint
- Node.js generates PDF invoice
- Node.js uploads PDF to S3
- Node.js sends email via AWS SES
Environment variables:
DATABASE_URL: PostgreSQL connection stringDATABASE_USERNAME: Database usernameDATABASE_PASSWORD: Database passwordSERVER_PORT: Server port (default: 8080)ORCHESTRATOR_CALLBACK_URL: Node.js callback URL
Environment variables:
PORT: Server port (default: 3000)JAVA_SERVICE_URL: Java service URLS3_BUCKET: S3 bucket for invoicesAWS_REGION: AWS regionAWS_ACCESS_KEY_ID: AWS access keyAWS_SECRET_ACCESS_KEY: AWS secret keyBUSINESS_NAME: Business name for invoicesFROM_EMAIL: Email address for sending invoices
- Create an S3 bucket for storing invoices
- Configure bucket permissions
- Set
S3_BUCKETenvironment variable
- Verify your sending email address in SES
- If in sandbox mode, verify recipient emails too
- Set
FROM_EMAILenvironment variable - Configure IAM permissions for SES
- Order creation is atomic - all or nothing
- Inventory updates use row-level locking (
SELECT ... FOR UPDATE) - Callbacks fire only after transaction commit
- Idempotent invoice generation allows safe retries
- Explicit error responses (no silent failures)
- Meaningful exception messages
- Defensive programming throughout
- Proper logging at all levels
Run tests:
# Java service
cd java-service
mvn test
# Node.js service
cd node-service
npm test- Build Docker images
- Push to ECR
- Create ECS task definitions
- Deploy services to Fargate
- Configure RDS PostgreSQL instance
- Set environment variables in ECS
- Package applications
- Deploy via EB CLI or console
- Configure RDS
- Set environment variables