update the repo
This commit is contained in:
45
AGENT_SKILL/coding_convention/CHECKLIST.md
Normal file
45
AGENT_SKILL/coding_convention/CHECKLIST.md
Normal 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
|
||||
139
AGENT_SKILL/coding_convention/EXAMPLES.md
Normal file
139
AGENT_SKILL/coding_convention/EXAMPLES.md
Normal 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
|
||||
```
|
||||
59
AGENT_SKILL/coding_convention/SKILL.md
Normal file
59
AGENT_SKILL/coding_convention/SKILL.md
Normal 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]`
|
||||
Reference in New Issue
Block a user