# Contributing to TrustOS Thank you for your interest in contributing to TrustOS! This document provides guidelines and instructions for contributing to the project. --- ## Table of Contents - [Code of Conduct](#code-of-conduct) - [Getting Started](#getting-started) - [Development Workflow](#development-workflow) - [Coding Standards](#coding-standards) - [Testing Guidelines](#testing-guidelines) - [Documentation Guidelines](#documentation-guidelines) - [Pull Request Process](#pull-request-process) - [Commit Message Guidelines](#commit-message-guidelines) - [Reporting Issues](#reporting-issues) - [Feature Requests](#feature-requests) - [Community Guidelines](#community-guidelines) --- ## Code of Conduct ### Our Pledge We are committed to providing a welcoming and inclusive environment for all contributors. We value diverse perspectives and constructive collaboration. ### Our Standards - Be respectful and considerate - Use inclusive language - Focus on constructive feedback - Accept feedback gracefully - Show empathy toward other community members ### Unacceptable Behavior - Harassment or discrimination - Personal attacks - Derogatory comments - Public or private harassment - Publishing others' private information ### Reporting Issues If you witness or experience unacceptable behavior, please contact the project maintainers at conduct@trustos.com. --- ## Getting Started ### Prerequisites Before contributing, ensure you have: - **Git** installed and configured - **Python 3.10+** for backend development - **Node.js 18+** and **npm 9+** for frontend development - **Docker** and **Docker Compose** for local development - Basic knowledge of Python, TypeScript, React, and FastAPI ### Setting Up Development Environment 1. **Fork the Repository** ```bash # Fork the repository on GitHub/Gitea # Clone your fork git clone https://gitea.thetempleofdoom.com/YOUR_USERNAME/trustos.git cd trustos ``` 2. **Set Up Backend** ```bash cd backend python3 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate pip install -r requirements.txt cp .env.example .env # Edit .env with your configuration ``` 3. **Set Up Frontend** ```bash cd frontend npm install cp .env.example .env.local # Edit .env.local with NEXT_PUBLIC_API_URL=http://localhost:8000 ``` 4. **Start Development Services** ```bash # From project root cd infra docker-compose up -d postgres ``` 5. **Initialize Database** ```bash cd backend python seed.py ``` 6. **Run Development Servers** ```bash # Terminal 1: Backend cd backend uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 # Terminal 2: Frontend cd frontend npm run dev ``` ### Development Tools #### Backend Tools - **Black**: Code formatting ```bash pip install black black app/ ``` - **isort**: Import sorting ```bash pip install isort isort app/ ``` - **flake8**: Linting ```bash pip install flake8 flake8 app/ ``` - **mypy**: Type checking ```bash pip install mypy mypy app/ ``` #### Frontend Tools - **ESLint**: Linting ```bash npm run lint ``` - **Prettier**: Code formatting ```bash npm run format ``` - **TypeScript**: Type checking ```bash npm run type-check ``` --- ## Development Workflow ### 1. Create a Branch Create a new branch for your work: ```bash git checkout -b feature/your-feature-name # or git checkout -b fix/your-bug-fix ``` Branch naming conventions: - `feature/` - New features - `fix/` - Bug fixes - `docs/` - Documentation changes - `refactor/` - Code refactoring - `test/` - Test additions/changes - `chore/` - Maintenance tasks ### 2. Make Your Changes - Write clean, readable code - Follow coding standards (see below) - Add tests for new functionality - Update documentation as needed ### 3. Test Your Changes ```bash # Backend tests cd backend pytest # Frontend tests cd frontend npm test # Manual testing # - Test the feature in the browser # - Test API endpoints at /docs # - Verify no regressions ``` ### 4. Commit Your Changes Follow commit message guidelines (see below): ```bash git add . git commit -m "feat: add user authentication" ``` ### 5. Push to Your Fork ```bash git push origin feature/your-feature-name ``` ### 6. Create a Pull Request - Go to the repository on GitHub/Gitea - Click "New Pull Request" - Provide a clear description of your changes - Link to any related issues - Request review from maintainers --- ## Coding Standards ### Python (Backend) #### Style Guide Follow [PEP 8](https://pep8.org/) style guidelines: ```python # Good def calculate_risk_score(findings: List[Finding]) -> float: """Calculate the overall risk score from a list of findings.""" score = 100.0 for finding in findings: score -= SEVERITY_DEDUCTIONS[finding.severity] return max(0.0, score) # Bad def calc(f): s=100 for x in f: s-=d[x.sev] return max(0,s) ``` #### Type Hints Use type hints for all function signatures: ```python from typing import List, Optional def get_findings( tenant_id: str, severity: Optional[str] = None, limit: int = 50 ) -> List[Finding]: ... ``` #### Docstrings Use Google-style docstrings: ```python def calculate_risk_score(findings: List[Finding]) -> float: """Calculate the overall risk score from a list of findings. Args: findings: List of findings to calculate score from. Returns: Overall risk score between 0 and 100. Raises: ValueError: If findings list is empty. """ ... ``` #### Error Handling Use specific exceptions: ```python # Good try: finding = await get_finding(finding_id) except NotFoundError: raise HTTPException(status_code=404, detail="Finding not found") # Bad try: finding = await get_finding(finding_id) except: raise HTTPException(status_code=500) ``` ### TypeScript (Frontend) #### Style Guide Follow ESLint rules and Prettier configuration: ```typescript // Good interface DashboardData { currentScore: number; topRisks: RiskCard[]; scoreTrend: TrendPoint[]; } async function fetchDashboard(tenantId: string): Promise { const response = await api.dashboard(tenantId); return response.data; } // Bad interface d { s: number; r: any[]; } async function f(id: string) { const r = await api.dashboard(id); return r.data; } ``` #### Component Structure ```typescript // Good: Clear component structure interface RiskCardProps { finding: Finding; onDetailClick: (id: string) => void; } export function RiskCard({ finding, onDetailClick }: RiskCardProps) { const [isExpanded, setIsExpanded] = useState(false); return (
{/* Component content */}
); } ``` #### Hooks Use custom hooks for reusable logic: ```typescript // Good: Custom hook for data fetching function useFindings(tenantId: string) { const [findings, setFindings] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { fetchFindings(tenantId).then(data => { setFindings(data); setLoading(false); }); }, [tenantId]); return { findings, loading }; } ``` ### General Guidelines - **Keep functions small**: Functions should do one thing well - **Avoid deep nesting**: Use early returns to reduce nesting - **Use meaningful names**: Variable and function names should be descriptive - **Comment complex logic**: Explain why, not what - **DRY principle**: Don't repeat yourself - **YAGNI principle**: You aren't gonna need it (avoid over-engineering) --- ## Testing Guidelines ### Backend Testing #### Test Structure ```python # tests/test_findings.py import pytest from app.models.models import Finding, FindingSeverity class TestFindings: """Test suite for findings endpoints.""" @pytest.fixture async def sample_finding(self, db): """Create a sample finding for testing.""" finding = Finding( tenant_id="test-tenant", title="Test Finding", severity=FindingSeverity.high, status=FindingStatus.open ) db.add(finding) await db.commit() await db.refresh(finding) return finding async def test_get_finding(self, client, sample_finding): """Test retrieving a single finding.""" response = await client.get(f"/api/v1/findings/{sample_finding.id}") assert response.status_code == 200 data = response.json() assert data["id"] == sample_finding.id ``` #### Test Coverage Aim for at least 80% test coverage: ```bash # Run with coverage pytest --cov=app --cov-report=html --cov-report=term ``` #### Testing Best Practices - Write tests before code (TDD when possible) - Test both happy path and error cases - Use fixtures for common test data - Mock external dependencies (API calls, database) - Keep tests independent and fast ### Frontend Testing #### Component Testing ```typescript // components/__tests__/RiskCard.test.tsx import { render, screen } from '@testing-library/react'; import { RiskCard } from '../RiskCard'; describe('RiskCard', () => { it('renders finding title', () => { const finding = { id: '1', title: 'Test Finding', severity: 'high', ai_summary: 'Test summary' }; render(); expect(screen.getByText('Test Finding')).toBeInTheDocument(); }); }); ``` #### Integration Testing ```typescript // __tests__/dashboard.test.tsx import { render, screen, waitFor } from '@testing-library/react'; import { Dashboard } from '../app/dashboard/page'; describe('Dashboard', () => { it('displays risk score after loading', async () => { render(); await waitFor(() => { expect(screen.getByText(/risk score/i)).toBeInTheDocument(); }); }); }); ``` #### Testing Best Practices - Test user behavior, not implementation details - Use meaningful test descriptions - Mock API calls in component tests - Test accessibility (ARIA labels, keyboard navigation) - Keep tests focused and independent --- ## Documentation Guidelines ### Code Documentation - Document all public functions and classes - Use docstrings for complex logic - Comment non-obvious algorithms - Keep documentation up to date with code changes ### API Documentation - Update OpenAPI/Swagger annotations for new endpoints - Include request/response examples - Document error responses - Note authentication requirements ### README Updates - Update README.md for user-facing changes - Add new features to the features list - Update installation instructions if needed - Add new environment variables to the configuration section ### Changelog Maintain a CHANGELOG.md: ```markdown ## [Unreleased] ### Added - New feature description ### Changed - Changed behavior description ### Fixed - Bug fix description ### Deprecated - Deprecated feature description ``` --- ## Pull Request Process ### Before Submitting - [ ] Code follows project style guidelines - [ ] Tests pass locally - [ ] New tests added for new functionality - [ ] Documentation updated - [ ] Commit messages follow guidelines - [ ] No merge conflicts with target branch ### Pull Request Description Provide a clear description: ```markdown ## Description Brief description of what this PR does. ## Type of Change - [ ] Bug fix - [ ] New feature - [ ] Breaking change - [ ] Documentation update ## Testing How did you test this change? ## Checklist - [ ] Tests added/updated - [ ] Documentation updated - [ ] No breaking changes (or documented) ``` ### Review Process 1. Automated checks (CI/CD) must pass 2. At least one maintainer approval required 3. Address all review comments 4. Update PR as needed 5. Maintainer merges when approved --- ## Commit Message Guidelines Follow [Conventional Commits](https://www.conventionalcommits.org/) specification: ### Format ``` ():