agentsclimarketplace

Software principles

Skill hilmifawwazsaad/ExpressJS-ts-Boilerplate/.agents/software-principles

Engineering principles for all code in this Express.js TypeScript project. Required reading before any code generation.From its SKILL.md

Install
npx -y skills add hilmifawwazsaad/ExpressJS-ts-Boilerplate --skill software-principles

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

6.2 KB, ~1.2k tokens by cl100k_base, as published. Nobody here has run it

Pre-Code Checklist

  1. One reason to change? If not — split it (SRP)
  2. Simpler solution with same outcome? — use it (KISS)
  3. Building for a future need that doesn't exist yet? — delete it (YAGNI)
  4. Name reveals intent without generic words? (and, data, info, manager, handle) — if not, rethink

Principles

PrincipleRuleSignalFix
SRP — Single ResponsibilityOne unit, one reason to changeand in name · file > 200 lines · fn > 20 linesSplit
OCP — Open/ClosedExtend without modifying existing codeAdding a variant by editing internalsNew module/strategy
DIP — Dependency InversionDepend on abstractions, not concretionsnew ConcreteService() hardcoded in logicInject dependencies
DRY — Don't Repeat YourselfOne source of truth per piece of logicCopy-paste logic across filesExtract to shared module
KISS — Keep It SimpleSimplest correct solutionUnnecessary abstraction · deep indirectionRemove layers · flatten
YAGNI — You Aren't Gonna Need ItBuild only what is needed nowUnused params · "might need later" codeDelete it
SoC — Separation of ConcernsEach module owns one concernBusiness logic mixed with request handlingSeparate into layers
LoD — Law of DemeterTalk only to direct collaboratorsa.b.c.method() chainsAdd intermediate method
Fail FastSurface errors at earliest pointSilent catch · late validationValidate at boundaries · throw early
SSOT — Single Source of TruthOne authoritative place per logicSame validation in multiple layersCentralize · import everywhere

Naming

Generic names destroy readability. Names must reveal intent.

ConceptPatternGoodBad
Functionsverb phrasegetUserById, validateEmail, hashPasswordhandle, process, doStuff, run
Booleansis / has / can prefixisActive, hasPermission, canDeleteactive, flag, check, status
Variablesnoun, specificuserId, paginatedUsers, hashedPassworddata, result, info, temp
Files[domain].[layer].tsuser.service.ts, auth.middleware.tsutils2.ts, misc.ts, helpers.ts

Rules: no abbreviations (except id, req, res, err, ctx) · no single-letter names outside loop counters.

Function Design

RuleLimitWhen exceeded
Single responsibilityOne actionSplit into smaller functions
Length≤ 20 linesExtract to named helper
Parameters≤ 3Group into options object
Nesting≤ 2 levelsEarly return (guard clause)
Return pathsPrefer single exitGuard clauses at top, one return at bottom

Applied to This Project

Express.js TypeScript — layered architecture (routes → handlers → services → repositories).

PrincipleExample
SRPUserService owns one domain — no mixing auth logic into user service
SoCHandlers receive/respond · services own logic · repositories own DB — never mix
DRYShared types in types/ · validation schema once in validations/ via z.infer
Fail Fastconfig/env.ts throws at startup if env vars missing · validate req.body at handler boundary
SSOTError classes → utils/errors.ts · env vars → config/env.ts
YAGNINo abstraction until needed by 2+ consumers
KISSHandler calls one service method — no orchestration logic in handlers
DIPServices depend on repository interfaces, not concrete implementations

Async Error Handling

  • Catch only where you can meaningfully recover
  • Never catch and return null/undefined — throw a typed error instead
  • Always propagate to Express error middleware via next(err)

Testing

  • Unit test pure functions and services in isolation
  • Integration test at route boundaries — not implementation details
  • Don't mock what you own; mock external services only
  • One assertion per test concept

Never Do

  • Name anything data, result, info, temp, manager, handleX, processX
  • Functions > 20 lines · parameters > 3 · nesting > 2 levels — split or group
  • as any or as unknown as T to bypass type checks — fix the actual type
  • Put business logic in handlers or routes — extract to service

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,851. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.