Skip to content

First Contribution

End-to-end walkthrough of the full development workflow using a real example change. The example adds internal_reference to the Project entity and surfaces it in the API and UI.

What this covers

Adding a field touches every layer:

  • Database migration
  • SQLAlchemy model
  • Pydantic schema
  • FastAPI endpoint
  • TypeScript type (auto-generated from OpenAPI spec)
  • React form

Workflow

1. Pick up the ticket

In Linear: find the ticket, move to In Progress, assign yourself.

2. Branch

git checkout main && git pull
git checkout -b feature/eng-001-internal-reference

Naming: <type>/<short-description> where type is feature, fix, or chore.

3. Migration

cd apps/api
alembic revision -m "add_internal_reference_to_projects"

Edit the generated file:

def upgrade() -> None:
    op.add_column(
        "projects",
        sa.Column("internal_reference", sa.String(100), nullable=True),
        schema="{tenant_schema}",
    )

def downgrade() -> None:
    op.drop_column("projects", "internal_reference", schema="{tenant_schema}")

See Database Migrations for the {tenant_schema} placeholder pattern.

4. Model

# apps/api/src/modules/projects/models.py
class Project(Base):
    # ...
    internal_reference: Mapped[str | None] = mapped_column(String(100), nullable=True)

5. Schema

# apps/api/src/modules/projects/schemas.py
class ProjectBase(BaseModel):
    name: str
    reference: str
    internal_reference: str | None = None

6. Write the test first

# apps/api/tests/modules/test_projects.py
def test_create_project_with_internal_reference(client, auth_headers):
    response = client.post(
        "/projects",
        json={"name": "Test", "reference": "T-001", "internal_reference": "INT-99"},
        headers=auth_headers,
    )
    assert response.status_code == 201
    assert response.json()["internal_reference"] == "INT-99"

Run it:

pytest tests/modules/test_projects.py::test_create_project_with_internal_reference

7. Regenerate frontend types

cd apps/web && npm run generate-types

Pulls the latest OpenAPI spec from the running backend and updates src/types/api.ts.

8. Frontend form

<TextField
  label="Internal Reference"
  {...register("internal_reference")}
  error={errors.internal_reference?.message}
/>

9. AI review before opening the PR

Paste the diff to Claude:

Review this diff for: missing tests, security issues, multi-tenancy bugs,
missing error handling, and adherence to project coding standards.

Fix every finding before submitting.

10. Open the PR

git add .
git commit -m "feat(projects): add internal_reference field

ENG-001"
git push -u origin feature/eng-001-internal-reference

Fill in the PR template completely. CI must be green before requesting review.

11. After merge

CI deploys to staging. Verify the change works on staging, then move the Linear ticket to Done.