Complete the Getting Started guide before making any changes.
| Branch | Purpose |
|---|---|
main |
Production-ready code. Direct commits are not allowed. |
feat/<description> |
New feature or enhancement |
fix/<description> |
Bug fix |
chore/<description> |
Dependency updates, tooling, config changes |
docs/<description> |
Documentation-only changes |
Branch from main:
git checkout main && git pull
git checkout -b feat/my-feature- Make your changes in the feature branch.
- Run lint before committing:
npm run lint
- Verify the app builds without errors:
npm run build
- Push your branch and open a pull request against
main.
- Keep PRs focused — one logical change per PR.
- Write a clear title and describe what changed and why in the body.
- Link any related issues.
- Ensure
npm run lintandnpm run buildboth pass before requesting review. - At least one approval is required before merging.
- Prefer
interfacefor object shapes; usetypefor unions and aliases. - Avoid
any. Useunknownwhen the type is genuinely unknown and narrow it explicitly. - Export types from
src/types/— do not co-locate type definitions with components unless they are truly component-specific.
- One component per file. File name matches the exported component name in kebab-case (
workspace-editor.tsx→export function WorkspaceEditor). - Keep components focused — extract logic into custom hooks when a component grows complex.
- Use
shadcn/uiprimitives fromsrc/components/ui/rather than raw HTML elements for interactive controls.
- New features go in
src/features/<feature-name>/. - API calls belong in
src/features/<feature-name>/api/, not inside components. - Use TanStack Query (
useQuery,useMutation) for all data fetching — do not callapiClientdirectly inside components.
- UI-only state (modals, toasts, preferences) → Zustand
useUIStore. - Server/async state → TanStack Query.
- Local ephemeral state (controlled inputs, toggles) →
useState.
- Use Tailwind utility classes. Avoid inline styles.
- Use
cn()(fromsrc/lib/utils.ts) to merge conditional class names. - Follow the existing design token conventions from
shadcn/ui(e.g.bg-primary,text-muted-foreground).
- All user-visible strings must use the
t()function fromreact-i18next. - Add keys to both
src/locales/en/andsrc/locales/bo/translation files. - Choose the appropriate namespace:
common,auth,admin,dashboard, orworkspace.
| Thing | Convention | Example |
|---|---|---|
| Files | kebab-case | workspace-editor.tsx |
| React components | PascalCase | WorkspaceEditor |
| Hooks | camelCase with use prefix |
useEditorDraft |
| Types / Interfaces | PascalCase | AssignedTask |
| Constants | UPPER_SNAKE_CASE | MAX_ZOOM_LEVEL |
| Zustand actions | camelCase | setEditorFontSize |
- Create the page component in
src/pages/<section>/. - Add a lazy import and route entry in
src/routes/app-routes.tsx. - If the page is role-restricted, wrap it with
<ProtectedRoute allowedRoles={[...]} />. - Add translations for any new strings in all relevant locale files.
- Create
src/features/<name>/with subdirectoriesapi/,components/, andhooks/as needed. - Export public API from an
index.tsbarrel file. - Register the feature's pages in the router.
- Add Zod schemas in
src/schema/if the feature introduces forms.