update the repo
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -207,3 +207,7 @@ secrets/
|
|||||||
# End of .gitignore
|
# End of .gitignore
|
||||||
*.docx
|
*.docx
|
||||||
*.bkp
|
*.bkp
|
||||||
|
*.drawio
|
||||||
|
*.gemini
|
||||||
|
*.claude
|
||||||
|
*.kilo
|
||||||
19
AGENT_SKILL/INTRODUCTION.md
Normal file
19
AGENT_SKILL/INTRODUCTION.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# VKIST MSK Pilot — Shared Agent Enforcement Skills
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
Create up to 5 shareable agent skills under `PILOT_PROJECT/AGENT_SKILL/` that automatically guide coding agents (Claude Code, Gemini CLI, KILO) to follow project conventions from `README.md` and architecture specs.
|
||||||
|
|
||||||
|
## How to add a new skill?
|
||||||
|
1. Create a new folder under AGENT_SKILL/<skill_name>/
|
||||||
|
2. Add SKILL.md, EXAMPLES.md, CHECKLIST.md
|
||||||
|
3. Update this INTRODUCTION.md index
|
||||||
|
4. Open a PR with at least one EXAMPLES.md entry per rule
|
||||||
|
|
||||||
|
## Skills Index
|
||||||
|
| Skill | Covers |
|
||||||
|
|-------|--------|
|
||||||
|
| file_naming_convention | File/dir names, forbidden extensions, LEGACY/ policy |
|
||||||
|
| coding_convention | Python PEP8, TS Airbnb, docstrings, error handling, RBAC |
|
||||||
|
| interface_contract_hygiene | Contract files, versioning, breaking-change policy |
|
||||||
|
| secrets_and_phi_safety | Secrets loading, PHI exclusion, CI safety, gitignore |
|
||||||
|
| design_pattern_compliance | Layered arch, DI, Zustand, Terraform IaC, pinning |
|
||||||
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]`
|
||||||
51
AGENT_SKILL/design_pattern_compliance/CHECKLIST.md
Normal file
51
AGENT_SKILL/design_pattern_compliance/CHECKLIST.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# Checklist: design_pattern_compliance
|
||||||
|
|
||||||
|
## Layered Architecture (Backend)
|
||||||
|
- [ ] No direct calls from presentation layer to data access layer
|
||||||
|
- [ ] Controllers only handle HTTP concerns (validation, serialization, routing)
|
||||||
|
- [ ] Business logic resides in service layer
|
||||||
|
- [ ] Data access layer handles only persistence concerns
|
||||||
|
- [ ] No upward dependencies (data layer does not depend on service layer)
|
||||||
|
|
||||||
|
## Dependency Injection
|
||||||
|
- [ ] No direct instantiation of infrastructure dependencies (e.g., `new MongoClient()`)
|
||||||
|
- [ ] Dependencies are injected (constructor, setter, or framework DI)
|
||||||
|
- [ ] Classes depend on interfaces/protocols, not concrete implementations
|
||||||
|
- [ ] Framework-appropriate DI mechanisms are used (e.g., FastAPI Depends, Spring @Autowired)
|
||||||
|
|
||||||
|
## Interface-Driven Development
|
||||||
|
- [ ] Business logic depends on abstractions (interfaces/repositories)
|
||||||
|
- [ ] No direct infrastructure calls in business logic (no `boto3`, `psycopg2.connect()`, etc. in services)
|
||||||
|
- [ ] Concrete implementations exist for interfaces but are injected, not instantiated internally
|
||||||
|
|
||||||
|
## Frontend State Management (Zustand)
|
||||||
|
- [ ] Global shared state is managed in Zustand stores
|
||||||
|
- [ ] Component state (`useState`) is used only for:
|
||||||
|
- Form inputs and UI controls
|
||||||
|
- Temporary UI state (loading states for local effects, animation states)
|
||||||
|
- Data that is truly isolated to a single component
|
||||||
|
- [ ] Store follows naming convention: `use[Domain]Store`
|
||||||
|
- [ ] Store actions are named as verbs
|
||||||
|
- [ ] No business logic in components that should be in store actions
|
||||||
|
|
||||||
|
## Infrastructure as Code
|
||||||
|
- [ ] Terraform configuration uses a remote backend (GCS, S3, etc.)
|
||||||
|
- [ ] No local `terraform.tfstate` files committed
|
||||||
|
- [ ] Resources are named with environment identifier (e.g., `${var.environment}`)
|
||||||
|
- [ ] IAM roles follow least privilege principle (specific permissions, no wildcards)
|
||||||
|
- [ ] Separate configurations or workspaces for different environments
|
||||||
|
- [ ] All providers and modules have explicit version pins
|
||||||
|
- [ ] Terraform files are formatted (`terraform fmt`)
|
||||||
|
|
||||||
|
## Dependency Pinning
|
||||||
|
- [ ] Python: `requirements.txt` or `pyproject.toml` contains exact versions (no `~`, `>`, `<` without corresponding lock file)
|
||||||
|
- [ ] Python: If using `pyproject.toml` with poetry or pipenv, lock file (`poetry.lock` or `Pipfile.lock`) is present
|
||||||
|
- [ ] Node.js: `package-lock.json` or `yarn.lock` is present and matches `package.json`
|
||||||
|
- [ ] Other languages: Equivalent lock files are present and committed
|
||||||
|
- [ ] No unpinned dependencies that could cause non-reproducible builds
|
||||||
|
|
||||||
|
## Code Quality
|
||||||
|
- [ ] Duplicated code has been considered for extraction
|
||||||
|
- [ ] Preference given to composition over inheritance where applicable
|
||||||
|
- [ ] Utility functions are placed in appropriate shared locations
|
||||||
|
- [ ] No "God classes" or objects with too many responsibilities
|
||||||
363
AGENT_SKILL/design_pattern_compliance/EXAMPLES.md
Normal file
363
AGENT_SKILL/design_pattern_compliance/EXAMPLES.md
Normal file
@@ -0,0 +1,363 @@
|
|||||||
|
# Examples: design_pattern_compliance
|
||||||
|
|
||||||
|
## Correct Examples
|
||||||
|
|
||||||
|
### Layered Architecture (Python/FastAPI)
|
||||||
|
```python
|
||||||
|
# GOOD: Proper layer separation
|
||||||
|
# presentation layer (api/patients.py)
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
|
from services.patient_service import PatientService
|
||||||
|
from models.patient import PatientResponse
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/patients", tags=["patients"])
|
||||||
|
|
||||||
|
def get_patient_service() -> PatientService:
|
||||||
|
# Dependency injection - could come from a DI container
|
||||||
|
return PatientService(
|
||||||
|
repository=PatientRepository() # In practice, this would be injected
|
||||||
|
)
|
||||||
|
|
||||||
|
@router.get("/{patient_id}", response_model=PatientResponse)
|
||||||
|
def get_patient(
|
||||||
|
patient_id: str,
|
||||||
|
service: PatientService = Depends(get_patient_service)
|
||||||
|
):
|
||||||
|
"""Controller handles only HTTP concerns."""
|
||||||
|
patient = service.get_patient_by_id(patient_id)
|
||||||
|
if not patient:
|
||||||
|
raise HTTPException(status_code=404, detail="Patient not found")
|
||||||
|
return patient
|
||||||
|
|
||||||
|
|
||||||
|
# service layer (services/patient_service.py)
|
||||||
|
from repositories.patient_repository import PatientRepository
|
||||||
|
from models.patient import PatientModel
|
||||||
|
|
||||||
|
class PatientService:
|
||||||
|
def __init__(self, repository: PatientRepository):
|
||||||
|
self.repository = repository # Dependency injected
|
||||||
|
|
||||||
|
def get_patient_by_id(self, patient_id: str) -> Optional[PatientModel]:
|
||||||
|
# Business logic lives here
|
||||||
|
return self.repository.get_by_id(patient_id)
|
||||||
|
|
||||||
|
|
||||||
|
# data access layer (repositories/patient_repository.py)
|
||||||
|
from models.patient import PatientModel
|
||||||
|
|
||||||
|
class PatientRepository:
|
||||||
|
def get_by_id(self, patient_id: str) -> Optional[PatientModel]:
|
||||||
|
# Data access concerns only
|
||||||
|
# In real implementation, this would query a database
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dependency Injection with Interfaces
|
||||||
|
```python
|
||||||
|
# GOOD: Interface-based dependencies
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from typing import Protocol
|
||||||
|
|
||||||
|
# Define interface (protocol)
|
||||||
|
class PatientRepository(Protocol):
|
||||||
|
def get_by_id(self, patient_id: str) -> Optional[PatientModel]: ...
|
||||||
|
def save(self, patient: PatientModel) -> bool: ...
|
||||||
|
|
||||||
|
# Concrete implementation
|
||||||
|
class PostgreSQLPatientRepository:
|
||||||
|
def __init__(self, connection_string: str):
|
||||||
|
self.connection_string = connection_string
|
||||||
|
|
||||||
|
def get_by_id(self, patient_id: str) -> Optional[PatientModel]:
|
||||||
|
# Implementation details
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Service depends on interface, not concrete class
|
||||||
|
class PatientService:
|
||||||
|
def __init__(self, repository: PatientRepository): # Accepts any implementation
|
||||||
|
self.repository = repository
|
||||||
|
|
||||||
|
def get_patient(self, patient_id: str) -> Optional[PatientModel]:
|
||||||
|
return self.repository.get_by_id(patient_id)
|
||||||
|
|
||||||
|
# Usage with dependency injection
|
||||||
|
def get_patient_service() -> PatientService:
|
||||||
|
repo = PostgreSQLPatientRepository(os.getenv("DB_CONNECTION"))
|
||||||
|
return PatientService(repository)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend Zustand Store
|
||||||
|
```javascript
|
||||||
|
// GOOD: Proper Zustand store usage
|
||||||
|
import { create } from 'zustand';
|
||||||
|
|
||||||
|
// Patient store slice
|
||||||
|
const usePatientStore = create((set, get) => ({
|
||||||
|
// State
|
||||||
|
patients: [],
|
||||||
|
loading: false,
|
||||||
|
error: null,
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
setPatients: (patients) => set({ patients }),
|
||||||
|
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 });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addPatient: (patient) => set((state) => ({
|
||||||
|
patients: [...state.patients, patient],
|
||||||
|
loading: false,
|
||||||
|
error: null
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Component using store - ONLY for UI state
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { usePatientStore } from '../store/patientStore';
|
||||||
|
|
||||||
|
export const PatientForm: React.FC = () => {
|
||||||
|
// LOCAL UI state only - correct use of useState
|
||||||
|
const [name, setName] = useState('');
|
||||||
|
const [dob, setDob] = useState('');
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
|
|
||||||
|
// GLOBAL state from store
|
||||||
|
const { patients, loading, error, addPatient } = usePatientStore();
|
||||||
|
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setSubmitting(true);
|
||||||
|
try {
|
||||||
|
await addPatient({ id: Date.now(), name, dob });
|
||||||
|
setName('');
|
||||||
|
setDob('');
|
||||||
|
} finally {
|
||||||
|
setSubmitting(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
{/* Form fields using local state */}
|
||||||
|
<input value={name} onChange={(e) => setName(e.target.value)} placeholder="Name" />
|
||||||
|
<input value={dob} onChange={(e) => setDob(e.target.value)} placeholder="Date of Birth" />
|
||||||
|
<button type="submit" disabled={submitting}>
|
||||||
|
{submitting ? 'Adding...' : 'Add Patient'}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Displaying global state */}
|
||||||
|
{loading && <p>Saving...</p>}
|
||||||
|
{error && <p>Error: {error}</p>}
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Infrastructure as Code (Terraform)
|
||||||
|
```hcl
|
||||||
|
# GOOD: Proper Terraform practices
|
||||||
|
terraform {
|
||||||
|
# REQUIRED: Remote backend
|
||||||
|
backend "gcs" {
|
||||||
|
bucket = "vkist-terraform-state"
|
||||||
|
prefix = "env/${var.environment}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# REQUIRED: Versioned providers
|
||||||
|
required_providers {
|
||||||
|
google = {
|
||||||
|
source = "hashicorp/google"
|
||||||
|
version = "~> 4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "environment" {
|
||||||
|
description = "Deployment environment"
|
||||||
|
type = string
|
||||||
|
validation {
|
||||||
|
condition = ["dev", "staging", "prod"].contains(var.upper)
|
||||||
|
error_message = "Environment must be either dev, staging, or prod."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# RESOURCE NAMING with environment
|
||||||
|
resource "google_compute_instance" "vm" {
|
||||||
|
name = "vkist-${var.environment}-backend"
|
||||||
|
machine_type = "e2-medium"
|
||||||
|
|
||||||
|
# ... other configuration
|
||||||
|
}
|
||||||
|
|
||||||
|
# LEAST PRIVILEGE IAM
|
||||||
|
resource "google_service_account" "backend" {
|
||||||
|
account_id = "vkist-backend-${var.environment}"
|
||||||
|
display_name = "VKIST Backend Service Account"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Grant only necessary roles
|
||||||
|
resource "google_project_iam_member" "storage_reader" {
|
||||||
|
role = "roles/storage.objectViewer"
|
||||||
|
member = "serviceAccount:${google_service_account.backend.email}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# VERSIONED MODULES
|
||||||
|
module "network" {
|
||||||
|
source = "terraform-google-modules/network/google"
|
||||||
|
version = "~> 5.0"
|
||||||
|
|
||||||
|
project_id = var.project_id
|
||||||
|
network_name = "vkist-${var.environment}-net"
|
||||||
|
# ... other parameters
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dependency Pinning
|
||||||
|
```txt
|
||||||
|
# GOOD: requirements.txt with exact versions
|
||||||
|
fastapi==0.104.1
|
||||||
|
uvicorn[standard]==0.24.0
|
||||||
|
pydantic==2.5.0
|
||||||
|
sqlalchemy==2.0.23
|
||||||
|
alembic==1.13.1
|
||||||
|
python-multipart==0.0.6
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
// GOOD: package.json with package-lock.json
|
||||||
|
{
|
||||||
|
"name": "vkist-frontend",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"zustand": "^4.4.1",
|
||||||
|
"axios": "^1.6.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// package-lock.json ensures exact versions are installed
|
||||||
|
```
|
||||||
|
|
||||||
|
## Incorrect Examples (to avoid)
|
||||||
|
|
||||||
|
### Layer Violation
|
||||||
|
```python
|
||||||
|
# BAD: Controller directly accessing repository (skipping service layer)
|
||||||
|
from fastapi import APIRouter, Depends
|
||||||
|
from repositories.patient_repository import PatientRepository
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
@router.get("/patients/{id}")
|
||||||
|
def get_patient(patient_id: str, repo: PatientRepository = Depends()):
|
||||||
|
# VIOLATION: Presentation layer accessing data layer directly
|
||||||
|
return repo.get_by_id(patient_id)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Direct Infrastructure Instantiation
|
||||||
|
```python
|
||||||
|
# BAD: Service creating its own database connection
|
||||||
|
import psycopg2
|
||||||
|
import os
|
||||||
|
|
||||||
|
class PatientService:
|
||||||
|
def __init__(self):
|
||||||
|
# VIOLATION: Direct instantiation of infrastructure
|
||||||
|
self.conn = psycopg2.connect(
|
||||||
|
host=os.getenv("DB_HOST"),
|
||||||
|
database=os.getenv("DB_NAME"),
|
||||||
|
user=os.getenv("DB_USER"),
|
||||||
|
password=os.getenv("DB_PASSWORD")
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_patient(self, patient_id: str):
|
||||||
|
cursor = self.conn.cursor()
|
||||||
|
cursor.execute("SELECT * FROM patients WHERE id = %s", (patient_id,))
|
||||||
|
return cursor.fetchone()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend Anti-pattern: State in Components
|
||||||
|
```javascript
|
||||||
|
// BAD: Using useState for shared data that should be in store
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { fetchPatients } from '../api/patientApi';
|
||||||
|
|
||||||
|
export const PatientList: React.FC = () => {
|
||||||
|
// WRONG: This state is shared and should be in a store
|
||||||
|
const [patients, setPatients] = useState([]);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadPatients = async () => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const data = await fetchPatients();
|
||||||
|
setPatients(data); // This state might be needed by other components
|
||||||
|
setLoading(false);
|
||||||
|
} catch (err) {
|
||||||
|
setError(err.message);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
loadPatients();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// ... render logic
|
||||||
|
};
|
||||||
|
|
||||||
|
// If another component needs patients data, it would have to fetch again
|
||||||
|
// or receive it via props - inefficient and not scalable
|
||||||
|
```
|
||||||
|
|
||||||
|
### Infrastructure Mistakes
|
||||||
|
```hcl
|
||||||
|
# BAD: Local state storage (should be remote)
|
||||||
|
terraform {
|
||||||
|
# MISSING: backend configuration
|
||||||
|
# state will be stored locally - VIOLATION
|
||||||
|
}
|
||||||
|
|
||||||
|
# BAD: Hard-coded environment (should be variable)
|
||||||
|
resource "google_compute_network" "vpc" {
|
||||||
|
name = "vkist-prod-network" # What if we want to deploy to staging?
|
||||||
|
}
|
||||||
|
|
||||||
|
# BAD: Overly permissive IAM
|
||||||
|
resource "google_project_iam_member" "admin" {
|
||||||
|
role = "roles/editor" # Too permissive - VIOLATION of least privilege
|
||||||
|
member = "user:admin@example.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
# BAD: Unpinned module version
|
||||||
|
module "network" {
|
||||||
|
source = "terraform-google-modules/network/google"
|
||||||
|
# MISSING: version parameter - could get breaking changes on next run
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dependency Issues
|
||||||
|
```txt
|
||||||
|
# BAD: Unpinned dependencies in requirements.txt
|
||||||
|
fastapi
|
||||||
|
uvicorn
|
||||||
|
pydantic
|
||||||
|
# Any of these could break on next pip install
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
// BAD: Missing or outdated lock file
|
||||||
|
{
|
||||||
|
"name": "my-app",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.17.21"
|
||||||
|
// No package-lock.json - versions not locked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
96
AGENT_SKILL/design_pattern_compliance/SKILL.md
Normal file
96
AGENT_SKILL/design_pattern_compliance/SKILL.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
# Skill: design_pattern_compliance
|
||||||
|
|
||||||
|
## Trigger Conditions
|
||||||
|
- Creation of a new class, function, or module
|
||||||
|
- Significant refactoring of existing code (architectural changes)
|
||||||
|
- Adding new infrastructure (Terraform modules)
|
||||||
|
- Creating new state slices
|
||||||
|
)
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
### 1. Layered Architecture (Backend)
|
||||||
|
- **Direction of Dependencies**:
|
||||||
|
- Presentation layer (API controllers) → Service layer → Data Access layer
|
||||||
|
- No skipping layers (e.g., controller directly accessing repository)
|
||||||
|
- No upward dependencies (data layer should not depend on service layer)
|
||||||
|
- **Separation of Concerns**:
|
||||||
|
- Controllers handle HTTP concerns only (validation, serialization, routing)
|
||||||
|
- Services contain business logic and orchestration
|
||||||
|
- Data Access/Repositories handle persistence concerns only
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 2. Dependency Injection and Inversion of Control
|
||||||
|
- **No Direct Instantiation**:
|
||||||
|
- Classes should not instantiate their dependencies directly (especially infrastructure clients)
|
||||||
|
- Dependencies should be injected via constructor or setter
|
||||||
|
- **Interface-Based Dependencies**:
|
||||||
|
- Depend on abstractions (interfaces/protocols) rather than concrete implementations
|
||||||
|
- Example: Service depends on `DatabaseRepository` interface, not `PostgreSQLRepository` directly
|
||||||
|
- **Framework-Compatible DI**:
|
||||||
|
- Use framework-provided dependency injection (e.g., FastAPI's `Depends`, Spring `@Autowired`)
|
||||||
|
- Avoid service locator pattern
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 3. Interface-Driven Development
|
||||||
|
- **Program to Interfaces**:
|
||||||
|
- Concrete classes should implement defined interfaces
|
||||||
|
- Clients should depend on interfaces, not implementations
|
||||||
|
- **No Concrete Infra in Business Logic**:
|
||||||
|
- Business logic should not contain direct calls to infrastructure (e.g., `boto3.client()`, `psycopg2.connect()`)
|
||||||
|
- Infrastructure access should be abstracted behind repository/service interfaces
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 4. Frontend State Management (Zustand)
|
||||||
|
- **Store Slices**:
|
||||||
|
- Global state should be split into logical slices using Zustand
|
||||||
|
- Each slice corresponds to a domain (e.g., `usePatientStore`, `useAppointmentStore`)
|
||||||
|
- **No Inline State for Shared Data**:
|
||||||
|
- Component state (`useState`) should only be used for:
|
||||||
|
- UI-specific state (form inputs, toggles, animation states)
|
||||||
|
- Data that is not shared across components
|
||||||
|
- Any data that is shared across components or needed by multiple hooks should be in a store
|
||||||
|
- **Store Structure**:
|
||||||
|
- Follow consistent naming: `use[Domain]Store`
|
||||||
|
- Actions should be named as verbs (e.g., `setPatients`, `fetchAppointments`)
|
||||||
|
- Selectors should be derived and memoized where appropriate
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 5. Infrastructure as Code (IaC) Best Practices
|
||||||
|
- **Terraform State**:
|
||||||
|
- All Terraform configurations must use a remote backend (GCS recommended for this project)
|
||||||
|
- No local `terraform.tfstate` files in the repository
|
||||||
|
- **Resource Naming**:
|
||||||
|
- Use consistent naming conventions that include environment (e.g., `vkist-${var.environment}-service`)
|
||||||
|
- **Least Privilege IAM**:
|
||||||
|
- IAM roles and policies must grant only the permissions necessary
|
||||||
|
- Avoid using wildcard permissions (`*`) or overly broad roles
|
||||||
|
- **Environment Separation**:
|
||||||
|
- Use separate workspaces or directories for different environments (e.g., `env/staging`, `env/prod`)
|
||||||
|
- Do not use the same resources for different environments
|
||||||
|
- **Version Pinning**:
|
||||||
|
- All external dependencies must be version-pinned:
|
||||||
|
- Terraform modules: `source = "terraform-google-modules/network/google//version"`
|
||||||
|
- Provider versions explicitly set
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 6. Dependency Pinning
|
||||||
|
- **Python**:
|
||||||
|
- `requirements.txt` or `pyproject.toml` must contain exact versions (no wildcards)
|
||||||
|
- Use `pip freeze > requirements.txt` for deterministic builds
|
||||||
|
- **Node.js**:
|
||||||
|
- `package-lock.json` or `yarn.lock` must be committed and up to date
|
||||||
|
- Dependencies in `package.json` should use caret (`^`) or tilde (`~`) ranges appropriately, but lock file ensures reproducibility
|
||||||
|
- **Other Ecosystems**:
|
||||||
|
- Equivalent lock files must be present and committed (e.g., `Pipfile.lock`, `poetry.lock`, `Cargo.lock`)
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 7. Code Reusability and Abstraction
|
||||||
|
- **Avoid Duplication**:
|
||||||
|
- Similar code in two or more places should be extracted to a shared utility or component
|
||||||
|
- **Prefer Composition Over Inheritance**:
|
||||||
|
- Especially in complex domain models, favor composing behavior over deep inheritance hierarchies
|
||||||
|
- **Utility Functions**:
|
||||||
|
- Place truly generic utilities in shared locations (e.g., `utils/`, `lib/`)
|
||||||
|
- Avoid creating utility classes with only static methods if not needed in the language
|
||||||
|
- Severity: `[WARN]`
|
||||||
18
AGENT_SKILL/file_naming_convention/CHECKLIST.md
Normal file
18
AGENT_SKILL/file_naming_convention/CHECKLIST.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Checklist: file_naming_convention
|
||||||
|
|
||||||
|
## File/Directory Creation/Rename/Move
|
||||||
|
- [ ] All new files and directories use `snake_case` (lowercase, digits, underscores only)
|
||||||
|
- [ ] No spaces or special characters in file/directory names
|
||||||
|
- [ ] Hyphens (`-`) used only in `docker-compose.yaml`, `docker-compose.yml`, `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`
|
||||||
|
- [ ] `UPPER_SNAKE_CASE` used only for root-level configuration constants (e.g., `CONFIG.json`, `Dockerfile`)
|
||||||
|
- [ ] Forbidden extensions (`.pdf`, `.pptx`, `.docx`, `.xlsx`, `.csv`, `.zip`, `.pth`, `.png`, `.jpg`, `.jpeg`, `.gif`, `.bmp`, `.tiff`, `.webp`, `.mp4`, `.mov`, `.avi`, `.dcm`, `.nii`, `.nii.gz`) are not present in the repository
|
||||||
|
- [ ] Any file under `LEGACY/` that is modified includes an inline comment `# LEGACY:` explaining the change
|
||||||
|
- [ ] Test files follow the pattern: `tests/<same_path_as_source>/test_<source_filename>`
|
||||||
|
|
||||||
|
## Verification Steps
|
||||||
|
1. Check all created/renamed/moved files for snake_case naming
|
||||||
|
2. Verify hyphen usage is limited to allowed files: docker-compose.yaml/.yml, package-lock.json, yarn.lock, pnpm-lock.yaml
|
||||||
|
3. Confirm UPPER_SNAKE_CASE appears only for root config files
|
||||||
|
4. Scan for forbidden file extensions
|
||||||
|
5. Inspect any changes in LEGACY/ directory for required comment
|
||||||
|
6. Validate test file placement matches source file structure
|
||||||
74
AGENT_SKILL/file_naming_convention/EXAMPLES.md
Normal file
74
AGENT_SKILL/file_naming_convention/EXAMPLES.md
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# Examples: file_naming_convention
|
||||||
|
|
||||||
|
## Correct Examples
|
||||||
|
|
||||||
|
### File Naming
|
||||||
|
- `patient_data.csv` → ❌ (forbidden extension, should be external)
|
||||||
|
- `patient_data.json` → ✅ (allowed extension, snake_case)
|
||||||
|
- `Dockerfile` → ✅ (UPPER_SNAKE_CASE allowed for root config)
|
||||||
|
- `docker-compose.yaml` → ✅ (hyphen allowed exception)
|
||||||
|
- `docker-compose.yml` → ✅ (hyphen allowed exception)
|
||||||
|
- `package-lock.json` → ✅ (hyphen allowed exception)
|
||||||
|
- `yarn.lock` → ✅ (hyphen allowed exception)
|
||||||
|
- `pnpm-lock.yaml` → ✅ (hyphen allowed exception)
|
||||||
|
- `config.json` → ✅ (snake_case, allowed extension)
|
||||||
|
- `api/v1/patient_routes.py` → ✅ (snake_case in path)
|
||||||
|
|
||||||
|
### Directory Naming
|
||||||
|
- `data_models/` → ✅
|
||||||
|
- `api_v2/` → ✅
|
||||||
|
- `legacy_data/` → ✅ (but see LEGACY/ rule below)
|
||||||
|
|
||||||
|
### LEGACY/ Directory
|
||||||
|
```python
|
||||||
|
# LEGACY: Temporary fix for migration issue #123
|
||||||
|
# TODO: Remove after migration complete
|
||||||
|
legacy_code_here()
|
||||||
|
```
|
||||||
|
→ ✅ (includes required comment)
|
||||||
|
|
||||||
|
### Test Files
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
models/
|
||||||
|
patient_model.py
|
||||||
|
tests/
|
||||||
|
models/
|
||||||
|
test_patient_model.py
|
||||||
|
```
|
||||||
|
→ ✅ (test file mirrors source path)
|
||||||
|
|
||||||
|
## Incorrect Examples
|
||||||
|
|
||||||
|
### File Naming
|
||||||
|
- `PatientData.json` → ❌ (PascalCase, should be snake_case)
|
||||||
|
- `patient-data.json` → ❌ (hyphen not allowed except docker-compose and lockfiles)
|
||||||
|
- `patient data.json` → ❌ (spaces not allowed)
|
||||||
|
- `patient.PDF` → ❌ (forbidden extension)
|
||||||
|
- `secret_key.pem` → ❌ (forbidden extension)
|
||||||
|
- `package_lock.json` → ❌ (should be package-lock.json with hyphens)
|
||||||
|
- `yarn_lock` → ❌ (should be yarn.lock with hyphen and extension)
|
||||||
|
- `docker_compose.yaml` → ❌ (should be docker-compose.yaml with hyphens)
|
||||||
|
|
||||||
|
### Directory Naming
|
||||||
|
- `DataModels/` → ❌ (PascalCase)
|
||||||
|
- `data-models/` → ❌ (hyphens not allowed)
|
||||||
|
- `data models/` → ❌ (spaces)
|
||||||
|
|
||||||
|
### LEGACY/ Directory
|
||||||
|
```python
|
||||||
|
# Modified legacy function
|
||||||
|
def old_function():
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
→ ❌ (missing `# LEGACY:` comment)
|
||||||
|
|
||||||
|
### Test Files
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
utils/
|
||||||
|
helper.py
|
||||||
|
tests/
|
||||||
|
test_helper.py # ❌ Incorrect: should be tests/utils/test_helper.py
|
||||||
|
```
|
||||||
|
→ ❌ (test file does not mirror source path)
|
||||||
40
AGENT_SKILL/file_naming_convention/SKILL.md
Normal file
40
AGENT_SKILL/file_naming_convention/SKILL.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Skill: file_naming_convention
|
||||||
|
|
||||||
|
## Trigger Conditions
|
||||||
|
Any file or directory create, rename, or move operation.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
### 1. File and Directory Naming
|
||||||
|
- All files and directories must use `snake_case` (lowercase letters, digits, underscores only).
|
||||||
|
- No spaces or special characters (except hyphens in specific cases).
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 2. Hyphen Usage Exception
|
||||||
|
- Hyphens (`-`) are allowed ONLY in the following specific filenames (where changing the name would break standard tooling):
|
||||||
|
- `docker-compose.yaml`, `docker-compose.yml`
|
||||||
|
- `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`
|
||||||
|
- Files beginning with '.' (like `.gitignore`, `.env`, `.npmrc`) are exempt from snake_case requirements for the prefix portion, but the suffix should follow naming conventions where practical.
|
||||||
|
- Any other use of hyphens in file or directory names is prohibited.
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 3. Uppercase Reserved for Root Constants
|
||||||
|
- `UPPER_SNAKE_CASE` is reserved only for root-level configuration constants (e.g., `CONFIG.json`, `Dockerfile`).
|
||||||
|
- Using `UPPER_SNAKE_CASE` for regular files or directories is prohibited.
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 4. Forbidden Extensions
|
||||||
|
The following file extensions are forbidden in the repository (must be stored externally and referenced by URL):
|
||||||
|
- `.pdf`, `.pptx`, `.docx`, `.xlsx`, `.csv`, `.zip`, `.pth`, `.png`, `.jpg`, `.jpeg`, `.gif`, `.bmp`, `.tiff`, `.webp`, `.mp4`, `.mov`, `.avi`, `.dcm`, `.nii`, `.nii.gz`
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 5. LEGACY/ Directory Policy
|
||||||
|
- The `LEGACY/` directory is read-only.
|
||||||
|
- Any modification to files under `LEGACY/` must include an inline comment `# LEGACY:` explaining why the change is necessary.
|
||||||
|
- Failure to include this comment when modifying LEGACY/ files is a violation.
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 6. Test File Naming
|
||||||
|
- Test files must mirror the source file path in a parallel `tests/` directory.
|
||||||
|
- Example: `src/module.py` → `tests/test_module.py`
|
||||||
|
- Severity: `[WARN]`
|
||||||
29
AGENT_SKILL/interface_contract_hygiene/CHECKLIST.md
Normal file
29
AGENT_SKILL/interface_contract_hygiene/CHECKLIST.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Checklist: interface_contract_hygiene
|
||||||
|
|
||||||
|
## New Module/Package Creation
|
||||||
|
- [ ] New module/package includes a `spec/` directory
|
||||||
|
- [ ] `spec/interface-contract.md` file exists in the new module
|
||||||
|
- [ ] Contract file is located at `<module_path>/spec/interface-contract.md`
|
||||||
|
|
||||||
|
## Contract Content Verification
|
||||||
|
- [ ] Contract includes a clear **Purpose** section
|
||||||
|
- [ ] Contract identifies an **Owner** (team or individual)
|
||||||
|
- [ ] Contract defines the **Boundary** (includes/excludes)
|
||||||
|
- [ ] Contract specifies a **Breaking-change Policy**
|
||||||
|
- [ ] Contract lists **Consumers** (other modules/systems that use this)
|
||||||
|
- [ ] Contract provides **References** to related documentation
|
||||||
|
- [ ] Contract follows the same format/structure as existing contracts in the same domain
|
||||||
|
|
||||||
|
## Contract Modification (Existing Modules)
|
||||||
|
When modifying a public API (changing function signatures, adding/removing endpoints, etc.):
|
||||||
|
- [ ] Breaking changes follow the versioning policy:
|
||||||
|
- Adding features: MINOR version bump
|
||||||
|
- Removing/changing types: MAJOR version with migration path and 60-day notice
|
||||||
|
- [ ] Deprecation warnings are added for removed/changed interfaces
|
||||||
|
- [ ] Migration documentation is provided for breaking changes
|
||||||
|
|
||||||
|
## Template Consistency Check
|
||||||
|
Before creating a new contract:
|
||||||
|
- [ ] Reviewed at least two existing interface-contract.md files in the same domain (backend/frontend/infra)
|
||||||
|
- [ ] Matched section headings and formatting conventions
|
||||||
|
- [ ] Used similar language and level of detail
|
||||||
161
AGENT_SKILL/interface_contract_hygiene/EXAMPLES.md
Normal file
161
AGENT_SKILL/interface_contract_hygiene/EXAMPLES.md
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
# Examples: interface_contract_hygiene
|
||||||
|
|
||||||
|
## Correct Examples
|
||||||
|
|
||||||
|
### Backend Service Contract Example
|
||||||
|
File: `backend/services/patient_service/spec/interface_contract.md`
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Patient Service Interface Contract
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Handles all patient-related business operations including registration, updates, and retrieval of patient records. Provides a clean API for frontend and other backend services.
|
||||||
|
|
||||||
|
## Owner
|
||||||
|
Platform Team (platform-team@vkist.example.com)
|
||||||
|
|
||||||
|
## Boundary
|
||||||
|
**Includes:**
|
||||||
|
- Patient data validation
|
||||||
|
- Appointment scheduling logic
|
||||||
|
- Insurance verification workflows
|
||||||
|
- HL7 message parsing for patient demographics
|
||||||
|
|
||||||
|
**Excludes:**
|
||||||
|
- Image storage and retrieval (handled by Imaging Service)
|
||||||
|
- Payment processing (handled by Billing Service)
|
||||||
|
- User authentication (handled by Auth Service)
|
||||||
|
|
||||||
|
## Breaking-change Policy
|
||||||
|
- **MINOR version**: Adding new optional fields to patient schema, new endpoints for non-core features
|
||||||
|
- **MAJOR version**: Removing fields, changing data types of existing fields, removing endpoints
|
||||||
|
- Requires 60-day deprecation period
|
||||||
|
- Migration guide provided in release notes
|
||||||
|
- Deprecation warnings added 30 days prior to removal
|
||||||
|
|
||||||
|
## Consumers
|
||||||
|
- Frontend Patient Portal (`frontend/modules/patient_portal`)
|
||||||
|
- Appointment Scheduling Service (`backend/services/scheduling`)
|
||||||
|
- Billing Service (`backend/services/billing`)
|
||||||
|
- Mobile App API (`backend/services/mobile-api`)
|
||||||
|
|
||||||
|
## References
|
||||||
|
- [Patient Data Model](../models/patient_model.md)
|
||||||
|
- [API Specification](api-spec.yaml)
|
||||||
|
- [HL7 Interface Specification](../integrations/hl7-spec.md)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend Module Contract Example
|
||||||
|
File: `frontend/modules/appointment_scheduler/spec/interface_contract.md`
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Appointment Scheduler Module Contract
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Provides UI components and state management for scheduling, rescheduling, and cancelling patient appointments. Integrates with calendar services and sends notifications.
|
||||||
|
|
||||||
|
## Owner
|
||||||
|
Frontend Team (frontend-team@vkist.example.com)
|
||||||
|
|
||||||
|
## Boundary
|
||||||
|
**Includes:**
|
||||||
|
- Appointment booking form components
|
||||||
|
- Calendar view widgets
|
||||||
|
- Conflict detection logic
|
||||||
|
- Notification scheduling (email/SMS)
|
||||||
|
- Form validation for appointment constraints
|
||||||
|
|
||||||
|
**Excludes:**
|
||||||
|
- Patient identity verification (handled by Auth Module)
|
||||||
|
- Payment collection for appointments (handled by Billing Module)
|
||||||
|
- Actual calendar sync with external systems (handled by Calendar Integration Service)
|
||||||
|
|
||||||
|
## Breaking-change Policy
|
||||||
|
- **MINOR**: Adding new optional props to components, new utility functions
|
||||||
|
- **MAJOR**: Removing props, changing prop types, removing components
|
||||||
|
- Requires minor version bump in package.json
|
||||||
|
- Migration guide in CHANGELOG.md
|
||||||
|
- Deprecated props logged as warnings for 2 minor versions
|
||||||
|
|
||||||
|
## Consumers
|
||||||
|
- Main App Layout (`frontend/layout/MainLayout`)
|
||||||
|
- Patient Dashboard (`frontend/modules/patient_dashboard`)
|
||||||
|
- Provider Portal (`frontend/modules/provider_portal`)
|
||||||
|
|
||||||
|
## References
|
||||||
|
- [Component Library Guidelines](../../shared/components/README.md)
|
||||||
|
- [API Contract with Backend](../services/appointment_service/spec/interface-contract.md)
|
||||||
|
- [Accessibility Requirements](../../docs/accessibility.md)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Infrastructure Module Contract Example
|
||||||
|
File: `infra/modules/networking/spec/interface_contract.md`
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Networking Module Contract
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Defines AWS/VPC networking infrastructure including subnets, route tables, security groups, and DNS configuration for the VKIST deployment.
|
||||||
|
|
||||||
|
## Owner
|
||||||
|
Infrastructure Team (infra-team@vkist.example.com)
|
||||||
|
|
||||||
|
## Boundary
|
||||||
|
**Includes:**
|
||||||
|
- VPC creation and CIDR allocation
|
||||||
|
- Public and private subnet configuration
|
||||||
|
- Internet gateway and NAT gateway setup
|
||||||
|
- Route table association
|
||||||
|
- Security group baseline rules
|
||||||
|
- DNS zone and record creation
|
||||||
|
|
||||||
|
**Excludes:**
|
||||||
|
- Compute resources (EC2/EKS) (handled by compute modules)
|
||||||
|
- Database infrastructure (handled by database module)
|
||||||
|
- Application-level security (handled by respective service modules)
|
||||||
|
|
||||||
|
## Breaking-change Policy
|
||||||
|
- **MINOR**: Adding new subnets, adding non-restrictive security group rules
|
||||||
|
- **MAJOR**: Changing VPC CIDR, removing subnets, altering route tables that break connectivity
|
||||||
|
- Requires terraform state migration plan
|
||||||
|
- 30-day review period with stakeholders
|
||||||
|
- Backward compatibility maintained via Terraform state import where possible
|
||||||
|
|
||||||
|
## Consumers
|
||||||
|
- Compute Module (`infra/modules/compute`)
|
||||||
|
- Database Module (`infra/modules/database`)
|
||||||
|
- EKS Cluster Module (`infra/modules/eks`)
|
||||||
|
- All environment-specific configurations (staging, production)
|
||||||
|
|
||||||
|
## References
|
||||||
|
- [AWS VPC Best Practices](../docs/aws_vpc_best practices.md)
|
||||||
|
- [Network Security Policy](../../docs/security/network_policy.md)
|
||||||
|
- [Terraform Module Guidelines](../../modules/README.md)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Incorrect Examples (to avoid)
|
||||||
|
|
||||||
|
### Missing Contract
|
||||||
|
```diff
|
||||||
|
- // No spec/interface-contract.md exists for this new service
|
||||||
|
+ mkdir -p backend/services/new_service
|
||||||
|
+ touch backend/services/new_service/main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Incomplete Contract
|
||||||
|
```markdown
|
||||||
|
# Incomplete Service
|
||||||
|
## Purpose
|
||||||
|
Handles user notifications.
|
||||||
|
|
||||||
|
// Missing: Owner, Boundary, Breaking-change Policy, Consumers, References
|
||||||
|
```
|
||||||
|
|
||||||
|
### Wrong Location
|
||||||
|
```diff
|
||||||
|
- // Contract should be in spec/ but is placed in root
|
||||||
|
+ NEW SERVICE/
|
||||||
|
+ interface_contract.md // WRONG LOCATION
|
||||||
|
+ main.py
|
||||||
|
+ requirements.txt
|
||||||
|
```
|
||||||
41
AGENT_SKILL/interface_contract_hygiene/SKILL.md
Normal file
41
AGENT_SKILL/interface_contract_hygiene/SKILL.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# Skill: interface_contract_hygiene
|
||||||
|
|
||||||
|
## Trigger Conditions
|
||||||
|
- Creation of a new module, package, or component
|
||||||
|
- Any modification to a public API (function signatures, class interfaces, endpoints)
|
||||||
|
- Creation of a new directory that represents a logical boundary (e.g., new service, new frontend module)
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
### 1. Interface Contract Requirement
|
||||||
|
- Every module boundary MUST have an `interface_contract.md` file in its `spec/` directory.
|
||||||
|
- Applies to: backend services, frontend modules, data access layers, infrastructure components.
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 2. Contract Content Requirements
|
||||||
|
Each `interface_contract.md` must include:
|
||||||
|
- **Purpose**: Brief description of what the module does
|
||||||
|
- **Owner**: Team or person responsible for the module
|
||||||
|
- **Boundary**: Clear definition of what is inside and outside the module
|
||||||
|
- **Breaking-change Policy**: How breaking changes are handled (versioning, deprecation)
|
||||||
|
- **Consumers**: List of other modules or systems that use this module
|
||||||
|
- **References**: Links to related documentation, diagrams, or external specifications
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 3. Versioning and Backward Compatibility
|
||||||
|
- Adding new fields, endpoints, or optional parameters: MINOR version bump (backward compatible)
|
||||||
|
- Removing or changing types of existing fields/endpoints: MAJOR version bump with:
|
||||||
|
- Migration path documentation
|
||||||
|
- 60-day deprecation notice minimum
|
||||||
|
- Deprecation warnings in code
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 4. Template Consistency
|
||||||
|
- When creating a new `interface_contract.md`, the author MUST review existing contracts in the same domain for naming and template consistency.
|
||||||
|
- Use the same section headings and format as neighboring contracts.
|
||||||
|
- Severity: `[WARN]`
|
||||||
|
|
||||||
|
### 5. Contract Location
|
||||||
|
- Contract must be located at `<module_path>/spec/interface_contract.md`
|
||||||
|
- If `spec/` directory does not exist, it must be created.
|
||||||
|
- Severity: `[ERROR]`
|
||||||
43
AGENT_SKILL/secrets_and_phi_safety/CHECKLIST.md
Normal file
43
AGENT_SKILL/secrets_and_phi_safety/CHECKLIST.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Checklist: secrets_and_phi_safety
|
||||||
|
|
||||||
|
## Secret Handling
|
||||||
|
- [ ] No hard-coded secrets (API keys, passwords, tokens, keys) in source code
|
||||||
|
- [ ] All secrets loaded via environment variables (`os.environ.get`, `process.env`, etc.)
|
||||||
|
- [ ] No `.env` files containing secrets in the repository
|
||||||
|
- [ ] No `secrets/` directory contents tracked by Git
|
||||||
|
- [ ] No private keys (`*.pem`, `*.key`) or certificates in the repository
|
||||||
|
- [ ] No model weights or training data files in the repository
|
||||||
|
|
||||||
|
## PHI Protection
|
||||||
|
- [ ] No patient names, IDs, MRNs, SSNs, DOBs, addresses, or phone numbers in:
|
||||||
|
- Console output (`print`, `console.log`)
|
||||||
|
- Application logs (any logging level)
|
||||||
|
- Error messages or exception text
|
||||||
|
- HTTP response bodies (including error responses)
|
||||||
|
- Debug output or test output
|
||||||
|
- [ ] Any identifiers used in logs/tests are clearly synthetic (e.g., `SYNTH-*` prefix)
|
||||||
|
- [ ] Image file paths in logs or responses do not contain actual patient identifiers
|
||||||
|
|
||||||
|
## Test Data and Fixtures
|
||||||
|
- [ ] All test data uses synthetic identifiers:
|
||||||
|
- Patient IDs start with `SYNTH-`
|
||||||
|
- Medical record numbers are clearly fake
|
||||||
|
- No real patient data or realistic facsimiles
|
||||||
|
- [ ] Test fixtures do not contain actual PHI
|
||||||
|
|
||||||
|
## Secrets Directory Protection
|
||||||
|
- [ ] The `secrets/` directory is listed in `.gitignore`
|
||||||
|
- [ ] Before writing to `secrets/`, verified that `.gitignore` includes `secrets/`
|
||||||
|
- [ ] No actual secrets stored in `secrets/` directory (use for non-sensitive configs only if at all)
|
||||||
|
|
||||||
|
## Configuration Safety
|
||||||
|
- [ ] Configuration files do not contain plain-text secrets
|
||||||
|
- [ ] Secrets in configs use environment variable substitution (e.g., `${VAR}` or `env.VAR`)
|
||||||
|
- [ ] TLS certificate paths are configured via environment variables, not hard-coded
|
||||||
|
- [ ] No connection strings with embedded credentials in config files
|
||||||
|
|
||||||
|
## Pre-commit Verification
|
||||||
|
- [ ] Reviewed git diff for accidental secret inclusion
|
||||||
|
- [ ] Checked for strings that resemble keys/tokens (long alphanumeric strings)
|
||||||
|
- [ ] Verified no patient-like identifiers appear in changed files
|
||||||
|
- [ ] Ran secret scanning tool if available (e.g., git-secrets, truffleHog)
|
||||||
191
AGENT_SKILL/secrets_and_phi_safety/EXAMPLES.md
Normal file
191
AGENT_SKILL/secrets_and_phi_safety/EXAMPLES.md
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
# Examples: secrets_and_phi_safety
|
||||||
|
|
||||||
|
## Correct Examples
|
||||||
|
|
||||||
|
### Secret Loading
|
||||||
|
```python
|
||||||
|
# Good: Loading from environment variables
|
||||||
|
import os
|
||||||
|
|
||||||
|
API_KEY = os.environ.get("EXTERNAL_API_KEY")
|
||||||
|
if not API_KEY:
|
||||||
|
raise ValueError("EXTERNAL_API_KEY environment variable not set")
|
||||||
|
|
||||||
|
DATABASE_URL = os.environ.get("DATABASE_URL")
|
||||||
|
SECRET_KEY = os.environ.get("SECRET_KEY", "default-dev-key-change-in-prod")
|
||||||
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Good: Node.js environment variables
|
||||||
|
const apiKey = process.env.API_KEY;
|
||||||
|
const dbPassword = process.env.DB_PASSWORD;
|
||||||
|
|
||||||
|
if (!apiKey || !dbPassword) {
|
||||||
|
throw new Error('Missing required environment variables');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### PHI Protection in Logs
|
||||||
|
```python
|
||||||
|
# Good: Logging without PHI
|
||||||
|
import logging
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def process_patient_record(patient_record):
|
||||||
|
# Log only non-identifying information
|
||||||
|
logger.info(
|
||||||
|
f"Processing record for patient age group: {get_age_group(patient_record.age)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# If logging an ID is absolutely necessary, use a hash
|
||||||
|
patient_hash = hashlib.sha256(
|
||||||
|
patient_record.medical_record_number.encode()
|
||||||
|
).hexdigest()[:8]
|
||||||
|
logger.debug(f"Processing hashed MRN: {patient_hash}...")
|
||||||
|
|
||||||
|
# Never do this:
|
||||||
|
# logger.info(f"Processing patient {patient_record.name} (MRN: {patient_record.mrn})")
|
||||||
|
# logger.error(f"Failed to process {patient_record.id}: {str(e)}") # if id is PHI
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Data with Synthetic Identifiers
|
||||||
|
```python
|
||||||
|
# Good: Test fixtures use SYNTH-* prefix
|
||||||
|
TEST_PATIENTS = [
|
||||||
|
{
|
||||||
|
"patient_id": "SYNTH-PAT-0001",
|
||||||
|
"name": "John Doe", # Note: In real tests, even names should be fake/synthetic
|
||||||
|
"mrn": "SYNTH-MRN-0001",
|
||||||
|
"date_of_birth": "1980-01-01",
|
||||||
|
# ... other test fields
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"patient_id": "SYNTH-PAT-0002",
|
||||||
|
"name": "Jane Smith",
|
||||||
|
"mrn": "SYNTH-MRN-0002",
|
||||||
|
"date_of_birth": "1992-05-15",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration Files
|
||||||
|
```yaml
|
||||||
|
# Good: docker-compose.yml using environment variables
|
||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
api:
|
||||||
|
image: medical-api:latest
|
||||||
|
environment:
|
||||||
|
- DATABASE_URL=${DATABASE_URL}
|
||||||
|
- API_KEY=${API_KEY}
|
||||||
|
- LOG_LEVEL=${LOG_LEVEL:-info}
|
||||||
|
secrets:
|
||||||
|
- db_cert # Reference to external secret store, not file in repo
|
||||||
|
|
||||||
|
# Secrets are NOT stored in the repo
|
||||||
|
# Use Docker secrets or Kubernetes secrets or similar external secret management
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# Good: config.ini with environment variable substitution
|
||||||
|
[database]
|
||||||
|
url = ${DATABASE_URL}
|
||||||
|
# or using os.path.expandvars equivalent
|
||||||
|
```
|
||||||
|
|
||||||
|
### .gitignore Protection
|
||||||
|
```gitignore
|
||||||
|
# .gitignore at repository root
|
||||||
|
# ... other entries
|
||||||
|
secrets/
|
||||||
|
*.env
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
|
```
|
||||||
|
|
||||||
|
### Safe Error Messages
|
||||||
|
```python
|
||||||
|
# Good: Generic error messages that don't leak PHI
|
||||||
|
try:
|
||||||
|
process_claim(claim_data)
|
||||||
|
except ValidationError as e:
|
||||||
|
# Log detailed error internally (without PHI)
|
||||||
|
logger.warning(f"Claim validation failed: {e}")
|
||||||
|
# Return generic message to user
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400,
|
||||||
|
detail="Claim validation failed. Please check the submitted information."
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Unexpected error processing claim: {e}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=500,
|
||||||
|
detail="Internal server error. Please contact support."
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Incorrect Examples
|
||||||
|
|
||||||
|
### Secret Exposure
|
||||||
|
```python
|
||||||
|
# Bad: Hard-coded secret
|
||||||
|
API_KEY = "sk_live_1234567890abcdef" # VIOLATION: exposed in code
|
||||||
|
|
||||||
|
# Bad: Secret in config file committed to repo
|
||||||
|
# config.yaml
|
||||||
|
# api_key: "actual_secret_key_here" # VIOLATION
|
||||||
|
|
||||||
|
# Bad: Using .env file that gets committed
|
||||||
|
# .env (committed to git)
|
||||||
|
# DATABASE_URL=postgres://user:password@localhost/db
|
||||||
|
```
|
||||||
|
|
||||||
|
### PHI in Logs and Errors
|
||||||
|
```python
|
||||||
|
# Bad: Logging full patient identifier
|
||||||
|
logger.error(f"Failed to update patient {patient.patient_id}: {str(e)}")
|
||||||
|
# If patient_id is MRN or similar, this leaks PHI
|
||||||
|
|
||||||
|
# Bad: Error message with PHI
|
||||||
|
raise ValueError(f"Invalid DOB for patient {patient.name}: {patient.dob}")
|
||||||
|
|
||||||
|
# Bad: Including PHI in HTTP response
|
||||||
|
return {
|
||||||
|
"error": f"Patient {patient.mrn} not found", # MRN is PHI
|
||||||
|
"code": "PATIENT_NOT_FOUND"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Real Data in Tests
|
||||||
|
```python
|
||||||
|
# Bad: Test using real patient-like data
|
||||||
|
TEST_PATIENT = {
|
||||||
|
"patient_id": "12345678", # Looks like real MRN
|
||||||
|
"name": "John Doe", # Realistic name
|
||||||
|
"ssn": "123-45-6789", # Actual SSN format
|
||||||
|
"dob": "1980-01-01",
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Missing .gitignore Protection
|
||||||
|
```gitignore
|
||||||
|
# .gitmissing: secrets/ directory NOT ignored
|
||||||
|
# This would allow secrets to be committed
|
||||||
|
# (no entry for secrets/ here)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Insecure Configuration
|
||||||
|
```yaml
|
||||||
|
# Bad: Hard-coded secrets in config
|
||||||
|
database:
|
||||||
|
host: localhost
|
||||||
|
port: 5432
|
||||||
|
username: admin
|
||||||
|
password: "super_secret_password" # VIOLATION
|
||||||
|
|
||||||
|
tls:
|
||||||
|
cert_file: "/etc/ssl/certs/real-cert.pem" # Hard-coded path, should be env var
|
||||||
|
key_file: "/etc/ssl/private/real-key.pem"
|
||||||
|
```
|
||||||
72
AGENT_SKILL/secrets_and_phi_safety/SKILL.md
Normal file
72
AGENT_SKILL/secrets_and_phi_safety/SKILL.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# Skill: secrets_and_phi_safety
|
||||||
|
|
||||||
|
## Trigger Conditions
|
||||||
|
Any code or configuration change involving:
|
||||||
|
- Environment variable access
|
||||||
|
- File I/O operations
|
||||||
|
- Logging statements
|
||||||
|
- HTTP request/response handling
|
||||||
|
- Exception handling
|
||||||
|
- Configuration loading
|
||||||
|
- Secret management systems
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
### 1. Secret Storage and Access
|
||||||
|
- **Never commit** secrets to version control:
|
||||||
|
- `.env` files
|
||||||
|
- `secrets/` directory contents
|
||||||
|
- Private keys (`*.pem`, `*.key`)
|
||||||
|
- API keys, passwords, tokens
|
||||||
|
- Model weights or training data
|
||||||
|
- All secrets must be loaded via environment variables using:
|
||||||
|
- `os.environ.get("KEY_NAME")` in Python
|
||||||
|
- `process.env.KEY_NAME` in Node.js
|
||||||
|
- Equivalent secure methods in other languages
|
||||||
|
- Hard-coded literal secrets in source code are strictly prohibited.
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 2. PHI (Protected Health Information) Protection
|
||||||
|
- **Never log, print, or expose** PHI in any form:
|
||||||
|
- Patient names, IDs, medical record numbers
|
||||||
|
- Dates of birth, ages, genders
|
||||||
|
- Addresses, phone numbers, email addresses
|
||||||
|
- Image file paths or URLs that could identify patients
|
||||||
|
- Diagnosis codes, procedure codes, or treatment details
|
||||||
|
- This applies to:
|
||||||
|
- Console logs (`print()`, `console.log()`)
|
||||||
|
- Application logs (any logging framework)
|
||||||
|
- Exception messages and stack traces
|
||||||
|
- HTTP response bodies (including error responses)
|
||||||
|
- Debug output or test output
|
||||||
|
- CI/CD pipeline artifacts and logs
|
||||||
|
- Use only synthetic/test data with `SYNTH-*` prefix for development and testing.
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 3. Test Data and Fixtures
|
||||||
|
- All test fixtures, mock data, and sample data must use synthetic identifiers:
|
||||||
|
- Patient IDs must start with `SYNTH-` (e.g., `SYNTH-PAT-0001`)
|
||||||
|
- Medical record numbers must be clearly fake
|
||||||
|
- No real patient data or derivations thereof
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 4. Secrets Directory Protection
|
||||||
|
- The `secrets/` directory must be ignored by Git:
|
||||||
|
- `secrets/` must be listed in `.gitignore` at the repository root
|
||||||
|
- Any attempt to write to `secrets/` directory must first verify that `.gitignore` contains `secrets/` (or `/*` negations, but effectively using a `secrets/` directory, verify `.gitignore` inclusion before first use
|
||||||
|
- Never store actual secrets in the repository, even if encrypted or obfuscated.
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 5. Configuration and Secrets Injection
|
||||||
|
- Configuration files (e.g., `.yaml`, `.json`, `.ini`) must not contain secrets.
|
||||||
|
- Use environment variable substitution in config files:
|
||||||
|
- Example: `password: ${DB_PASSWORD}` or `password: env.DB_PASSWORD`
|
||||||
|
- TLS/SSL certificate paths must come from environment variables, not be hardcoded.
|
||||||
|
- Severity: `[ERROR]`
|
||||||
|
|
||||||
|
### 6. Audit and Detection
|
||||||
|
- Before committing, run secret scanning tools if available (e.g., git-secrets, truffleHog, git-leaks)
|
||||||
|
- Review diff for accidental inclusion of:
|
||||||
|
- Strings resembling passwords, keys, or tokens
|
||||||
|
- File paths that look like they could contain PHI
|
||||||
|
- Any literal that looks like an ID number, SSN, MRN, etc.
|
||||||
@@ -6,16 +6,17 @@
|
|||||||
- For large datasets, documents, presentations, or binary assets, store them in an external storage system (e.g., Amazon S3, Google Cloud Storage, Azure Blob) and reference them via a URL/link in the appropriate markdown or documentation file.
|
- For large datasets, documents, presentations, or binary assets, store them in an external storage system (e.g., Amazon S3, Google Cloud Storage, Azure Blob) and reference them via a URL/link in the appropriate markdown or documentation file.
|
||||||
- Images that illustrate documentation or design (e.g., diagrams, screenshots) may be committed directly **if** they are small and aid understanding, but large image datasets must be stored externally and linked.
|
- Images that illustrate documentation or design (e.g., diagrams, screenshots) may be committed directly **if** they are small and aid understanding, but large image datasets must be stored externally and linked.
|
||||||
- Keep the repository lightweight and IDE‑friendly to ensure fast cloning, searching, and navigation.
|
- Keep the repository lightweight and IDE‑friendly to ensure fast cloning, searching, and navigation.
|
||||||
- Use **snake_case** naming for files and directories (lowercase letters, numbers, and underscores only). Avoid spaces and special characters. Hyphens are discouraged except for specific configuration files like `docker-compose.yaml` or `docker-compose.yml`. Uppercase is acceptable for constants (e.g., `CONFIG.json`) but prefer lowercase.
|
- Use **snake_case** naming for files and directories (lowercase letters, numbers, and underscores only). Avoid spaces and special characters. Hyphens `-` are discouraged except for specific configuration files like `docker-compose.yaml` or `docker-compose.yml`. Uppercase is acceptable for constants / important and root modules (e.g., `CONFIG.json`) but prefer lowercase.
|
||||||
- **Legacy code**: Files under the `LEGACY/` directory are deprecated and intended only for reference or maintenance; new development should use modern implementations. Treat them as read‑only references.
|
- **Legacy code**: Files under the `LEGACY/` directory are deprecated and intended only for reference or maintenance; new development should use / implement a modern implementations in the `CODEBASE/`. Treat them as read‑only references / if have to use - use with cautious & signal through comment.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
This repository contains the research, design, and implementation materials for the MSK Ultrasound Stack pilot project. It includes documentation, design artifacts, source code, and supporting files organized to facilitate collaborative development while maintaining clear separation between shared assets and individual developer secrets.
|
This repository contains the research, design, and implementation materials for the MSK Ultrasound Stack pilot project. It includes documentation, design artifacts, source code, and supporting files organized to facilitate collaborative development while maintaining clear separation between shared assets and individual developer secrets. It also includes agent skills definitions in the `AGENT_SKILL/` directory for AI-assisted development.
|
||||||
|
|
||||||
## Directory Structure
|
## Directory Structure
|
||||||
```
|
```
|
||||||
PILOT_PROJECT/
|
PILOT_PROJECT/
|
||||||
├── .gitignore # Git ignore rules (includes OS/editor temp files, dependencies, and `secrets/` folder)
|
├── .gitignore # Git ignore rules (includes OS/editor temp files, dependencies, and `secrets/` folder)
|
||||||
|
├── AGENT_SKILL # Skills file for the agentic automation system
|
||||||
├── Reading_docs/ # Reference and background materials
|
├── Reading_docs/ # Reference and background materials
|
||||||
│ ├── PLAN/ # Project plans and timelines
|
│ ├── PLAN/ # Project plans and timelines
|
||||||
│ ├── Requirement_Analysis/ # Stakeholder and functional requirements
|
│ ├── Requirement_Analysis/ # Stakeholder and functional requirements
|
||||||
@@ -105,8 +106,6 @@ Each developer is responsible for:
|
|||||||
|
|
||||||
If you need to share a secret securely with a teammate, use your organization’s approved secret‑sharing tool (e.g., 1Password Teams, HashiCorp Vault, AWS Secrets Manager) — **never** commit plaintext secrets.
|
If you need to share a secret securely with a teammate, use your organization’s approved secret‑sharing tool (e.g., 1Password Teams, HashiCorp Vault, AWS Secrets Manager) — **never** commit plaintext secrets.
|
||||||
|
|
||||||
## License
|
|
||||||
[Specify your license here, e.g., MIT, Apache 2.0, or internal proprietary.]
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
ComponentName,ReqID,ReqName,IsOptional,UserProfileCode,Sys/Act,PreCondition,PostCondition,VerboseDescription,Engineer
|
|
||||||
Prescription Parser / WebML Module,ULTS-Prescription Parser / WebML Module-FR-4,PARSE clinical text on-device,No,UP6,System,[The physical therapist opens the camera scanner within the PWA and captures the text-based prescription],"[The targeted joint zone, therapy modality, and frequency are extracted locally, and any structural contraindication warnings are displayed]","ULTS-Prescription Parser / WebML Module-FR-4: As an [Physical Therapist], provide that [The physical therapist opens the camera scanner within the PWA and captures the text-based prescription], the [System] shall PARSE clinical text on-device, ensuring that [The targeted joint zone, therapy modality, and frequency are extracted locally, and any structural contraindication warnings are displayed]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
3D Mapping / Visualization Engine,ULTS-3D Mapping / Visualization Engine-FR-5,MAP spatial coordinates to visual models,No,UP6,System,[Abstract text tokens are successfully parsed from the prescription.],[A dynamic visual guide—rendered via WebGL or a zero-GPU CPU-bound 2D image sequence based on device capabilities—with an SVG vector highlight over the target tissue area is displayed.],"ULTS-3D Mapping / Visualization Engine-FR-5: As an [Physical Therapist], provide that [Abstract text tokens are successfully parsed from the prescription.], the [System] shall MAP spatial coordinates to visual models, ensuring that [A dynamic visual guide—rendered via WebGL or a zero-GPU CPU-bound 2D image sequence based on device capabilities—with an SVG vector highlight over the target tissue area is displayed.]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Kinetic Overlay Module,ULTS-Kinetic Overlay Module-FR-6,RENDER muscle depth cross-sections,No,UP6,System,[The physical therapist activates the Kinetic Overlay Toggle within the canvas view],[Lightweight HTML SVG paths detailing muscle cross-sections and 1 cm to 5 cm depth color-coding are dynamically appended over the target treatment viewport],"ULTS-Kinetic Overlay Module-FR-6: As an [Physical Therapist], provide that [The physical therapist activates the Kinetic Overlay Toggle within the canvas view], the [System] shall RENDER muscle depth cross-sections, ensuring that [Lightweight HTML SVG paths detailing muscle cross-sections and 1 cm to 5 cm depth color-coding are dynamically appended over the target treatment viewport]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Progress Tracking Module,ULTS-Progress Tracking Module-FR-7,LOG kinetic progress pins,No,UP6,System,[The physical therapist taps the screen workspace layer within the distinct Kinetic Tracking Channel.],"[Localized metrics including Range of Motion, 1-10 pain indices, and tissue behavior are serialized and pushed to the physician's tracking panel without mutating the primary medical file.]","ULTS-Progress Tracking Module-FR-7: As an [Physical Therapist], provide that [The physical therapist taps the screen workspace layer within the distinct Kinetic Tracking Channel.], the [System] shall LOG kinetic progress pins, ensuring that [Localized metrics including Range of Motion, 1-10 pain indices, and tissue behavior are serialized and pushed to the physician's tracking panel without mutating the primary medical file.]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Patient Education Module,ULTS-Patient Education Module-FR-8,DEMONSTRATE joint mechanics dynamically,No,UP6,System,[The physical therapist moves the HTML Range-of-Motion slider within the Patient Demonstration Mode split layout.],"[A cached array of 2D illustrations seamlessly cycles using 0% GPU power to visually indicate joint flexion, extension, and soft-tissue impingement.]","ULTS-Patient Education Module-FR-8: As an [Physical Therapist], provide that [The physical therapist moves the HTML Range-of-Motion slider within the Patient Demonstration Mode split layout.], the [System] shall DEMONSTRATE joint mechanics dynamically, ensuring that [A cached array of 2D illustrations seamlessly cycles using 0% GPU power to visually indicate joint flexion, extension, and soft-tissue impingement.]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
DICOM Viewer / Annotation Module,ULTS-DICOM Viewer / Annotation Module-FR-9,RENDER haptic-assisted edge-snapping magnifier,No,UP7,System,[The clinician activates the annotation tool and drags the crosshairs near a high-contrast bone boundary on the multi-touch viewport.],"[A high-magnification lens appears 150px vertically above the touch point, the crosshairs automatically snap to the nearest boundary, and a localized native haptic pulse is triggered.]","ULTS-DICOM Viewer / Annotation Module-FR-9: As an [Rheumatologist & Orthopedic Surgeon], provide that [The clinician activates the annotation tool and drags the crosshairs near a high-contrast bone boundary on the multi-touch viewport.], the [System] shall RENDER haptic-assisted edge-snapping magnifier, ensuring that [A high-magnification lens appears 150px vertically above the touch point, the crosshairs automatically snap to the nearest boundary, and a localized native haptic pulse is triggered.]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Asynchronous Communication Engine,ULTS-Asynchronous Communication Engine-FR-10,RECORD asynchronous voice and canvas telemetry (Session Recording & Replay),No,UP7,System,[The sending clinician records audio while navigating the viewport and drawing vectors on the case file workspace.],"[The microphone input and viewport coordinate state changes (X, Y positions, zoom, panning) are compiled into a serialized JSON timeline file for synchronized, threaded playback.]","ULTS-Asynchronous Communication Engine-FR-10: As an [Rheumatologist & Orthopedic Surgeon], provide that [The sending clinician records audio while navigating the viewport and drawing vectors on the case file workspace.], the [System] shall RECORD asynchronous voice and canvas telemetry (Session Recording & Replay), ensuring that [The microphone input and viewport coordinate state changes (X, Y positions, zoom, panning) are compiled into a serialized JSON timeline file for synchronized, threaded playback.]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
User Interface / Push Notifications,ULTS-User Interface / Push Notifications-FR-11,DISPLAY progressive disclosure sheets and native alerts,No,UP7,System,[A case update occurs or the clinician interacts with the clinical data layout over the active DICOM canvas.],"[A deep-linked native OS push alert is sent, and clinical telemetry is confined within a 3-state (25%, 60%, 100%) expandable native Bottom-Sheet component.]","ULTS-User Interface / Push Notifications-FR-11: As an [Rheumatologist & Orthopedic Surgeon], provide that [A case update occurs or the clinician interacts with the clinical data layout over the active DICOM canvas.], the [System] shall DISPLAY progressive disclosure sheets and native alerts, ensuring that [A deep-linked native OS push alert is sent, and clinical telemetry is confined within a 3-state (25%, 60%, 100%) expandable native Bottom-Sheet component.]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Gửi dữ liệu tự kiểm tra mức độ viêm tại nhà về hệ thống của bệnh viện.,ULTS-Gửi dữ liệu tự kiểm tra mức độ viêm tại nhà về hệ thống của bệnh viện.-FR-20,KẾT NỐI và GỬI Báo cáo Tự kiểm tra cho Bác sĩ Điều trị,No,UP8,System,Bệnh nhân vừa hoàn thành bài tự kiểm tra mức độ viêm (REQ-PAT-03) và phát hiện có dấu hiệu bất thường (đau tăng lên).,"Hệ thống đóng gói lịch sử triệu chứng kèm biểu đồ xu hướng gần nhất, gửi an toàn qua kênh mã hóa tới bác sĩ quản lý ca bệnh để bác sĩ có thể chủ động hẹn lịch tái khám sớm.","ULTS-Gửi dữ liệu tự kiểm tra mức độ viêm tại nhà về hệ thống của bệnh viện.-FR-20: As an [MSK Patient & Family Caregiver], provide that Bệnh nhân vừa hoàn thành bài tự kiểm tra mức độ viêm (REQ-PAT-03) và phát hiện có dấu hiệu bất thường (đau tăng lên)., the [System] shall KẾT NỐI và GỬI Báo cáo Tự kiểm tra cho Bác sĩ Điều trị, ensuring that Hệ thống đóng gói lịch sử triệu chứng kèm biểu đồ xu hướng gần nhất, gửi an toàn qua kênh mã hóa tới bác sĩ quản lý ca bệnh để bác sĩ có thể chủ động hẹn lịch tái khám sớm.",tahuykl
|
|
||||||
Nhắc nhở uống thuốc và thực hiện phác đồ điều trị tại nhà.,ULTS-Nhắc nhở uống thuốc và thực hiện phác đồ điều trị tại nhà.-FR-19,GIÁM SÁT việc bệnh nhân tuân thủ Đơn thuốc và Nhắc nhở Lịch Điều trị,No,UP8,System,Bác sĩ đã kê đơn thuốc (REQ-RAD-05) và phác đồ điều trị được đồng bộ sang tài khoản của bệnh nhân.,"Ứng dụng tự động phát thông báo nhắc nhở giờ uống thuốc, giờ tập vật lý trị liệu cho Bệnh nhân và Người chăm sóc, đồng thời cho phép tích chọn ""Đã uống"" để lưu lại lịch sử tuân thủ điều trị.","ULTS-Nhắc nhở uống thuốc và thực hiện phác đồ điều trị tại nhà.-FR-19: As an [MSK Patient & Family Caregiver], provide that Bác sĩ đã kê đơn thuốc (REQ-RAD-05) và phác đồ điều trị được đồng bộ sang tài khoản của bệnh nhân., the [System] shall GIÁM SÁT việc bệnh nhân tuân thủ Đơn thuốc và Nhắc nhở Lịch Điều trị, ensuring that Ứng dụng tự động phát thông báo nhắc nhở giờ uống thuốc, giờ tập vật lý trị liệu cho Bệnh nhân và Người chăm sóc, đồng thời cho phép tích chọn ""Đã uống"" để lưu lại lịch sử tuân thủ điều trị.",tahuykl
|
|
||||||
Đánh giá nhanh nguy cơ viêm tái phát qua bảng câu hỏi triệu chứng,ULTS-Đánh giá nhanh nguy cơ viêm tái phát qua bảng câu hỏi triệu chứng-FR-18,SÀNG LỌC và TỰ KIỂM TRA dấu hiệu Viêm tại nhà,No,UP8,System,"Bệnh nhân đang ở nhà (ngoài bệnh viện) và truy cập vào mục ""Kiểm tra sức khỏe định kỳ"" trên ứng dụng.","Hệ thống hiển thị bảng khảo sát tương tác (độ sưng, độ nóng, mức độ đau khi co duỗi); dựa trên câu trả lời, hệ thống tính điểm và đưa ra cảnh báo mức độ viêm lâm sàng hiện tại (Ổn định / Cần theo dõi / Cần đi khám ngay).","ULTS-Đánh giá nhanh nguy cơ viêm tái phát qua bảng câu hỏi triệu chứng-FR-18: As an [MSK Patient & Family Caregiver], provide that Bệnh nhân đang ở nhà (ngoài bệnh viện) và truy cập vào mục ""Kiểm tra sức khỏe định kỳ"" trên ứng dụng., the [System] shall SÀNG LỌC và TỰ KIỂM TRA dấu hiệu Viêm tại nhà, ensuring that Hệ thống hiển thị bảng khảo sát tương tác (độ sưng, độ nóng, mức độ đau khi co duỗi); dựa trên câu trả lời, hệ thống tính điểm và đưa ra cảnh báo mức độ viêm lâm sàng hiện tại (Ổn định / Cần theo dõi / Cần đi khám ngay).",tahuykl
|
|
||||||
Theo dõi và kiểm tra biến thiên mức độ viêm khớp gối qua các thời kỳ.,ULTS-Theo dõi và kiểm tra biến thiên mức độ viêm khớp gối qua các thời kỳ.-FR-17,KIỂM TRA mức độ viêm trực quan qua Biểu đồ Xu hướng,No,UP8,System,Hệ thống có dữ liệu lịch sử từ ít nhất một lần khám (REQ-PAT-01) trở lên.,"Hệ thống hiển thị một biểu đồ đường (Line chart) trực quan hóa mức độ viêm (từ Nhẹ đến Nặng) và độ dày màng hoạt dịch qua các lần khám, giúp người bệnh biết tình trạng viêm của mình đang thuyên giảm hay tăng lên.","ULTS-Theo dõi và kiểm tra biến thiên mức độ viêm khớp gối qua các thời kỳ.-FR-17: As an [MSK Patient & Family Caregiver], provide that Hệ thống có dữ liệu lịch sử từ ít nhất một lần khám (REQ-PAT-01) trở lên., the [System] shall KIỂM TRA mức độ viêm trực quan qua Biểu đồ Xu hướng, ensuring that Hệ thống hiển thị một biểu đồ đường (Line chart) trực quan hóa mức độ viêm (từ Nhẹ đến Nặng) và độ dày màng hoạt dịch qua các lần khám, giúp người bệnh biết tình trạng viêm của mình đang thuyên giảm hay tăng lên.",tahuykl
|
|
||||||
Xem và tải về lịch sử các lần siêu âm và khám khớp gối,ULTS-Xem và tải về lịch sử các lần siêu âm và khám khớp gối-FR-16,TRA CỨU lịch sử khám bệnh và Siêu âm Toàn diện,No,UP8,System,Bệnh nhân hoặc Người chăm sóc đăng nhập thành công vào hệ thống bằng tài khoản định danh hợp lệ.,"Hệ thống hiển thị danh sách toàn bộ các mốc thời gian đã khám, cho phép người dùng bấm vào từng ngày để xem lại ảnh siêu âm, đơn thuốc, và các chỉ số đo đạc cũ.","ULTS-Xem và tải về lịch sử các lần siêu âm và khám khớp gối-FR-16: As an [MSK Patient & Family Caregiver], provide that Bệnh nhân hoặc Người chăm sóc đăng nhập thành công vào hệ thống bằng tài khoản định danh hợp lệ., the [System] shall TRA CỨU lịch sử khám bệnh và Siêu âm Toàn diện, ensuring that Hệ thống hiển thị danh sách toàn bộ các mốc thời gian đã khám, cho phép người dùng bấm vào từng ngày để xem lại ảnh siêu âm, đơn thuốc, và các chỉ số đo đạc cũ.",tahuykl
|
|
||||||
Patient Education Module / 3D Visualization Engine,ULTS-Patient Education Module / 3D Visualization Engine-FR-12,SYNCHRONIZE hardware-adaptive musculoskeletal models,No,UP8,System,[The patient opens the 3D visualization view and the client-side feature detection script evaluates local GPU capabilities.],[Abstract 2D pathologies map to either a real-time WebGL 3D skeletal mesh (High-Spec) or a CPU-bound 36-frame 2D sprite-sheet turntable rendering at 10° increments (Low-Spec).],"ULTS-Patient Education Module / 3D Visualization Engine-FR-12: As an [MSK Patient & Family Caregiver], provide that [The patient opens the 3D visualization view and the client-side feature detection script evaluates local GPU capabilities.], the [System] shall SYNCHRONIZE hardware-adaptive musculoskeletal models, ensuring that [Abstract 2D pathologies map to either a real-time WebGL 3D skeletal mesh (High-Spec) or a CPU-bound 36-frame 2D sprite-sheet turntable rendering at 10° increments (Low-Spec).]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Patient Portal / Security Module,ULTS-Patient Portal / Security Module-FR-13,ENCRYPT and deliver sanitized patient payloads,No,UP8,System,"[The patient provides explicit, native opt-in consent and scans the unique 14-day tokenized QR code or deep link.]","[The locally AES-256 encrypted, sanitized, and flattened locomotive health summary loads into an adaptive dashboard in ≤ 2.0 seconds.]","ULTS-Patient Portal / Security Module-FR-13: As an [MSK Patient & Family Caregiver], provide that [The patient provides explicit, native opt-in consent and scans the unique 14-day tokenized QR code or deep link.], the [System] shall ENCRYPT and deliver sanitized patient payloads, ensuring that [The locally AES-256 encrypted, sanitized, and flattened locomotive health summary loads into an adaptive dashboard in ≤ 2.0 seconds.]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Đề xuất danh mục thuốc kháng viêm và giảm đau theo ca bệnh,ULTS-Đề xuất danh mục thuốc kháng viêm và giảm đau theo ca bệnh-FR-27,ĐỀ XUẤT Đơn thuốc Hỗ trợ (Clinical Decision Support),No,UP5,System,"Chẩn đoán mức độ viêm đã có và bác sĩ lựa chọn phương án ""Điều trị nội khoa bằng thuốc"" (REQ-RAD-04)","Hệ thống đưa ra danh sách các loại thuốc phù hợp (ví dụ: NSAIDs, Thuốc chống bôi trơn khớp) kèm liều lượng khuyến cáo dựa trên mức độ viêm, kiểm tra tương tác thuốc/chống chỉ định, hỗ trợ bác sĩ xuất đơn thuốc nhanh chóng","ULTS-Đề xuất danh mục thuốc kháng viêm và giảm đau theo ca bệnh-FR-27: As an [Diagnostic Radiologist], provide that Chẩn đoán mức độ viêm đã có và bác sĩ lựa chọn phương án ""Điều trị nội khoa bằng thuốc"" (REQ-RAD-04), the [System] shall ĐỀ XUẤT Đơn thuốc Hỗ trợ (Clinical Decision Support), ensuring that Hệ thống đưa ra danh sách các loại thuốc phù hợp (ví dụ: NSAIDs, Thuốc chống bôi trơn khớp) kèm liều lượng khuyến cáo dựa trên mức độ viêm, kiểm tra tương tác thuốc/chống chỉ định, hỗ trợ bác sĩ xuất đơn thuốc nhanh chóng",tahuykl
|
|
||||||
Gợi ý phương án điều trị dựa trên mức độ viêm khớp gối,ULTS-Gợi ý phương án điều trị dựa trên mức độ viêm khớp gối-FR-26,ĐỀ XUẤT Phác đồ Điều trị và Kế hoạch Can thiệp,No,UP5,System,Bác sĩ đã phê duyệt và khóa kết quả chẩn đoán mức độ viêm,"Hệ thống hiển thị các gợi ý điều trị tương ứng (ví dụ: Viêm nhẹ, tiến hành Vật lý trị liệu/Nghỉ ngơi; Viêm nặng tiến hành Chọc hút dịch khớp dưới hướng dẫn siêu âm/Tiêm corticoid nội khớp) để bác sĩ lựa chọn và đưa vào báo cáo.","ULTS-Gợi ý phương án điều trị dựa trên mức độ viêm khớp gối-FR-26: As an [Diagnostic Radiologist], provide that Bác sĩ đã phê duyệt và khóa kết quả chẩn đoán mức độ viêm, the [System] shall ĐỀ XUẤT Phác đồ Điều trị và Kế hoạch Can thiệp, ensuring that Hệ thống hiển thị các gợi ý điều trị tương ứng (ví dụ: Viêm nhẹ, tiến hành Vật lý trị liệu/Nghỉ ngơi; Viêm nặng tiến hành Chọc hút dịch khớp dưới hướng dẫn siêu âm/Tiêm corticoid nội khớp) để bác sĩ lựa chọn và đưa vào báo cáo.",tahuykl
|
|
||||||
Đánh giá và phân cấp mức độ viêm màng hoạt dịch (Synovitis Grading),ULTS-Đánh giá và phân cấp mức độ viêm màng hoạt dịch (Synovitis Grading)-FR-25,CHUẨN ĐOÁN Phân loại Mức độ Viêm Khớp gối,No,UP5,System,Hệ thống đã ghi nhận độ dày màng hoạt dịch (REQ-RAD-02) và kết quả quét Doppler dòng máu (Hypervascularity),"Hệ thống đưa ra gợi ý chẩn đoán mức độ viêm theo thang chuẩn y khoa (ví dụ: Không viêm, Viêm nhẹ - Độ 1, Viêm vừa - Độ 2, Viêm nặng - Độ 3) để bác sĩ xác nhận hoặc điều chỉnh","ULTS-Đánh giá và phân cấp mức độ viêm màng hoạt dịch (Synovitis Grading)-FR-25: As an [Diagnostic Radiologist], provide that Hệ thống đã ghi nhận độ dày màng hoạt dịch (REQ-RAD-02) và kết quả quét Doppler dòng máu (Hypervascularity), the [System] shall CHUẨN ĐOÁN Phân loại Mức độ Viêm Khớp gối, ensuring that Hệ thống đưa ra gợi ý chẩn đoán mức độ viêm theo thang chuẩn y khoa (ví dụ: Không viêm, Viêm nhẹ - Độ 1, Viêm vừa - Độ 2, Viêm nặng - Độ 3) để bác sĩ xác nhận hoặc điều chỉnh",tahuykl
|
|
||||||
Đo độ dày màng hoạt dịch tại ngách trên xương bánh chè,ULTS-Đo độ dày màng hoạt dịch tại ngách trên xương bánh chè-FR-24,ĐO Độ dày Màng hoạt dịch Tự động,No,UP5,System,Tính năng phân vùng (REQ-RAD-01) đã xác định được lớp màng hoạt dịch (Synovium) trên hình ảnh siêu âm,"Hệ thống tự động hiển thị thước đo (bằng milimet) tại điểm dày nhất của màng hoạt dịch, cho phép bác sĩ kéo thả điều chỉnh thủ công và lưu thông số này vào hồ sơ đo đạc của ca bệnh","ULTS-Đo độ dày màng hoạt dịch tại ngách trên xương bánh chè-FR-24: As an [Diagnostic Radiologist], provide that Tính năng phân vùng (REQ-RAD-01) đã xác định được lớp màng hoạt dịch (Synovium) trên hình ảnh siêu âm, the [System] shall ĐO Độ dày Màng hoạt dịch Tự động, ensuring that Hệ thống tự động hiển thị thước đo (bằng milimet) tại điểm dày nhất của màng hoạt dịch, cho phép bác sĩ kéo thả điều chỉnh thủ công và lưu thông số này vào hồ sơ đo đạc của ca bệnh",tahuykl
|
|
||||||
Phân vùng hình ảnh cấu trúc giải phẫu khớp gối bằng AI,ULTS-Phân vùng hình ảnh cấu trúc giải phẫu khớp gối bằng AI-FR-23,PHÂN VÙNG Tự động các Bộ phận Khớp gối (Image Segmentation),No,UP5,System,Bác sĩ đã tải lên hoặc chụp thành công hình ảnh cắt dọc/cắt ngang của khớp gối trên hệ thống,"Hệ thống tự động nhận diện, phân vùng và tô màu phân biệt các bộ phận (gân bánh chè, sụn chêm, xương đùi, xương chày, màng hoạt dịch) trên màn hình mà không làm mờ ảnh gốc.","ULTS-Phân vùng hình ảnh cấu trúc giải phẫu khớp gối bằng AI-FR-23: As an [Diagnostic Radiologist], provide that Bác sĩ đã tải lên hoặc chụp thành công hình ảnh cắt dọc/cắt ngang của khớp gối trên hệ thống, the [System] shall PHÂN VÙNG Tự động các Bộ phận Khớp gối (Image Segmentation), ensuring that Hệ thống tự động nhận diện, phân vùng và tô màu phân biệt các bộ phận (gân bánh chè, sụn chêm, xương đùi, xương chày, màng hoạt dịch) trên màn hình mà không làm mờ ảnh gốc.",tahuykl
|
|
||||||
|
@@ -1,15 +0,0 @@
|
|||||||
ComponentName,Device,ReqID,ReqName,Priority,IsOptional,Drop,LinkUseCases,EngineerDesignUC,UserProfileCode,Sys/Act,PreCondition,PostCondition,VerboseDescription,Engineer
|
|
||||||
Progress Tracking Module,Mobile Web,ULTS-Progress Tracking Module-FR-7,RECORD Asynchronous PT Progress Metrics,,No,No,,,UP6,System,[The physical therapist taps the screen workspace layer within the distinct Kinetic Tracking Channel.],"[Localized metrics including Range of Motion, 1-10 pain indices, and tissue behavior are serialized and pushed to the physician's tracking panel without mutating the primary medical file.]","ULTS-Progress Tracking Module-FR-7: As an [Physical Therapist], provide that [The physical therapist taps the screen workspace layer within the distinct Kinetic Tracking Channel.], the [System] shall RECORD Asynchronous PT Progress Metrics, ensuring that [Localized metrics including Range of Motion, 1-10 pain indices, and tissue behavior are serialized and pushed to the physician's tracking panel without mutating the primary medical file.]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Patient Education Module,Mobile Web,ULTS-Patient Education Module-FR-8,DEMONSTRATE joint mechanics dynamically during physical therapy section,-1,No,No,,,UP6,System,[The physical therapist moves the HTML Range-of-Motion slider within the Patient Demonstration Mode split layout.],"[A cached array of 2D illustrations seamlessly cycles using 0% GPU power to visually indicate joint flexion, extension, and soft-tissue impingement.]","ULTS-Patient Education Module-FR-8: As an [Physical Therapist], provide that [The physical therapist moves the HTML Range-of-Motion slider within the Patient Demonstration Mode split layout.], the [System] shall DEMONSTRATE joint mechanics dynamically during physical therapy section, ensuring that [A cached array of 2D illustrations seamlessly cycles using 0% GPU power to visually indicate joint flexion, extension, and soft-tissue impingement.]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Patient Education / Care Logic Module,Mobile Web,ULTS-Patient Education / Care Logic Module-FR-19,NHẮC NHỞ việc bệnh nhân tuân thủ Đơn thuốc và lịch Điều trị,,No,No,,tahuykl,UP8,System,Bác sĩ đã kê đơn thuốc (REQ-RAD-05) và phác đồ điều trị được đồng bộ sang tài khoản của bệnh nhân.,"Ứng dụng tự động phát thông báo nhắc nhở giờ uống thuốc, giờ tập vật lý trị liệu cho Bệnh nhân và Người chăm sóc, đồng thời cho phép tích chọn ""Đã uống"" để lưu lại lịch sử tuân thủ điều trị.","ULTS-Patient Education / Care Logic Module-FR-19: As an [MSK Patient & Family Caregiver], provide that Bác sĩ đã kê đơn thuốc (REQ-RAD-05) và phác đồ điều trị được đồng bộ sang tài khoản của bệnh nhân., the [System] shall NHẮC NHỞ việc bệnh nhân tuân thủ Đơn thuốc và lịch Điều trị, ensuring that Ứng dụng tự động phát thông báo nhắc nhở giờ uống thuốc, giờ tập vật lý trị liệu cho Bệnh nhân và Người chăm sóc, đồng thời cho phép tích chọn ""Đã uống"" để lưu lại lịch sử tuân thủ điều trị.",tahuykl
|
|
||||||
Xem và tải về lịch sử các lần siêu âm và khám khớp gối,Mobile Web,ULTS-Xem và tải về lịch sử các lần siêu âm và khám khớp gối-FR-16,TRA CỨU lịch sử khám bệnh và Siêu âm Toàn diện,,No,No,,tahuykl,UP8,System,Bệnh nhân hoặc Người chăm sóc đăng nhập thành công vào hệ thống bằng tài khoản định danh hợp lệ.,"Hệ thống hiển thị danh sách toàn bộ các mốc thời gian đã khám, cho phép người dùng bấm vào từng ngày để xem lại ảnh siêu âm, đơn thuốc, và các chỉ số đo đạc cũ.","ULTS-Xem và tải về lịch sử các lần siêu âm và khám khớp gối-FR-16: As an [MSK Patient & Family Caregiver], provide that Bệnh nhân hoặc Người chăm sóc đăng nhập thành công vào hệ thống bằng tài khoản định danh hợp lệ., the [System] shall TRA CỨU lịch sử khám bệnh và Siêu âm Toàn diện, ensuring that Hệ thống hiển thị danh sách toàn bộ các mốc thời gian đã khám, cho phép người dùng bấm vào từng ngày để xem lại ảnh siêu âm, đơn thuốc, và các chỉ số đo đạc cũ.",tahuykl
|
|
||||||
Tạo mới nhật ký chữa bệnh khớp gối cho bệnh nhân,Mobile Web,ULTS-Tạo mới nhật ký chữa bệnh khớp gối cho bệnh nhân-FR-28,CREATE patient treatment journal,,No,No,,tahuykl,UP8,System,Bệnh nhân hoặc Người chăm sóc đã đăng nhập thành công vào tài khoản hệ thống (ứng dụng di động hoặc cổng thông tin bệnh nhân) và hồ sơ bệnh án siêu âm khớp gối hiện tại đang ở trạng thái kích hoạt.,"Hệ thống khởi tạo thành công một biểu mẫu nhật ký mới gắn liền với đợt điều trị hiện tại, thiết lập sẵn các trường thông tin cần theo dõi (như mức độ đau, độ sưng gối, các triệu chứng bất thường, trạng thái dùng thuốc) và sẵn sàng cho lượt nhập liệu đầu tiên.","ULTS-Tạo mới nhật ký chữa bệnh khớp gối cho bệnh nhân-FR-28: As an [MSK Patient & Family Caregiver], provide that Bệnh nhân hoặc Người chăm sóc đã đăng nhập thành công vào tài khoản hệ thống (ứng dụng di động hoặc cổng thông tin bệnh nhân) và hồ sơ bệnh án siêu âm khớp gối hiện tại đang ở trạng thái kích hoạt., the [System] shall CREATE patient treatment journal, ensuring that Hệ thống khởi tạo thành công một biểu mẫu nhật ký mới gắn liền với đợt điều trị hiện tại, thiết lập sẵn các trường thông tin cần theo dõi (như mức độ đau, độ sưng gối, các triệu chứng bất thường, trạng thái dùng thuốc) và sẵn sàng cho lượt nhập liệu đầu tiên.",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Cập nhật diễn biến triệu chứng và tiến trình điều trị vào nhật ký,Mobile Web,ULTS-Cập nhật diễn biến triệu chứng và tiến trình điều trị vào nhật ký-FR-29,UPDATE patient treatment journal,,No,No,,tahuykl,UP8,System,Nhật ký chữa bệnh đã được khởi tạo thành công và đang trong thời gian theo dõi điều trị,"Hệ thống ghi nhận và lưu trữ dòng thời gian các dữ liệu mới do người dùng nhập (ví dụ: mức độ đau giảm từ 7 xuống 4, gối bớt sưng sau khi chườm đá, đã uống thuốc đúng giờ); đồng thời tự động cập nhật các số liệu này lên biểu đồ xu hướng tiến triển của khớp gối","ULTS-Cập nhật diễn biến triệu chứng và tiến trình điều trị vào nhật ký-FR-29: As an [MSK Patient & Family Caregiver], provide that Nhật ký chữa bệnh đã được khởi tạo thành công và đang trong thời gian theo dõi điều trị, the [System] shall UPDATE patient treatment journal, ensuring that Hệ thống ghi nhận và lưu trữ dòng thời gian các dữ liệu mới do người dùng nhập (ví dụ: mức độ đau giảm từ 7 xuống 4, gối bớt sưng sau khi chườm đá, đã uống thuốc đúng giờ); đồng thời tự động cập nhật các số liệu này lên biểu đồ xu hướng tiến triển của khớp gối",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Gửi báo cáo nhật ký chữa bệnh khớp gối cho Bác sĩ Chẩn đoán Hình ảnh hoặc Bác sĩ Điều trị,Mobile Web,ULTS-Gửi báo cáo nhật ký chữa bệnh khớp gối cho Bác sĩ Chẩn đoán Hình ảnh hoặc Bác sĩ Điều trị-FR-30,SEND patient treatment journal toward Clinicians & PT,,No,No,Send Treatment Journal (https://app.notion.com/p/Send-Treatment-Journal-376f910aea75808492a9ff771d46d442?pvs=21),tahuykl,UP8,System,Nhật ký chữa bệnh đã có dữ liệu được cập nhật và hệ thống đã xác định được danh tính bác sĩ phụ trách ca bệnh của bệnh nhân,"Hệ thống đóng gói toàn bộ lịch sử dữ liệu nhật ký (dưới dạng biểu đồ và bảng tóm tắt triệu chứng), mã hóa bảo mật dữ liệu y tế và chuyển trực tiếp tới màn hình làm việc (Dashboard) của bác sĩ phụ trách, đồng thời phát thông báo xác nhận ""Gửi thành công"" cho bệnh nhân/người chăm sóc","ULTS-Gửi báo cáo nhật ký chữa bệnh khớp gối cho Bác sĩ Chẩn đoán Hình ảnh hoặc Bác sĩ Điều trị-FR-30: As an [MSK Patient & Family Caregiver], provide that Nhật ký chữa bệnh đã có dữ liệu được cập nhật và hệ thống đã xác định được danh tính bác sĩ phụ trách ca bệnh của bệnh nhân, the [System] shall SEND patient treatment journal toward Clinicians & PT, ensuring that Hệ thống đóng gói toàn bộ lịch sử dữ liệu nhật ký (dưới dạng biểu đồ và bảng tóm tắt triệu chứng), mã hóa bảo mật dữ liệu y tế và chuyển trực tiếp tới màn hình làm việc (Dashboard) của bác sĩ phụ trách, đồng thời phát thông báo xác nhận ""Gửi thành công"" cho bệnh nhân/người chăm sóc",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Gửi dữ liệu tự kiểm tra mức độ viêm tại nhà về hệ thống của bệnh viện,Mobile Web,ULTS-Gửi dữ liệu tự kiểm tra mức độ viêm tại nhà về hệ thống của bệnh viện-FR-20,KẾT NỐI và GỬI Báo cáo Nhật Ký Bệnh Lý cho Bác sĩ Điều trị & Physiotherpist,-1,No,No,,,UP8,System,Bệnh nhân vừa hoàn thành bài tự kiểm tra mức độ viêm (REQ-PAT-03) và phát hiện có dấu hiệu bất thường (đau tăng lên).,"Hệ thống đóng gói lịch sử triệu chứng kèm biểu đồ xu hướng gần nhất, gửi an toàn qua kênh mã hóa tới bác sĩ quản lý ca bệnh để bác sĩ có thể chủ động hẹn lịch tái khám sớm.","ULTS-Gửi dữ liệu tự kiểm tra mức độ viêm tại nhà về hệ thống của bệnh viện-FR-20: As an [MSK Patient & Family Caregiver], provide that Bệnh nhân vừa hoàn thành bài tự kiểm tra mức độ viêm (REQ-PAT-03) và phát hiện có dấu hiệu bất thường (đau tăng lên)., the [System] shall KẾT NỐI và GỬI Báo cáo Nhật Ký Bệnh Lý cho Bác sĩ Điều trị & Physiotherpist, ensuring that Hệ thống đóng gói lịch sử triệu chứng kèm biểu đồ xu hướng gần nhất, gửi an toàn qua kênh mã hóa tới bác sĩ quản lý ca bệnh để bác sĩ có thể chủ động hẹn lịch tái khám sớm.",tahuykl
|
|
||||||
Patient Education Module / 3D Visualization Engine,Mobile Web,ULTS-Patient Education Module / 3D Visualization Engine-FR-12,SYNCHRONIZE hardware-adaptive musculoskeletal models for visualizing MSK-condition after each visiting,-1,No,No,,,UP8,System,[The patient opens the 3D visualization view and the client-side feature detection script evaluates local GPU capabilities.],[Abstract 2D pathologies map to either a real-time WebGL 3D skeletal mesh (High-Spec) or a CPU-bound 36-frame 2D sprite-sheet turntable rendering at 10° increments (Low-Spec).],"ULTS-Patient Education Module / 3D Visualization Engine-FR-12: As an [MSK Patient & Family Caregiver], provide that [The patient opens the 3D visualization view and the client-side feature detection script evaluates local GPU capabilities.], the [System] shall SYNCHRONIZE hardware-adaptive musculoskeletal models for visualizing MSK-condition after each visiting, ensuring that [Abstract 2D pathologies map to either a real-time WebGL 3D skeletal mesh (High-Spec) or a CPU-bound 36-frame 2D sprite-sheet turntable rendering at 10° increments (Low-Spec).]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Patient Portal / Security Module,Mobile Web,ULTS-Patient Portal / Security Module-FR-13,ENCRYPT and deliver sanitized patient payloads,-1,No,No,,,UP8,System,"[The patient provides explicit, native opt-in consent and scans the unique 14-day tokenized QR code or deep link.]","[The locally AES-256 encrypted, sanitized, and flattened locomotive health summary loads into an adaptive dashboard in ≤ 2.0 seconds.]","ULTS-Patient Portal / Security Module-FR-13: As an [MSK Patient & Family Caregiver], provide that [The patient provides explicit, native opt-in consent and scans the unique 14-day tokenized QR code or deep link.], the [System] shall ENCRYPT and deliver sanitized patient payloads, ensuring that [The locally AES-256 encrypted, sanitized, and flattened locomotive health summary loads into an adaptive dashboard in ≤ 2.0 seconds.]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Patient Education Module / Personalized - Controlled Q&A,Mobile Web,ULTS-Patient Education Module / Personalized - Controlled Q&A-FR-31,INTERPRET diagnostic report profile from Clinic to Patient,,No,No,,,UP8,System,[Clinician has set the diagnostic report status to FINALIZED and a diagnosis code exists],"[A plain-language summary explaining the diagnosis (include terminology, why the patient should care and concern, the impact-to-patient analysis) is available on the patient's dashboard]","ULTS-Patient Education Module / Personalized - Controlled Q&A-FR-31: As an [MSK Patient & Family Caregiver], provide that [Clinician has set the diagnostic report status to FINALIZED and a diagnosis code exists], the [System] shall INTERPRET diagnostic report profile from Clinic to Patient, ensuring that [A plain-language summary explaining the diagnosis (include terminology, why the patient should care and concern, the impact-to-patient analysis) is available on the patient's dashboard]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Patient Education / Care Logic Module,Mobile Web,ULTS-Patient Education / Care Logic Module-FR-32,GUIDE lifestyle via personalized recovery tasks,,No,No,,,UP8,System,[Clinician has finalized the daily grade (0-3) in the medical record],"[The patient receives an updated, conversational, and actionable daily checklist]","ULTS-Patient Education / Care Logic Module-FR-32: As an [MSK Patient & Family Caregiver], provide that [Clinician has finalized the daily grade (0-3) in the medical record], the [System] shall GUIDE lifestyle via personalized recovery tasks, ensuring that [The patient receives an updated, conversational, and actionable daily checklist]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Patient Education Module / Personalized - Controlled Q&A,Mobile Web,ULTS-Patient Education Module / Personalized - Controlled Q&A-FR-33,TRIAGE patient-input queries against clinical status,,No,No,,,UP8,System,[Patient submits a health-related query via the Q&A interface while a clinical record exists],"[The query is tagged as Verified, Neutral, or Cautionary based on its relevance to the specific medical record]","ULTS-Patient Education Module / Personalized - Controlled Q&A-FR-33: As an [MSK Patient & Family Caregiver], provide that [Patient submits a health-related query via the Q&A interface while a clinical record exists], the [System] shall TRIAGE patient-input queries against clinical status, ensuring that [The query is tagged as Verified, Neutral, or Cautionary based on its relevance to the specific medical record]",Đạt Trần Tiến (Daves Tran)
|
|
||||||
Đánh giá và phân cấp mức độ viêm màng hoạt dịch (Synovitis Grading),Mobile Web,ULTS-Đánh giá và phân cấp mức độ viêm màng hoạt dịch (Synovitis Grading)-FR-25,CHUẨN ĐOÁN Phân loại Mức độ Viêm Khớp gối,,Yes,No,"Load Patient Scan Session (https://app.notion.com/p/Load-Patient-Scan-Session-376f910aea75807586e9e64a7883c7b6?pvs=21), Review Suggested Synovitis Grade (0-3) (https://app.notion.com/p/Review-Suggested-Synovitis-Grade-0-3-378f910aea75802492c7d60b707b988e?pvs=21), Finalize & Sign Electronic Record (https://app.notion.com/p/Finalize-Sign-Electronic-Record-378f910aea758088b010f6f1c52c006d?pvs=21), Generate GradCAM & CoT Explanation Panel (https://app.notion.com/p/Generate-GradCAM-CoT-Explanation-Panel-378f910aea7580cdb530f06312577e6f?pvs=21), Log High-Trust Concur Block (https://app.notion.com/p/Log-High-Trust-Concur-Block-378f910aea7580baa4aace53fe624e23?pvs=21), Trigger Conversational Circuit Breaker (https://app.notion.com/p/Trigger-Conversational-Circuit-Breaker-378f910aea7580b2949be22396e2e159?pvs=21), Facilitate Socratic Reasoning Dialogue (https://app.notion.com/p/Facilitate-Socratic-Reasoning-Dialogue-378f910aea7580ee9d93d1988a1e5146?pvs=21), Monitor Context Drift via BERT Sub-Layer (https://app.notion.com/p/Monitor-Context-Drift-via-BERT-Sub-Layer-378f910aea7580c5b69bcad54c8fe21c?pvs=21), Arbitrate Evidence via RAG-Referee (https://app.notion.com/p/Arbitrate-Evidence-via-RAG-Referee-378f910aea75805b83dadeb609585473?pvs=21), Expose Pixel-Level Activation Logic (https://app.notion.com/p/Expose-Pixel-Level-Activation-Logic-378f910aea7580a49250ee97e865637c?pvs=21), Isolate Visual Noise/Artifacts (https://app.notion.com/p/Isolate-Visual-Noise-Artifacts-378f910aea7580898125d5a2d073c9db?pvs=21), Commit Validated Ground-Truth Record (https://app.notion.com/p/Commit-Validated-Ground-Truth-Record-378f910aea7580f6853bc7427402864f?pvs=21), Activate Clinical Investigation Mode (https://app.notion.com/p/Activate-Clinical-Investigation-Mode-378f910aea758059ab78df2595b9f5f6?pvs=21), Execute Structured Morphology Annotation (https://app.notion.com/p/Execute-Structured-Morphology-Annotation-378f910aea758013b687d8272c7be796?pvs=21), Serialize Session to Telemetry Queue (https://app.notion.com/p/Serialize-Session-to-Telemetry-Queue-378f910aea75808dbeeddaaa8ae1580f?pvs=21)",Đạt Trần Tiến (Daves Tran),UP5,System,Hệ thống đã ghi nhận độ dày màng hoạt dịch (REQ-RAD-02) và kết quả quét Doppler dòng máu (Hypervascularity),"Hệ thống đưa ra gợi ý chẩn đoán mức độ viêm theo thang chuẩn y khoa (ví dụ: Không viêm, Viêm nhẹ - Độ 1, Viêm vừa - Độ 2, Viêm nặng - Độ 3) để bác sĩ xác nhận hoặc điều chỉnh","ULTS-Đánh giá và phân cấp mức độ viêm màng hoạt dịch (Synovitis Grading)-FR-25: As an [Diagnostic Radiologist], provide that Hệ thống đã ghi nhận độ dày màng hoạt dịch (REQ-RAD-02) và kết quả quét Doppler dòng máu (Hypervascularity), the [System] should CHUẨN ĐOÁN Phân loại Mức độ Viêm Khớp gối, ensuring that Hệ thống đưa ra gợi ý chẩn đoán mức độ viêm theo thang chuẩn y khoa (ví dụ: Không viêm, Viêm nhẹ - Độ 1, Viêm vừa - Độ 2, Viêm nặng - Độ 3) để bác sĩ xác nhận hoặc điều chỉnh",tahuykl
|
|
||||||
|
@@ -1,184 +0,0 @@
|
|||||||
ReqName,ComponentName,Created time,Engineer,ID,NotViloate,Project Prefix,Rationale,ReqCategory,ReqID,TargetSpec,UserProfileCode,Validation,VerboseDescription
|
|
||||||
DICOM Collaborative Rendering Speed,PR,"June 5, 2026 10:41 AM",Đạt Trần Tiến (Daves Tran),NFR-1,The user/event response time for transforming a standard DICOM X-ray into a shared collaborative canvas with ML diagnostic overlays SHALL NOT exceed 3.0 seconds.,ULTS,prevention losing the trust and adoption of fast-paced Professional Clinicians (UP2) operating under intense multitasking and heavy ward volumes.,Efficiency (Speed & Space),ULTS-PR-NFR-1,"Optimize the interactive workspace canvas performance during the ingestion and
|
|
||||||
rendering of medical image assets.",UP2,"Deploy network throttling profiles (clamped at exactly 10 Mbps) on a test client terminal. Trigger 100 consecutive DICOM collaborative canvas initializations.
|
|
||||||
Measure end-to-end latency via automated browser performance scripts.
|
|
||||||
SUCCESS CRITERIA: 100% of test runs must clock an event duration ≤ 3000ms.","📌 As a result of prevention losing the trust and adoption of fast-paced Professional Clinicians (UP2) operating under intense multitasking and heavy ward volumes.,
|
|
||||||
⚙️ The system must satisfy: Optimize the interactive workspace canvas performance during the ingestion and
|
|
||||||
rendering of medical image assets.,
|
|
||||||
🛑 And it shall not violate: The user/event response time for transforming a standard DICOM X-ray into a shared collaborative canvas with ML diagnostic overlays SHALL NOT exceed 3.0 seconds.."
|
|
||||||
Client Memory Footprint & Constraints,PR,"June 5, 2026 11:13 AM",Đạt Trần Tiến (Daves Tran),NFR-4,The active client application memory allocation SHALL NOT exceed 150 Mbytes of RAM during an ongoing multi-user collaborative review session. Additionally the program have to run on client hardware devices with baseline configurations down to 3GB total RAM.,ULTS,"Practitioners (UP3) operate in resource-constrained provincial and commune
|
|
||||||
clinics using legacy mobile and tablet form-factors with limited system memory.",Efficiency (Speed & Space),ULTS-PR-NFR-4,Constrain the runtime store occupancy of the active browser application workspace.,UP3,"Connect a low-end test tablet to Chrome DevTools Memory Profiler. Initialize a 4-user
|
|
||||||
shared collaborative workshop session. Simulate continuous annotation changes for
|
|
||||||
30 minutes.
|
|
||||||
SUCCESS CRITERIA: Peak heap memory allocation logged in heap snapshots must stay strictly below 150MB, with 0 instances of OS-level browser crashes.","📌 As a result of Practitioners (UP3) operate in resource-constrained provincial and commune
|
|
||||||
clinics using legacy mobile and tablet form-factors with limited system memory.,
|
|
||||||
⚙️ The system must satisfy: Constrain the runtime store occupancy of the active browser application workspace.,
|
|
||||||
🛑 And it shall not violate: The active client application memory allocation SHALL NOT exceed 150 Mbytes of RAM during an ongoing multi-user collaborative review session. Additionally the program have to run on client hardware devices with baseline configurations down to 3GB total RAM.."
|
|
||||||
Core Vision Inference Latency Limit,PR,"June 5, 2026 11:16 AM",Đạt Trần Tiến (Daves Tran),NFR-5,The processing time for raw DICOM matrix parsing and diagnostic bounding-box generation SHALL NOT exceed 1.5 seconds. Additionally the computation must be calculated locally on the designated on-premise local server configuration node.,ULTS,"prevention local compute bottlenecks from pushing the overall collaborative
|
|
||||||
workspace sync execution beyond the critical user threshold.",Efficiency (Speed & Space),ULTS-PR-NFR-5,The local computer vision model must complete image processing rapidly on the edge tier.,UP2,"Inject a test batch of 500 un-analyzed musculoskeletal DICOM files into the
|
|
||||||
local image processing queue. Read backend server performance tracing timestamps.
|
|
||||||
SUCCESS CRITERIA: Arithmetic mean of inference execution time must be ≤ 1500ms,
|
|
||||||
with a maximum upper bound outlier limit of 1800ms.","📌 As a result of prevention local compute bottlenecks from pushing the overall collaborative
|
|
||||||
workspace sync execution beyond the critical user threshold.,
|
|
||||||
⚙️ The system must satisfy: The local computer vision model must complete image processing rapidly on the edge tier.,
|
|
||||||
🛑 And it shall not violate: The processing time for raw DICOM matrix parsing and diagnostic bounding-box generation SHALL NOT exceed 1.5 seconds. Additionally the computation must be calculated locally on the designated on-premise local server configuration node.."
|
|
||||||
Server-Side Edge Model Quantization,PR,"June 5, 2026 11:20 AM",Đạt Trần Tiến (Daves Tran),NFR-6,"The active memory allocation of the deployed models SHALL NOT require more than
|
|
||||||
2 GB of VRAM on the target server nodes, and the system shall have to execute on local server nodes or specialized on-premise clinical workstations.",ULTS,"prevention hardware resource exhaustion on local public hospital servers and keep
|
|
||||||
deployment costs sustainable for district clinics.",Efficiency (Speed & Space),ULTS-PR-NFR-6,Apply optimization protocols to the deployed musculoskeletal computer vision models.,UP2,"Boot up the localized AI model server container cluster. Query GPU hardware parameters via
|
|
||||||
system telemetry CLI commands (e.g., nvidia-smi) during peak load tasks.
|
|
||||||
SUCCESS CRITERIA: System-reported dedicated VRAM consumption per inference runner
|
|
||||||
must remain under 2.0 GB.","📌 As a result of prevention hardware resource exhaustion on local public hospital servers and keep
|
|
||||||
deployment costs sustainable for district clinics.,
|
|
||||||
⚙️ The system must satisfy: Apply optimization protocols to the deployed musculoskeletal computer vision models.,
|
|
||||||
🛑 And it shall not violate: The active memory allocation of the deployed models SHALL NOT require more than
|
|
||||||
2 GB of VRAM on the target server nodes, and the system shall have to execute on local server nodes or specialized on-premise clinical workstations.."
|
|
||||||
Real-Time UI Screen Refresh (Token Streaming),PR,"June 5, 2026 11:24 AM",Đạt Trần Tiến (Daves Tran),NFR-7,The initial UI screen refresh response time for text generation SHALL NOT be greater than 200 milliseconds from the moment inference begins. Also the system SHALL be able to rendered within standard browsers on legacy field-deployed budget tablets.,ULTS,"the acomodation of low-performance client screens and prevent UI freezing while
|
|
||||||
Practitioners (UP3) manage heavy, fast-moving clinical queues.",Efficiency (Speed & Space),ULTS-PR-NFR-7,Utilize a server-side processing architecture that pushes model text outputs as an asynchronous data stream.,UP3,"Trigger 50 distinct patient summary generation prompts on a legacy tablet.
|
|
||||||
Capture screen-to-render timelines using programmatic UI tracing (Time to First Token).
|
|
||||||
SUCCESS CRITERIA: The duration between user request submit and the rendering of
|
|
||||||
the first character on-screen must be ≤ 200ms in 100% of test cycles.","📌 As a result of the acomodation of low-performance client screens and prevent UI freezing while
|
|
||||||
Practitioners (UP3) manage heavy, fast-moving clinical queues.,
|
|
||||||
⚙️ The system must satisfy: Utilize a server-side processing architecture that pushes model text outputs as an asynchronous data stream.,
|
|
||||||
🛑 And it shall not violate: The initial UI screen refresh response time for text generation SHALL NOT be greater than 200 milliseconds from the moment inference begins. Also the system SHALL be able to rendered within standard browsers on legacy field-deployed budget tablets.."
|
|
||||||
Local Network Fault Tolerance (Robustness),PR,"June 5, 2026 11:27 AM",Đạt Trần Tiến (Daves Tran),NFR-8,"The objective probability of data corruption upon unexpected local connection failure
|
|
||||||
SHALL BE EXACTLY 0%, additional the system shall be able to Active / Remember the user-request during unexpected mid-session Wi-Fi disconnections or data link failures.",ULTS,"Rural district and commune-level healthcare nodes suffer from highly unstable
|
|
||||||
local network connectivity and frequent local Wi-Fi dropouts.",Dependability & Robustness,ULTS-PR-NFR-8,Integrate automated client-side data caching layers and silent background sync pipelines.,UNK,"Open an active collaborative review session on a client device. While drawing
|
|
||||||
canvas annotations, disconnect the clinic's local network router. Continue drawing 5 additions.
|
|
||||||
Restore router power after 60 seconds. Inspect the central database state.
|
|
||||||
SUCCESS CRITERIA: 0% data structural loss or canvas layer corruption. All offline edits
|
|
||||||
must synchronize seamlessly to the local server within 2.0 seconds of reconnection.","📌 As a result of Rural district and commune-level healthcare nodes suffer from highly unstable
|
|
||||||
local network connectivity and frequent local Wi-Fi dropouts.,
|
|
||||||
⚙️ The system must satisfy: Integrate automated client-side data caching layers and silent background sync pipelines.,
|
|
||||||
🛑 And it shall not violate: The objective probability of data corruption upon unexpected local connection failure
|
|
||||||
SHALL BE EXACTLY 0%, additional the system shall be able to Active / Remember the user-request during unexpected mid-session Wi-Fi disconnections or data link failures.."
|
|
||||||
Localized System Availability Matrix,PR,"June 5, 2026 11:30 AM",Đạt Trần Tiến (Daves Tran),NFR-9,"Local system availability SHALL NOT fall below a rate of 99.9% during official public
|
|
||||||
sector operating windows. Unexpected system downtime SHALL NOT exceed 45 seconds in any single day. Given the context that Mon–Fri, 07:00–16:30 (including lunch service from 11:30–13:30); selected evening windows
|
|
||||||
(17:00–20:00); continuous 24/7 coverage for emergency room department instances.",ULTS,"the condition that system must remain constantly online during standard and extended operating blocks
|
|
||||||
to prevent administrative blockages in crowded public patient queues.",Dependability & Robustness,ULTS-PR-NFR-9,"Ensure reliable, continuous local cluster operations without service interruptions.",UNK,"Review availability tracking logs generated by automated site reliability tools
|
|
||||||
(e.g., Prometheus/Grafana) continuously across a 30-day monitoring trial.
|
|
||||||
SUCCESS CRITERIA: Uptime logs must confirm ≤ 99.9% availability across all
|
|
||||||
designated operational shift blocks, with no un-escalated crashes exceeding 45 seconds.","📌 As a result of the condition that system must remain constantly online during standard and extended operating blocks
|
|
||||||
to prevent administrative blockages in crowded public patient queues.,
|
|
||||||
⚙️ The system must satisfy: Ensure reliable, continuous local cluster operations without service interruptions.,
|
|
||||||
🛑 And it shall not violate: Local system availability SHALL NOT fall below a rate of 99.9% during official public
|
|
||||||
sector operating windows. Unexpected system downtime SHALL NOT exceed 45 seconds in any single day. Given the context that Mon–Fri, 07:00–16:30 (including lunch service from 11:30–13:30); selected evening windows
|
|
||||||
(17:00–20:00); continuous 24/7 coverage for emergency room department instances.."
|
|
||||||
Automated Generative Safety Guardrails,PR,"June 5, 2026 11:33 AM",Đạt Trần Tiến (Daves Tran),NFR-10,"Less than 90% verification processing is prohibited (on these metric: Faithfulness / Groundedness Score, Policy Compliance Rate, Jailbreak/Toxicity Detection Rate, and Latency & Token Usage) ; 100% of LLM-generated patient text
|
|
||||||
explanations SHALL pass verification before rendering on the client interface.",ULTS,"the constrain that system have to safely insulate Support Staff & Patients (UP4) from unverified text outputs,
|
|
||||||
translation errors, or inappropriate medical claims.",Dependability & Robustness,ULTS-PR-NFR-10,"Intercept raw model generation streams with an automated verification layer
|
|
||||||
(e.g., NVIDIA NeMo Guardrails or Llama Guard). This constrain have to apply to all outward-facing user communications and text interfaces. ",UP4,"Inject a test suite containing 200 adversarial prompts designed to trigger unsafe medical
|
|
||||||
claims or guideline deviations. Analyze the resulting UI delivery logs.
|
|
||||||
SUCCESS CRITERIA: The system must successfully catch, block, or rewrite 100% of the
|
|
||||||
violating outputs, displaying a safe fallback notification instead.","📌 As a result of the constrain that system have to safely insulate Support Staff & Patients (UP4) from unverified text outputs,
|
|
||||||
translation errors, or inappropriate medical claims.,
|
|
||||||
⚙️ The system must satisfy: Intercept raw model generation streams with an automated verification layer
|
|
||||||
(e.g., NVIDIA NeMo Guardrails or Llama Guard). This constrain have to apply to all outward-facing user communications and text interfaces. ,
|
|
||||||
🛑 And it shall not violate: Less than 90% verification processing is prohibited (on these metric: Faithfulness / Groundedness Score, Policy Compliance Rate, Jailbreak/Toxicity Detection Rate, and Latency & Token Usage) ; 100% of LLM-generated patient text
|
|
||||||
explanations SHALL pass verification before rendering on the client interface.."
|
|
||||||
Frontline Usability & Training Curve,PR,"June 5, 2026 11:42 AM",Đạt Trần Tiến (Daves Tran),NFR-11,"The required onboarding training window to achieve independent user proficiency SHALL NOT
|
|
||||||
exceed 45 minutes. The subsequent average error rate SHALL NOT exceed 1 configuration slip per week.",ULTS,"Frontline Practitioners and Support Staff, and Patient exhibit low digital confidence and face severe
|
|
||||||
daily time constraints, making them resistant to tools that require complex setups.",Usability (Ease of Use),ULTS-PR-NFR-11,"Simplify user interaction flows for core workflows (patient registration, queue routing,
|
|
||||||
and media casting).","UP2, UP3, UP4","Run a validation test with 30 target users (Profiles 3 & 4). Provide a standard 45-minute
|
|
||||||
instructional session. Task users with processing a mock 10-patient throughput queue. Log
|
|
||||||
operational missteps over their first week of live work. Also ones have to run the evaluation on frontline staff with typical vocational/basic/ entry-level healthcare backgrounds.
|
|
||||||
SUCCESS CRITERIA: 90% or more of participants must pass the initial throughput test
|
|
||||||
independently, with a tracked post-onboarding error rate ≤ 1 configuration slip per week. - ","📌 As a result of Frontline Practitioners and Support Staff, and Patient exhibit low digital confidence and face severe
|
|
||||||
daily time constraints, making them resistant to tools that require complex setups.,
|
|
||||||
⚙️ The system must satisfy: Simplify user interaction flows for core workflows (patient registration, queue routing,
|
|
||||||
and media casting).,
|
|
||||||
🛑 And it shall not violate: The required onboarding training window to achieve independent user proficiency SHALL NOT
|
|
||||||
exceed 45 minutes. The subsequent average error rate SHALL NOT exceed 1 configuration slip per week.."
|
|
||||||
Zero-Friction Explainability Integration,ORG,"June 5, 2026 11:58 AM",Đạt Trần Tiến (Daves Tran),NFR-12,"Accessing baseline model confidence intervals or guideline justifications SHALL require
|
|
||||||
EXACTLY 0 extra user clicks or separate modal pop-up windows. - and the model’s result have to displayed inside the primary medical viewport layout used during image interpretation.",ULTS,"Senior Experts (UP1) & professional-clinicians have an exceptionally low tolerance for workflow friction and
|
|
||||||
remain highly skeptical of opaque, un-verifiable ""black-box"" systems.",Operational Process,ULTS-ORG-NFR-12,"Display automated safety checks, objective alerts, and validation states cleanly within
|
|
||||||
the specialist's primary visual focus field.","UP1, UP2","Open a clinical record entry as a UP1 user. Use a UI click-tracking extension to log
|
|
||||||
the step count required to read the model's confidence scores.
|
|
||||||
SUCCESS CRITERIA: Information must render automatically alongside the image asset.
|
|
||||||
The recorded click count to reveal basic explanation data must be exactly zero.","📌 As a result of Senior Experts (UP1) & professional-clinicians have an exceptionally low tolerance for workflow friction and
|
|
||||||
remain highly skeptical of opaque, un-verifiable ""black-box"" systems.,
|
|
||||||
⚙️ The system must satisfy: Display automated safety checks, objective alerts, and validation states cleanly within
|
|
||||||
the specialist's primary visual focus field.,
|
|
||||||
🛑 And it shall not violate: Accessing baseline model confidence intervals or guideline justifications SHALL require
|
|
||||||
EXACTLY 0 extra user clicks or separate modal pop-up windows. - and the model’s result have to displayed inside the primary medical viewport layout used during image interpretation.."
|
|
||||||
Spatial Layer-Activation Mapping (The Anti-Black-Box Mandate),ORG,"June 5, 2026 12:16 PM",Đạt Trần Tiến (Daves Tran),NFR-13,"The vision stack SHALL natively output spatial layer-activation maps (such as Grad-CAM overlays).
|
|
||||||
Displaying these anatomical heatmaps upon selecting an identified finding SHALL require zero extra clicks, during all automated musculoskeletal pathology screening tasks.",ULTS,"establishing the immediate clinical trust and give Senior Experts & Professional Expert (UP2, UP1) clear, objective
|
|
||||||
evidence to justify diagnosis choices and manage legal liabilities.","The ""Anti-Black-Box"" Mandate",ULTS-ORG-NFR-13,Expose the exact spatial foundations of the machine learning model's diagnostic conclusions.,"UP1, UP2","Process a standard diagnostic session. Select an automated finding label on the interface.
|
|
||||||
Observe viewport updates.
|
|
||||||
SUCCESS CRITERIA: The corresponding region of interest on the X-ray must instantly
|
|
||||||
highlight its Grad-CAM layer activation overlay with zero intermediate user input.","📌 As a result of establishing the immediate clinical trust and give Senior Experts & Professional Expert (UP2, UP1) clear, objective
|
|
||||||
evidence to justify diagnosis choices and manage legal liabilities.,
|
|
||||||
⚙️ The system must satisfy: Expose the exact spatial foundations of the machine learning model's diagnostic conclusions.,
|
|
||||||
🛑 And it shall not violate: The vision stack SHALL natively output spatial layer-activation maps (such as Grad-CAM overlays).
|
|
||||||
Displaying these anatomical heatmaps upon selecting an identified finding SHALL require zero extra clicks, during all automated musculoskeletal pathology screening tasks.."
|
|
||||||
Legacy Local Hardware Compatibility,ORG,"June 5, 2026 12:30 PM",Đạt Trần Tiến (Daves Tran),NFR-14,"The user interface modules SHALL NOT require a dedicated external client-side GPU or hardware
|
|
||||||
neural accelerator. The system must operate seamlessly on tablet form-factors running
|
|
||||||
Android 10+ with as little as 3GB of RAM. Also, the system shall be applicable to all field-deployed operational and patient-facing user portals.",ULTS,"Severe hardware shortages and legacy systems are common across rural district and commune clinics.
|
|
||||||
",Environmental,ULTS-ORG-NFR-14,Ensure the user applications run smoothly on existing low-end client hardware assets.,UNK,"Install the client web application on an entry-level Android 10 test tablet (equipped with exactly
|
|
||||||
3GB RAM and an integrated low-tier mobile processor). Run a complete end-to-end patient flow.
|
|
||||||
SUCCESS CRITERIA: Frame rendering rates must stay ≤ 30 frames per second, with
|
|
||||||
zero hardware-induced memory crashes or system hangs.","📌 As a result of Severe hardware shortages and legacy systems are common across rural district and commune clinics.
|
|
||||||
,
|
|
||||||
⚙️ The system must satisfy: Ensure the user applications run smoothly on existing low-end client hardware assets.,
|
|
||||||
🛑 And it shall not violate: The user interface modules SHALL NOT require a dedicated external client-side GPU or hardware
|
|
||||||
neural accelerator. The system must operate seamlessly on tablet form-factors running
|
|
||||||
Android 10+ with as little as 3GB of RAM. Also, the system shall be applicable to all field-deployed operational and patient-facing user portals.."
|
|
||||||
National EMR Compliance (Circular 46/2018/TT-BYT),ER,"June 5, 2026 12:32 PM",Đạt Trần Tiến (Daves Tran),NFR-15,"Any data processing architecture that breaks the provisions of the Vietnamese Ministry
|
|
||||||
of Health’s Circular 46/2018/TT-BYT governing electronic medical records is strictly prohibited. Additionally, the system have to governs all patient medical histories, clinical records, and diagnostic storage pipelines, and the hospital & the user shall own this.",ULTS,"addressing intense legal liability concerns raised by Senior Experts (UP1) and Clinical
|
|
||||||
Directors regarding health data processing.",Legislative & Regulatory,ULTS-ER-NFR-15,"Build data security & data-minimization models, anonymization logic, and electronic transfer handoffs that conform to national laws.",UP1,"Submit the complete application architectural specification, encryption protocols, and data data
|
|
||||||
handling designs to a certified medical compliance auditor or legal team.
|
|
||||||
SUCCESS CRITERIA: Obtain a formal compliance sign-off confirming 100% alignment with
|
|
||||||
Circular 46/2018/TT-BYT.","📌 As a result of addressing intense legal liability concerns raised by Senior Experts (UP1) and Clinical
|
|
||||||
Directors regarding health data processing.,
|
|
||||||
⚙️ The system must satisfy: Build data security & data-minimization models, anonymization logic, and electronic transfer handoffs that conform to national laws.,
|
|
||||||
🛑 And it shall not violate: Any data processing architecture that breaks the provisions of the Vietnamese Ministry
|
|
||||||
of Health’s Circular 46/2018/TT-BYT governing electronic medical records is strictly prohibited. Additionally, the system have to governs all patient medical histories, clinical records, and diagnostic storage pipelines, and the hospital & the user shall own this.."
|
|
||||||
Local Intranet Cloud & Air-Gapped Data Isolation,ER,"June 5, 2026 12:35 PM",Đạt Trần Tiến (Daves Tran),NFR-16,"The platform tech stack (Llama-3, PhoGPT, or MedGemma) SHALL NOT transmit any diagnostic or
|
|
||||||
identifiable clinical information across the public internet. External cloud processing (that outside Vietnam) is prohibited. Only execute & deployed on on-premise servers, local intranet infrastructures, or isolated specialist machines.",ULTS,"the Public health laws protection on medical data sovereignty, making it illegal to use public,
|
|
||||||
commercial cloud AI APIs where patient data leaves the national borders.",Ethical & Safety,ULTS-ER-NFR-16,"Restrict the platform's execution, storage, and model evaluation environments to internal networks.",UNK,"Boot up the full platform cascade. Trigger active DICOM analysis and text generation tasks on a
|
|
||||||
client machine. Run a network packet analyzer (e.g., Wireshark) on the outward-facing router port.
|
|
||||||
SUCCESS CRITERIA: 100% of packets containing health or analysis records must resolve inside local
|
|
||||||
IP ranges (LAN). Outbound public internet traffic matching these profiles must remain exactly zero.","📌 As a result of the Public health laws protection on medical data sovereignty, making it illegal to use public,
|
|
||||||
commercial cloud AI APIs where patient data leaves the national borders.,
|
|
||||||
⚙️ The system must satisfy: Restrict the platform's execution, storage, and model evaluation environments to internal networks.,
|
|
||||||
🛑 And it shall not violate: The platform tech stack (Llama-3, PhoGPT, or MedGemma) SHALL NOT transmit any diagnostic or
|
|
||||||
identifiable clinical information across the public internet. External cloud processing (that outside Vietnam) is prohibited. Only execute & deployed on on-premise servers, local intranet infrastructures, or isolated specialist machines.."
|
|
||||||
Cryptographic Accountability Logging,ER,"June 5, 2026 12:37 PM",Đạt Trần Tiến (Daves Tran),NFR-17,"The application layer SHALL NOT allow any user, including database administrators, to alter or delete the logs. Every action where an AI recommendation is accepted or overridden must be saved immutably. - This constrain have to apply to all active clinical screening and diagnostic check workflows.",ULTS,"the need oreliable audit trails that help Professional Clinicians (UP2) justify their
|
|
||||||
treatment paths upward and satisfy institutional safety standards.",Ethical & Safety,ULTS-ER-NFR-17,Maintain a highly secure ledger recording every clinical decision point that interacts with AI insights.,UP2,"Log into the system back-end using full database administrator (DBA) root privileges. Attempt to execute
|
|
||||||
SQL UPDATE or DELETE commands directly on the clinical_decision_ledger table.
|
|
||||||
SUCCESS CRITERIA: The database kernel must block the transaction with a fatal database permission
|
|
||||||
error, proving Row-Level Security and append-only constraints are working.","📌 As a result of the need oreliable audit trails that help Professional Clinicians (UP2) justify their
|
|
||||||
treatment paths upward and satisfy institutional safety standards.,
|
|
||||||
⚙️ The system must satisfy: Maintain a highly secure ledger recording every clinical decision point that interacts with AI insights.,
|
|
||||||
🛑 And it shall not violate: The application layer SHALL NOT allow any user, including database administrators, to alter or delete the logs. Every action where an AI recommendation is accepted or overridden must be saved immutably. - This constrain have to apply to all active clinical screening and diagnostic check workflows.."
|
|
||||||
MOH Guideline-Anchored RAG Pipeline,ER,"June 5, 2026 12:39 PM",Đạt Trần Tiến (Daves Tran),NFR-18,"The system SHALL NOT render open-ended clinical text summaries that do not append a clear, traceable
|
|
||||||
footnote citation referencing official Ministry of Health (MOH) medical protocols. - This constrain have to active across all patient education modules and text summary generators.",ULTS,"Large Language Models hallucination on factual errors, which could present dangerous or misleading
|
|
||||||
medical claims to patients.",Ethical & Safety,ULTS-ER-NFR-18,"Restrict the model's educational text generation by using Retrieval-Augmented Generation (RAG)
|
|
||||||
tied to official health guidelines.",UNK,"Run a suite of 100 patient information queries through the generation pipeline. Use semantic
|
|
||||||
evaluation scripts to compare the output text strings against your verified guideline database.
|
|
||||||
SUCCESS CRITERIA: 100% of the generated outputs must include a verifiable source footnote ID,
|
|
||||||
showing an objective mathematical semantic alignment match (≤ 0.85 cosine similarity)
|
|
||||||
with official MOH protocols.","📌 As a result of Large Language Models hallucination on factual errors, which could present dangerous or misleading
|
|
||||||
medical claims to patients.,
|
|
||||||
⚙️ The system must satisfy: Restrict the model's educational text generation by using Retrieval-Augmented Generation (RAG)
|
|
||||||
tied to official health guidelines.,
|
|
||||||
🛑 And it shall not violate: The system SHALL NOT render open-ended clinical text summaries that do not append a clear, traceable
|
|
||||||
footnote citation referencing official Ministry of Health (MOH) medical protocols. - This constrain have to active across all patient education modules and text summary generators.."
|
|
||||||
Human-in-the-Loop (HITL) Clinical Gatekeeping,ER,"June 5, 2026 12:40 PM",Đạt Trần Tiến (Daves Tran),NFR-19,"The database layer SHALL NOT allow any automated ML/LLM diagnosis asset or report
|
|
||||||
to transition to a 'FINALIZED', 'ARCHIVED', or 'PATIENT_ACCESSIBLE' status code without an authenticating digital signature from a licensed human clinician. The constrain shall apply to 100% of diagnostic sessions, triage check-sheets, and generated
|
|
||||||
musculoskeletal patient-education outputs before saving.",ULTS,"the need of mitigating the medical liability, prevention the downstream propagation of AI
|
|
||||||
hallucinations or edge-case diagnostic errors, and ensure that final clinical
|
|
||||||
accountability rests solely with a licensed human medical practitioner.",Ethical & Safety,ULTS-ER-NFR-19,"Implement an architectural air-gap gatekeeper where no automated ML insights or
|
|
||||||
generative patient summaries can be committed to the official Electronic Medical
|
|
||||||
Record (EMR) or finalized for patient distribution without explicit human sign-off.",UNK,"Attempt to programmatically bypass the UI and send a raw API transaction to commit
|
|
||||||
an automated MedGemma diagnostic report directly to the patient's EMR table with
|
|
||||||
the licensed_clinician_id column left blank or null.
|
|
||||||
SUCCESS CRITERIA: The local server database kernel must instantly abort the transaction,
|
|
||||||
triggering a foreign key or check constraint failure that rolls back the write operation.","📌 As a result of the need of mitigating the medical liability, prevention the downstream propagation of AI
|
|
||||||
hallucinations or edge-case diagnostic errors, and ensure that final clinical
|
|
||||||
accountability rests solely with a licensed human medical practitioner.,
|
|
||||||
⚙️ The system must satisfy: Implement an architectural air-gap gatekeeper where no automated ML insights or
|
|
||||||
generative patient summaries can be committed to the official Electronic Medical
|
|
||||||
Record (EMR) or finalized for patient distribution without explicit human sign-off.,
|
|
||||||
🛑 And it shall not violate: The database layer SHALL NOT allow any automated ML/LLM diagnosis asset or report
|
|
||||||
to transition to a 'FINALIZED', 'ARCHIVED', or 'PATIENT_ACCESSIBLE' status code without an authenticating digital signature from a licensed human clinician. The constrain shall apply to 100% of diagnostic sessions, triage check-sheets, and generated
|
|
||||||
musculoskeletal patient-education outputs before saving.."
|
|
||||||
|
|
Before Width: | Height: | Size: 189 KiB After Width: | Height: | Size: 189 KiB |
|
Before Width: | Height: | Size: 254 KiB After Width: | Height: | Size: 254 KiB |
Reference in New Issue
Block a user