Building elysia apis
Skill WasDavidOliveira/irracional-skills/builder/building-elysia-apis
Agent Skills para Cursor & Claude Code: revisão crítica + APIs Bun/Elysia/Drizzle/Zod — padrões que o chat não “inventa” de novo a cada conversa.
npx -y skills add WasDavidOliveira/irracional-skills --skill building-elysia-apisAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 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 author says it does
Copied from the file, not written here
Use quando for implementar ou alterar APIs com Bun, Elysia, PostgreSQL, Drizzle, Zod ou OpenAPI Scalar e pastas por funcionalidade (`src/modules/<feature>`); ou quando a ordem global de plugins está incorreta, `src/index.ts` importa rotas isoladas em vez de `modulesRoutes`, o service acede a `db` sem repository, as exceções são `Error` genéricas, há `process.env` nos módulos, pastas de plugin expõem barrel `index.ts`, rotas fora de `src/modules/<feature>`, ou JWT, guards e RBAC estão inconsistentes.
SKILL.md
7.4 KB, ~1.9k tokens by cl100k_base, as published. Nobody here has run it
APIs Elysia (stack Astro / feature modules)
Visão geral
Padrão para APIs Bun + Elysia + Drizzle (pg) + Zod + Scalar: feature folders, plugins por categoria, bootstrap ordenado, erros centralizados, service/repository separados, configs agrupadas, OpenAPI por <feature>.docs.ts.
Progressive disclosure: manter este SKILL.md como índice enxuto; carregar reference/*.md só para o tópico em causa; copiar templates TypeScript da raiz desta skill apenas ao implementar. Alinha aos critérios de skills de equipa curadas (metadados curtos, corpo focado, detalhe sob demanda), na linha de repositórios como VoltAgent/awesome-agent-skills — secção Skill Quality Standards (sem caminhos absolutos de máquina; palavras-chave pesquisáveis na description).
Mapa de recursos
| Recurso | Consultar quando |
|---|---|
reference/01-stack-and-bootstrap.md | Stack, ordem dos .use(), fluxo erro global |
reference/02-modules-and-plugins.md | src/modules/<feature>, plugins, auth, configs |
reference/03-errors-openapi.md | HttpError, exceções, Zod, Scalar |
reference/04-database-config-tests.md | Drizzle, aliases, testes, limites service/repository |
http-status.constants.ts, http-error.ts, error-handler.plugin.ts, strategies/ | Copiar/adaptar para src/plugins/core/error-handler/ |
templates/*.exception.ts | Modelo para src/exceptions/ |
Quando usar
- Novo serviço ou módulo; PR que mexe em bootstrap, plugins, módulos ou persistência.
- Sintomas:
.use()fora de ordem, handler gordo, SQL no service, falta demodules.routes.ts, literais de status,throw new Errorem rotas.
Quando não usar
- Stack ou estrutura de pastas do repositório contradiz este padrão — seguir a documentação do projeto.
- App sem HTTP ou sem Elysia.
Padrões centrais
- Bootstrap: error handler primeiro; depois cors → rate limit → helmet → swagger → activity log (se existir) →
modulesRoutes;index.tssó agrega plugins +modulesRoutes(verreference/01-stack-and-bootstrap.md). - Feature folders:
src/modules/<feature>/com sufixosroutes,service,repository,schema,types,docs,constants(verreference/02-modules-and-plugins.md). - SRP: rota orquestra; service com regras; repository com Drizzle; uma responsabilidade por ficheiro.
- Zod: validação nos handlers; schemas em
*.schema.ts; docs OpenAPI em*.docs.tscom spread nas rotas. HTTP_STATUS: um ficheiro de constantes;set.status = HTTP_STATUS.CREATED(aliasHttpStatusCodeexportado para compat).- Erros:
onError({ as: "global" });ZodErroreHttpErrorvia estratégias; módulos lançam exceções emsrc/exceptions/(estenderHttpError); evitartry/catchde fluxo (verreference/03-errors-openapi.mde templates emtemplates/). - Plugins: categorias
core,auth,infra,docs; semindex.tsgenérico — nomes explícitos (*.plugin.ts). - Config: nunca
process.envdireto nos módulos — usarsrc/configs/*.config.ts. - Auth: jwt plugin; rotas protegidas com guard de sessão; RBAC com permission guard depois do auth guard quando aplicável.
Estrutura alvo (resumo)
src/
index.ts
configs/
database/
connection.ts
index.ts
schema/
migrations/
exceptions/
plugins/
core/error-handler/ # ou espelhar templates desta skill
auth/
infra/
docs/
modules/
<feature>/
<feature>.routes.ts
<feature>.service.ts
<feature>.repository.ts
<feature>.schema.ts
<feature>.types.ts
<feature>.docs.ts
<feature>.constants.ts
modules.routes.ts
Ficheiros desta skill (copiar para o repo)
Caminhos relativos ao repositório de código; sem paths absolutos de máquina.
| Origem (skill) | Destino típico (repo) |
|---|---|
http-status.constants.ts | src/plugins/core/error-handler/http-status.constants.ts |
http-error.ts | src/plugins/core/error-handler/http-error.ts |
strategies/* | src/plugins/core/error-handler/strategies/ |
error-handler.plugin.ts | src/plugins/core/error-handler/error-handler.plugin.ts |
templates/*.exception.ts | src/exceptions/<nome>.exception.ts (ajustar imports) |
Referência rápida
| Sintoma | Direção |
|---|---|
| Error handler no fim da cadeia | Mover para o primeiro .use() |
index.ts importa user.routes | Passar a usar só modulesRoutes |
Service importa db | Mover queries para *.repository.ts |
throw new Error("…") em rota | Exceção em src/exceptions/ estendendo HttpError |
process.env no módulo | src/configs/<domínio>.config.ts |
| Plugin folder com barrel opaco | Ficheiros explícitos, sem index.ts de atalho |
| Status mágico | HTTP_STATUS |
| Validação só no service | Subir Zod no route + *.schema.ts |
Erros comuns
- Esquecer que ordem dos plugins altera CORS, limite, segurança e documentação antes das rotas.
activityLogcommapResponseglobal a interferir com testes — isolar dados ou esperas (ver referência de testes).- Misturar
detailOpenAPI à mão sem*.docs.tspor feature. permissionGuardsemauthGuardquando a rota exige utilizador autenticado.
Exemplo mínimo (módulo + HTTP_STATUS + error plugin)
Caminhos relativos à pasta da skill; no repo, viver em src/modules/items/ e importar plugins por alias.
import { Elysia } from "elysia";
import { z } from "zod";
import { errorHandlerPlugin } from "./error-handler.plugin";
import { HTTP_STATUS } from "./http-status.constants";
const bodySchema = z.object({ name: z.string().min(1) });
const responseSchema = z.object({
id: z.string().uuid(),
name: z.string(),
});
export const itemsRoutes = new Elysia({ prefix: "/items" }).post(
"",
({ body, set }) => {
set.status = HTTP_STATUS.CREATED;
return { id: crypto.randomUUID(), name: body.name };
},
{
body: bodySchema,
response: responseSchema,
},
);
export const application = new Elysia()
.use(errorHandlerPlugin)
.use(itemsRoutes);
Racionalizações a ignorar
| Desculpa | Realidade |
|---|---|
| “Ordem dos plugins não interessa” | CORS e erro global deixam de cobrir o que deveriam. |
“Service com db é mais rápido” | Acoplamento impossível de testar e de trocar persistência. |
| “Uma exception genérica basta” | Cliente e logs não distinguem 401/403/404 nem contratos estáveis. |
“index.ts no plugin simplifica imports” | Esconde ficheiros reais e quebra convenção explícita do repositório. |
Violar bootstrap, agregação modules.routes.ts, camadas service/repository, exceções tipadas ou configs centralizadas reproduz dívida que esta skill existe para evitar.
Gives 0 of the 12 instructions most databases sql skills give in ~1.9k tokens
Counted across 589 of the 662 authors here whose files we hold, read 2026-08-06
- use parameterized queriesin 36 of 589, across 32 files
- use timestamptz for timestampsin 30 of 589, across 12 files
- create indexes concurrentlyin 29 of 589, across 23 files
- index foreign keysin 28 of 589, across 17 files
- use numeric type for moneyin 25 of 589, across 8 files
- select only required columnsin 24 of 589, across 19 files
- use cursor pagination instead of OFFSETin 23 of 589, across 15 files
- add indexes manually on foreign key columnsin 22 of 589, across 11 files
- read individual rule files for detailed explanationsin 18 of 589, across 4 files
- configure connection poolingin 18 of 589, across 16 files
- put equality columns before range columns in indexesin 17 of 589, across 9 files
- normalize to third normal formin 17 of 589, across 8 files
Said here and by no other author read
- register error handler first in bootstrap
- isolate routes in feature folders
- keep one responsibility per file
- throw typed exceptions in modules
- name plugin files explicitly
- manage configuration in config files
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.