21 KiB
NestJS Retail POS Backend API Expert Guidelines
🎯 Backend Overview
A robust NestJS-based REST API backend for the Retail POS Flutter application, providing product management, category organization, transaction processing, and user authentication with offline-sync capabilities.
🤖 SUBAGENT DELEGATION SYSTEM 🤖
CRITICAL: BE PROACTIVE WITH SUBAGENTS! YOU HAVE SPECIALIZED EXPERTS AVAILABLE!
🚨 DELEGATION MINDSET
Instead of thinking "I'll handle this myself" Think: "Which specialist is BEST suited for this task?"
📋 AVAILABLE SPECIALISTS
You have access to these expert subagents - USE THEM PROACTIVELY:
🌐 nestjs-api-expert
- MUST BE USED for: Controllers, DTOs, REST endpoints, request/response handling, validation
- Triggers: "API endpoint", "controller", "DTO", "validation", "REST", "route"
🗄️ nestjs-database-expert
- MUST BE USED for: TypeORM entities, database schema, migrations, queries, relationships
- Triggers: "database", "entity", "migration", "query", "TypeORM", "Prisma", "PostgreSQL"
🏗️ nestjs-architecture-expert
- MUST BE USED for: Module structure, dependency injection, services, clean architecture
- Triggers: "architecture", "module", "service", "dependency injection", "structure"
🔐 nestjs-auth-expert
- MUST BE USED for: JWT authentication, guards, security, authorization, user management
- Triggers: "auth", "JWT", "guard", "security", "login", "authentication"
⚡ nestjs-performance-expert
- MUST BE USED for: Caching, query optimization, rate limiting, performance tuning
- Triggers: "performance", "cache", "Redis", "optimization", "slow", "rate limit"
🎯 DELEGATION STRATEGY
BEFORE starting ANY task, ASK YOURSELF:
- "Which of my specialists could handle this better?"
- "Should I break this into parts for different specialists?"
- "Would a specialist complete this faster and better?"
💼 WORK BALANCE RECOMMENDATION:
- Simple Tasks (20%): Handle independently - quick fixes, minor updates
- Complex Tasks (80%): Delegate to specialists for expert-level results
🔧 HOW TO DELEGATE
# Explicit delegation examples:
> Use the nestjs-api-expert to create the products CRUD endpoints
> Have the nestjs-database-expert design the transaction entity relationships
> Ask the nestjs-architecture-expert to structure the sync module
> Use the nestjs-auth-expert to implement JWT authentication
> Have the nestjs-performance-expert optimize product queries with caching
NestJS Best Practices
- Use TypeScript with strict mode enabled
- Implement modular architecture with feature-based organization
- Follow dependency injection patterns with NestJS IoC
- Use DTOs with class-validator for request validation
- Implement proper error handling with exception filters
- Use TypeORM for database operations
- Follow RESTful API design principles
- Implement comprehensive API documentation with Swagger
- Use environment variables for configuration
- Write unit and e2e tests for all endpoints
Project Structure
src/
common/
decorators/
current-user.decorator.ts
roles.decorator.ts
public.decorator.ts
dto/
pagination.dto.ts
api-response.dto.ts
filters/
http-exception.filter.ts
all-exceptions.filter.ts
guards/
jwt-auth.guard.ts
roles.guard.ts
interceptors/
logging.interceptor.ts
transform.interceptor.ts
cache.interceptor.ts
pipes/
validation.pipe.ts
interfaces/
pagination.interface.ts
utils/
helpers.ts
formatters.ts
config/
app.config.ts
database.config.ts
jwt.config.ts
redis.config.ts
database/
migrations/
1234567890-CreateProductsTable.ts
1234567891-CreateCategoriesTable.ts
1234567892-CreateTransactionsTable.ts
seeds/
categories.seed.ts
products.seed.ts
data-source.ts
modules/
products/
dto/
create-product.dto.ts
update-product.dto.ts
get-products.dto.ts
product-response.dto.ts
entities/
product.entity.ts
products.controller.ts
products.service.ts
products.repository.ts
products.module.ts
categories/
dto/
create-category.dto.ts
update-category.dto.ts
category-response.dto.ts
entities/
category.entity.ts
categories.controller.ts
categories.service.ts
categories.repository.ts
categories.module.ts
transactions/
dto/
create-transaction.dto.ts
get-transactions.dto.ts
transaction-response.dto.ts
entities/
transaction.entity.ts
transaction-item.entity.ts
transactions.controller.ts
transactions.service.ts
transactions.repository.ts
transactions.module.ts
auth/
dto/
login.dto.ts
register.dto.ts
strategies/
jwt.strategy.ts
local.strategy.ts
guards/
jwt-auth.guard.ts
local-auth.guard.ts
auth.controller.ts
auth.service.ts
auth.module.ts
users/
dto/
create-user.dto.ts
update-user.dto.ts
entities/
user.entity.ts
users.controller.ts
users.service.ts
users.repository.ts
users.module.ts
sync/
dto/
sync-request.dto.ts
sync-response.dto.ts
sync.controller.ts
sync.service.ts
sync.module.ts
app.module.ts
main.ts
test/
unit/
products/
products.service.spec.ts
products.controller.spec.ts
categories/
transactions/
e2e/
products.e2e-spec.ts
categories.e2e-spec.ts
auth.e2e-spec.ts
.env
.env.example
package.json
tsconfig.json
ormconfig.json
docker-compose.yml
Backend Context - Retail POS API
About This Backend
A comprehensive NestJS REST API backend that powers the Flutter Retail POS mobile application. Provides robust endpoints for product management, category organization, transaction processing, and user authentication, with offline-sync capabilities and real-time data synchronization.
Target Users
- Flutter Mobile App: Primary consumer of the API
- Admin Dashboard: Future web-based management interface (optional)
- Third-party Integrations: Payment gateways, inventory systems
Core Features
📦 Product Management
Endpoints:
GET /api/products- List all products with pagination and filteringGET /api/products/:id- Get single product detailsPOST /api/products- Create new productPUT /api/products/:id- Update productDELETE /api/products/:id- Delete productGET /api/products/category/:categoryId- Products by categoryGET /api/products/search- Search products
Features:
- Full CRUD operations
- Advanced filtering (category, price range, availability)
- Search by name and description
- Stock management
- Image URL storage
- Pagination and sorting
- Soft delete support (optional)
Business Logic:
- Validate category exists before creating product
- Check stock availability
- Update product count in category
- Track inventory changes
📁 Category Management
Endpoints:
GET /api/categories- List all categoriesGET /api/categories/:id- Get single categoryPOST /api/categories- Create new categoryPUT /api/categories/:id- Update categoryDELETE /api/categories/:id- Delete categoryGET /api/categories/:id/products- Products in category
Features:
- CRUD operations
- Product count tracking
- Icon/image support
- Color coding
- Cascade delete (optional)
Business Logic:
- Prevent deletion if category has products (or cascade)
- Update product count when products added/removed
- Unique category names
💰 Transaction Management
Endpoints:
GET /api/transactions- List transactions with paginationGET /api/transactions/:id- Get transaction detailsPOST /api/transactions- Create new transactionGET /api/transactions/stats- Transaction statisticsGET /api/transactions/daily- Daily sales report
Features:
- Complete transaction logging
- Transaction items tracking
- Subtotal, tax, discount calculation
- Payment method tracking
- Transaction history
- Sales reporting
Business Logic:
- Validate stock availability
- Update product stock on transaction
- Calculate totals automatically
- Atomic transaction creation (all or nothing)
- Track product at transaction time (price snapshot)
🔐 Authentication & Authorization
Endpoints:
POST /api/auth/register- Register new userPOST /api/auth/login- Login userGET /api/auth/profile- Get current user profilePOST /api/auth/refresh- Refresh access token
Features:
- JWT-based authentication
- Password hashing with bcrypt
- Role-based access control (RBAC)
- Token refresh mechanism
- Secure password policies
Roles:
- Admin: Full access to all endpoints
- Manager: Product and category management
- Cashier: Transaction processing only
- User: Read-only access (optional)
🔄 Sync Management
Endpoints:
POST /api/sync/products- Sync products to mobilePOST /api/sync/categories- Sync categories to mobileGET /api/sync/status- Get last sync statusGET /api/sync/changes- Get changes since last sync
Features:
- Incremental sync support
- Last modified timestamp tracking
- Change detection
- Bulk data transfer
- Sync conflict resolution
Technical Stack
Core Technologies
- Framework: NestJS 10.x
- Language: TypeScript 5.x
- Database: PostgreSQL 15.x
- ORM: TypeORM 0.3.x (or Prisma as alternative)
- Cache: Redis 7.x
- Authentication: JWT (jsonwebtoken)
- Validation: class-validator, class-transformer
- Documentation: Swagger/OpenAPI
Key Dependencies
{
"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/typeorm": "^10.0.0",
"@nestjs/jwt": "^10.0.0",
"@nestjs/passport": "^10.0.0",
"@nestjs/swagger": "^7.0.0",
"@nestjs/config": "^3.0.0",
"@nestjs/cache-manager": "^2.0.0",
"@nestjs/throttler": "^5.0.0",
"typeorm": "^0.3.17",
"pg": "^8.11.0",
"bcrypt": "^5.1.0",
"passport-jwt": "^4.0.1",
"class-validator": "^0.14.0",
"class-transformer": "^0.5.1",
"cache-manager": "^5.2.0",
"cache-manager-redis-store": "^3.0.0"
}
}
Database Schema
Products Table
CREATE TABLE products (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(255) NOT NULL,
description TEXT,
price DECIMAL(10, 2) NOT NULL,
image_url VARCHAR(500),
category_id UUID REFERENCES categories(id) ON DELETE CASCADE,
stock_quantity INTEGER DEFAULT 0,
is_available BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_products_name (name),
INDEX idx_products_category (category_id),
INDEX idx_products_name_category (name, category_id)
);
Categories Table
CREATE TABLE categories (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(255) UNIQUE NOT NULL,
description TEXT,
icon_path VARCHAR(255),
color VARCHAR(50),
product_count INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_categories_name (name)
);
Transactions Table
CREATE TABLE transactions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
subtotal DECIMAL(10, 2) NOT NULL,
tax DECIMAL(10, 2) DEFAULT 0,
discount DECIMAL(10, 2) DEFAULT 0,
total DECIMAL(10, 2) NOT NULL,
payment_method VARCHAR(50) NOT NULL,
completed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_transactions_date (completed_at)
);
Transaction Items Table
CREATE TABLE transaction_items (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
transaction_id UUID REFERENCES transactions(id) ON DELETE CASCADE,
product_id UUID REFERENCES products(id),
product_name VARCHAR(255) NOT NULL,
price DECIMAL(10, 2) NOT NULL,
quantity INTEGER NOT NULL,
line_total DECIMAL(10, 2) NOT NULL,
INDEX idx_transaction_items_transaction (transaction_id),
INDEX idx_transaction_items_product (product_id)
);
Users Table
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
roles TEXT[] DEFAULT ARRAY['user'],
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_users_email (email)
);
API Response Format
Success Response
{
"success": true,
"data": {
// Response data
},
"message": "Operation successful"
}
Paginated Response
{
"success": true,
"data": [
// Array of items
],
"meta": {
"page": 1,
"limit": 20,
"total": 100,
"totalPages": 5
}
}
Error Response
{
"success": false,
"error": {
"statusCode": 400,
"message": "Validation failed",
"details": [
"name must be a string",
"price must be a positive number"
]
},
"timestamp": "2025-01-15T10:30:00.000Z",
"path": "/api/products"
}
Key API Endpoints
Products API
List Products
GET /api/products?page=1&limit=20&categoryId=uuid&search=laptop&minPrice=100&maxPrice=1000
Response:
{
"success": true,
"data": [
{
"id": "uuid",
"name": "Laptop",
"description": "Gaming laptop",
"price": 999.99,
"imageUrl": "https://...",
"categoryId": "uuid",
"stockQuantity": 50,
"isAvailable": true,
"category": {
"id": "uuid",
"name": "Electronics"
},
"createdAt": "2025-01-15T10:00:00.000Z",
"updatedAt": "2025-01-15T10:00:00.000Z"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 100,
"totalPages": 5
}
}
Create Product
POST /api/products
Content-Type: application/json
Authorization: Bearer <token>
{
"name": "Laptop",
"description": "Gaming laptop",
"price": 999.99,
"imageUrl": "https://...",
"categoryId": "uuid",
"stockQuantity": 50,
"isAvailable": true
}
Categories API
List Categories
GET /api/categories
Response:
{
"success": true,
"data": [
{
"id": "uuid",
"name": "Electronics",
"description": "Electronic devices",
"iconPath": "/icons/electronics.png",
"color": "#FF5722",
"productCount": 150,
"createdAt": "2025-01-15T10:00:00.000Z"
}
]
}
Transactions API
Create Transaction
POST /api/transactions
Content-Type: application/json
Authorization: Bearer <token>
{
"items": [
{
"productId": "uuid",
"quantity": 2
}
],
"paymentMethod": "cash",
"discount": 10.00
}
Response:
{
"success": true,
"data": {
"id": "uuid",
"subtotal": 1999.98,
"tax": 199.99,
"discount": 10.00,
"total": 2189.97,
"paymentMethod": "cash",
"items": [
{
"id": "uuid",
"productId": "uuid",
"productName": "Laptop",
"price": 999.99,
"quantity": 2,
"lineTotal": 1999.98
}
],
"completedAt": "2025-01-15T10:30:00.000Z"
}
}
Authentication API
Login
POST /api/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "Password123!"
}
Response:
{
"success": true,
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "uuid",
"email": "user@example.com",
"name": "John Doe",
"roles": ["admin"]
}
}
}
Caching Strategy
Cache Layers
- Product List Cache: 5 minutes TTL
- Single Product Cache: 10 minutes TTL
- Category List Cache: 15 minutes TTL
- Transaction Stats Cache: 1 hour TTL
Cache Invalidation
- Invalidate on CREATE, UPDATE, DELETE operations
- Smart invalidation: Only clear related caches
- Use cache tags for grouped invalidation
Redis Configuration
{
host: process.env.REDIS_HOST,
port: 6379,
ttl: 300, // Default 5 minutes
max: 1000 // Max items in cache
}
Performance Optimization
Database Optimization
- Index frequently queried columns
- Use query builders for complex queries
- Implement connection pooling (max: 20, min: 5)
- Paginate all list endpoints
- Eager load only necessary relations
API Optimization
- Enable response compression (gzip)
- Implement rate limiting (100 req/min per IP)
- Cache frequently accessed data
- Use streaming for large responses
- Implement query result caching
Monitoring
- Log all API requests with response times
- Track database query performance
- Monitor cache hit/miss rates
- Alert on slow endpoints (>1s)
- Track error rates
Security Implementation
Authentication
- JWT with 1-day expiration
- Refresh tokens with 7-day expiration
- bcrypt password hashing (10 rounds)
- Rate limiting on auth endpoints (5 req/min)
Authorization
- Role-based access control (RBAC)
- Protected routes with guards
- Public endpoints clearly marked
- Admin-only endpoints separated
API Security
- CORS enabled with whitelist
- Helmet for security headers
- Input validation on all endpoints
- SQL injection prevention (TypeORM)
- XSS prevention
- HTTPS only in production
Environment Variables
# Application
NODE_ENV=development
PORT=3000
API_PREFIX=api
# Database
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_DATABASE=retail_pos
# JWT
JWT_SECRET=your-super-secret-key-change-in-production
JWT_EXPIRES_IN=1d
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
CACHE_TTL=300
# CORS
CORS_ORIGIN=http://localhost:3000,capacitor://localhost
# Rate Limiting
THROTTLE_TTL=60
THROTTLE_LIMIT=100
Testing Strategy
Unit Tests
- Test all service methods
- Test business logic
- Test error handling
- Mock all dependencies
- Aim for 80%+ coverage
Integration Tests
- Test database operations
- Test repository methods
- Test data transformations
E2E Tests
- Test complete API flows
- Test authentication flows
- Test CRUD operations
- Test error scenarios
- Test edge cases
Test Structure
describe('ProductsService', () => {
let service: ProductsService;
let repository: MockType<ProductsRepository>;
beforeEach(async () => {
const module = await Test.createTestingModule({
providers: [
ProductsService,
{
provide: ProductsRepository,
useFactory: mockRepository,
},
],
}).compile();
service = module.get(ProductsService);
repository = module.get(ProductsRepository);
});
it('should create a product', async () => {
const dto = { name: 'Test', price: 10 };
repository.create.mockResolvedValue(dto);
const result = await service.create(dto);
expect(result).toEqual(dto);
expect(repository.create).toHaveBeenCalledWith(dto);
});
});
Deployment
Docker Setup
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/main"]
Docker Compose
version: '3.8'
services:
api:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
depends_on:
- postgres
- redis
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: retail_pos
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- postgres-data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres-data:
Development Workflow
Setup
# Install dependencies
npm install
# Setup database
npm run migration:run
npm run seed:run
# Start development server
npm run start:dev
Development Commands
# Run tests
npm run test
npm run test:e2e
npm run test:cov
# Generate migration
npm run migration:generate -- -n MigrationName
# Run migration
npm run migration:run
# Revert migration
npm run migration:revert
# Seed database
npm run seed:run
API Documentation
- Swagger UI: http://localhost:3000/api/docs
- JSON: http://localhost:3000/api/docs-json
Remember: ALWAYS DELEGATE TO SPECIALISTS FOR BETTER RESULTS!
When working on this NestJS backend:
- API/Endpoints → nestjs-api-expert
- Database/Entities → nestjs-database-expert
- Architecture → nestjs-architecture-expert
- Auth/Security → nestjs-auth-expert
- Performance → nestjs-performance-expert
Think delegation first, implementation second!