Development
Local Setup
Mobile App
Infrastructure
Development Workflow with jj
This project uses jj (Jujutsu) for version control.
JJ vs Git Cheat Sheet
| Action | Git Command | JJ Command |
|---|---|---|
| Status | git status | jj st |
| Commit | git add . && git commit -m "msg" | jj describe -m "msg" |
| New Branch | git checkout -b new-branch | jj new |
| Push | git push | jj git push |
[!IMPORTANT] In
jj, your working copy is always a commit (@). You do not "stage" files. Justdescribeyour work and create anewcommit on top.
Workflow: 1. Work: Make changes. YOU ARE ALREADY IN A COMMIT. 2. Format: Run jj fix often. 3. Describe: jj describe -m "feat: implemented X" 4. Finish: jj new (creates a new empty commit on top).
Testing & Code Quality
Overview
This project uses a two-gate system to ensure code quality:
- Hard Gate (Pre-commit): Fast checks run locally before you can commit
- Soft Gate (CI/CD): Full test suite runs on every PR
Pre-commit Hooks (Hard Gate)
When you commit code, these checks run automatically:
Formatting & Linting: - Python: Black (formatting), Ruff (linting) - TypeScript/JavaScript: Prettier (formatting), ESLint (linting) - Terraform: terraform fmt and terraform validate
Type Checking: - TypeScript: tsc --noEmit (type checking) - Python: Type checking runs in CI (not pre-commit to keep it fast)
Security: - Python: Bandit (security vulnerability scanning) - JavaScript: npm audit (dependency vulnerability checks) - All: Detect-secrets (prevents committing secrets)
Tests: - Unit tests run automatically for changed files - Python: pytest tests/unit/ when .py files change - TypeScript: npm test when .ts/.tsx files change
Commit Messages: - Enforces Conventional Commits format - Format: type(scope): description - Types: feat, fix, docs, refactor, test, chore, etc.
CI/CD Pipeline (Soft Gate)
On every PR, GitHub Actions runs:
Phone App Tests: - Linting (ESLint) - Type checking (TypeScript) - Unit tests with coverage - Reports coverage to DeepSource
AWS Backend Tests: - Formatting check (Black) - Linting (Ruff) - Type checking (mypy) - non-blocking - Security scanning (Bandit) - non-blocking - Unit tests with coverage - Reports coverage to DeepSource
Integration Tests: - End-to-end tests with real PostgreSQL database - Tests full pipeline: Meta SDK → Phone → AWS
Validation: - JSON Schema validation - Terraform validation - SAM template validation
Writing Tests
Phone App (TypeScript/React Native)
Location: main/app/__tests__/ (colocated with code)
// main/app/services/__tests__/event-builder.test.ts
import { EventBuilder } from '../event-builder';
import type { EventManifest } from '../../types/manifest';
describe('EventBuilder', () => {
it('should merge overlapping events', () => {
const builder = new EventBuilder();
const event1 = createMockManifest('event1', { t_start: 1000, t_end: 2000 });
const event2 = createMockManifest('event2', { t_start: 1500, t_end: 2500 });
builder.add(event1);
builder.add(event2);
const merged = builder.forceFlush();
expect(merged.length).toBe(1);
expect(merged[0].t_start).toBe(1000);
expect(merged[0].t_end).toBe(2500);
});
});
AWS Backend (Python)
Location: main/server/tests/unit/ (unit tests) and main/server/tests/integration/ (integration tests)
# main/server/tests/unit/test_ingest_manifest.py
import pytest
from main.server.ingest_manifest.app import lambda_handler
def test_validate_manifest():
event = {
'body': json.dumps({
'manifest_version': '2.1.0',
'event_id': 'test-123',
# ... rest of manifest
})
}
response = lambda_handler(event, {})
assert response['statusCode'] == 200
Best Practices
- Write tests first (TDD) or alongside code:
- Don't commit code without tests
-
Tests should be fast (<1s for unit tests)
-
Test behavior, not implementation:
- Test what the code does, not how it does it
-
Focus on inputs and outputs
-
Keep tests isolated:
- Each test should be independent
- Use
beforeEach/afterEachfor setup/teardown - Don't rely on test execution order
Development Guidelines
See .agents.md for comprehensive development guidelines including: - Canonical IDs and timestamp handling - Schema versioning and migrations - Security model and threat boundaries - Failure modes and idempotency - Observability and logging - Cost guardrails - Edge ML constraints - Code quality standards