# How to Implement Backend Patterns in ECC: A Complete Guide to Scalable Node.js Architecture

> Implement backend patterns in ECC using repository interfaces, service layers, and middleware for secure, scalable Node.js and Next.js APIs. Get the complete guide now.

- Repository: [Affaan Mustafa/ECC](https://github.com/affaan-m/ECC)
- Tags: how-to-guide
- Published: 2026-05-26

---

**Implement backend patterns in ECC by combining repository interfaces, service layers, and middleware wrappers defined in [`skills/backend-patterns/SKILL.md`](https://github.com/affaan-m/ECC/blob/main/skills/backend-patterns/SKILL.md) to build secure, scalable Node.js and Next.js APIs.**

Everything Claude Code (ECC) provides production-ready architectural guidelines for building server-side components in the `affaan-m/ECC` repository. These patterns help developers implement backend patterns in ECC projects using TypeScript, covering everything from data access abstraction to Redis caching and JWT authentication.

## Core Architectural Patterns

ECC organizes backend architecture into discrete, composable layers that separate concerns and improve testability.

### RESTful API Design

Start every service with clear resource-based URLs using plural, kebab-case naming and proper HTTP verbs. According to [`skills/backend-patterns/SKILL.md`](https://github.com/affaan-m/ECC/blob/main/skills/backend-patterns/SKILL.md), ECC demonstrates standard CRUD routes for resources like `markets` with query-parameter conventions for filtering, sorting, and pagination.

### Repository Pattern for Data Access

Define a technology-agnostic interface such as `MarketRepository` that declares data-layer operations (`find`, `create`, `update`, `delete`). Concrete implementations like `SupabaseMarketRepository` encapsulate storage-specific logic while keeping business logic decoupled from database vendors.

### Service Layer Implementation

Business rules live in service classes like `MarketService` that consume repository interfaces. This layer handles complex operations such as vector search, embedding generation, and result sorting, ensuring controllers remain thin and focused on HTTP concerns.

### Middleware for Cross-Cutting Concerns

Wrap API handlers with reusable middleware functions such as `withAuth` to enforce authentication, attach request-scoped data, and handle errors uniformly before they reach route handlers.

## Database Optimization Patterns

ECC provides specific guidance for efficient database interactions that prevent common performance anti-patterns.

### Selective Column Queries

Avoid `SELECT *` queries by specifying only required columns. The pattern uses syntax like `select('id, name, status, volume')` to minimize data transfer and memory overhead.

### N+1 Query Prevention

Batch fetch related entities and map them back to parent objects in a single round-trip. This pattern eliminates the typical ORM performance issue where iterating over collections triggers individual database queries.

### Transaction Management

Use Supabase RPC calls or raw SQL `BEGIN ... COMMIT` blocks to ensure atomic operations. The transaction pattern ensures that multi-step operations complete entirely or roll back without leaving partial data modifications.

## Caching and Performance Strategies

Implementing backend patterns in ECC includes robust caching layers to reduce database load and improve response times.

### Cache-Aside Pattern with Redis

Create a decorator class `CachedMarketRepository` that wraps a base repository implementation. This pattern checks the Redis cache before querying the database and populates the cache on misses with a configurable TTL.

```typescript
// src/lib/repositories/cachedMarketRepository.ts
import { MarketRepository } from '@/lib/repositories';
import { RedisClient } from '@/lib/redis';

export class CachedMarketRepository implements MarketRepository {
  constructor(
    private baseRepo: MarketRepository,
    private redis: RedisClient
  ) {}

  async findById(id: string) {
    const cached = await this.redis.get(`market:${id}`);
    if (cached) return JSON.parse(cached);

    const market = await this.baseRepo.findById(id);
    if (market) {
      await this.redis.setex(`market:${id}`, 300, JSON.stringify(market));
    }
    return market;
  }
}

```

### Explicit Cache Functions

For simpler use cases, implement helper functions like `getMarketWithCache` that centralize cache logic and TTL management without requiring full repository decoration.

## Error Handling and Resilience

ECC emphasizes centralized error management to ensure consistent API responses across all endpoints.

### Centralized Error Handling

Implement an `errorHandler` function that distinguishes between application errors (`ApiError`), validation errors (`ZodError`), and unexpected failures. Controllers wrap logic in `try/catch` blocks and delegate to this handler for standardized JSON responses.

### Retry Logic with Exponential Backoff

Use the `fetchWithRetry` utility for external API calls, implementing exponential back-off to handle transient network failures gracefully without overwhelming downstream services.

## Security and Access Control

### JWT Authentication

Validate tokens using the `verifyToken` function, which retrieves the secret from `process.env.JWT_SECRET`. This pattern ensures stateless authentication for API routes.

### Role-Based Access Control

Implement permission checks using higher-order functions like `hasPermission` and `requirePermission`. These wrappers enforce authorization logic before executing route handlers.

```typescript
// src/app/api/markets/[id]/route.ts
import { DELETE as deleteHandler } from '@/lib/handlers';
import { requirePermission } from '@/lib/auth';

export const DELETE = requirePermission('delete')(deleteHandler);

```

### Rate Limiting Strategies

Configure rate limiting using a shared store such as Redis, an API gateway, or platform-provided limiters. ECC explicitly warns against in-process counters that reset when scaling horizontally.

## Background Processing and Observability

### Job Queue Implementation

Process asynchronous tasks serially using the generic `JobQueue<T>` class. This pattern suits background operations such as search indexing, email sending, or data aggregation without blocking request threads.

### Structured Logging

Emit JSON-structured logs using a `Logger` utility that includes request IDs, user IDs, and error stacks. This format enables efficient log aggregation and alerting in production environments.

## Complete Implementation Example

Wire together the repository, service, and middleware patterns in a Next.js API route:

```typescript
// src/app/api/markets/route.ts
import { NextResponse } from 'next/server';
import { withAuth } from '@/lib/middleware';
import { SupabaseMarketRepository } from '@/lib/repositories';
import { MarketService } from '@/lib/services';
import { errorHandler } from '@/lib/error';

const repo = new SupabaseMarketRepository();
const service = new MarketService(repo);

export const GET = withAuth(async (req) => {
  try {
    const markets = await service.searchMarkets(req.query.get('q') ?? '');
    return NextResponse.json({ success: true, data: markets });
  } catch (err) {
    return errorHandler(err, req);
  }
});

export const POST = withAuth(async (req) => {
  // Implementation for creating markets
});

```

## Summary

- **Repository Pattern**: Isolate data access behind interfaces like `MarketRepository` to swap storage implementations without affecting business logic.
- **Service Layer**: Encapsulate complex operations in `MarketService` classes to keep controllers focused on HTTP transport.
- **Middleware**: Use wrappers like `withAuth` and `requirePermission` to handle cross-cutting concerns uniformly.
- **Caching**: Implement `CachedMarketRepository` or explicit cache functions using Redis to reduce database load.
- **Error Handling**: Centralize error processing in `errorHandler` and use `fetchWithRetry` for resilient external calls.
- **Security**: Combine JWT validation (`verifyToken`) with role-based access control (`requirePermission`) and shared-store rate limiting.

## Frequently Asked Questions

### What file contains the backend pattern definitions in ECC?

The primary documentation lives in [`skills/backend-patterns/SKILL.md`](https://github.com/affaan-m/ECC/blob/main/skills/backend-patterns/SKILL.md) within the `affaan-m/ECC` repository. A localized version for the KiRo documentation system exists at [`.kiro/skills/backend-patterns/SKILL.md`](https://github.com/affaan-m/ECC/blob/main/.kiro/skills/backend-patterns/SKILL.md), and Chinese translations are available at [`docs/zh-CN/skills/backend-patterns/SKILL.md`](https://github.com/affaan-m/ECC/blob/main/docs/zh-CN/skills/backend-patterns/SKILL.md).

### How does ECC implement the cache-aside pattern?

ECC implements cache-aside through decorator classes like `CachedMarketRepository` that wrap base repositories. These classes check Redis first via `redis.get()`, return cached data if present, or query the database and populate the cache using `redis.setex()` with a TTL (typically 300 seconds).

### What authentication mechanisms does ECC support?

ECC supports JWT token validation via `verifyToken` for stateless authentication and role-based access control through `hasPermission` and `requirePermission` higher-order functions. The patterns require storing `JWT_SECRET` in environment variables and wrapping sensitive routes with authentication middleware.

### How does ECC prevent the N+1 query problem?

The repository recommends batch fetching related entities and manually mapping them back to parent objects rather than relying on ORM lazy loading. This approach retrieves all necessary data in a single query, preventing the performance degradation caused by iterative database calls within loops.