Agent skill
code-guidelines
Apply this repository's coding conventions and patterns. Use when writing or reviewing code in this codebase to ensure consistency with established patterns for DI, logging, error handling, testing, and documentation. Auto-trigger when implementing features, fixing bugs, or reviewing code changes.
Install this agent skill to your Project
npx add-skill https://github.com/frmlabz/frm-stack/tree/main/capabilities/general/skills/code-guidelines
SKILL.md
Code Guidelines
This repo is a demo. Patterns here are suggestions; swap for what fits your team.
Dependency Injection
Prefer constructor/function injection for side effects:
// Good: injectable
function createUserService(db: Database, logger: Logger) {
return { ... }
}
// Bad: global import
import { db } from '../db'
- Wire at edges (app startup, router factories)
- Avoid global singleton imports from deep modules
- Tests supply fakes without patching globals
Error Handling (neverthrow)
Use Result<T, E> for explicit success/error flow.
// Services return Result
function findUser(id: string): ResultAsync<User, NotFoundError | DbError>
// Validate input early
const validated = validateInput(schema, input);
if (validated.isErr()) return err(validated.error);
// Wrap throwy code once
return await fromAsyncThrowable(
async () => dbCall(),
(e) => typedError(e),
)();
Error mapping:
- auth/ownership → 401/403
- missing resources → 404
- validation → 400
- unexpected → 500 (log with context)
Helpers: packages/backend/core/src/validation.ts (validateInput, typedError)
Logging (pino)
Use structured logging:
logger.info("user created", { userId: user.id, email: user.email })
logger.error("operation failed", err, { orderId, userId })
Rules:
- Log at boundaries (request → router → service)
- Never log secrets (tokens, passwords, cookies)
- Use levels: error, warn, info, debug
- Optional
REQUEST_LOGGINGflag inapps/backend/api/src/orpc.ts
Location: apps/backend/api/src/log.ts, packages/backend/core/src/log.ts
oRPC (Type-safe RPC)
Type-safe RPC between frontend and backend with React Query helpers.
Server Pattern
// Router factory pattern
orpc.router({
user: userRouter(),
todo: todoRouter(),
});
// Protected procedure with authOnly middleware
orpc.use(authOnly).input(zodSchema).handler(...)
Client Usage
const api = useApi();
// Queries
const todosQuery = useQuery(api.todo.list.queryOptions({ input: { completed: false } }));
// Mutations
const createTodo = useMutation(api.todo.create.mutationOptions({
onSuccess: () => queryClient.invalidateQueries({ queryKey: api.todo.key() })
}));
Key files:
- Server router:
apps/backend/api/src/routers/index.ts - Server setup:
apps/backend/api/src/orpc.ts - Client:
apps/frontend/web/app/providers/orpc-provider.tsx
Auth (Better Auth)
Cookie-based auth with typed user/session in oRPC context.
// Read user in oRPC handlers
const userId = context.user.id;
// Use authOnly middleware for protected procedures
orpc.use(authOnly).handler(...)
CORS requirements:
- Backend:
hono/corswithcredentials: true - Frontend: fetch with
credentials: "include"
Key files:
- Backend:
apps/backend/api/src/auth.ts - Core:
packages/backend/core/src/auth.ts - Frontend:
apps/frontend/web/app/providers/*
Config (env + Zod)
Validate env vars at startup with Zod:
// Backend: parse process.env at module load
const appConfig = configSchema.parse(process.env);
// Frontend: read import.meta.env
const config = getConfig();
Vite env file priority:
.env.[mode].local(git-ignored).env.[mode].env.local(git-ignored).env
Only VITE_* variables exposed to client. Keep .env.*.example in sync.
CI/CD
Local (Husky): On git push:
pnpm lint:checkpnpm format:checkpnpm typecheck
Bypass: HUSKY=0 git push
GitHub Actions: On PR:
- All above +
pnpm test
Workflow: .github/workflows/ci.yml
Tech Choices Summary
| Layer | Choice | Why |
|---|---|---|
| DB | Kysely | Typed query builder, SQL-first, easy DI |
| RPC | oRPC | End-to-end typed, React Query helpers |
| Router | TanStack Router | Type-safe, file-based |
| Errors | neverthrow | Explicit success/failure flows |
| Auth | Better Auth | Free, good coverage, easy swap |
| Testing | testcontainers | Real Postgres, shared container for speed |
When Writing Code
- Check existing patterns in similar files
- Use DI for testability
- Handle errors explicitly with Result types
- Add structured logging at boundaries
- Write tests that use DI
- Run
pnpm typecheckandpnpm test
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
testing
Shared database testing patterns with testcontainers and Vitest. Use when writing backend tests, setting up test files, debugging test failures, or configuring Vitest. Triggers on "write tests", "test setup", "testcontainers", "vitest config", "test isolation", or when creating new test suites.
db-workflow
Database workflow with Postgres, Kysely, and Atlas migrations. Use when modifying database schema, creating migrations, generating TypeScript types, or troubleshooting database issues. Triggers on "schema change", "migration", "db-migrate", "kysely", "atlas", or when editing db/schema.sql.
mobile-auth
Better Auth integration with Expo/React Native. Use when working on mobile authentication, session management, or debugging auth issues in the mobile app. Triggers on "mobile auth", "expo auth", "better-auth expo", "session provider", "SecureStore", or when editing apps/frontend/mobile auth files.
react-useeffect
React useEffect best practices from official docs. Use when writing/reviewing useEffect, useState for derived values, data fetching, or state synchronization. Teaches when NOT to use Effect and better alternatives.
frontend-design
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.
resolve-pr-comments
Address GitHub PR review comments end-to-end, fetch unresolved review threads (via `gh` GraphQL), implement fixes, reply with what changed, and resolve threads using the bundled scripts. Use when asked to “address PR comments”, “resolve review threads”, or “clear requested changes”.
Didn't find tool you were looking for?