Skip to content

Latest commit

 

History

History
32 lines (23 loc) · 1.92 KB

File metadata and controls

32 lines (23 loc) · 1.92 KB

We prioritize type safety, testability, and clear separation of concerns using Effect-TS.

Core Architecture

1. API Contracts (@adequate/api)

We separate API Configuration from Implementation.

  • The Contract: Routes, schemas, and error definitions live in packages/api. These are shared with the frontend to ensure end-to-end type safety.
  • Enforcement: The compiler ensures your backend implementation strictly matches the contract. You cannot deploy a route that doesn't handle its declared errors.

2. Testable Domain Services

Business logic is decoupled from infrastructure (DB, Auth) using Context Tags.

  • Fast Feedback: Write unit tests (e.g., loan.service.test.ts) that verify complex rules without needing a running database or network.
  • Portability: Services are pure logic, making them easy to move or refactor.

3. Type Safety & Error Handling

We treat type safety as a law, not a suggestion.

  • Build-Time Safety: If you change a schema or fail to handle a DatabaseError, the build will fail. This eliminates entire classes of runtime crashes.
  • Explicit Effects: Using Effect-TS, every failure path must be acknowledged. We don't use global "catch-all" exceptions; we handle errors gracefully where they occur.

4. Infrastructure

  • Drizzle ORM: Database types are automatically generated and synced with our domain models.
  • Cloudflare Integration: Environment bindings are managed via FiberRef to keep domain logic clean and independent of the platform.

Dev Workflow

When implementing a new feature, follow this "Contract-First" flow:

  1. Define the Contract: Add your routes and effect schemas to packages/api.
  2. Implement the Service: Write the business logic in a domain service using Effect tags.
  3. Write the Handler: Map your service logic to the API route.
  4. Wire the Runtime: Register the new implementation in the application layers.