Skill: create-elysia-service
Generate service + stub + service-port + factory for one entity.
Prerequisites
| Item | Action if missing |
|---|---|
package.json in cwd |
Tell the user this works inside an existing Bun project |
src/port/{entityLower}.ts with {Entity}Repository |
Mode A generates it; Mode B requires it |
Step 1 — Choose mode
AskUserQuestion({
question: "How should we source the entity for this service?",
header: "Mode",
options: [
{ label: "New schema (Recommended)", description: "No repo exists yet — generate the full repository layer first via create-elysia-repository, then the service" },
{ label: "Existing repo", description: "Repository already exists in src/adapter/outbound/repository/ — just generate the service files" }
]
})
Mode A — New schema: run /create-elysia-repository Mode A in full first (domain + port + repository + schema + apperr), ts_diagnose + tsc clean, then continue.
Mode B — Existing repo: find src/adapter/outbound/repository -name '*.ts' -not -name '*.test.ts', surface the pick (≤4 → AskUserQuestion; >4 → numbered prompt). Derive Entity from the filename. Verify src/port/{entityLower}.ts has {Entity}Repository — if missing, tell the user to run /create-elysia-repository first and stop.
Step 2 — Collect inputs
Read package.json name for Module. Derive Entity/EntityLower. Mode A: parse the schema per /create-elysia-repository Step 3.
Step 3 — Render
Templates at ${CLAUDE_SKILL_DIR}/../create-elysia-app/references/:
| Template | Output |
|---|---|
port_service.ts.tmpl |
src/port/{entityLower}-service.ts |
service.ts.tmpl |
src/service/{entityLower}.ts |
service_stub.ts.tmpl |
src/service/stub/{entityLower}.ts |
service_factory.ts.tmpl |
src/service/factory.ts (per-project) |
If factory.ts already exists (multiple entities), add the new entity's new{Entity}Service export to it rather than overwriting. If a per-entity file exists, ask before overwriting.
Key patterns enforced by the templates
- The service holds
repo: port.{Entity}Repository— depends on the port, never the concrete adapter (DIP);implements {Entity}Service. creategenerates a UUID + stamps timestamps;updateis find-then-write (preservescreatedAt, refreshesupdatedAt).- The stub (
src/service/stub/) is stateless with deterministic ids"{entityLower}-stub-<i>"so FE fixtures survive restarts. - The factory selects real vs stub: gated by the
SERVICE_STUBcompile-time constant (tree-shaken from the productionbun build) and the runtimeSERVICE_BACKENDenv. See/create-elysia-app"Stub mode".
Step 4 — Verify
mcp__ts-lsp__ts_diagnoseon each generated file. Fix all errors.bunx tsc --noEmitfrom the project root. Fix all errors.bun build ./src/index.ts --define SERVICE_STUB=true --outdir /tmp/stub-checkmust also succeed (stub build links cleanly). Clean up/tmp/stub-checkafter.- Do not report done until all pass clean.