Files
retail-nest/docs/DATABASE_SETUP.md
2025-10-10 16:04:10 +07:00

11 KiB

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

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

# 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

# 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

# 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)

# 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

# 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

# TypeORM CLI operations
npm run typeorm -- <command>

# 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:

    npm run migration:generate -- -n AddColumnToProduct
    
  3. Review generated migration in src/database/migrations/

  4. Run migration:

    npm run migration:run
    
  5. Test rollback (in development):

    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"

# Solution: Check if migration already ran
psql -U postgres retail_pos
SELECT * FROM migrations;
\q

Problem: Can't connect to database

# 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

# 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

# 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


Database Expert: NestJS Database Expert Subagent Created: 2025-10-10 Status: Complete and Ready for Development