> ## Documentation Index
> Fetch the complete documentation index at: https://docs-kfhye.zochil.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Modules & Services

> Understanding the module structure and service organization

## Module Structure

A module is the basic building block of the Zochil API. Each module represents a specific business domain and contains two essential files: `routes.ts` and `service.ts`.

### Module Pattern

```
domain_module/
├── routes.ts    # Route definitions and Express router
└── service.ts   # Business logic and data access
```

## Routes (routes.ts)

The `routes.ts` file creates and exports an Express Router. It handles HTTP route definitions, request validation, and middleware integration.

### Example Route File

```typescript theme={null}
import { Router } from "express";
import { body as checkBody } from "express-validator";
import SomeService from "./service";
import { DBConnection } from "core/types";

export default (db: DBConnection) => {
  const routes: any = Router();
  const service = new SomeService(db);

  routes.get(
    "/list",
    service.handleOk(async (req) => await service.getAll(req.query))
  );

  routes.post(
    "/create",
    [checkBody("name").notEmpty()],
    service.handleOk(async (req) => await service.createRecord(req.body))
  );

  return routes;
};
```

### Route Responsibilities

* **Express Router**: Create and configure HTTP routes
* **Validation**: Input validation with express-validator
* **Authentication**: Apply authentication middleware
* **Response Handling**: Use `service.handleOk()` for consistent responses
* **Dependency Injection**: Receive `DBConnection` from parent router

## Services (service.ts)

The `service.ts` file contains the business logic and data access layer. All service classes extend the base `APIService` class.

### Example Service File

```typescript theme={null}
import APIService from "core/base/service";
import { DBConnection, ID } from "core/types";

export default class SomeService extends APIService {
  constructor(db: DBConnection) {
    super(db, "table_name");
  }

  async getAll(filters = {}) {
    return await this.findForList(filters);
  }

  async createRecord(data: any) {
    return await this.create(data);
  }
}
```

### Service Responsibilities

* **Business Logic**: Core domain logic and data processing
* **Database Access**: Query database using Knex.js patterns
* **Multi-tenancy**: Automatic filtering by `shop_id`/`merchant_id`
* **Error Handling**: Use `CustomError` for structured exceptions
* **Event Publishing**: Publish domain events via `this.publishEvent()`

## Base Classes

### APIService Base Class

Located at `./api/@core/base/service.ts`, provides common functionality:

```typescript theme={null}
import APIService from "core/base/service";

export default class ModuleService extends APIService {
  constructor(db: DBConnection) {
    super(db, "module_table_name");
  }

  // Inherited methods available:
  // - findForList(filters, pagination)
  // - findOneOrThrow(id)
  // - create(data)
  // - update(id, data)
  // - publishEvent(eventName, data)
}
```

### Merchant Service Composition

For merchant-related functionality, use the `MerchantService` as a composed property:

```typescript theme={null}
import APIService from "core/base/service";
import MerchantService from "core/merchants/service";
import { DBConnection } from "core/types";

export default class ModuleWithMerchant extends APIService {
  private _merchantService: MerchantService;

  constructor(db: DBConnection) {
    super(db, "module_table_name");
    this._merchantService = new MerchantService(db, "shops");
  }

  async getMerchantData(merchantId: string) {
    return await this._merchantService.findOneOrThrow(merchantId);
  }
}
```

## Database Connection

All modules receive a `DBConnection` interface containing:

```typescript theme={null}
export type DBConnection = {
  db: Knex; // PostgreSQL connection
  kv: RedisClient; // Redis connection
  paymentDB?: Knex; // Optional separate payment DB
};
```

### Database Access Patterns

* **Knex Queries**: Use `this.connector.db(tableName)` for database access
* **Multi-tenancy**: Always filter by `shop_id` or `merchant_id`
* **Transactions**: Use Knex transactions for complex operations
* **Connection Pooling**: Automatic connection management

## Authentication & Middleware

### Request Context

Authentication middlewares populate request objects with user context:

```typescript theme={null}
// Available on authenticated requests
req.currentUser; // User data (excluding sensitive fields)
req.merchant_id; // Merchant ID from headers
req.device_id; // Device ID from headers
```

### Authentication Middleware

```typescript theme={null}
import { authenticateUser, authenticateAdmin } from "core/auth/middlewares";

// In routes.ts
routes.use("*", authenticateUser(db)); // For user endpoints
routes.use("*", authenticateAdmin(db)); // For admin endpoints
```

### Authorization

Role-based access control using user context:

```typescript theme={null}
// Check user roles
if (!req.currentUser.is_super) {
  throw new CustomError("FORBIDDEN", "Super admin required");
}

// Check specific roles
if (!req.currentUser.roles.includes("merchant_manager")) {
  throw new CustomError("FORBIDDEN", "Insufficient permissions");
}
```
