AgentStack
SKILL verified MIT Self-run

Review Subdomain

skill-softtor-nestjs-hexagonal-review-subdomain · by Softtor

Reviews a NestJS bounded context implementation for Hexagonal Architecture + DDD + CQRS compliance. Checks 6 dimensions — domain purity, application patterns, infrastructure isolation, presentation concerns, testing coverage, and module organization. Produces a structured Pass/Warning/Fail report.

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-softtor-nestjs-hexagonal-review-subdomain

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README — it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-softtor-nestjs-hexagonal-review-subdomain)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
4mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming — see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps — measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Review Subdomain? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

review-subdomain

Review a bounded context for architectural compliance. Accept the BC path as the argument (e.g., src/enterprise/billing/invoices). Run each dimension in order. Produce a structured report at the end.

The rubric with scoring criteria is in references/review-rubric.md.


Setup

Resolve the target directory from the argument. If no argument is given, ask the user for the path.

Verify the directory exists:

ls 

If the directory does not exist, stop and report an error.

Set BC_PATH to the resolved absolute path. All grep and glob searches below use BC_PATH as the root.


Dimension 1 — Domain Purity

Purpose: Confirm the domain layer has zero framework or infrastructure dependencies.

Run the following checks against /domain/:

Check D1 — No NestJS common imports in domain:

grep -r "@nestjs/common" /domain/ --include="*.ts" -l

FAIL if any files are returned. Exception: @nestjs/cqrs is allowed (for AggregateRoot, IEvent).

Check D2 — No class-validator in VOs:

grep -r "class-validator" /domain/value-objects/ --include="*.ts" -l

FAIL if any files are returned. class-validator is allowed in domain/validators/ only.

Check D3 — No Prisma imports in domain:

grep -r "PrismaClient\|PrismaService\|@prisma/client" /domain/ --include="*.ts" -l

FAIL if any files are returned.

Check D4 — Entity uses apply() not addDomainEvent():

grep -r "addDomainEvent\|pullDomainEvents" /domain/ --include="*.ts" -l

FAIL if any files are returned. Entities must use this.apply(event).

Check D5 — Entity has create() and restore() factories:

For each entity file found in /domain/entities/:

  • Read the file
  • Confirm static create( is present
  • Confirm static restore( is present
  • Confirm private constructor is present

FAIL if any entity is missing one of these.

Check D6 — Repository interface is a pure interface (no @Injectable):

grep -r "@Injectable" /domain/repositories/ --include="*.ts" -l

FAIL if any files are returned.

Check D7 — Data builders exist:

ls /domain/testing/helpers/

WARNING if the directory is empty or does not exist.


Dimension 2 — Application Patterns

Purpose: Confirm the application layer follows the chosen pattern correctly and does not hold framework concerns.

Check A1 — EventPublisher not in use cases:

grep -r "EventPublisher" /application/ --include="*.ts" -l

FAIL if EventPublisher appears in application/usecases/ or application/dtos/. It is allowed in application/commands/ (Pattern B/C handlers).

Check A2 — No class-validator in application DTOs:

grep -r "IsString\|IsNotEmpty\|IsEmail\|IsOptional\|IsUUID\|IsEnum\|IsNumber\|IsBoolean\|IsArray\|ValidateNested" /application/ --include="*.ts" -l

FAIL if any files are returned. class-validator belongs only in presentation request DTOs.

Check A3 — Pattern A use cases have no @Injectable:

Find files matching /application/usecases/*.usecase.ts:

grep -r "@Injectable" /application/usecases/ --include="*.ts" -l

FAIL if @Injectable appears in use case files.

Check A4 — Write handlers return void or { id: string }:

Read each command handler in /application/commands/:

  • Check the return type annotation on execute()
  • FAIL if return type is an entity class or a full output DTO with many fields
  • PASS if return type is void, Promise, { id: string }, or Promise

Check A5 — commit() called in handlers, not in use cases:

grep -r "\.commit()" /application/usecases/ --include="*.ts" -l

FAIL if .commit() appears in use case files.

Check A6 — Ports defined in application/ports/ with TOKEN symbol:

Find files in /application/ports/:

  • Each port file should export a Symbol token
grep -r "Symbol(" /application/ports/ --include="*.ts" -l

WARNING if port files exist without a Symbol( token export.


Dimension 3 — Infrastructure Isolation

Purpose: Confirm infrastructure wires domain to the outside world without leaking domain logic.

Check I1 — Module exports only tokens:

Read /infrastructure/*.module.ts:

  • Find the exports: array
  • FAIL if any class name (not a Symbol constant) appears in the exports array
  • PASS if exports contains only token constants (e.g., _REPOSITORY, _PORT_TOKEN)

Check I2 — Repository has no event dispatch:

grep -r "\.commit()\|EventBus\|EventPublisher\|publish(" /infrastructure/database/ --include="*.ts" -l

FAIL if any of these appear in repository files.

Check I3 — Mapper uses restore() not create():

grep -r "Entity\.create\|\.create(" /infrastructure/database/prisma/models/ --include="*.ts" -l

FAIL if entity create() is called inside a mapper. Mappers must call restore().

Check I4 — In-memory repository exists:

ls /infrastructure/database/in-memory/repositories/

WARNING if directory is empty or missing.

Check I5 — Event handlers use @EventsHandler not @OnEvent:

grep -r "@OnEvent" /infrastructure/listeners/ --include="*.ts" -l

FAIL if @OnEvent is used in listeners. All new domain event handlers must use @EventsHandler.

Check I6 — Event handlers have try/catch:

Read each file in /infrastructure/listeners/:

  • FAIL if handle() method does not contain a try { block

Check I7 — organizationId (or tenant id) in all Prisma queries:

Read each Prisma repository file in /infrastructure/database/prisma/repositories/:

  • Check search() has organizationId (or tenant field) in whereClause
  • WARNING if search() does not scope by tenant

Dimension 4 — Presentation Concerns

Purpose: Confirm controllers are thin HTTP adapters and request DTOs hold all input validation.

Check P1 — class-validator used only in request DTOs:

grep -r "IsString\|IsNotEmpty\|IsEmail\|IsOptional\|IsUUID\|IsEnum\|ValidateNested" /infrastructure/controllers/dtos/ --include="*.ts" -l

This should return files. If no files returned: WARNING (validation may be missing).

grep -r "IsString\|IsNotEmpty\|IsEmail\|IsOptional\|IsUUID\|IsEnum\|ValidateNested" /infrastructure/controllers/ --include="*.ts" -l

Cross-check: all results should be inside dtos/, not in the controller itself.

Check P2 — organizationId not taken from request body:

grep -r "body\.organizationId\|dto\.organizationId\|req\.body.*organizationId" /infrastructure/controllers/ --include="*.ts" -l

FAIL if organizationId is read from the request body in a controller. Must come from @CurrentOrganization().

Check P3 — Swagger decorators present:

grep -r "@ApiOperation\|@ApiResponse\|@ApiTags" /infrastructure/controllers/ --include="*.ts" -l

WARNING if no Swagger decorators found in controller files.

Check P4 — Guards applied:

grep -r "@UseGuards\|@ApiBearerAuth" /infrastructure/controllers/ --include="*.ts" -l

WARNING if no guards found on any controller.

Check P5 — No business logic in controllers:

Read each controller file. Flag as FAIL if any of these patterns appear directly in a controller method (not in a called service):

  • Direct repository calls (this.repository.findById)
  • Domain entity instantiation (XxxEntity.create)
  • Business rule conditions beyond simple null checks

Dimension 5 — Testing Coverage

Purpose: Confirm test files exist and follow the test-first structure.

Check T1 — Entity spec files exist:

find /domain/entities/__tests__ -name "*.spec.ts" 2>/dev/null

WARNING if no spec files found.

Check T2 — VO spec files exist:

find /domain/value-objects/__tests__ -name "*.spec.ts" 2>/dev/null

WARNING if VO files exist but no specs.

Check T3 — Application spec files exist:

find /application -name "*.spec.ts" 2>/dev/null

WARNING if application layer has no specs.

Check T4 — Controller spec files exist:

find /infrastructure/controllers/__tests__ -name "*.spec.ts" 2>/dev/null

WARNING if controllers exist but no specs.

Check T5 — In-memory repository used in application tests:

grep -r "InMemoryRepository" /application --include="*.spec.ts" -l

WARNING if application specs exist but none use the in-memory repository.


Dimension 6 — Module Organization

Purpose: Confirm the directory structure and naming conventions are correct.

Check M1 — Standard directories present:

Verify these paths exist under BC_PATH:

  • domain/entities/
  • domain/repositories/
  • domain/events/
  • application/
  • infrastructure/

WARNING for each missing standard directory.

Check M2 — Module file exists:

find /infrastructure -maxdepth 1 -name "*.module.ts" 2>/dev/null

FAIL if no module file found.

Check M3 — No cross-layer imports (domain importing infrastructure):

grep -r "from.*infrastructure\|require.*infrastructure" /domain/ --include="*.ts" -l
grep -r "from.*infrastructure\|require.*infrastructure" /application/ --include="*.ts" -l

FAIL if domain or application imports from infrastructure.

Check M4 — File naming conventions:

Spot-check a few files:

  • Entity files: .entity.ts
  • VO files: .vo.ts
  • Event files: -ed.event.ts
  • Handler files: .handler.ts or -ed.handler.ts
  • Repository files: .repository.ts, prisma-.repository.ts

WARNING if files deviate significantly from these naming conventions.


Report Format

Produce a structured markdown report after all checks:

# Architecture Review: 

## Summary

| Dimension | Status |
|---|---|
| Domain Purity | PASS / FAIL |
| Application Patterns | PASS / FAIL |
| Infrastructure Isolation | PASS / FAIL |
| Presentation Concerns | PASS / WARNING |
| Testing Coverage | PASS / WARNING |
| Module Organization | PASS / FAIL |

Overall: PASS / NEEDS WORK

---

## Findings

### FAIL Items (must fix before merge)

- **[D1] No NestJS common imports in domain:** Found in `domain/entities/order.entity.ts` (line 3: `import { Injectable }`)
  Fix: Remove `@Injectable` — entities have no framework decorators.

- **[I1] Module exports only tokens:** `PrismaOrderRepository` exported from `orders.module.ts`
  Fix: Change to `exports: [ORDER_REPOSITORY]`.

### WARNING Items (recommended improvements)

- **[T1] Entity spec files:** No spec files found in `domain/entities/__tests__/`
  Recommendation: Add entity unit tests covering `create()`, `restore()`, and each mutating method.

- **[D7] Data builders:** `domain/testing/helpers/` is empty
  Recommendation: Add `OrderDataBuilder` with faker defaults for use in all test files.

### PASS Items

- Domain purity: no framework imports in domain
- Application DTOs: no class-validator found
- Mapper uses restore(): confirmed in `order-model.mapper.ts`
- Module exports: only token Symbols exported

After the Report

  • FAIL items are blocking — the BC is not ready to merge until all FAILs are resolved.
  • WARNING items are advisory — present them to the user and ask whether to address now or log as tech debt.
  • If all items are PASS or WARNING: report the BC as architecture-compliant.

Suggest specific fixes for each FAIL item, referencing the relevant layer skill (nestjs-hexagonal:domain, nestjs-hexagonal:application, etc.) for implementation guidance.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.