The Adapter Pattern
Relevant source files
The following files were used as context for generating this wiki page:
The Adapter Pattern is the foundational architectural principle of the wrelik-kit repository. It establishes a vendor-agnostic layer between application code and third-party services, ensuring that the Wrelik ecosystem remains flexible, maintainable, and resilient to vendor lock-in. By defining explicit integration boundaries, the project ensures that application repositories never interact with vendor SDKs directly.
Sources: README.md:3-6, README.md:10-15
Core Objectives and Principles
The primary purpose of implementing adapters is to standardize integrations and enforce discipline across all Wrelik applications. The architecture is designed to be "intentionally boring," treating these adapters as stable infrastructure rather than feature-rich playgrounds.
Key principles include:
- No Direct SDK Usage: Application repositories are strictly prohibited from importing third-party SDKs (e.g., Clerk, Prisma, AWS SDK).
- Minimal Surface Area: Adapters expose only the specific functionality required by the applications, reducing complexity.
- Vendor Interchangeability: Switching a service provider (e.g., changing an email provider) only requires updates within the specific adapter package rather than a full application rewrite.
- Enforced Best Practices: Centralized adapters allow for the enforcement of naming conventions and standardized error handling.
Sources: README.md:11-15, README.md:65-68, DECISIONS.md:21-25
Implementation Architecture
The architecture follows a modular monorepo structure where each adapter is isolated within the packages/ directory. Each package serves as a wrapper for a specific service domain.
Component Relationship
The following diagram illustrates how applications interact with the adapter layer instead of the underlying service providers:
This structure ensures that the "Application Layer" remains decoupled from the "Third-Party Vendors."
Sources: README.md:21-49, DECISIONS.md:3-15
Adapter Domains and Mappings
The project categorizes adapters into specific domains, each mapped to a primary vendor.
| Domain | Package | Vendor | Purpose |
|---|---|---|---|
| Auth | @wrelik/auth | Clerk | Session handling and RBAC. |
| Database | @wrelik/db | Neon (Prisma) | Singleton client and multi-tenant helpers. |
| Storage | @wrelik/storage | Cloudflare R2 | S3-compatible uploads and signed URLs. |
| Analytics | @wrelik/analytics | PostHog | Server-side event tracking. |
@wrelik/email | Resend | Transactional templates and delivery. | |
| Jobs | @wrelik/jobs | Inngest | Event-driven background workflows. |
| Errors | @wrelik/errors | Sentry | Centralized error tracking and typed errors. |
Sources: README.md:23-49, DECISIONS.md:5-15
Enforcement via Tooling
The project uses ESLint to programmatically enforce the Adapter Pattern. The @wrelik/eslint-config package contains no-restricted-imports rules that prevent developers from bypassing the adapters.
// packages/eslint-config/index.js
rules: {
'no-restricted-imports': [
'error',
{
paths: [
{ name: '@clerk/nextjs', message: 'Please use @wrelik/auth instead.' },
{ name: '@prisma/client', message: 'Please use @wrelik/db instead.' },
{ name: 'resend', message: 'Please use @wrelik/email instead.' },
{ name: 'posthog-node', message: 'Please use @wrelik/analytics instead.' },
{ name: 'inngest', message: 'Please use @wrelik/jobs instead.' },
],
patterns: [
{ group: ['@aws-sdk/*'], message: 'Please use @wrelik/storage instead.' },
],
},
],
}
Sources: packages/eslint-config/index.js:15-40
Data Transformation and Validation
Adapters are responsible for transforming vendor-specific data structures into internal Wrelik formats. For example, the @wrelik/auth package converts Clerk's authentication objects into a standardized session format used by the applications.
Sequence: Authentication Data Flow
The following sequence shows how a vendor-specific object is sanitized and standardized before reaching the application logic:
Summary
The Adapter Pattern in wrelik-kit serves as a strategic integration boundary. By wrapping third-party services like Clerk, Prisma, and Cloudflare R2, the project centralizes configuration, enforces security patterns (such as multi-tenant access in @wrelik/db), and ensures that the core application logic remains independent of the underlying service providers. This infrastructure-first approach minimizes the impact of vendor changes and maintains a high standard of code discipline across the ecosystem.