Files
clubber/openspec/specs/project-setup/spec.md
T
gurixandClaude 5bb27bdadf chore: archive add-graphql-member-api proposal and create capability specs
Archive completed GraphQL API implementation proposal:
- Move proposal to openspec/changes/archive/2025-11-20-add-graphql-member-api/
- Create capability specs in openspec/specs/:
  - database-layer: SQLAlchemy async with Alembic migrations
  - graphql-api: Strawberry GraphQL with FastAPI integration
  - member-crud: Member management with conditional validation
  - project-setup: Python 3.11+ with uv package manager

All 73 tasks completed and validated.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 13:26:43 +01:00

6.9 KiB

project-setup Specification

Purpose

TBD - created by archiving change add-graphql-member-api. Update Purpose after archive.

Requirements

Requirement: Python project structure with uv dependency management

The project MUST use Python 3.11+ with uv for fast, reliable dependency management and provide a standard src/ layout for code organization.

Scenario: Developer initializes new development environment

Given a developer has cloned the repository When they run uv sync Then all dependencies are installed in a virtual environment And the environment is ready for development within 30 seconds

Scenario: Developer runs the application

Given dependencies are installed When developer runs uv run uvicorn src.main:app --reload Then the FastAPI server starts on http://localhost:8000 And GraphQL playground is available at http://localhost:8000/graphql

Requirement: Project configuration in pyproject.toml

The project MUST define all metadata, dependencies, and tool configurations in pyproject.toml following modern Python packaging standards.

Dependencies required:

  • fastapi >= 0.104.0 (Web framework)
  • strawberry-graphql[fastapi] >= 0.215.0 (GraphQL integration)
  • sqlalchemy[asyncio] >= 2.0.0 (ORM with async support)
  • aiosqlite >= 0.19.0 (Async SQLite driver)
  • alembic >= 1.12.0 (Database migrations)
  • pydantic-settings >= 2.0.0 (Configuration management)
  • uvicorn[standard] >= 0.24.0 (ASGI server)

Development dependencies required:

  • pytest >= 7.4.0 (Test framework)
  • pytest-asyncio >= 0.21.0 (Async test support)
  • black >= 23.0.0 (Code formatting)
  • ruff >= 0.1.0 (Linting)
  • isort >= 5.12.0 (Import sorting)

Scenario: Dependencies are declared with version constraints

Given pyproject.toml exists When developer inspects [project.dependencies] Then all required packages are listed with minimum versions And version constraints allow patch/minor updates

Scenario: Development tools are configured

Given pyproject.toml contains tool configurations When developer runs black . Then code is formatted with line length 88 When developer runs ruff check . Then code is linted against configured rules

Requirement: Source directory structure following layered architecture

The project MUST organize code into src/ directory with clear separation of concerns across API, business logic, and data layers.

Required directory structure:

src/
├── __init__.py
├── main.py              # FastAPI application, startup/shutdown
├── config.py            # Settings and configuration
├── database.py          # Database connection, session factory
├── models/              # SQLAlchemy ORM models
│   ├── __init__.py
│   └── member.py
├── schemas/             # Strawberry GraphQL types
│   ├── __init__.py
│   └── member.py
└── resolvers/           # GraphQL query/mutation resolvers
    ├── __init__.py
    └── member.py

Scenario: Code is organized by architectural layer

Given the src/ directory exists When a developer navigates the codebase Then models/ contains only SQLAlchemy ORM definitions And schemas/ contains only Strawberry GraphQL type definitions And resolvers/ contains only GraphQL resolver functions And each module has clear, single responsibility

Scenario: Main application entry point is defined

Given src/main.py exists When the file is imported Then it exports a FastAPI app instance And app includes GraphQL route at /graphql And app includes startup event to verify database connection

Requirement: Testing infrastructure with pytest

The project MUST provide pytest configuration for running async tests with database fixtures and code coverage reporting.

Scenario: Async tests can be executed

Given pytest and pytest-asyncio are installed When developer runs pytest Then all tests in tests/ directory are discovered And async test functions execute correctly And test results are displayed with pass/fail status

Scenario: Database fixtures are available for tests

Given tests/conftest.py defines database fixtures When a test function requests db_session fixture Then an isolated test database session is provided And session is rolled back after test completion And no test data persists between test runs

Requirement: Code quality tooling configuration

The project MUST configure black, ruff, and isort for consistent code formatting and linting with settings in pyproject.toml.

Black configuration:

  • Line length: 88 characters
  • Target version: Python 3.11
  • Skip string normalization: false

Ruff configuration:

  • Line length: 88 characters
  • Select: E, F, W, I (pycodestyle, pyflakes, warnings, isort)
  • Ignore: E501 (line too long, handled by black)

Isort configuration:

  • Profile: black (compatible settings)
  • Multi-line output: 3 (vertical hanging indent)

Scenario: Code formatting is enforced

Given black is configured in pyproject.toml When developer runs black --check . Then all Python files are checked for formatting And exit code is 0 if all files are formatted correctly And exit code is 1 if any files need formatting

Scenario: Code quality checks pass

Given ruff is configured in pyproject.toml When developer runs ruff check . Then all Python files are linted And no errors are reported for compliant code And clear error messages are shown for violations

Requirement: Environment configuration with .env support

The project MUST support environment-based configuration using .env files with pydantic-settings for type-safe config values.

Scenario: Default configuration works for development

Given no .env file exists When application starts Then it uses default SQLite database path And it runs in debug mode And application starts successfully

Scenario: Environment variables override defaults

Given .env file contains DATABASE_URL=sqlite+aiosqlite:///./test.db When application loads configuration Then settings.database_url equals "sqlite+aiosqlite:///./test.db" And custom database path is used

Scenario: Configuration is type-safe

Given src/config.py defines Settings class When invalid configuration value is provided Then pydantic validation raises clear error And application fails fast on startup

Requirement: Development scripts for common tasks

The project MUST provide executable scripts for database seeding and common development tasks.

Required scripts:

  • scripts/seed.py - Populate database with sample member

Scenario: Seed script creates sample data

Given database schema exists from migrations When developer runs uv run python scripts/seed.py Then sample member is created in database And script is idempotent (safe to run multiple times) And success message is displayed