Technical Documentation

CarsPoint Backend

A comprehensive guide to the architecture, authentication flows, API endpoints, and implementation details of the CarsPoint car dealership platform.

Version 3.0 Release
Last Updated February 2026
Framework NestJS + TypeORM
Database MySQL 8.x

Documentation Contents

Navigate through all sections of the technical documentation

1 System Overview

CarsPoint is a multi-tenant car dealership platform backend built with NestJS, providing comprehensive APIs for car listings, dealer management, customer interactions, and administrative operations.

Key Capabilities

Multi-Tenant Architecture

Complete company-scoped data isolation ensuring dealers only access their own data.

Role-Based Access Control

CASL-based authorization with 5 distinct user roles and granular permissions.

Two-Factor Authentication

OTP-based 2FA with SMS delivery for enhanced account security.

Multi-Channel Notifications

5 SMS drivers and 3 Email drivers with pluggable architecture.

Flexible Storage

Support for local filesystem or AWS S3 with automatic image processing.

Comprehensive Audit Trail

Complete activity logging for compliance and security monitoring.

Technology Stack

N NestJS 10.x
TS TypeScript 5.x
DB MySQL 8.x
R Redis Cache
ORM TypeORM
JWT JSON Web Tokens
CASL Authorization
IMG Sharp Processing

2 System Architecture

Understanding the layered architecture and module dependencies that power the CarsPoint platform.

Layered Architecture

graph TB
    subgraph "Presentation Layer"
        Controllers["Controllers"]
    end

    subgraph "Business Layer"
        Services["Services"]
        Guards["Guards & Policies"]
    end

    subgraph "Data Access Layer"
        Repositories["Repositories"]
        Entities["Entities"]
    end

    subgraph "Infrastructure"
        Cache[("Redis Cache")]
        DB[("MySQL Database")]
        Storage[("File Storage")]
        Queue["Bull Queue"]
    end

    Controllers --> Services
    Services --> Guards
    Services --> Repositories
    Repositories --> Entities
    Entities --> DB
    Services --> Cache
    Services --> Storage
    Services --> Queue
                

Module Dependencies

graph LR
    Auth["Auth Module"] --> User["User Module"]
    Auth --> Notification["Notification Module"]
    Car["Car Module"] --> Company["Company Module"]
    Car --> Upload["Upload Module"]
    Company --> Location["Location Module"]
    Customer["Customer Module"] --> Car
    Upload --> Shared["Shared Module"]
                

Request Lifecycle

sequenceDiagram
    participant Client
    participant Guard as Auth Guard
    participant CASL as CASL Guard
    participant Controller
    participant Service
    participant DB as Database

    Client->>Guard: HTTP Request + JWT
    Guard->>Guard: Validate Token
    Guard->>CASL: Check Permissions
    CASL->>Controller: Authorized
    Controller->>Service: Call Method
    Service->>DB: Query/Mutate
    DB-->>Service: Result
    Service-->>Controller: DTO
    Controller-->>Client: JSON Response
                

3 Authentication

Secure authentication using JWT tokens with refresh token rotation and optional two-factor authentication.

Login Flow (Standard)

When a user logs in without 2FA enabled, the system validates credentials and returns access and refresh tokens.

sequenceDiagram
    participant User
    participant API as Auth API
    participant Service as Auth Service
    participant DB as Database
    participant Cache as Redis

    User->>API: POST /auth/login
    API->>Service: login(phone, password)
    Service->>DB: Find user by phone
    DB-->>Service: User record
    Service->>Service: Verify password (bcrypt)
    Service->>Service: Generate JWT access token
    Service->>Service: Generate refresh token (UUID)
    Service->>DB: Store hashed refresh token
    Service->>Cache: Cache user session
    Service-->>API: Tokens + User
    API-->>User: 200 OK
                

Login Flow (With 2FA)

When 2FA is enabled, the user must verify their identity with an OTP before receiving tokens.

sequenceDiagram
    participant User
    participant API
    participant Service
    participant Cache as Redis
    participant SMS

    User->>API: POST /auth/login
    API->>Service: login()
    Service->>Service: Validate credentials
    Service->>Service: Check is2FAenabled = true
    Service->>Service: Generate 6-digit OTP
    Service->>SMS: Send OTP via SMS
    Service->>Cache: Store 2FA session (5 min TTL)
    Service-->>API: requires2FA: true
    API-->>User: 2FA Required

    User->>API: POST /auth/verify-2fa
    API->>Service: verify2FA(token, otp)
    Service->>Cache: Get 2FA session
    Service->>Service: Verify OTP (bcrypt)
    Service->>Cache: Delete 2FA session
    Service->>Service: Generate tokens
    Service-->>API: Tokens + User
    API-->>User: 200 OK
                

Token Refresh Flow

The system implements token rotation - each refresh revokes the old token and issues a new one.

1
Client sends refresh token
POST /auth/refresh with the refresh token in request body
2
Server validates token
Compare against hashed tokens in database using bcrypt
3
Revoke old token
Mark the used refresh token as revoked (isRevoked = true)
4
Issue new tokens
Generate new access token (JWT) and refresh token (UUID)
i
Token Rotation Security
Each refresh operation invalidates the previous refresh token. This limits the damage window if a token is compromised.

Session Management

Method Endpoint Description
GET /auth/sessions List all active sessions with device info
DELETE /auth/sessions/:id Revoke a specific session
POST /auth/logout Logout current device
POST /auth/logout-all Logout from all devices

OTP Security Configuration

4 Authorization (RBAC)

Fine-grained access control using CASL with hierarchical roles and company-scoped isolation.

Role Hierarchy

graph TD
    SA["Super Admin"] --> DA["Dealer Admin"]
    DA --> ST["Staff"]
    DA --> AU["Auditor"]
    SA --> CU["Customer"]

    SA -->|"Manage ALL"| ALL["All Resources"]
    DA -->|"Manage Company"| COMP["Company Resources"]
    ST -->|"Create Own"| OWN["Own Resources"]
    AU -->|"Read Only"| READ["Company Data"]
    CU -->|"Public Access"| PUB["Public + Own Data"]
                

Permission Matrix

Resource Super Admin Dealer Admin Staff Auditor Customer
Users CRUD all CRUD company Read company, Update self Read company Read/Update self
Cars CRUD all CRUD company CRUD own Read company Read public
Companies CRUD all Read/Update own Read own Read own Read public
Roles CRUD all Read - - -
Requests CRUD all CRUD company Read company Read company Create, Read own

Authorization Flow

sequenceDiagram
    participant Request
    participant AuthGuard
    participant CaslGuard
    participant CompanyGuard
    participant Controller

    Request->>AuthGuard: JWT Token
    AuthGuard->>AuthGuard: Validate & decode JWT
    AuthGuard->>CaslGuard: User context

    CaslGuard->>CaslGuard: Build ability for role
    CaslGuard->>CaslGuard: Check @CheckPolicies

    CaslGuard->>CompanyGuard: Authorized
    CompanyGuard->>CompanyGuard: Check @RequireCompany
    CompanyGuard->>Controller: Execute handler
                
!
Security: Company ID Resolution
Company ID for operations is always extracted from the authenticated user's session, never from the request body. This prevents users from creating resources for other companies.

5 Car Management

Complete car inventory management with filtering, bulk operations, and image handling.

Car Creation Flow

flowchart TD
    A["POST /car"] --> B{"Authenticated?"}
    B -->|No| C["401 Unauthorized"]
    B -->|Yes| D{"Has permission?"}
    D -->|No| E["403 Forbidden"]
    D -->|Yes| F["Resolve company from session"]
    F --> G{"Company resolved?"}
    G -->|No| H["403 Company required"]
    G -->|Yes| I["Validate brand"]
    I --> J["Start transaction"]
    J --> K["Create car record"]
    K --> L["Commit transaction"]
    L --> M["Return car data"]
                

Filtering Parameters

Parameter Type Description
brandIdUUIDFilter by car brand
companyIdUUIDFilter by dealer company
minPrice / maxPricenumberPrice range filter
yearnumberManufacturing year
bodyTypeenumSEDAN, SUV, VAN, TRUCK, etc.
fuelTypeenumPETROL, DIESEL, HYBRID, ELECTRIC
transmissionenumAUTOMATIC, MANUAL
statusenumAVAILABLE, SOLD, FEATURED

Bulk Operations

Bulk Status Update

Update status for up to 100 cars at once. Returns success/failure count per car.

Bulk Delete

Soft delete up to 100 cars. Only cars owned by the user's company can be deleted.

Bulk Import

Import up to 50 cars from JSON. Returns created count and error details for failures.

API Endpoints

Method Endpoint Description Auth
GET /car List cars with filtering Public
GET /car/:id Get car details Public
GET /car/stats Platform statistics Public
POST /car Create car listing Dealer
PATCH /car/:id Update car Owner
DELETE /car/:id Soft delete car Owner
POST /car/:id/images Upload car images Owner
PATCH /car/bulk/status Bulk status update Dealer
DELETE /car/bulk Bulk delete Dealer
POST /car/import Bulk import from JSON Dealer

6 Company Management

Multi-tenant dealer management with tiered subscription levels and location support.

Company Tiers

BRONZE

Basic tier - default for new dealers with standard visibility.

SILVER

Standard tier with enhanced search visibility and analytics.

GOLD

Premium tier with priority listing and featured placements.

PLATINUM

Enterprise tier with full features and dedicated support.

Data Model

erDiagram
    Company ||--o{ Car : "has"
    Company ||--o{ User : "employs"
    Company ||--o| Location : "located at"

    Company {
        uuid id PK
        string name
        string email UK
        string phoneNumber
        enum companyLevel
        json socialHandle
        int yearsOfExperience
        string companyLogo
        boolean isActive
    }

    Location {
        uuid id PK
        string city
        string country
        string physicalAddress
        decimal latitude
        decimal longitude
    }
                

API Endpoints

Method Endpoint Description
GET /company List companies (public)
GET /company/:id Get company details
POST /company Create company
POST /company/search Search companies
PATCH /company/:id Update company
POST /company/:id/company-logo Upload company logo

7 File Uploads

Flexible file storage with Sharp-based image processing and intelligent caching.

Upload Architecture

flowchart TD
    A["Client uploads file"] --> B["UploadController"]
    B --> C["ImageProcessor"]
    C --> D{"Validate image"}
    D -->|Invalid| E["400 Error"]
    D -->|Valid| F["Resize & Compress"]
    F --> G["Convert format"]
    G --> H{"Storage Provider?"}
    H -->|Local| I["LocalStorageService"]
    H -->|S3| J["S3StorageService"]
    I --> K["Save metadata to DB"]
    J --> K
    K --> L["Invalidate cache"]
    L --> M["Return upload info"]
                

Image Processing Pipeline

1
Validation
Check format (JPEG, PNG, GIF, WebP, AVIF) and file size limits
2
Resize
Scale to max dimensions (2000x2000) maintaining aspect ratio
3
Compress
Apply quality setting (default: 80%) for optimal file size
4
Convert
Transform to target format (default: WebP for web optimization)

Storage Providers

Provider Configuration URL Format
Local STORAGE_PROVIDER=local {APP_BASE_URL}/uploads/{type}/{filename}
AWS S3 STORAGE_PROVIDER=s3 https://{bucket}.s3.{region}.amazonaws.com/...

Caching Strategy

8 Notification System

Multi-channel notifications with pluggable driver architecture for SMS and Email delivery.

Driver Architecture

flowchart TD
    subgraph "Notification Service"
        A["sendSMS / sendEmail"] --> B{"Get active driver"}
    end

    subgraph "SMS Drivers"
        B --> C1["Twilio"]
        B --> C2["Brevo"]
        B --> C3["Africa's Talking"]
        B --> C4["Termii"]
        B --> C5["Console"]
    end

    subgraph "Email Drivers"
        B --> D1["SMTP"]
        B --> D2["Brevo"]
        B --> D3["Console"]
    end

    C1 & C2 & C3 & C4 & C5 --> E["Track delivery status"]
    D1 & D2 & D3 --> E
                

Driver Configuration

Driver Type Environment Variables
Twilio SMS TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_SENDER_ID
Brevo SMS/Email BREVO_API_KEY, BREVO_SMS_SENDER_ID
Africa's Talking SMS AT_API_KEY, AT_USERNAME, AT_SENDER_ID
Termii SMS TERMII_API_KEY, TERMII_SENDER_ID
SMTP Email SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD
Console Both No config required (logs to console for development)

Rate Limits

Endpoint Rate Limit Window
POST /notification/email 5 requests per minute
POST /notification/sms 3 requests per minute
POST /notification/otp 3 requests per 5 minutes

9 Customer Features

Personalized customer experience with favorites, activity tracking, and analytics.

Saved Cars Flow

flowchart LR
    A["Customer"] -->|Save| B["POST /customer/saved-cars/:carId"]
    A -->|Unsave| C["DELETE /customer/saved-cars/:carId"]
    A -->|List| D["GET /customer/saved-cars"]

    B --> E[("saved_cars table")]
    C --> E
    D --> E
                

Activity Types

Activity Type Description Metadata Example
CAR_VIEWViewed a car listingcarId, source
CAR_SEARCHSearched for carsquery, filters
CAR_SAVESaved car to favoritescarId
CAR_UNSAVERemoved from favoritescarId
CONTACT_REQUESTContacted dealerdealerId, carId
PROFILE_UPDATEUpdated profilefields changed
LOGINLogged indevice, IP address

Data Retention Policy

10 Request Management

Managing customer inquiries, dealer applications, and financial quote requests.

Request Lifecycle

flowchart TD
    subgraph "Call Requests"
        A1["Customer"] -->|"Wants callback"| B1["Create request"]
        B1 --> C1["PENDING"]
        C1 --> D1["CONTACTED"]
        D1 --> E1["COMPLETED"]
    end

    subgraph "Dealer Applications"
        A2["New Dealer"] -->|"Apply"| B2["Submit application"]
        B2 --> C2["PENDING"]
        C2 --> D2["UNDER_REVIEW"]
        D2 --> E2["APPROVED / REJECTED"]
    end

    subgraph "Financial Quotes"
        A3["Customer"] -->|"Finance inquiry"| B3["Submit request"]
        B3 --> C3["PENDING"]
        C3 --> D3["QUOTED"]
        D3 --> E3["CLOSED"]
    end
                

Call Request Flow

sequenceDiagram
    participant Customer
    participant API
    participant DB
    participant Dealer

    Customer->>API: POST /call-request
    Note over API: No auth required
    API->>DB: Create status: PENDING
    API-->>Customer: Request submitted

    Dealer->>API: GET /call-request
    API->>DB: Query requests
    API-->>Dealer: Pending requests

    Dealer->>API: PATCH /call-request/:id
    API->>DB: Update status
    API-->>Dealer: Updated
                

Financial Quote Types

CASH

Full payment purchase inquiry for immediate sale.

FINANCE

Loan financing with configurable down payment and terms.

LEASE

Monthly lease arrangement with flexible duration.

TRADE_IN

Exchange existing vehicle as part of purchase.

11 Scheduled Jobs

Automated maintenance tasks for system health and data hygiene.

Job Schedule Description
Expired Token Cleanup Every hour Remove expired refresh tokens from database
Revoked Token Cleanup Daily at midnight Remove revoked tokens older than 7 days
OTP Cleanup Every 30 minutes Remove expired OTP records
Used OTP Cleanup Daily at 1 AM Remove used OTPs older than 24 hours
Anonymous Activity Cleanup Weekly (Sat 2 AM) Remove anonymous activities older than 30 days
Registered Activity Cleanup Monthly (1st 3 AM) Remove registered activities older than 365 days
Cache Warming Every 5 minutes Pre-warm upload caches for recent entities

12 Health Checks

Kubernetes-ready health endpoints for monitoring and orchestration.

Endpoint Purpose Response
GET /health Basic health check {"status": "healthy", "uptime": 123}
GET /health/ready Readiness probe 200 OK if ready, 503 Service Unavailable if not
GET /health/live Liveness probe {"status": "alive"}
OK
Kubernetes Ready
The /health/ready and /health/live endpoints are designed for K8s readiness and liveness probes respectively.