Skip to content

Base Classes Documentation

This document provides an overview of the base classes implemented for the PRS Backend project as part of the DDD refactoring effort.

Overview

The following base classes have been implemented:

  1. BaseRepository: Provides standard data access methods for repository layer implementations.
  2. BaseService: Provides common CRUD operations and utilities for service layer implementations.
  3. BaseController: Provides standard response handling for controller layer implementations.

These base classes are designed to be extended by concrete implementations to reduce code duplication and ensure consistency across the codebase.

BaseRepository

The BaseRepository class provides standard data access methods for interacting with the database.

Location

Text Only
src/infra/repositories/baseRepository.js

Usage

JavaScript
const BaseRepository = require('./baseRepository');

class YourRepository extends BaseRepository {
  constructor({ db }) {
    super(db.yourModel);

    this.db = db;
    this.Sequelize = db.Sequelize;
  }

  // Add your custom repository methods here
}

module.exports = YourRepository;

Available Methods

  • create(payload, options): Creates a new record
  • update(where, payload, options): Updates existing records
  • findOne(payload): Finds a single record
  • findAll(payload): Finds all records with pagination support
  • getById(id, options): Gets a record by ID
  • destroy(where, options): Deletes records
  • upsert(payload, options): Creates or updates a record
  • bulkCreate(payload, options): Creates multiple records
  • count(payload): Counts records
  • updateById(id, payload, options): Updates a record by ID
  • destroyById(id, options): Deletes a record by ID
  • findByIds(ids, options): Finds records by a list of IDs

BaseService

The BaseService class provides common CRUD operations and utilities for service layer implementations.

Location

Text Only
src/app/services/baseService.js

Usage

JavaScript
const BaseService = require('./baseService');

class YourService extends BaseService {
  constructor(container) {
    super(container);

    const { yourRepository } = container;

    this.yourRepository = yourRepository;
  }

  // Add your custom service methods here
}

module.exports = YourService;

Available Methods

  • withTransaction(callback): Executes a callback within a transaction
  • create(repository, data, options): Creates a new record
  • update(repository, where, data, options): Updates an existing record
  • delete(repository, where, options): Deletes a record
  • getById(repository, id, options): Gets a record by ID
  • getAll(repository, query): Gets all records with pagination

BaseController

The BaseController class provides standard response handling for controller layer implementations.

Location

Text Only
src/app/handlers/controllers/baseController.js

Usage

JavaScript
const BaseController = require('./baseController');

class YourController extends BaseController {
  constructor(container) {
    super(container);

    const { yourService, entities } = container;

    this.yourService = yourService;
    this.yourEntity = entities.your;
  }

  // Add your custom controller methods here
}

module.exports = YourController;

Available Methods

  • sendSuccess(reply, data, statusCode, message): Handles successful response
  • sendCreated(reply, data, message): Handles created response
  • sendNoContent(reply): Handles no content response
  • handleError(error): Handles error response
  • validate(schema, data): Validates request data against a schema
  • executeAction(action, request, reply): Executes a controller action with error handling
  • createAction(handler): Creates a controller action with standard error handling

Example Implementations

Example implementations of each base class are provided:

  • ExampleRepository: src/infra/repositories/exampleRepository.js
  • ExampleService: src/app/services/exampleService.js
  • ExampleController: src/app/handlers/controllers/exampleController.js

These examples demonstrate how to extend and use the base classes in your own implementations.

Best Practices

  1. Always extend the base classes: Don't copy and paste the base class methods into your implementations.
  2. Use the provided methods: The base classes provide common methods that should be used instead of reimplementing them.
  3. Add custom methods: Extend the base classes with your own custom methods for domain-specific functionality.
  4. Use transactions: Use the withTransaction method in services for operations that require multiple database changes.
  5. Handle errors properly: Use the provided error handling methods in controllers.
  6. Validate input: Use the validate method in controllers to validate request data against schemas.

Benefits

Using these base classes provides several benefits:

  1. Reduced code duplication: Common functionality is implemented once and reused.
  2. Consistent error handling: Errors are handled consistently across the application.
  3. Standardized responses: API responses follow a consistent format.
  4. Transaction support: Database transactions are handled consistently.
  5. Pagination support: Pagination is handled consistently across the application.
  6. Improved maintainability: Changes to common functionality only need to be made in one place.