Files
YPMS/pyproject.toml
T
Chris TonjesandClaude Opus 4.7 393631ad69 Phase 0 milestone 0.1: repo scaffold + Docker Compose
Scaffolding for the YPMS in-house build. Mirrors OWC's structure so
future OWC framework code can be vendored in with minimal fiddling
(milestone 0.2).

Includes:

- pyproject.toml — Python 3.12, FastAPI, SQLAlchemy 2.x, Alembic,
  Postgres, pydantic-settings, structlog, cryptography. Dev extras:
  pytest, ruff, mypy, bandit, pip-audit.
- Dockerfile — multi-stage builder + slim runtime.
- docker-compose.yml — app + Postgres (on 5433 to avoid clashing with
  OWC on 5432) + Adminer (on 8081).
- alembic.ini + migrations/env.py + baseline 0001_baseline.py (empty
  by design; every future change is additive and immutable once merged).
- src/ypms/main.py — FastAPI factory with /healthz and /readyz.
- src/ypms/settings.py — pydantic-settings config (DB URL, JWT,
  column encryption key, log level, env, CORS).
- src/ypms/logging.py — structlog + sanitize_for_log() for the
  sensitive-fields-never-in-logs rule from ARCHITECTURE.md §10.1.
- src/ypms/db.py — SQLAlchemy Base, engine, session factory, get_db.
- src/ypms/middleware.py — RequestIdMiddleware; X-Request-ID header
  echoed both ways.
- src/ypms/framework/ and src/ypms/security/ — empty packages, to be
  populated in milestones 0.2 and 0.3-0.4.
- tests/test_health.py — 3 smoke tests (healthz OK, header present,
  header honoured on incoming).
- README.md — quickstart.
- CONTRIBUTING.md — hard rules mirrored from OWC.
- .github/workflows/ci.yml — lint (ruff), types (mypy), tests + 80%
  coverage floor, SAST (bandit), SCA (pip-audit), gitleaks.

Green locally: ruff clean, mypy clean, pytest 3 passed.

Advances YPMS-POAM-040 (architecture doc + Phase 0 kickoff).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-09-30 16:15:45 -04:00

70 lines
1.3 KiB
TOML

[project]
name = "ypms"
version = "0.1.0"
description = "DC Youth Program Management System"
requires-python = ">=3.12"
dependencies = [
"fastapi>=0.115",
"uvicorn[standard]>=0.30",
"sqlalchemy>=2.0",
"alembic>=1.13",
"psycopg[binary]>=3.2",
"pydantic[email]>=2.8",
"pydantic-settings>=2.4",
"passlib>=1.7",
"python-jose[cryptography]>=3.3",
"python-multipart>=0.0.9",
"structlog>=24.4",
"cryptography>=43",
"jinja2>=3.1",
]
[project.optional-dependencies]
dev = [
"pytest>=8.3",
"pytest-asyncio>=0.24",
"pytest-cov>=5.0",
"httpx>=0.27",
"ruff>=0.6",
"mypy>=1.11",
"bandit>=1.7",
"pip-audit>=2.7",
]
[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"
[tool.setuptools.packages.find]
where = ["src"]
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
addopts = "-ra --strict-markers"
[tool.coverage.run]
source = ["src/ypms"]
omit = ["tests/*"]
[tool.coverage.report]
show_missing = true
skip_covered = false
[tool.ruff]
line-length = 100
target-version = "py312"
[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B", "SIM"]
# E501: handled by formatter; B008: FastAPI's Depends() in defaults is canonical
ignore = ["E501", "B008"]
[tool.mypy]
python_version = "3.12"
strict = true
ignore_missing_imports = true
[tool.bandit]
exclude_dirs = ["tests", "migrations"]