Service Types Module
Overview
The Service Types module manages categorizable service types within a business. Each service type is scoped to a single business (multi-tenant) and can be activated or deactivated.
Examples: "Food Tour", "Cooking Class", "Private Tour", "Cultural Experience".
Architecture
Follows hexagonal architecture (ports & adapters):
service-types/
├── service-types.module.ts # NestJS module
├── application/
│ └── service-types.service.ts # Use cases
├── domain/
│ └── service-types-repository.domain.ts # Repository port (interface + DI token)
├── infrastructure/
│ └── service-types.repository.ts # Kysely adapter (implements port)
└── interfaces/
├── service-types.controller.ts # HTTP controller
├── dtos/
│ ├── create-service-type.dto.ts
│ └── update-service-type.dto.ts
└── query/
└── paginate-service-types.query.ts
Dependency Flow
Controller → Service → IServiceTypesRepository (port)
↑
ServiceTypesRepository (adapter)
The service depends on the domain interface, not the concrete repository. Injection is via SERVICE_TYPES_REPOSITORY Symbol token.
Domain Model
ServiceType entity:
| Field | Type | Description |
|---|---|---|
| id | UUID | Auto-generated primary key |
| name | string | Service type name |
| businessId | UUID | Owning business (multi-tenant) |
| isActive | boolean | Active/inactive flag |
| createdBy | UUID | User who created |
| updatedBy | UUID? | User who last updated |
| createdAt | timestamp | Auto-generated |
| updatedAt | timestamp | Auto-updated on changes |
API Endpoints
All endpoints require Bearer authentication and ServiceType resource permission.
POST /service-types
Create a new service type.
Body:
{
"name": "Food Tour",
"businessId": "uuid",
"isActive": true,
"createdBy": "uuid"
}
GET /service-types
List service types with pagination, search, and sorting.
Required query: businessId
Optional query: page, size, search, orderBy (name), order (asc/desc)
GET /service-types/:id
Get a single service type by ID.
Required query: businessId
PATCH /service-types/:id
Partially update a service type.
Body:
{
"name": "Updated Name",
"updatedBy": "uuid",
"businessId": "uuid"
}
DELETE /service-types/:id
Delete a service type.
Required query: businessId
Security
- Authentication: Firebase token (global
AuthGuard) - Authorization:
RolesGuard+ CASL permission checks - Resource:
PolicyResource.ServiceType - Multi-tenancy: All queries scoped by
businessId
Design Decisions
- businessId required on all operations — prevents cross-tenant data access
- Transaction support — repository methods accept optional
Transaction<DB>for composability - Delete returns void — consistent with addresses module; throws if not found
- Update DTO omits immutable fields —
businessIdandcreatedBycannot be changed through the update body;businessIdis sent separately for scoping