code-enforce-layers

Enforce layered architecture for TanStack Start code changes across routes, components, hooks, queries, server functions, use cases, and database access.

22|3|Updated Jul 28, 2024
One-click install
npx skills add https://github.com/webdevcody/go-mailing-list --skill code-enforce-layers
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: code-enforce-layers
Source: https://github.com/webdevcody/go-mailing-list/tree/main/.claude/skills/code-enforce-layers
Command: npx skills add https://github.com/webdevcody/go-mailing-list --skill code-enforce-layers

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

It prevents accidental coupling between UI routes/components, server functions, and database access so your TanStack Start app stays maintainable and testable as features grow.

Core Features & Use Cases

  • Fixed dependency chain: Enforces that routes/components/hooks/queries call server functions in src/fn/, which only call use cases or data-access, with Drizzle/database calls confined to src/data-access/.
  • Correct placement for infra I/O: Ensures third-party SDK calls (e.g., Stripe, S3/R2 presigning, email send) are wrapped and placed under src/data-access/ and invoked from fn/use cases instead of being called directly from fn/ or use-cases.
  • Query correctness with TanStack Query: Requires queryOptions and query keys to live in src/queries/ and be reused by hooks and route loaders via ensureQueryData to avoid cache key drift.
  • Business-rule guardrails: Routes multi-step invariants (plan limits, ownership across entities, cross-entity orchestration) into src/use-cases/, keeping data-access as a thin DB shim.
  • Auth boundary clarity: Keeps authentication/ownership checks at the fn handler boundary (with authenticatedMiddleware and row ownership comparisons), not inside data-access or use cases.

Quick Start

Ask the AI to add or change a feature by following the dependency chain and placing database access only in src/data-access/, business rules only in src/use-cases/, and query/mutation behavior through src/queries/ and src/hooks/ with no cross-layer shortcutting.

Frequently Asked Questions about code-enforce-layers

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I enforce layered architecture in TanStack Start to prevent coupling between UI and database access?

Enforcing layered architecture in TanStack Start requires a fixed dependency chain where routes and components call server functions, which then invoke use cases or data-access layers, keeping database calls isolated. This prevents accidental coupling and maintains testability.

Where should Drizzle queries and third-party SDK calls be placed in a layered architecture?

Drizzle queries and third-party SDK calls must be confined to the data-access layer. Wrapping infrastructure I/O like Stripe or S3 presigning in this layer ensures server functions and use cases invoke them indirectly rather than calling external services directly.

How do I manage TanStack Query keys and options to avoid cache drift across routes and hooks?

To avoid cache key drift, centralize queryOptions and query keys in a dedicated queries directory. Reuse these centralized definitions in hooks and route loaders via ensureQueryData to maintain consistent caching behavior across the application.

Where should authentication and ownership checks be placed in a server function architecture?

Authentication and ownership checks belong at the server function handler boundary. Keeping auth logic at this boundary, using authenticatedMiddleware and row ownership comparisons, prevents it from leaking into data-access or use-case layers.

How do I separate business rules from database access logic in a full-stack TypeScript application?

Separate business rules from database access by routing multi-step invariants, plan limits, and cross-entity orchestration into dedicated use cases. This keeps the data-access layer as a thin database shim, maintaining clear architectural boundaries.

What is the best way to structure server functions and data access in TanStack Start for scalable features?

The best way to structure server functions in TanStack Start is enforcing a strict dependency chain: UI layers call server functions, which orchestrate use cases, which interact with data-access layers. This prevents architectural drift and keeps features maintainable.