mcpField
A
architecture

architecture

github.com/liaoannDevelopment044 installsUpdated 4w ago
Repository

About architecture

An architecture skill for developers maintaining codebases as they grow. It emphasizes domain-oriented organization, clear module boundaries, acyclic dependencies, thin transport layers, and authorization on protected request paths.

Key features

  1. 01Organize code by domain
  2. 02Communicate through public APIs
  3. 03Keep dependency graphs acyclic
  4. 04Keep transport logic thin
  5. 05Authorize on the request path

Use cases

  1. 01Plan directories for new features
  2. 02Reduce cross-module internal imports
  3. 03Identify and break dependency cycles
  4. 04Review handler logic and authorization placement

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/liaoann/skills --skill architecture

After installing, type/architecturein Claude Code to confirm it loaded.

Details

From the project README

Architecture

Principles for keeping a codebase navigable as it grows. Apply against the project's own conventions — these are defaults, not overrides for a repo that already has a documented structure.

Organize by Domain, Not by Layer

Group code by the capability it serves, so one feature can be understood by exploring one area:

features/
  bookings/      ← services, data access, UI, tests for bookings
  availability/  ← services, data access, UI, tests for availability

Avoid top-level technical layers (controllers/, services/, repositories/) when they scatter one domain change across many directories. Local technical subfolders inside a feature are fine when they make that feature easier to navigate.

Communicate Through Public APIs

A feature imports another feature only through its public entry point, never by reaching into internal files:

// ❌ reaching into internals
import { calculateSlots } from "features/availability/services/internal/slotCalculator";

// ✅ through the public API
import { getAvailability } from "features/availability";

Put domain-agnostic utilities (logging, auth, generic helpers) in a shared low-level module; put shared UI primitives in a shared UI module. Enforce import boundaries with lint rules where the toolchain allows.

Keep the Dependency Graph Acyclic

Dependencies should flow one direction, from lower-level shared code toward higher-level application entry points:

shared utils → shared domain modules → features → transport/API → app entry

Lower layers must not import higher ones. A utility that imports a feature, or two features that import each other, is a cycle — it causes build failures, type errors, and a structure that no longer reflects what depends on what. Break cycles by extracting the shared piece downward.

Keep Transport Thin

HTTP handlers, RPC routers, CLI commands, queue consumers, and UI event handlers are delivery mechanisms. They should validate input, adapt it into application data, call the domain/application code, and adapt the result back out.

Do not let a transport boundary become the place where business decisions, persistence details, or complex orchestration accumulate. If the same behavior would be needed from another transport, move it behind a domain-facing interface.

Place Authorization on the Request Path

This is a placement decision like the rest of this skill: a guard belongs at the boundary it actually protects, not one level out where coverage is assumed but not guaranteed.

Put the authorization check on the path every request provably passes — the handler that guards the resource itself. A shared outer shell (an inherited layout, a wrapping decorator, a middleware some entry points skip) is bypassable whenever a request can reach the protected resource without traversing it. Validate identity and role before any restricted data is read, and fail closed: deny by default, redirect or return early for the unauthorized.

Completion Criterion

The change respects existing boundaries: new files sit with the capability they serve, cross-module imports go through public entry points, no import introduces a cycle or points from a lower layer to a higher one, transport code stays thin, and any authorization check sits on the protected request path rather than in a bypassable wrapper. A single violation means it is not met.

Comments

Markdown supported