smithery/Nikola-Milovic

code-guidelines

Apply this repository's coding conventions and patterns.

Installation

$ npx skills add smithery/Nikola-Milovic --skill code-guidelines

Summary

  • 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.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/Nikola-Milovic.

npx skills add smithery/Nikola-Milovic

Browse all from smithery/Nikola-Milovic

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,686 B
  • docs SUMMARY.md 321 B

History

  1. First recorded snapshot · 0 installs

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_LOGGING flag in apps/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/cors with credentials: 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:

  1. .env.[mode].local (git-ignored)
  2. .env.[mode]
  3. .env.local (git-ignored)
  4. .env

Only VITE_ variables exposed to client. Keep .env..example in sync.

CI/CD

Local (Husky): On git push:

  • pnpm lint:check
  • pnpm format:check
  • pnpm 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

  1. Check existing patterns in similar files
  2. Use DI for testability
  3. Handle errors explicitly with Result types
  4. Add structured logging at boundaries
  5. Write tests that use DI
  6. Run pnpm typecheck and pnpm test