Getting it into your agent
It runs from inside its repository, so the clone comes first — what it calls does not travel with the file alone.
git clone --depth 1 https://github.com/Softtor/nestjs-hexagonalnpx agentmods add skills/softtor/nestjs-hexagonal/infrastructureWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/softtor/nestjs-hexagonal/infrastructure)<a href="https://agentmods.dev/skills/softtor/nestjs-hexagonal/infrastructure"><img src="https://agentmods.dev/badge/skills/softtor/nestjs-hexagonal/infrastructure/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/softtor/nestjs-hexagonal/infrastructure"><img src="https://agentmods.dev/badge/skills/softtor/nestjs-hexagonal/infrastructure.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00053 | $0.03106 |
| Opus 5.5 | $0.00021 | $0.01242 |
| Sonnet 5.5 | $0.00011 | $0.00621 |
| Haiku 4.5 | $0.00005 | $0.00311 |
Grade A, and why
infrastructure scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 9d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 348 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Infrastructure Layer
Infrastructure wires the domain to the outside world: databases, event buses, HTTP frameworks, and external services. It is the only layer allowed to import NestJS decorators and Prisma.
Directory Structure
infrastructure/
├── <context>.module.ts # @Module wiring — exports ONLY port tokens
├── controllers/
│ ├── <context>.controller.ts
│ └── dtos/ # Request DTOs — class-validator lives here only
│ └── __tests__/
├── database/
│ ├── prisma/
│ │ ├── models/
│ │ │ └── <context>-model.mapper.ts # static toEntity() / toModel()
│ │ └── repositories/
│ │ ├── prisma-<context>.repository.ts
│ │ └── __tests__/
│ └── in-memory/
│ └── repositories/
│ └── <context>-in-memory.repository.ts # for unit tests
├── adapters/
│ └── <context>.adapter.ts # implements cross-module port interface
└── listeners/
└── <context>-created.handler.ts # @EventsHandler — side effects only
1. Prisma Repository
Pure persistence. No domain logic, no event dispatch.
// infrastructure/database/prisma/repositories/prisma-<context>.repository.ts
import { Injectable } from '@nestjs/common';
import { PrismaService } from '@/shared/infrastructure/database/prisma.service';
import { <Context>Entity } from '../../domain/entities/<context>.entity';
import type { <Context>Repository } from '../../domain/repositories/<context>.repository';
@Injectable()
export class Prisma<Context>Repository implements <Context>Repository.Repository {
sortableFields: string[] = ['name', 'createdAt'];
constructor(private readonly prisma: PrismaService) {}
async findById(id: string): Promise<<Context>Entity | null> {
const record = await this.prisma.<context>.findUnique({ where: { id } });
if (!record) return null;
return <Context>ModelMapper.toEntity(record);
}
async save(entity: <Context>Entity): Promise<void> {
const data = <Context>ModelMapper.toModel(entity);
const existing = await this.prisma.<context>.findUnique({ where: { id: entity.id } });
if (existing) {
await this.prisma.<context>.update({ where: { id: entity.id }, data });
} else {
await this.prisma.<context>.create({ data });
}
}
async search(
props: <Context>Repository.SearchParams,
): Promise<<Context>Repository.SearchResult> {
const sortable = this.sortableFields.includes(props.sort ?? '') || false;
const orderByField = sortable ? props.sort : 'createdAt';
const orderByDir = sortable ? props.sortDir : 'desc';
const whereClause: Record<string, unknown> = {
organizationId: props.filter?.organizationId,
};
if (typeof props.filter?.name === 'string') {
whereClause.name = { contains: props.filter.name, mode: 'insensitive' };
}
const [count, records] = await Promise.all([
this.prisma.<context>.count({ where: whereClause }),
this.prisma.<context>.findMany({
where: whereClause,
orderBy: { [orderByField]: orderByDir },
skip: props.page > 0 ? (props.page - 1) * props.perPage : 0,
take: props.perPage > 0 ? props.perPage : 15,
}),
]);
return new <Context>Repository.SearchResult({
items: records.map(<Context>ModelMapper.toEntity),
total: count,
currentPage: props.page,
perPage: props.perPage,
sort: orderByField,
sortDir: orderByDir,
filter: props.filter,
});
}
async delete(id: string, organizationId: string): Promise<void> {
await this.prisma.<context>.delete({ where: { id, organizationId } });
}
}
What ships with it
5 files beside SKILL.md in the same directory: the scripts, references and assets a skill reads on demand. Not counted in the per-session cost; read them before you install if any of them is executable.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 9d ago Changed · +4 lines 32a86bdef64d
- 27d ago Changed 5bf05eabf7be
- 1mo ago First seen · 344 lines · 53 tokens per session scan A 40f367bc5d62
infrastructure is a skill published in the GitHub repository Softtor/nestjs-hexagonal (5 stars, last pushed 10d ago), licensed MIT. It adds 53 tokens to every session and 3,106 once invoked, about $0.0002 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other skills, from other repositories
doctrine-migrations
Create and manage Doctrine migrations (bundle 4.x, library 3.9) for schema versioning; handle dependencies, rollbacks, and production deployment.
doctrine-batch-processing
Process large datasets with Doctrine (ORM 3 toIterable, flush+clear, bulk DQL) and memory management.
doctrine-events
React to Doctrine entity lifecycle in Symfony with attribute listeners (#[AsDoctrineListener]/#[AsEntityListener], ORM 3) and lifecycle callbacks.
cqrs-event-sourcing
CQRS and Event Sourcing patterns for scalable, auditable systems with separated read/write models. Use when building audit-required systems, implementing temporal queries, or designing high-scale applications with complex domain logic.
doctrine-transactions
Handle Doctrine transactions (ORM 3 wrapInTransaction), optimistic/pessimistic locking, flush strategies, and transaction boundaries.
phoenix-contexts
Phoenix context design — creating/splitting contexts, Scope (1.8+), Ecto.Multi, PubSub, routers, plugs, controllers. Use when editing contexts, routers, or designing boundaries.