Skip to main content

Contributing to Morphee

Thank you for your interest in contributing to Morphee! This guide is for human contributors. If you're an AI agent, see CLAUDE.md instead.


Getting Started

  1. Read the docs

  2. Set up your environment

    # Clone repository
    git clone https://github.com/your-org/morphee-beta.git
    cd morphee-beta

    # Start backend (Docker)
    docker compose -f docker-compose.dev.yml up -d

    # Start frontend (dev server)
    cd frontend && npm install && npm run dev
  3. Verify your setup


How to Contribute

Finding Work

Check docs/status.md — this is the primary work tracker. Look for:

  • Current sprint checklists (items not yet checked off)
  • "What's Next" sections
  • Future phase planning

Or propose new work:

  • Open an issue describing the problem or feature
  • Wait for maintainer feedback before starting work
  • Reference the issue in your PR

Branch Naming

Use descriptive branch names with prefixes:

  • feat/ — New features (e.g., feat/add-push-notifications)
  • fix/ — Bug fixes (e.g., fix/auth-token-refresh)
  • refactor/ — Code refactoring (e.g., refactor/extract-auth-service)
  • docs/ — Documentation updates (e.g., docs/update-api-reference)
  • test/ — Test additions or fixes (e.g., test/cover-chat-service)
  • chore/ — Tooling, dependencies (e.g., chore/upgrade-react-19)

Development Workflow

1. Create a Branch

git checkout -b feat/your-feature-name

2. Make Changes

Follow our coding standards (see Code Style).

3. Write Tests

Required for all code changes. See Testing.

  • Backend: pytest tests in backend/tests/
  • Frontend: vitest unit tests + playwright E2E tests
  • Tauri Rust: cargo test in frontend/src-tauri/

Aim for:

  • Backend: >80% coverage
  • Frontend: >70% coverage
  • Rust: All critical paths covered

4. Run Tests Locally

# Backend
docker compose -f docker-compose.dev.yml exec -T backend pytest -q --cov=. --cov-report=term-missing

# Tauri Rust
cd frontend/src-tauri && cargo test

# Frontend unit
cd frontend && npx vitest run

# Frontend E2E (needs backend running)
cd frontend && npm run test:e2e

# Frontend build check
cd frontend && npm run build

All tests must pass before submitting a PR.

5. Update Documentation

If your change affects:

  • API endpoints → update docs/api.md
  • Project structure → update CLAUDE.md
  • Features or architecture → update relevant docs in docs/
  • Test counts → update docs/test-results.md (single source of truth)
  • New feature design doc → add to docs/features/. Two naming conventions are both accepted:
    • Date-prefixed: YYYY-MM-DD-feature-name.md (preferred for new design docs — makes history scannable)
    • Descriptive-only: feature-name.md (acceptable for evergreen reference docs)

6. Commit Changes

Use clear, descriptive commit messages:

# Good
git commit -m "feat: add push notification support for iOS/Android"
git commit -m "fix: resolve auth token refresh race condition"
git commit -m "test: add coverage for chat service message pagination"

# Bad
git commit -m "update code"
git commit -m "fixes"
git commit -m "WIP"

Commit message format:

<type>: <description>

[optional body explaining why, not what]

[optional footer with issue references]

Types: feat, fix, refactor, docs, test, chore, perf, style

7. Push and Create PR

git push origin feat/your-feature-name

Then create a Pull Request on GitHub with:

  • Title: Clear, concise description (e.g., "Add push notification support")
  • Description:
    • What changed and why
    • Link to related issue
    • Test plan (how to verify the change)
    • Screenshots/videos for UI changes

PR Description Template:

## Summary
Brief description of what this PR does.

## Changes
- Bullet list of key changes
- Include file/component names

## Test Plan
- [ ] Backend tests pass (X new tests added)
- [ ] Frontend tests pass (X new tests added)
- [ ] Manually tested: [describe steps]

## Related Issues
Fixes #123

8. Code Review

  • Maintainers will review your PR
  • Address feedback by pushing new commits to the same branch
  • Once approved, a maintainer will merge your PR

Code Style

Backend (Python)

  • Async everywhere — use async def for all route handlers and services
  • Type hints — use Python type annotations
  • Pydantic — use for request/response models
  • Testingpytest with pytest-asyncio
  • Formattingblack (100 char line length) + isort (install separately: pip install black isort)
  • Lintingmypy + pylint (install separately: pip install mypy pylint)

Run formatters:

cd backend
black .
isort .
mypy .
pylint **/*.py

Frontend (TypeScript)

  • Zustand for state (not React Context)
  • shadcn/ui for components (Radix-based)
  • react-hook-form + zod for forms
  • Functional components with hooks
  • TypeScript strict mode — no any types

Format and lint code:

cd frontend
npm run lint

Tauri Rust

  • cargo fmt for formatting
  • cargo clippy for linting
  • Error handling — use Result<T, MorpheeError>
  • Testing — comprehensive unit tests for all public APIs
cd frontend/src-tauri
cargo fmt
cargo clippy

Testing

Backend Testing

cd backend
pytest tests/ # All tests
pytest tests/test_auth.py # Specific file
pytest -k test_name # Specific test
pytest --cov=. --cov-report=html # With coverage

Test structure:

  • tests/unit/ — Unit tests (services, models)
  • tests/integration/ — API endpoint tests

Patterns:

import pytest
from backend.services.example import ExampleService

@pytest.mark.asyncio
async def test_example_service():
service = ExampleService()
result = await service.do_something()
assert result == expected

Frontend Testing

Unit tests (Vitest):

cd frontend
npx vitest run # All tests
npx vitest run Chat # Tests matching "Chat"
npx vitest --ui # Interactive UI
npx vitest --coverage # With coverage

E2E tests (Playwright):

cd frontend
npm run test:e2e # Headless
npm run test:e2e -- --ui # Interactive
npm run test:e2e -- --debug # Debug mode

Test patterns:

import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';

describe('Component', () => {
it('renders correctly', () => {
render(<Component />);
expect(screen.getByText('Hello')).toBeInTheDocument();
});
});

Tauri Rust Testing

cd frontend/src-tauri
cargo test # All tests
cargo test test_name # Specific test
cargo test -- --nocapture # Show println! output

Project Structure

See CLAUDE.md § Codebase Map for detailed structure.

Key directories:

  • backend/ — Python FastAPI backend
  • frontend/src/ — React TypeScript frontend
  • frontend/src-tauri/ — Tauri Rust layer
  • docs/ — All documentation
  • supabase/ — Database migrations

Common Tasks

Add a new API endpoint

  1. Define route in backend/api/your_module.py
  2. Add service method in backend/your_module/service.py
  3. Add Pydantic models in backend/your_module/models.py
  4. Write tests in backend/tests/test_your_module.py
  5. Document in docs/api.md

Add a new React component

  1. Create component in frontend/src/components/
  2. Add Zustand store if needed in frontend/src/store/
  3. Write tests in same directory (e.g., Component.test.tsx)
  4. Use shadcn/ui primitives when possible

Add a database migration

  1. Create SQL file in supabase/migrations/XXX_description.sql
  2. Test migration on dev database
  3. Update docs if schema changes affect API

Need Help?

  • Documentation: Check docs/ directory
  • Questions: Open a GitHub Discussion
  • Bugs: Open a GitHub Issue with reproduction steps
  • Features: Open an issue to discuss before implementing

License

By contributing, you agree that your contributions will be licensed under the MIT License.