Business Services Layer
Relevant source files
The following files were used as context for generating this wiki page:
- packages/services/src/index.ts
- packages/services/README.md
- README.md
- packages/services/src/ProviderCredentialService.ts (Referenced via
index.tsandREADME.md) - packages/services/src/SubscriptionService.ts (Referenced via
index.tsandREADME.md) - packages/services/src/EntitlementService.ts (Referenced via
index.tsandREADME.md) - packages/services/src/AuthService.ts (Referenced via
index.tsandREADME.md) - packages/services/src/RepositoryService.ts (Referenced via
index.tsandREADME.md)
The Business Services Layer (located in @repo/services) serves as the central repository for all domain logic within the AI Code Reviewer project. It acts as an intermediary between the transport layers (such as tRPC routers in the Next.js web app) and the data access layers (Prisma/PostgreSQL). This layer ensures that business rules—such as authorization, billing entitlements, and provider configurations—are applied consistently across the application.
Services in this layer are implemented as classes using manual constructor injection to facilitate testing and maintain clear dependency boundaries. They are designed to be "headless," meaning they contain no HTTP-specific concepts like request or response objects, allowing them to be utilized by both the web server and background workers.
Sources: packages/services/src/index.ts:1-15, packages/services/README.md:1-12, README.md:110-116
Architectural Principles
The service layer follows strict architectural rules to maintain a clean separation of concerns:
- Thin Controllers: tRPC routers and route handlers must remain "thin," focusing only on parsing input via Zod and calling the appropriate service method.
- Encapsulated Data Access: Services are the primary consumers of
@repo/db. Routers and external handlers are prohibited from touching the database directly. - Dependency Injection: Services use constructor injection for all dependencies (Prisma, feature flags, other services). A central DI container in
apps/web/src/server/container.tswires these implementations. - No Module Singletons: Business state is never stored in module-level singletons; all state and logic are contained within service instances.
Sources: packages/services/src/index.ts:3-15, packages/services/README.md:5-12, README.md:104-108
Layered Communication Flow
The following diagram illustrates how the Business Services Layer fits into the overall application request flow:
The diagram shows the standard flow where a transport layer invokes a service, which then orchestrates database operations and external API calls.
Sources: README.md:110-116, packages/services/README.md:14-18
Core Service Components
The Business Services Layer is divided into several specialized services, each handling a distinct domain of the application.
Identity and Repository Management
These services manage the lifecycle of user sessions and their connected GitHub assets.
| Service | Primary Responsibility |
|---|---|
| AuthService | Handles GitHub OAuth flows, session creation, and linking GitHub installations to user accounts. |
| RepositoryService | Manages the listing, enabling, and disabling of repositories for a given installation. |
Sources: packages/services/src/index.ts:25-28, packages/services/README.md:20-22
Billing and Entitlements
These services enforce usage limits and handle subscription state.
| Service | Primary Responsibility |
|---|---|
| SubscriptionService | Manages plan lookups and usage meters. Uses SELECT ... FOR UPDATE for race-safe meter increments. |
| EntitlementService | Evaluates if a specific installation can perform an action (e.g., a review) based on their current plan and costs. |
Sources: packages/services/README.md:25-29, packages/services/src/index.ts:22-24
Provider Configuration
The ProviderCredentialService is responsible for managing user-supplied LLM API keys. It handles the storage, validation, and decryption of these keys using @repo/crypto.
Sources: packages/services/README.md:23-24, packages/services/src/index.ts:21
Logic and Data Flow
Services often depend on each other to fulfill complex business requirements. For instance, the EntitlementService interacts with feature flags to determine if billing enforcement is globally active before checking specific plan limits.
Entitlement Check Flow
This diagram demonstrates the conditional logic within the EntitlementService where feature flags can short-circuit standard business logic.
Sources: packages/services/README.md:32-46
Summary of Logic Ownership
The following table summarizes the specific types of logic owned by the Business Services Layer as defined in the project architecture:
| Category | Logic Description |
|---|---|
| Authorization | Determining if a specific user has the rights to enable a repository. |
| Orchestration | Multi-step processes, such as enabling a repository and subsequently enqueueing an ingestion job. |
| Resolution | Identifying which LLM provider or credential should be used for a specific installation. |
| Integrity | Ensuring race-safe updates to usage meters and maintaining consistent state across database tables. |
Sources: packages/services/src/index.ts:7-12, packages/services/README.md:26-28
The Business Services Layer provides a robust, testable foundation for the application's core functionality. By centralizing logic here, the project ensures that as it scales—adding new RAG layers or complex retrieval services—the rules governing the system remain decoupled from the specifics of the web framework or background worker implementation.