Engineering Principles
Owner: Engineering Last reviewed: 2026-Q2
These principles guide how we design, build, and operate software at WorkOpti. They reflect our product needs and the stack in this repo (FastAPI + PostgreSQL + React + Azure).
1) Customer Impact > Output
- Build the smallest valuable slice; ship iteratively.
- Prefer changes that improve end-to-end flow (frontend → API → DB) over local optimizations.
- Validate with metrics and feedback, not opinions.
2) Ownership Across the Stack
- Developers own features from UX to API and data.
- Keep contracts explicit: OpenAPI drives the TypeScript client (
frontend/orval.config.ts). - When changing an API route or schema, update OpenAPI and regenerate clients (
npm run orval).
3) Security by Default
- Enforce secure defaults (see
backend/py/main.pySecurityHeadersMiddleware; HSTS for non-dev). - Validate uploads strictly (file size, MIME, extensions in
backend/py/core/config.py). - Scope access via our dual-auth model (Clerk JWT + local user, ADR-001). Avoid cross-user data leaks.
- Never log secrets or PII. Use structured logs and trace IDs.
4) Reliability and Observability
- Health endpoints (
/health/*) must reflect actual dependencies (DB, storage, external APIs) as appropriate. - Instrument services with OpenTelemetry; export to Azure Monitor (see requirements and config).
- Write idempotent and retry-safe integrations. Prefer deterministic keys (e.g.,
content_hash).
5) Explicit Architecture Decisions
- Record significant decisions as ADRs (
backend/py/docs/adr/*). - Capture context, options, decision, and consequences. Keep them short and practical.
6) Small, Reviewable Changes
- Favor small PRs with clear intent, passing CI, and updated docs.
- Include tests touching the changed surface: unit for pure logic, integration for routes/services.
- Keep changes scoped; avoid opportunistic refactors unless directly improving the work at hand.
7) Paved Paths > Cleverness
- Use established patterns in this repo (FastAPI routers, service layer, Pydantic schemas, React Query on the client).
- Prefer composition over inheritance, functions over magic.
- Optimize for readability; the next engineer should understand it quickly.
8) Performance with Guardrails
- Measure first; optimize the hot path only.
- Cache and batch external calls where safe (e.g., embeddings batching).
- For list endpoints, paginate by default and bound query costs (indexes, selective projections).
9) Consistent Interfaces
- Backend: Pydantic response models live in
backend/py/schemas/; route groups use stable tags and prefixes. - Frontend: generated API clients in
frontend/src/api/generated, queries via TanStack Query, errors viauseApiError. - Keep DTOs and types synchronized through OpenAPI.
Resolving Trade-Offs
When principles conflict, use this order:
- Security and data isolation outrank speed, convenience, and visual polish.
- Reliability outranks new capability when a change risks data loss, broken auth, or failed deploys.
- Customer impact outranks internal elegance when both options are safe and maintainable.
- Consistent interfaces outrank local shortcuts when the change affects multiple clients or teams.
- Small changes outrank broad refactors unless the refactor is required to make the change safe.
Example: a small feature that needs a new sharing permission must first use the established authorization helpers and tests, even if a direct query would be faster to write. After that, keep the product slice narrow and defer unrelated cleanup.
10) Operational Excellence
- CI builds containers; CD targets Azure Web Apps with commit-based tags.
- Rollouts are incremental per environment (dev → showcase → prod). Use health + logs to verify.
- On incidents: fix forward safely, then write a brief postmortem + action items.
Checklist for changes
- Update OpenAPI and regenerate clients if API surface changes.
- Add/adjust tests for new behavior.
- Update ADRs if the change reflects a lasting architectural decision.
- Verify security: authZ boundaries, input validation, secrets handling.
- Ensure observability: logs, traces, and health checks cover the change.