{
  "id": "ledger-api/scaffold-invoice-service",
  "slug": "scaffold-invoice-service",
  "title": "Session: scaffold-invoice-service — 2026-08-18",
  "type": "source",
  "project": "ledger-api",
  "date": "2026-08-18",
  "started": "2026-08-18T09:10:00+00:00",
  "ended": "2026-08-18T11:40:00+00:00",
  "model": "claude-sonnet-4-6",
  "cwd": "/home/dev/code/ledger-api",
  "git_branch": "main",
  "permission_mode": "default",
  "user_messages": 2,
  "tool_calls": 5,
  "tools_used": [
    "Bash",
    "Edit",
    "Write"
  ],
  "is_subagent": false,
  "wikilinks_out": [
    "Alembic",
    "FastAPI",
    "MoneyAsMinorUnits",
    "SQLAlchemy",
    "ledger-api"
  ],
  "body_text": "Project: ledger-api · Branch: main · Mode: default · Model: claude-sonnet-4-6\n\nSummary\n\nBootstrapped the invoicing service: FastAPI app factory, SQLAlchemy 2.0 models for customers, invoices and line items, Alembic baseline migration, and a pytest fixture that spins up Postgres in Docker. Money is stored as integer minor units from day one.\n\nConversation\n\nTurn 1 — User\n\nScaffold a FastAPI service for invoices. Postgres, SQLAlchemy 2.0, Alembic. Money must never be a float.\n\nTurn 1 — Assistant\n\nPlan: app factory in ledger/app.py, typed models in ledger/models.py, amounts as BIGINT minor units plus an ISO-4217 currency column, Alembic baseline, Docker-based Postgres fixture for tests.\n\nclass LineItem(Base):\n    __tablename__ = \"line_items\"\n\n    id: Mapped[int] = mapped_column(primary_key=True)\n    invoice_id: Mapped[int] = mapped_column(ForeignKey(\"invoices.id\"))\n    description: Mapped[str] = mapped_column(String(200))\n    quantity: Mapped[int] = mapped_column(default=1)\n    unit_amount: Mapped[int]  # minor units (cents)\n    currency: Mapped[str] = mapped_column(String(3))\n\nTools used in this turn:\n\n- Write: ledger/app.py\n- Write: ledger/models.py\n- Bash: alembic init migrations — exit 0\n\nTurn 2 — User\n\nAdd the line-item total as a computed column.\n\nTurn 2 — Assistant\n\nDone as a SQLAlchemy column_property summing quantity * unit_amount; invoice totals are derived, never stored, so they cannot drift. 9 tests pass.\n\nTools used in this turn:\n\n- Edit: ledger/models.py — column_property for totals\n- Bash: pytest -q — 9 passed\n\nConnections\n\n- ledger-api\n- FastAPI\n- SQLAlchemy\n- Alembic\n- MoneyAsMinorUnits",
  "sha256": "e9fac8829a9ec2dc",
  "source_url": "sessions/ledger-api/2026-08-18-scaffold-invoice-service.html"
}