# Sojustack Best Practices

> Best-practice guidance for the SojuStack monorepo (NestJS + Drizzle + Better Auth + TanStack Start). Use when editing files in apps/api or apps/web, designing routes, query/form patterns, auth/transaction flows, or implementing cross-stack features.

- Skill: `diegosouzapw/sojustack-best-practices` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add diegosouzapw/sojustack-best-practices`
- Raw SKILL.md: https://api.skillmd.com/api/skills/diegosouzapw/sojustack-best-practices/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: diegosouzapw (https://skillmd.com/u/diegosouzapw)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/diegosouzapw/sojustack-best-practices

---


# SojuStack Best Practices

Use this skill to keep changes idiomatic and safe in this repository.

## Repository Map

- Backend: `apps/api/` (NestJS + Drizzle ORM + Better Auth)
- Frontend: `apps/web/` (TanStack Start + TanStack Query + TanStack Form + ShadCN/Base UI)
- Shared config: `packages/typescript-config/`

## Universal Rules

- Keep scope tight to the user request; avoid opportunistic refactors.
- Maintain strict typing; avoid `any` and unsafe casts.
- Match naming and folder conventions already used in the touched area.
- Prefer small reusable helpers over duplicate logic.
- If behavior changes, update/add tests for the impacted area.

## Frontend Rules (`apps/web`)

### Routing (TanStack Start)

- Keep route modules focused; move reusable logic to hooks or components.

### Data Fetching (TanStack Query)

- Use stable query keys like `['resource', id, 'sub-resource']`.
- Use `invalidateQueries()` without parameters when broad refresh is intended.
- Keep server-state logic in query/mutation hooks, not presentational components.

### UI (ShadCN + Base UI)

- Prefer components from `apps/web/src/components/ui/`.
- Prefer Base UI primitives over raw HTML where an equivalent exists.
- Use `cn()` from `apps/web/src/lib/utils.ts` for class composition.
- Keep Tailwind usage aligned with existing tokens and utility patterns.

## Backend Rules (`apps/api`)

### Database (Drizzle)

- Add tables in `apps/api/src/databases/tables/{name}.table.ts`.
- Export new tables from `drizzle.schema.ts`.
- Add/update relations in `drizzle.relations.ts`.

### Auth (Better Auth)

- Follow existing setup in `apps/api/src/auth/better-auth.provider.ts`.
- Use framework auth helpers (`@Auth()`, `@ActiveUser()`, `@ActiveSession()`) rather than ad hoc request parsing.

### Transactions

- Use `@Transactional()` with `TransactionHost<DrizzleTransactionClient>`.
- Do not manually nest/start transactions via `tx.transaction()`.

### Services and Errors

- Keep controllers thin; place business logic in services or providers.
- Use NestJS exceptions (`NotFoundException`, `UnauthorizedException`, etc.) for expected failures.

### API Type Safety

- Treat `apps/api/generated/openapi.d.ts` as generated source of truth for E2E typing.
- Use existing DTO and serialization patterns in the module.

## Execution Workflow

1. Read nearby code and existing module patterns.
2. Implement the smallest correct change.
3. Run repository validation commands from the repo root:
   - `pnpm typecheck`
   - `pnpm format`
   - `pnpm lint`
4. If any of those commands fail, fix the issues and re-run until they pass.
5. Ensure unrelated files are not modified.
6. Report what changed, why, and how it was validated.

## Do / Don't

### Do

- Prefer simplicity and human readability of code over complex or verbose implementations.
- Heir on asking more questions rather than too little.
- Beware of premature optimization
- Reuse existing providers/utilities before adding abstractions.
- Keep functions cohesive and predictable.
- Add short comments only for non-obvious logic.

### Don't

- Introduce architectural shifts unless requested.
- Add dependencies when existing stack primitives are sufficient.
- Bypass validation, auth, or typing conventions.

