# Database Setup Guide - Retail POS Backend ## Overview Complete TypeORM database setup for the Retail POS NestJS backend with PostgreSQL. ## Created Files ### 1. Entity Files (Domain Models) #### `/src/modules/users/entities/user.entity.ts` - User entity with bcrypt password hashing - UserRole enum (admin, manager, cashier, user) - @BeforeInsert/@BeforeUpdate hooks for automatic password hashing - validatePassword() method for authentication - Exclude password from JSON responses - Index on email field #### `/src/modules/categories/entities/category.entity.ts` - Category entity with unique name constraint - Fields: name, description, iconPath, color, productCount - OneToMany relationship with Products - Index on name field - Timestamps (createdAt, updatedAt) #### `/src/modules/products/entities/product.entity.ts` - Product entity with complete product information - Fields: name, description, price, imageUrl, stockQuantity, isAvailable - ManyToOne relationship with Category (CASCADE delete) - OneToMany relationship with TransactionItems - Composite index on [name, categoryId] - Individual indexes on name and categoryId #### `/src/modules/transactions/entities/transaction.entity.ts` - Transaction entity for sales records - Fields: subtotal, tax, discount, total, paymentMethod - OneToMany relationship with TransactionItems (CASCADE) - Index on completedAt for date-based queries #### `/src/modules/transactions/entities/transaction-item.entity.ts` - Transaction line items - Fields: productName, price, quantity, lineTotal - ManyToOne relationships with Transaction and Product - Indexes on transactionId and productId - Stores product snapshot at transaction time ### 2. Configuration Files #### `/src/config/database.config.ts` - TypeORM configuration using @nestjs/config - Environment-based settings - All entities registered - Migration paths configured - SSL support for production - Synchronize always false (use migrations!) #### `/src/database/data-source.ts` - TypeORM DataSource for CLI operations - Used by migration and seed commands - Loads from .env file - Same configuration as database.config.ts ### 3. Migration Files #### `/src/database/migrations/1736518800000-InitialSchema.ts` - Complete initial database schema - Creates all 5 tables: - users (with email index) - categories (with name index) - products (with name, categoryId, and composite indexes) - transactions (with completedAt index) - transaction_items (with transactionId and productId indexes) - Sets up all foreign key relationships - Enables uuid-ossp extension - Proper up/down methods for rollback ### 4. Seed Files #### `/src/database/seeds/categories.seed.ts` - Seeds 6 common retail categories: - Electronics (Blue) - Clothing (Pink) - Food & Beverages (Green) - Home & Garden (Orange) - Sports & Outdoors (Purple) - Books & Media (Brown) - Each with icon path and color - Checks for existing records #### `/src/database/seeds/products.seed.ts` - Seeds 14 sample products across all categories - Realistic prices and stock quantities - Placeholder images - Updates category product counts - Covers all seeded categories #### `/src/database/seeds/run-seeds.ts` - Main seed runner script - Runs seeds in correct order (categories → products) - Proper error handling - Database connection management ### 5. Environment Configuration #### `.env.example` - Complete environment variable template - Database credentials - JWT configuration - Redis settings - CORS configuration - Rate limiting settings ## Database Schema ### Tables Created ```sql users ├── id (uuid, PK) ├── name (varchar 255) ├── email (varchar 255, unique, indexed) ├── password (varchar 255) ├── roles (text array) ├── isActive (boolean) ├── createdAt (timestamp) └── updatedAt (timestamp) categories ├── id (uuid, PK) ├── name (varchar 255, unique, indexed) ├── description (text, nullable) ├── iconPath (varchar 255, nullable) ├── color (varchar 50, nullable) ├── productCount (int) ├── createdAt (timestamp) └── updatedAt (timestamp) products ├── id (uuid, PK) ├── name (varchar 255, indexed) ├── description (text, nullable) ├── price (decimal 10,2) ├── imageUrl (varchar 500, nullable) ├── categoryId (uuid, FK, indexed) ├── stockQuantity (int) ├── isAvailable (boolean) ├── createdAt (timestamp) └── updatedAt (timestamp) └── FK: categories(id) ON DELETE CASCADE └── Composite Index: (name, categoryId) transactions ├── id (uuid, PK) ├── subtotal (decimal 10,2) ├── tax (decimal 10,2) ├── discount (decimal 10,2) ├── total (decimal 10,2) ├── paymentMethod (varchar 50) └── completedAt (timestamp, indexed) transaction_items ├── id (uuid, PK) ├── transactionId (uuid, FK, indexed) ├── productId (uuid, FK, indexed) ├── productName (varchar 255) ├── price (decimal 10,2) ├── quantity (int) └── lineTotal (decimal 10,2) └── FK: transactions(id) ON DELETE CASCADE └── FK: products(id) ON DELETE RESTRICT ``` ## Setup Instructions ### 1. Prerequisites ```bash # Ensure PostgreSQL is installed and running psql --version # Create database createdb retail_pos # Or using psql psql -U postgres CREATE DATABASE retail_pos; \q ``` ### 2. Configure Environment ```bash # Copy example environment file cp .env.example .env # Edit .env with your database credentials # At minimum, update: DB_HOST=localhost DB_PORT=5432 DB_USERNAME=postgres DB_PASSWORD=your_password DB_DATABASE=retail_pos ``` ### 3. Run Migrations ```bash # Run all pending migrations npm run migration:run # Expected output: # query: SELECT * FROM "information_schema"."tables" WHERE "table_schema" = 'public' AND "table_name" = 'migrations' # query: CREATE TABLE "migrations" (...) # Migration InitialSchema1736518800000 has been executed successfully. ``` ### 4. Seed Database (Optional) ```bash # Run seed scripts to populate with sample data npm run seed:run # Expected output: # 🌱 Starting database seeding... # ✓ Database connection established # 📦 Seeding categories... # ✓ Created category: Electronics # ✓ Created category: Clothing # ... (more categories) # 📦 Seeding products... # ✓ Created product: Wireless Mouse # ... (more products) # 🎉 Database seeding completed successfully! ``` ### 5. Verify Setup ```bash # Connect to database psql -U postgres retail_pos # Check tables \dt # Check products count SELECT COUNT(*) FROM products; # Check categories with product counts SELECT name, "productCount" FROM categories; # Exit \q ``` ## Available NPM Scripts ```bash # TypeORM CLI operations npm run typeorm -- # Generate a new migration (based on entity changes) npm run migration:generate -- -n MigrationName # Create an empty migration file npm run migration:create -- src/database/migrations/MigrationName # Run all pending migrations npm run migration:run # Revert the last migration npm run migration:revert # Seed the database npm run seed:run ``` ## Migration Workflow ### Creating New Migrations 1. **Modify entities** (add/remove fields, change relationships) 2. **Generate migration**: ```bash npm run migration:generate -- -n AddColumnToProduct ``` 3. **Review generated migration** in `src/database/migrations/` 4. **Run migration**: ```bash npm run migration:run ``` 5. **Test rollback** (in development): ```bash npm run migration:revert ``` ### Migration Best Practices - ✅ Always review generated migrations before running - ✅ Test migrations in development first - ✅ Keep migrations small and focused - ✅ Never modify existing migrations that have run in production - ✅ Always provide up() and down() methods - ✅ Backup database before running migrations in production - ❌ Never use synchronize: true in production ## Entity Relationships ``` User (standalone) Category (1) ----< Products (N) | | v Transaction (1) ----< TransactionItems (N) >---- Products (N) ``` ## Key Features Implemented ### 1. Password Security - Bcrypt hashing with 10 rounds - Automatic hashing on insert/update - Password excluded from JSON responses - Validation method for authentication ### 2. UUID Primary Keys - All tables use UUID v4 - uuid-ossp extension enabled - Better for distributed systems - No sequential ID exposure ### 3. Proper Indexing - Email index on users - Name index on categories - Multiple indexes on products (name, categoryId, composite) - Date index on transactions - Foreign key indexes on transaction_items ### 4. Data Integrity - Foreign key constraints - Cascade deletes where appropriate - Unique constraints (email, category name) - Default values for booleans and integers - Nullable vs required fields clearly defined ### 5. Timestamps - Automatic createdAt on insert - Automatic updatedAt on update - Custom completedAt for transactions ## Troubleshooting ### Migration Issues **Problem**: Migration fails with "relation already exists" ```bash # Solution: Check if migration already ran psql -U postgres retail_pos SELECT * FROM migrations; \q ``` **Problem**: Can't connect to database ```bash # Check PostgreSQL is running pg_isready # Check credentials in .env # Verify database exists psql -U postgres -c "\l" | grep retail_pos ``` ### Seed Issues **Problem**: Seeds fail with foreign key constraint ```bash # Solution: Run seeds in correct order (already handled in run-seeds.ts) # Or clear database and re-seed: npm run migration:revert npm run migration:run npm run seed:run ``` ### TypeORM Issues **Problem**: Entity not found ```bash # Solution: Ensure entity is: # 1. Exported from entity file # 2. Added to data-source.ts entities array # 3. Added to database.config.ts entities array ``` ## Production Considerations 1. **Environment Variables**: Never commit .env to git 2. **SSL**: Enable SSL for production databases 3. **Connection Pooling**: Configure in data-source.ts 4. **Migrations**: Always run migrations manually, never use synchronize 5. **Backups**: Backup database before running migrations 6. **Monitoring**: Log slow queries in production 7. **Security**: Use strong passwords, restrict database access ## Next Steps After database setup: 1. ✅ Create repository classes (see CLAUDE.md) 2. ✅ Create service classes for business logic 3. ✅ Create DTOs for validation 4. ✅ Create controllers for REST endpoints 5. ✅ Add authentication middleware 6. ✅ Implement caching with Redis 7. ✅ Add comprehensive tests ## Reference - **TypeORM Docs**: https://typeorm.io - **NestJS Database**: https://docs.nestjs.com/techniques/database - **PostgreSQL Docs**: https://www.postgresql.org/docs/ --- **Database Expert**: NestJS Database Expert Subagent **Created**: 2025-10-10 **Status**: ✅ Complete and Ready for Development