Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.git
.github
.agents
.env
.env.*
!.env.example
.venv
**/.venv
__pycache__
**/__pycache__
*.py[cod]
node_modules
**/node_modules
.pnpm-store
**/.pnpm-store
dist
build
coverage
**/coverage
playwright-report
test-results
postgres-data
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Local PostgreSQL settings only. These defaults are intentionally non-secret.
# Copy to .env to override them; never commit a real .env file.
POSTGRES_DB=medcheck
POSTGRES_USER=medcheck
POSTGRES_PASSWORD=medcheck_local_only
POSTGRES_PORT=127.0.0.1:5432

18 changes: 18 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: 2
updates:
- package-ecosystem: "uv"
directory: "/backend"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/web"
schedule:
interval: "weekly"
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
88 changes: 88 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: Pull-request checks

on:
pull_request:

permissions:
contents: read

jobs:
secrets:
name: Secret scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: gitleaks/gitleaks-action@v2
//changed here because github told me...
env:
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}

backend:
name: Backend tooling
runs-on: ubuntu-latest
defaults:
run:
working-directory: backend
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-dependency-glob: backend/uv.lock
- uses: actions/setup-python@v5
with:
python-version-file: backend/.python-version
- name: Install locked dependencies
run: uv sync --all-groups --frozen
- name: Check formatting
run: uv run ruff format --check .
- name: Lint
run: uv run ruff check .
- name: Type check
run: uv run pyright
- name: Run infrastructure tests with coverage
run: uv run pytest --cov=tests --cov-report=xml
- name: Scan Python infrastructure
run: uv run bandit --quiet --recursive tests
- name: Upload backend coverage
if: always()
uses: actions/upload-artifact@v4
with:
name: backend-coverage
path: backend/coverage.xml
if-no-files-found: ignore

web:
name: Web tooling
runs-on: ubuntu-latest
defaults:
run:
working-directory: web
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22.14.0
- name: Enable Corepack
run: corepack enable
- uses: actions/setup-node@v4
with:
cache: pnpm
cache-dependency-path: web/pnpm-lock.yaml
- name: Install locked dependencies
run: pnpm install --frozen-lockfile
- name: Check formatting
run: pnpm format:check
- name: Lint
run: pnpm lint
- name: Type check
run: pnpm typecheck
- name: Run infrastructure tests with coverage
run: pnpm test
- name: Upload web coverage
if: always()
uses: actions/upload-artifact@v4
with:
name: web-coverage
path: web/coverage
if-no-files-found: ignore
32 changes: 32 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Environment and secrets
.env
.env.*
!.env.example

# Python
__pycache__/
*.py[cod]
.venv/
.pytest_cache/
.ruff_cache/
.pyright/
.coverage
coverage.xml
htmlcov/

# JavaScript
node_modules/
dist/
build/
coverage/
playwright-report/
test-results/
.pnpm-store/

# Docker/local services
postgres-data/

# Editor and OS files
.DS_Store
.idea/
.vscode/
60 changes: 60 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Agent Guidance

## Current status

`infrastructure_plan.md` is the source of truth. The web-only tooling and Docker
foundation are in place, but production application code has not been created. Do not introduce
pages, routes, API handlers, domain models, authentication, or business data
while performing infrastructure work.

## Repository map

- `infrastructure_plan.md` — approved decisions; revise it through the
planning skill before changing architectural choices.
- `docker/backend.Dockerfile`, `docker-compose.yml`, and `.dockerignore` —
Docker tooling and local PostgreSQL only.
- `scripts/docker-smoke.sh` — infrastructure-owned smoke test.
- `backend/` — Python dependency/tool configuration and infrastructure-only tests;
no Django application package exists yet.
- `web/` — React/Vite dependency/tool configuration and infrastructure-only tests;
no React application entrypoint exists yet.
- `.github/workflows/pr-checks.yml` — web-only pull-request quality checks.
- `.github/workflows/release.yml` — not created; it requires a selected hosting provider.
- `docs/` — not created yet.
- `.agents/skills/` — project-specific skills and instructions.

## Required reading and skill selection

Before changing files, read `infrastructure_plan.md`, this file, and relevant
local instructions. Use `infra-planner` for plan decisions, `infra-builder`
for infrastructure, `spec-driven-development` and `incremental-implementation`
for application work, `test-driven-development` for behavior changes,
`test-in-browser` or `browser-testing-with-devtools` for web verification,
`security-and-hardening` for untrusted-data/auth work,
`documentation-and-adrs` for durable decisions, `ci-cd-and-automation` for
workflows, `code-review-and-quality` before merging, and
`git-workflow-and-versioning` for every change.

## Docker lifecycle

Run `docker compose up --detach postgres` to start the local database and
`docker compose down --volumes` to stop it and remove its named volume. Run
`./scripts/docker-smoke.sh` for a disposable readiness test; it always cleans
up its Compose project and volume. Never place real secrets in `.env`, images,
workflow logs, or tracked files.

## Verification and change checklist

For Docker changes, run:

```bash
docker build --file docker/backend.Dockerfile --tag medcheck-backend-tooling .
docker compose config --quiet
./scripts/docker-smoke.sh
(cd backend && uv run ruff format --check . && uv run ruff check . && uv run pyright && uv run pytest --cov=tests)
(cd web && pnpm format:check && pnpm lint && pnpm typecheck && pnpm test)
git diff --check
```

Keep CI commands equivalent once workflows are added. Update README and this
file whenever paths, setup commands, services, or verification steps change.
87 changes: 86 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,86 @@
# TechStartup-Template
# Medcheck

## Status

The repository has a web-only development foundation: pinned backend and web
tooling, a local PostgreSQL service, and pull-request checks. No production
Django or React application code exists yet.

## Repository map

- `docker/backend.Dockerfile` — non-root Python and uv tooling image; it is not
a runnable application image until a backend entrypoint is implemented.
- `docker-compose.yml` — local PostgreSQL 17.6 service with a named volume and
readiness health check.
- `scripts/docker-smoke.sh` — disposable PostgreSQL readiness and `SELECT 1`
smoke test.
- `backend/` — Python/Django tooling, locked dependencies, and infrastructure
probes; no Django project or API code exists yet.
- `web/` — React/Vite tooling, locked dependencies, and infrastructure probes;
no page, component, or Vite entrypoint exists yet.
- `.github/workflows/pr-checks.yml` — web-only infrastructure quality checks.
- `.github/dependabot.yml` — weekly dependency-update configuration.
- `infrastructure_plan.md` — the approved infrastructure plan and source of
truth for future configuration.
- `.agents/skills/` — local agent skills.
- `docs/` and production application source directories — not created yet.

## Getting Started

1. Install [Docker Desktop](https://www.docker.com/products/docker-desktop/)
or Docker Engine with Compose v2, [Python 3.13](https://www.python.org/downloads/),
[uv](https://docs.astral.sh/uv/getting-started/installation/), and Node.js
22 LTS with Corepack enabled. The Docker image supplies Python and uv only
for Docker work; host tools support editor and local quality-check workflows.
2. Optionally copy the non-secret local database defaults:

```bash
cp .env.example .env
```

3. Install the locked tooling dependencies:

```bash
(cd backend && uv sync --all-groups --frozen)
(cd web && corepack enable && pnpm install --frozen-lockfile)
```

4. Build the development-tooling image:

```bash
docker build --file docker/backend.Dockerfile --tag medcheck-backend-tooling .
```

5. Start PostgreSQL locally:

```bash
docker compose up --detach postgres
```

6. Run the available infrastructure checks and clean up the Docker foundation:

```bash
(cd backend && uv run ruff format --check . && uv run ruff check . && uv run pyright && uv run pytest --cov=tests)
(cd web && pnpm format:check && pnpm lint && pnpm typecheck && pnpm test)
./scripts/docker-smoke.sh
docker compose down --volumes
```

The local database is exposed only on `127.0.0.1:5432` by default. Change
`POSTGRES_PORT` in an untracked `.env` if that port is occupied. Reset local
database data with `docker compose down --volumes`.

Vite builds and Playwright end-to-end tests are intentionally unavailable until
the future React application supplies an entrypoint and workflows. A production
release workflow is also deferred until a hosting provider is selected.

## Troubleshooting

- **Docker socket permission denied:** ensure Docker Desktop/Engine is running
and that your user has permission to use the Docker daemon.
- **Port 5432 is occupied:** set `POSTGRES_PORT=127.0.0.1:5433` in `.env` and
restart the Compose service.
- **A stale database is causing unexpected results:** run `docker compose down
--volumes` before starting again.
- **`uv` or `pnpm` is missing:** install the host prerequisite from the links
above, then rerun the locked install command.
1 change: 1 addition & 0 deletions backend/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13.11
45 changes: 45 additions & 0 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[project]
name = "medcheck-backend"
version = "0.0.0"
description = "Infrastructure-only backend tooling for Medcheck."
requires-python = ">=3.13,<3.14"
dependencies = [
"Django>=5.2,<5.3",
"djangorestframework>=3.16,<3.17",
"psycopg[binary]>=3.2,<3.3",
]

[dependency-groups]
dev = [
"bandit>=1.8,<2",
"pyright>=1.1,<2",
"pytest>=8.3,<9",
"pytest-cov>=6,<7",
"pytest-django>=4.9,<5",
"ruff>=0.9,<1",
"testcontainers[postgres]>=4.9,<5",
]

[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--strict-markers"

[tool.coverage.run]
branch = true
source = ["tests"]

[tool.coverage.report]
show_missing = true
skip_empty = true

[tool.ruff]
target-version = "py313"
line-length = 100

[tool.ruff.lint]
select = ["E", "F", "I", "UP"]

[tool.pyright]
pythonVersion = "3.13"
include = ["tests"]
typeCheckingMode = "basic"
9 changes: 9 additions & 0 deletions backend/tests/infrastructure/test_toolchain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Infrastructure-only dependency smoke checks; application tests belong elsewhere."""

from importlib.metadata import version


def test_backend_toolchain_dependencies_are_installed() -> None:
# Test assertions are not production input validation.
assert version("Django") # nosec B101
assert version("djangorestframework") # nosec B101
Loading