A NestJS-based backend API for mortgage data entry and verification system. Provides comprehensive data management, search capabilities, audit trails, and real-time collaboration features.
- RESTful API: Complete CRUD operations for mortgage records
- AutoComplete Search: Vector-based full-text search with pagination
- Record Locking: Prevents concurrent editing with automatic timeout
- Batch Management: Organize records into daily/weekly batches
- Audit Trails: Complete action logging for compliance
- Authentication: JWT-based secure access control
- Database Integration: PostgreSQL with TypeORM
- Vector Search: Full-text search across multiple fields
- Pagination: Efficient large dataset handling
- Field Validation: Input sanitization and validation
- Scheduled Tasks: Automatic cleanup of expired locks
- County Integration: Automated county website URL generation
- Statistics API: Real-time record count and status metrics
- NestJS 10.0.0: Node.js framework
- TypeORM 0.3.20: Database ORM
- PostgreSQL: Primary database
- JWT: Authentication
- bcrypt: Password hashing
- class-validator: Input validation
- @nestjs/schedule: Cron jobs
- Node.js (v16 or higher)
- PostgreSQL (v12 or higher)
- npm or yarn
-
Clone the repository
git clone https://github.com/pintu544/Data-Entry-and-Verification-System cd mortgage-data
-
Install dependencies
npm install
-
Database Setup
# Install PostgreSQL and create database createdb mortgage_data
-
Environment Configuration Create
.env
file:DATABASE_HOST=localhost DATABASE_PORT=5432 DATABASE_USER=postgres DATABASE_PASSWORD=postgres DATABASE_NAME=mortgage_data JWT_SECRET=your_jwt_secret_key_here NODE_ENV=development
-
Start the development server
npm run start:dev
-
API Access Backend runs on http://localhost:3000
# Run unit tests
npm run test
# Run e2e tests
npm run test:e2e
# Run specific test file
npm run test -- records.service.spec.ts
# Login (get JWT token)
curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"secret"}'
# Create record
curl -X POST http://localhost:3000/records \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"property_address": "123 Main St",
"transaction_date": "2024-01-15",
"borrower_name": "John Doe",
"loan_amount": 300000,
"sales_price": 350000,
"down_payment": 50000,
"apn": "123-456-789",
"entered_by": "user123"
}'
# Search records
curl "http://localhost:3000/records/search?query=Main St&page=1&limit=10" \
-H "Authorization: Bearer <token>"
# Get record by ID
curl http://localhost:3000/records/<record-id> \
-H "Authorization: Bearer <token>"
# Test autocomplete for property address
curl "http://localhost:3000/records/autocomplete/property_address?q=123&limit=10" \
-H "Authorization: Bearer <token>"
# Test autocomplete for borrower name
curl "http://localhost:3000/records/autocomplete/borrower_name?q=John&limit=5" \
-H "Authorization: Bearer <token>"
# Lock record
curl -X PUT http://localhost:3000/records/<record-id>/lock \
-H "Authorization: Bearer <token>"
# Unlock record
curl -X PUT http://localhost:3000/records/<record-id>/unlock \
-H "Authorization: Bearer <token>"
# Verify record (Good/Bad)
curl -X PUT http://localhost:3000/records/<record-id>/verify \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"isGood": true}'
# Get record statistics
curl http://localhost:3000/records/statistics \
-H "Authorization: Bearer <token>"
# Create batch
curl -X POST http://localhost:3000/batches \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"batch_name": "2024-01-15-Daily", "batch_type": "Daily"}'
# Get all batches
curl http://localhost:3000/batches \
-H "Authorization: Bearer <token>"
-- Check tables created
\dt
-- Verify record structure
\d records
-- Check sample data
SELECT id, property_address, borrower_name, status FROM records LIMIT 5;
-- Verify audit logs
SELECT * FROM audit_logs ORDER BY timestamp DESC LIMIT 10;
-- Check indexes
\di
src/
βββ auth/ # Authentication module
β βββ auth.controller.ts
β βββ auth.service.ts
β βββ jwt.strategy.ts
β βββ interfaces/
βββ records/ # Records management
β βββ entities/record.entity.ts
β βββ dto/
β βββ records.controller.ts
β βββ records.service.ts
βββ batches/ # Batch management
βββ audit-logs/ # Audit trail
βββ users/ # User management
βββ common/ # Shared utilities
β βββ decorators/
β βββ guards/
β βββ tasks/
βββ app.module.ts # Main application module
CREATE TABLE records (
id UUID PRIMARY KEY,
property_address VARCHAR NOT NULL,
transaction_date DATE NOT NULL,
borrower_name VARCHAR NOT NULL,
loan_amount DECIMAL(12,2) NOT NULL,
sales_price DECIMAL(12,2) NOT NULL,
down_payment DECIMAL(12,2) NOT NULL,
apn VARCHAR NOT NULL,
status VARCHAR DEFAULT 'Pending',
locked_by VARCHAR,
lock_timestamp TIMESTAMP,
entered_by VARCHAR NOT NULL,
entered_by_date TIMESTAMP NOT NULL,
reviewed_by VARCHAR,
reviewed_by_date TIMESTAMP,
search_vector TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE audit_logs (
id UUID PRIMARY KEY,
record_id VARCHAR NOT NULL,
user_id VARCHAR NOT NULL,
action VARCHAR NOT NULL,
field_name VARCHAR,
old_value TEXT,
new_value TEXT,
timestamp TIMESTAMP DEFAULT NOW()
);
# Database Configuration
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USER=postgres
DATABASE_PASSWORD=your_password
DATABASE_NAME=mortgage_data
# Security
JWT_SECRET=your_jwt_secret_key
JWT_EXPIRES_IN=1h
# Application
NODE_ENV=development
PORT=3000
- Auto-synchronization enabled in development
- Entity auto-loading
- Logging enabled for development
- Connection pooling optimized
-
Database Connection Failed
Error: ECONNREFUSED 127.0.0.1:5432
- Verify PostgreSQL is running
- Check DATABASE_* environment variables
- Ensure database exists
-
JWT Authentication Errors
Error: Invalid token
- Verify JWT_SECRET is set
- Check token expiration
- Ensure proper Authorization header format
-
TypeORM Synchronization Issues
Error: relation "records" does not exist
- Check database permissions
- Verify entity imports in modules
- Ensure synchronize: true in development
-
Search Performance Issues
Slow query execution
- Verify database indexes exist
- Check search_vector field population
- Monitor query execution plans
-
Database Indexing
CREATE INDEX idx_records_search ON records USING gin(to_tsvector('english', search_vector)); CREATE INDEX idx_records_status ON records(status); CREATE INDEX idx_records_locked ON records(locked_by, lock_timestamp);
-
Query Optimization
- Use query builders for complex searches
- Implement result caching for autocomplete
- Paginate large result sets
-
Memory Management
- Connection pooling configuration
- Query result streaming for large datasets
- Garbage collection optimization
- Input Validation: class-validator decorators
- SQL Injection Protection: Parameterized queries
- Authentication: JWT token-based
- Authorization: Role-based access control
- Password Hashing: bcrypt with salt rounds
- CORS Configuration: Configurable origins
- API Response Time: < 200ms average
- Database Query Time: < 100ms average
- Search Results: < 500ms for 10k+ records
- Concurrent Users: 100+ supported
- Memory Usage: < 512MB baseline
# Build and run with Docker Compose
docker-compose up --build
# Production deployment
docker-compose -f docker-compose.prod.yml up -d
NODE_ENV=production
DATABASE_SSL=true
JWT_SECRET=strong_production_secret
PORT=3000
# API health check
curl http://localhost:3000/health
# Database connectivity
curl http://localhost:3000/health/db
- Structured logging with NestJS Logger
- Request/response logging
- Error tracking and alerting
- Performance metrics
- Query performance tracking
- Connection pool monitoring
- Lock timeout detection
- Audit trail analysis
- Schedule: Every 5 minutes
- Function: Unlocks records with expired timestamps (>10 minutes)
- Logging: Records number of unlocked records
- Schedule: Daily at midnight
- Function: Archives old audit logs (>90 days)
- Retention: Configurable retention period
# Generate new module
nest g module feature-name
# Generate controller
nest g controller feature-name
# Generate service
nest g service feature-name
# Database migration
npm run migration:generate -- -n MigrationName
npm run migration:run
# Start with debugging
npm run start:debug
# Watch mode with debugging
npm run start:dev --debug
- Swagger UI available at
/api/docs
in development - OpenAPI specification auto-generated
- Postman collection available
Note: Ensure PostgreSQL is running and properly configured before starting the application.