5.6 KiB
5.6 KiB
Salestech Products Development Guidelines
Always obey the Salestech Products Development Guidelines. These are enforceable rules — non-compliant code will be rejected during review.
Source
- Notion (Live, authoritative): https://candylabs.notion.site/development-guidelines
- Connect via Notion MCP server (HTTP requires JS, so MCP is the only reliable way).
- Always consult the live document for the latest version.
Summary (snapshot — refer to live doc for authority)
1. Code Formatting & Style
- 4 spaces indentation (JS/TS and Python). No tabs.
- Max 120 chars per line.
- No trailing whitespace; files end with a single newline.
- JS/TS: no semicolons (
semi: false), single quotes, trailing commas where valid in ES5, omit parens around single arrow params. - Python: double quotes for strings.
- Tools: Prettier + ESLint (JS/TS, npm); Ruff (Python, uv).
2. Naming
- JS/TS:
camelCasevars/funcs,PascalCaseclasses/types/enums,UPPER_SNAKE_CASEconstants,kebab-casefilenames, boolean prefixesis/has/should. - Python:
snake_casevars/funcs/files,PascalCaseclasses,UPPER_SNAKE_CASEconstants,_leading_underscoreprivate. - No abbreviations (except
id,url,http). - No single-letter vars (except short lambda / loop indices).
- No Hungarian notation.
3. Comments & Documentation
- Don't comment the obvious — comment the why.
TODO:/FIXME:must include a ticket reference.- JS/TS: JSDoc on all exported functions, classes, interfaces.
- Python: Google-style docstrings on all public funcs/classes/modules.
4. Git Workflow
- Branch:
<type>/<ticket-id>-<short-description>(feat,fix,chore,docs,hotfix). - Commits: Conventional Commits, lowercase, imperative, max 72 chars,
no period, no
Co-Authored-By:watermarks. - PRs: linked to a ticket, ≥1 human approval, all CI checks pass, squash-merge feature branches, delete source branch after merge.
- Never commit directly to
main/dev; never force-push shared branches; never commit secrets.
5. React & TypeScript
- Component file order: imports → types → constants → helpers → component.
- Named exports only; function declarations for components.
- Props types named
<ComponentName>Props; neverReact.FC. - Hooks start with
use; never call hooks conditionally. - React Router v7: file/config-based routes (don't mix), use
loader/action,useNavigate,useSearchParams,<Link>,<Outlet>. - TanStack Query: centralized query key factories, never
fetch/axiosin components, always handle loading/success/error, preferinvalidateQueriesover manual cache. - State priority: URL → TanStack Query → component state → Context. Never duplicate server state into local state.
6. Tailwind 4 (CSS-only config)
- Component styles inline as Tailwind classes; no separate CSS modules per component.
- Use
clsxfor dynamic classes. - Mobile-first responsive prefixes.
prettier-plugin-tailwindcssordering required.- No
!important(Tailwind!) without justification + comment. main.cssonly for@import,@theme, global base styles, third- party overrides.
7. Folder Structure
- Layer-based for frontend (
api/,components/,hooks/,pages/,queries/,routes/,types/,utils/). - FastAPI:
routers/,models/,schemas/,services/; PydanticBaseSettings; business logic in services not routers. - Django:
config/,apps/<app>/,common/; one app per domain; business logic inservices.py; max one migration per app per PR; custom User model from day 1. - Django templates:
snake_case.htmlintemplates/<app_name>/, partials prefixed_,{% extends %}mandatory, DjHTML formatter,{% url %}for all URLs. - Root directory: configuration files only.
- README.md mandatory (setup, env vars, run/test).
8. Accessibility
- WCAG 2.1 Level AA.
- Semantic HTML; one
<h1>per page; no skipped heading levels. - All images need
alt; decorative usealt="". - 4.5:1 / 3:1 contrast minimums.
- Every form input: visible
<label>linked viahtmlFor/id. - Keyboard accessible; native
<button>for actions,<a>/<Link>for navigation. - Custom widgets: implement WAI-ARIA pattern + keyboard handling.
- Modals trap focus and restore on close.
9. Environments, Secrets, Dependencies
.envnever committed;.env.examplealways provided and current.- Client-exposed vars use framework prefix (e.g.,
VITE_). - Never commit / log secrets. Rotate immediately if leaked.
- Verify a new dep is necessary; prefer well-maintained, MIT/Apache/BSD.
- No trivial deps (
is-odd,left-pad, etc.). - Lock files always committed, exact versions, no
latestranges. - Dev dependencies separated from production.
10. Security
- Validate/sanitize all user input on the server.
- Parameterize all DB queries.
- Auto-escape templating; no
dangerouslySetInnerHTML/| safewithout lead approval. - AuthN/AuthZ on every endpoint.
- HTTPS only (except
localhost). - Security headers: CSP, X-Content-Type-Options, HSTS, X-Frame-Options.
- CSRF protection (Django middleware / secure token storage on SPA).
- Rate-limit auth endpoints + public APIs.
- Never log passwords/tokens/PII.
- Principle of least privilege for service accounts.
11. Infrastructure
compose.yaml(noversion:key) for Docker Compose.
12. Enforcement
- Pre-commit hooks: format, lint, import order.
- CI: tests, lint, type check, build, dep audit.
- Code review: naming, docs, architecture, a11y.
- Non-compliance is grounds for requesting changes.
When in doubt, fetch the latest version from Notion via the MCP server and follow it — these guidelines evolve.