update the repo

This commit is contained in:
DatTT127
2026-06-23 13:39:43 +07:00
parent 3283a8f8af
commit fdb384434d
61 changed files with 1450 additions and 226 deletions

View File

@@ -0,0 +1,45 @@
# Checklist: coding_convention
Instructions: For each item below, mark whether the change complies with the rule.
## Python Conventions
- [ ] File names use snake_case (e.g., `patient_service.py`)
- [ ] Class names use PascalCase (e.g., `PatientService`)
- [ ] Function and variable names use snake_case (e.g., `get_patient_by_id`)
- [ ] Constants use UPPER_SNAKE_CASE (e.g., `MAX_PATIENTS_PER_PAGE`)
- [ ] Line length does not exceed 100 characters
- [ ] Every public function, class, and module has a docstring
- [ ] Docstrings follow Google/NumPy style (Args, Returns, Side Effects)
- [ ] No `print()` statements; logging is used instead
- [ ] Exceptions are typed and not overly broad (avoid bare `except:`)
- [ ] FastAPI routers use `APIRouter(prefix=...)`
## TypeScript/React Conventions
- [ ] File names use snake_case (e.g., `patient_list.tsx`)
- [ ] Component names use PascalCase (e.g., `PatientList`)
- [ ] Hook names use `useSnakeCase` (e.g., `usePatientData`)
- [ ] Follows Airbnb JavaScript/TypeScript style guide
- [ ] No `console.log()` in production code (use proper logging)
## Error Handling
- [ ] No `print()` or `console.log()` for error reporting
- [ ] Errors are logged at appropriate level (debug/info/warn/error)
- [ ] Custom exceptions are used where appropriate
- [ ] Exceptions are not swallowed without handling
## RBAC
- [ ] Only use role constants: `RO_RADIOLOGIST`, `RO_THERAPIST`
- [ ] No hard-coded role strings in conditionals
- [ ] Role checks are centralized where possible
## Configuration
- [ ] No hard-coded endpoints, API keys, or configuration values
- [ ] Configuration loaded via environment variables or secrets/
- [ ] `secrets/` directory is properly gitignored
- [ ] No secrets in code, logs, or comments
## Commit Messages
- [ ] Commit message follows Conventional Commits format
- [ ] Type is one of: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
- [ ] Scope is provided when applicable
- [ ] Subject is imperative, lowercase, no trailing period

View File

@@ -0,0 +1,139 @@
# Examples: coding_convention
## Correct Examples
### Python
```python
"""
Module: patient_service
Purpose: Handle patient-related business logic.
"""
from typing import List, Optional
from fastapi import APIRouter, HTTPException
from models.patient import PatientModel
from services.database import DatabaseService
router = APIRouter(prefix="/patients", tags=["patients"])
class PatientService:
"""Service for managing patient records.
Attributes:
db: Database service instance
"""
def __init__(self, db: DatabaseService):
self.db = db
def get_patient_by_id(self, patient_id: str) -> Optional[PatientModel]:
"""Retrieve a patient by their ID.
Args:
patient_id: Unique identifier for the patient
Returns:
PatientModel if found, None otherwise
Side Effects:
None
"""
try:
return self.db.get_patient(patient_id)
except DatabaseError as e:
logger.error(f"Failed to retrieve patient {patient_id}: {e}")
raise
```
### TypeScript/React
```typescript
import { create } from 'zustand';
import { useEffect } from 'react';
// Hook name follows useSnakeCase
const usePatientStore = create<PatientState>((set, get) => ({
patients: [],
loading: false,
error: null,
fetchPatients: async () => {
set({ loading: true, error: null });
try {
const response = await api.getPatients();
set({ patients: response.data, loading: false });
} catch (err) {
set({ error: err.message, loading: false });
}
},
}));
export const PatientList: React.FC = () => {
const { patients, loading, error } = usePatientStore();
// Component name: PascalCase
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return (
<ul>
{patients.map(patient => (
<li key={patient.id}>{patient.name}</li>
))}
</ul>
);
};
```
### Error Handling
```python
# Good: Using logging instead of print
import logging
logger = logging.getLogger(__name__)
def process_data(data: dict) -> dict:
try:
# Process data
result = transform_data(data)
return result
except ValidationError as e:
logger.warning(f"Validation failed: {e}")
raise InvalidInputError(str(e)) from e
except Exception as e:
logger.error(f"Unexpected error in process_data: {e}")
raise
```
### RBAC
```python
# Good: Using role constants
from auth.roles import RO_RADIOLOGIST, RO_THERAPIST
def can_read_patient_records(user_role: str) -> bool:
return user_role in [RO_RADIOLOGIST, RO_THERAPIST]
# Bad: Hard-coded role strings
def can_read_patient_records_bad(user_role: str) -> bool:
return user_role in ["radiologist", "therapist"] # VIOLATION
```
### Configuration
```python
# Good: Loading from environment
import os
API_BASE_URL = os.environ.get("API_BASE_URL", "http://localhost:8000")
MAX_UPLOAD_SIZE = int(os.environ.get("MAX_UPLOAD_SIZE", "10485760")) # 10MB
# Bad: Hard-coded values
API_BASE_URL = "http://localhost:8000" # VIOLATION
```
### Commit Messages
```
feat(auth): add JWT refresh token endpoint
fix(patient-api): fix patient ID validation typo
docs(api): update patient endpoint documentation
refactor(core): extract database connection logic
```

View File

@@ -0,0 +1,59 @@
# Skill: coding_convention
## Trigger Conditions
Any code edit or creation (files with extensions: .py, .js, .ts, .tsx, .java, .cpp, .h, etc.)
## Rules
### 1. Python Conventions
- Follow PEP 8 with line length ≤ 100 characters
- Use `ruff`-compatible formatting
- Class names: `PascalCase`
- Function and variable names: `snake_case`
- Constants: `UPPER_SNAKE_CASE`
- FastAPI routers should be grouped under `APIRouter(prefix=...)`
- Every public function, class, and module must have a docstring:
- Purpose: brief description
- Parameters: list with types and descriptions
- Return: return type and description
- Side-effects: note any side effects (if applicable)
- Severity: `[ERROR]`
### 2. TypeScript/JavaScript Conventions
- Follow Airbnb JavaScript Style Guide
- Use ESLint with `eslint-config-airbnb` as base
- Component names: `PascalCase`
- Hook names: `useSnakeCase` (e.g., `useUserData`)
- File names: `snake_case.tsx` or `snake_case.ts`
- Use TypeScript strict mode
- Prefer interfaces over types for object shapes
- Export constants as `const` in UPPER_SNAKE_CASE
- Severity: `[ERROR]`
### 3. Error Handling
- Never use `print()` for logging or debugging
- Use appropriate logging levels: `debug`, `info`, `warn`, `error`
- Raise typed exceptions (custom exceptions preferred over generic Exception)
- Handle exceptions at appropriate levels; do not swallow exceptions silently
- Severity: `[ERROR]`
### 4. RBAC (Role-Based Access Control)
- Use only declared role constants for permission checks:
- `RO_RADIOLOGIST` (Read-Only Radiologist)
- `RO_THERAPIST` (Read-Only Therapist)
- Do not hard-code role strings in conditionals
- Severity: `[ERROR]`
### 5. Configuration Management
- No hard-coded endpoints, API keys, or configuration values
- Load configuration from environment variables via `os.environ.get()` (Python) or `process.env` (Node.js)
- Secrets must be loaded from the `secrets/` directory or environment variables only
- Severity: `[ERROR]`
### 6. Commit Messages
- Follow Conventional Commits format: `<type>(<scope>): <subject>`
- Types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`
- Scope should be the module or component affected (optional but recommended)
- Subject should be imperative, lowercase, no trailing period
- Body and footer optional but recommended for complex changes
- Severity: `[WARN]`