Skip to content

Repository Template

This template provides a standard structure for creating new repositories in the PRS system, extending the BaseRepository class.

Usage Instructions

  1. Replace EntityName with your entity name
  2. Implement the methods below
  3. Register the repository in the container

Template Code

JavaScript
/**
 * Template for creating a new repository
 * 
 * Instructions:
 * 1. Replace EntityName with your entity name
 * 2. Implement the methods below
 * 3. Register the repository in the container
 */
const BaseRepository = require('../../infra/repositories/baseRepository');

class EntityNameRepository extends BaseRepository {
  constructor({ db }) {
    super(db.entityNameModel);
    this.db = db;
    this.Sequelize = db.Sequelize;
  }

  /**
   * Find all entities with optional filtering and pagination
   * 
   * @param {Object} options - Query options
   * @returns {Promise<Object>} - Paginated list of entities
   */
  async findAll(options = {}) {
    // Add any custom logic for finding all entities
    return super.findAll(options);
  }

  /**
   * Find one entity by criteria
   * 
   * @param {Object} options - Query options
   * @returns {Promise<Object>} - Entity object
   */
  async findOne(options = {}) {
    // Add any custom logic for finding one entity
    return super.findOne(options);
  }

  /**
   * Create a new entity
   * 
   * @param {Object} data - Entity data
   * @param {Object} options - Query options
   * @returns {Promise<Object>} - Created entity
   */
  async create(data, options = {}) {
    // Add any custom logic for creating an entity
    return super.create(data, options);
  }

  /**
   * Update an entity
   * 
   * @param {Object} where - Criteria for finding entity to update
   * @param {Object} data - Updated entity data
   * @param {Object} options - Query options
   * @returns {Promise<Array>} - [rowsUpdated, updatedEntities]
   */
  async update(where, data, options = {}) {
    // Add any custom logic for updating an entity
    return super.update(where, data, options);
  }

  /**
   * Delete an entity
   * 
   * @param {Object} where - Criteria for finding entity to delete
   * @param {Object} options - Query options
   * @returns {Promise<number>} - Number of deleted entities
   */
  async destroy(where, options = {}) {
    // Add any custom logic for deleting an entity
    return super.destroy(where, options);
  }

  // Custom query methods...
}

Key Features

  1. Inheritance: Extends BaseRepository for common functionality
  2. Sequelize Integration: Uses Sequelize for database operations
  3. Customizable Methods: Override base methods for custom behavior
  4. Advanced Queries: Support for complex queries and aggregations
  5. Association Handling: Support for including related data

Common Methods

  1. findAll: Retrieve all entities with optional filtering and pagination
  2. findOne: Retrieve a single entity by criteria
  3. create: Create a new entity
  4. update: Update an existing entity
  5. destroy: Delete an entity

Advanced Query Examples

JavaScript
async findByStatus(status) {
  return this.findAll({
    where: { status },
    include: [
      {
        model: this.db.userModel,
        as: 'createdByUser',
        attributes: ['id', 'firstName', 'lastName', 'username'],
      },
    ],
    order: [['createdAt', 'DESC']],
    paginate: false, // Return all results without pagination
  });
}

Complex Conditions

JavaScript
async findWithComplexConditions(filters) {
  const { status, createdBy, fromDate, toDate } = filters;

  const where = {};

  if (status) {
    where.status = status;
  }

  if (createdBy) {
    where.createdBy = createdBy;
  }

  if (fromDate || toDate) {
    where.createdAt = {};

    if (fromDate) {
      where.createdAt[this.Sequelize.Op.gte] = new Date(fromDate);
    }

    if (toDate) {
      where.createdAt[this.Sequelize.Op.lte] = new Date(toDate);
    }
  }

  return this.findAll({
    where,
    include: [
      // Add associations as needed
    ],
    order: [['createdAt', 'DESC']],
  });
}

Aggregation Queries

JavaScript
async getAggregatedData(filters) {
  const { groupBy, status } = filters;

  const where = {};

  if (status) {
    where.status = status;
  }

  const attributes = [
    [this.Sequelize.fn('COUNT', this.Sequelize.col('id')), 'count'],
  ];

  if (groupBy === 'status') {
    attributes.unshift('status');

    return this.model.findAll({
      attributes,
      where,
      group: ['status'],
      raw: true,
    });
  }

  // Additional aggregation options...
}

Best Practices

  1. Extend BaseRepository for common functionality
  2. Use Sequelize operators for complex conditions
  3. Include related data using associations
  4. Use transactions for write operations
  5. Implement custom query methods for specific business needs