From 9c0715637fae4ed11ee354dafff011440a8a4b5a Mon Sep 17 00:00:00 2001 From: abhishekbhakat Date: Thu, 18 Dec 2025 17:41:25 +0530 Subject: [PATCH] docs: introduce comprehensive coding standards for the zhealth monorepo. --- PROJECT_MGMT/coding_standards.md | 189 +++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 PROJECT_MGMT/coding_standards.md diff --git a/PROJECT_MGMT/coding_standards.md b/PROJECT_MGMT/coding_standards.md new file mode 100644 index 0000000..cd9bb23 --- /dev/null +++ b/PROJECT_MGMT/coding_standards.md @@ -0,0 +1,189 @@ +# Coding Standards: zhealth Monorepo + +## Core Principles + +1. **Modularity First** — Every component should be independent and reusable. +2. **Self-Documenting Structure** — The folder tree and file names should explain purpose without needing comments. +3. **Small Files** — Max **200 lines** per file. A function belongs in a file **only if its purpose is obvious from the filename**. When in doubt, create a separate file. + +--- + +## File & Folder Naming + +| Type | Convention | Example | +|------|------------|---------| +| Folders | `snake_case` | `auth_handlers/`, `biomarker_utils/` | +| Rust files | `snake_case.rs` | `user_service.rs`, `jwt_middleware.rs` | +| TypeScript/React files | `PascalCase.tsx` for components | `Dashboard.tsx`, `BiomarkerCard.tsx` | +| TypeScript utilities | `camelCase.ts` | `apiClient.ts`, `formatDate.ts` | +| Test files | `*.test.ts` / `*_test.rs` | `auth.test.ts`, `user_service_test.rs` | +| Config files | `lowercase` with dots | `vite.config.ts`, `.env.local` | + +--- + +## Folder Structure (Monorepo) + +``` +zhealth/ +├── PROJECT_MGMT/ # Project planning & docs +├── backend/ # Rust API +│ ├── src/ +│ │ ├── handlers/ # Route handlers (one file per resource) +│ │ ├── models/ # SeaORM entities +│ │ ├── services/ # Business logic +│ │ ├── middleware/ # Auth, logging, etc. +│ │ ├── utils/ # Shared helpers +│ │ └── main.rs +│ └── Cargo.toml +├── frontend/ # React + Vite +│ ├── src/ +│ │ ├── components/ # Reusable UI components +│ │ ├── pages/ # Route-level components +│ │ ├── hooks/ # Custom React hooks +│ │ ├── services/ # API calls +│ │ ├── utils/ # Helper functions +│ │ └── App.tsx +│ └── package.json +└── shared/ # Shared types/constants (if needed) +``` + +--- + +## Makefile as Command Runner + +All common tasks are executed through the root **Makefile**. Do not use raw `cargo`, `npm`, or tool-specific commands directly — always use `make`. + +| Command | Purpose | +|---------|---------| +| `make lint` | Run linters (Clippy + ESLint) | +| `make typecheck` | Type checking (Rust + TypeScript) | +| `make dev` | Start dev servers (backend + frontend) | +| `make build` | Build for development | +| `make release` | Build optimized production bundle | +| `make serve` | Serve production build locally | +| `make test` | Run all tests | +| `make clean` | Clean build artifacts | + +### Why Makefile? +- **Single source of truth** for all commands +- **Works across all platforms** (unlike npm scripts for Rust) +- **Self-documenting** — run `make help` to see available targets +- **Composable** — targets can depend on each other + +--- + +## Configuration (`config.yaml`) + +All backend configuration is centralized in a **`config.yaml`** file at the backend root. Never hardcode paths, ports, or environment-specific values. + +### Required Config Keys + +```yaml +# backend/config.yaml + +server: + host: "0.0.0.0" + port: 3000 + +paths: + database: "./data/zhealth.db" + logs: "./logs" + +auth: + jwt_secret: "${JWT_SECRET}" # Loaded from env + token_expiry_hours: 24 + +ai: + provider: "gemini" # gemini | openai | anthropic + api_key: "${AI_API_KEY}" +``` + +### Rules +- **Secrets via env vars** — Use `${VAR_NAME}` syntax for sensitive values +- **Paths are relative** to the backend folder (or absolute if needed) +- **No hardcoding** — If it might change across environments, put it in config + +--- + +## File Size Rules + +| Rule | Action | +|------|--------| +| File > 200 lines | Split into smaller modules | +| Function > 50 lines | Extract to helper or break into sub-functions | +| Single responsibility | One file = one purpose | + +### Example: Splitting a Large Handler + +❌ **Bad**: `handlers/biomarkers.rs` with 400 lines + +✅ **Good**: +``` +handlers/ +├── biomarkers/ +│ ├── mod.rs # Re-exports +│ ├── create.rs # POST /biomarkers +│ ├── read.rs # GET /biomarkers +│ ├── update.rs # PUT /biomarkers/:id +│ └── delete.rs # DELETE /biomarkers/:id +``` + +--- + +## Import & Module Organization + +### Rust +```rust +// 1. Standard library +use std::collections::HashMap; + +// 2. External crates +use axum::{Router, Json}; +use serde::{Deserialize, Serialize}; + +// 3. Internal modules +use crate::models::User; +use crate::services::auth_service; +``` + +### TypeScript +```typescript +// 1. React/Framework +import { useState, useEffect } from 'react'; + +// 2. External packages +import axios from 'axios'; + +// 3. Internal components/utils +import { BiomarkerCard } from '@/components/BiomarkerCard'; +import { formatDate } from '@/utils/formatDate'; +``` + +--- + +## Commit & Branch Naming + +| Type | Format | Example | +|------|--------|---------| +| Branch | `type/short-description` | `feat/biomarker-crud`, `fix/auth-token-expiry` | +| Commit | `type: short description` | `feat: add biomarker create endpoint` | + +**Types**: `feat`, `fix`, `docs`, `refactor`, `test`, `chore` + +--- + +## Code Comments + +- **Avoid obvious comments** — Code should be self-explanatory. +- **Document "why", not "what"** — Explain non-obvious decisions. +- **Use doc comments** for public APIs: + - Rust: `///` for functions, `//!` for modules + - TypeScript: JSDoc `/** */` for exported functions + +--- + +## Enforcement + +- [ ] Pre-commit hooks for linting (Clippy for Rust, ESLint for TS) +- [ ] CI pipeline checks for file size violations +- [ ] PR reviews must verify modularity standards