procedure
Vovk.ts procedures in depth (`base` already has a complete endpoint, validation, errors and status codes) — atomic unit of server-side logic in Vovk project.
Skill by finom
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/finom-procedure
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: frontend, backend, data, security
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/procedure
What's inside
- Skill name
procedure- Description
- Vovk.ts procedures in depth (`base` already has a complete endpoint, validation, errors and status codes) — atomic unit of server-side logic in Vovk project. Use whenever user asks to build ANYTHING producing or consuming data on server — page loading data ("users page", "dashboard", "product list"), endpoint, API handler, server action, form submission, controller, validation with Zod / Valibot / ArkType, request/response shape, file upload, file download, error handling (`HttpException`, status codes), content types (JSON, multipart, text, binary), or calling server code from React Server Component / SSR / SSG / PPR / server action. Triggers on phrasings like "build a users page", "add an endpoint", "create a form handler", "fetch X from the server", "handle file upload", "validate input", "throw a 404", "server action for Y", "controller for Z", "add `req.body` parsing", ".fn()", "CORS". Does NOT cover segments / `route.ts` / `initSegment` → hand off to `segment` skill. Does NOT cover RPC client generation, fetcher, `@/client` imports → hand off to `rpc` skill. Does NOT cover custom decorators, `createDecorator`, authorization / auth guards → hand off to `decorators` skill. Does NOT cover `deriveTools` / MCP / AI tool wiring → hand off to `tools` skill. Does NOT cover JSON Lines streaming / generators / `JSONLinesResponder` → hand off to `jsonlines` skill. Does NOT cover `@operation` metadata / Scalar docs → hand off to `openapi` skill.
- License
- MIT
- Instructions
- 476 lines in SKILL.md · view on GitHub
Agent Skills spec issues
- description: longer than 1024 characters
Files (1)
- SKILL.md
SKILL.md (first lines)
# Vovk.ts procedures
**Procedure** = typed, validated server-logic unit. Built with `procedure({ ... }).handle(...)`. Atom of every Vovk app.
**Mental model:**
- **Procedure valuable alone.** Typed server function — call via `.fn()` from RSC, server actions, SSR/SSG/PPR, any server code. No HTTP.
- **HTTP decorator (`@get`, `@post`, `@put`, `@patch`, `@del`) OPTIONAL.** Add only when exposing procedure as HTTP endpoint (also makes callable via generated RPC client from browser).
Opposite of most frameworks: procedures first, HTTP opt-in.
## Procedure, minimally
```ts
import { procedure } from 'vovk';
import { z } from 'zod';
class UserController {
static getUser = procedure({
params: z.object({ id: z.string().uuid() }),
output: z.object({ id: z.string(), email: z.email() }),
}).handle(async (_req, { id }) => {
return UserService.byId(id); // plain call
});
}
```
**What you have:**
- Typed, validated procedure.
- Callable from ANY server code via `UserController.getUser.fn({ params: { id: '…' } })`.
- **Not** HTTP endpoint. Not in generated RPC client.
Expose over HTTP — add HTTP decorator:
```ts
import { z } from 'zod';
import { get, prefix, procedure } from 'vovk';
import UserService from './user-service';
@prefix('users')
export default class UserController {
@get('{id}')
static getUser = procedure({
params: z.object({ id: z.string().uuid() }),
output: z.object({ id: z.string(), email: z.email() }),
}).handle(async (_req, { id }) => {
return UserService.byId(id);
});
}
```
Now also `GET /api/users/{id}` and available as `UserRPC.getUser(...)` on client.
## Deciding: decorator or no?
**When user says...**
| User intent | What to build |
|---|---|
| "Build users page" / "load X on server" / "dashboard showing Y" | Procedure, no decorator. Call via `.fn()` from server component. |
| "Server action for form submit" | Procedure, no decorator. Call via `.fn()` inside `'use server'` function. |
| "Add `/api/users` endpoint" / "expose X as API" / "browser needs to call it" | Procedure + HTTP decorator. |
| "Users page AND also API" | Procedure + HTTP decorator. Call `.fn()` from server component; RPC client covers browser path. |
| "Internal helper used only from other procedures" | Plain service function, not procedure. Use `procedure` only when you want validation/types as contract. |
**Default:** when in doubt, start without HTTP decorator. Adding later = one-line change. Exposing too eagerly and retracting is harder.
## Controller / procedure / service — split of responsibilities
- **Services** = **always** business-logic module — data access, domain rules, calls to other services. Not optional "once logic gets big enough"; domain logic lives there from line one.
- **Procedures** do only *thin pre-calculation*: pull validated body/query/params from `req.vovk`, read actor info from `req.vovk.meta()` / `next/headers`, delegate to service, return its result.
- **Services must never touch `req` / `VovkRequest`.** Take plain typed args — ideally via `VovkBody` / `VovkParams` / `VovkOutput` (see "Type inference").
```ts
static updateUser = procedure({
body: z.object({ email: z.email() }),
params: z.object({ id: z.uuid() }),
}).handle(async ({ vovk }, params) => {
const body = await vovk.body();
const { userId } = vovk.meta<SessionMeta>(); // e.g. from an auth decorator
return UserService.updateUser({ body, params, actorId: userId });
});
```
Service taking `VovkRequest` — or branching on request shape — = layering leak. Services must be callable from cron jobs, CLI scripts, migrations, sibling procedures; if any path needs fake request, logic in wrong file.
## Scaffolding via CLI
```bash
npx vovk new controller service <name> # shortcut: npx vovk n c s <name>
```
`<name>` = `[segmentPath/]moduleName`, combines two conventions:
- **`moduleName`** (after last `/`) **must be camelCase**. Normalize user input: `USER` → `user`, `user-profile` → `userProfile`, `MyUser` → `myUser`. Example: "User-Profile in Admin segment" → `admin/userProfile`.
- **`segmentPath`** (before last `/`) = **existing** segment path — URL slug, kebab-case, slash-separated for nested (`admin`, `foo/bar`). Not camelCase. See `segment` skill.
Flags: `--empty` (no CRUD boilerplate), `--overwrite`, `--no-segment-update` (skip `route.ts` edit, rare), `--dry-run`.
Creates `src/modules/<name>/<name>-controller.ts` + `<name>-service.ts`, registers controller in segment's `controllers` map. Scaffold ships with CRUD placeholders — **overwrite in place** when writing real logic; don't leave dummies next to real code. Fails if no segment exists — create one first (`segment` skill).
## `procedure()` options — full reference
```ts
procedure({
// Input validation (all optional):
params: ZodSchema, // Route parameters
body: ZodSchema, // Request body (shape depends on contentType)
query: ZodSchema, // Query string
// Output validation (optional):
output: ZodSchema, // Single JSON response
iteration: ZodSchema, // Per-item schema for JSON Lines streams, not with output (see jsonlines skill)
// Content-type control:
contentType: 'application/json' | 'multipart/form-data' |
'application/x-www-form-urlencoded' | 'text/*' |
'image/*' | 'video/*' | '*/*' | string | string[],From finom/vovk, MIT.
More from finom/vovk
- 0.664score
bundle
finom
Vovk.ts `vovk bundle` CLI — packages composed TypeScript client as zero-dep publishable npm package.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
jsonlines
finom
Vovk.ts JSON Lines streaming — generator handlers (`function*`, `async function*`), the `iteration` validation option, `validateEachIteration`, the…
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
config
finom
Vovk.ts configuration — vovk.config.{mjs,cjs,js} shape, every config key + default (rootEntry, schemaOutDir, libs, exposeConfigKeys, logLevel, devHttps…
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
multitenant
finom
Multi-tenant / multitenancy patterns in Vovk.ts — hosting multiple tenants from one Next.js app via subdomain routing.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
decorators
finom
Vovk.ts decorators — built-in (`@prefix`, `@operation`, `@get/@post/@put/@patch/@del`, `.auto()`) and custom via `createDecorator`.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
base
finom
Vovk.ts essentials — ALWAYS load first for any Vovk.ts task, including building a back end or API in a project that has vovk.config.* or .vovk-schema/.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
tools
finom
Building LLM tools with Vovk.ts — `deriveTools()` (procedures → tools) returning a `StandardToolV0[]` array, standalone tools via the `standard-tool` package…
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
python
finom
The Vovk.ts Python client — generating a typed Python package from a Vovk API with `vovk-python`, the `py` / `pySrc` templates, `TypedDict` shapes, JSON +…
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
segment
finom
Vovk.ts segments in depth (`base` already covers the one root segment and its `route.ts`) — the unit of backend slicing in a Vovk project.
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
init
finom
Initialize a backend — via Vovk.ts, a TypeScript-first RPC/API framework plugging into Next.js App Router, using official vovk-cli.
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
mixins
finom
Vovk.ts OpenAPI mixins — importing third-party OpenAPI 3.x schemas as typed client modules that share the same call signature as native Vovk RPC modules.
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
rpc
finom
Vovk.ts RPC client — how `vovk generate` turns controllers into type-safe client modules, composed vs segmented clients, call shape (`apiRoot`, `params`…
SkillAFreshness: A★ 54Claude Code +9
Signals
- Stars
- 54
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Oct 17, 2026 (10 days ago)
- Last release
- Oct 22, 2026 (5 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/finom/vovk
- Website
- vovk.dev
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from finom
- 0.664score
multitenant
finom
Multi-tenant / multitenancy patterns in Vovk.ts — hosting multiple tenants from one Next.js app via subdomain routing.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
bundle
finom
Vovk.ts `vovk bundle` CLI — packages composed TypeScript client as zero-dep publishable npm package.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
decorators
finom
Vovk.ts decorators — built-in (`@prefix`, `@operation`, `@get/@post/@put/@patch/@del`, `.auto()`) and custom via `createDecorator`.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
config
finom
Vovk.ts configuration — vovk.config.{mjs,cjs,js} shape, every config key + default (rootEntry, schemaOutDir, libs, exposeConfigKeys, logLevel, devHttps…
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
jsonlines
finom
Vovk.ts JSON Lines streaming — generator handlers (`function*`, `async function*`), the `iteration` validation option, `validateEachIteration`, the…
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
base
finom
Vovk.ts essentials — ALWAYS load first for any Vovk.ts task, including building a back end or API in a project that has vovk.config.* or .vovk-schema/.
SkillAFreshness: A★ 54Claude Code +9
Cite this page
procedure skill. Agent Mart. https://agentmart.dev/skills/finom-procedure (last updated 2026-10-24)