Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
17957a5
chore: add `.python-version` and `uv.lock` for Python version managem…
nicky-mezzina-lhc Jul 31, 2026
75ff3e0
chore: add OpenAPI export tool and configure `.gitattributes` for lin…
nicky-mezzina-lhc Jul 31, 2026
67dbe85
chore(makefile): add `export-openapi` target and update OpenAPI expor…
nicky-mezzina-lhc Jul 31, 2026
87786ff
chore: add `pytest` for testing, update `uv.lock` with new dependenci…
nicky-mezzina-lhc Jul 31, 2026
93055aa
chore: refactor project structure to `src` layout, rename package to …
nicky-mezzina-lhc Aug 3, 2026
2f9d9b0
chore: add core enums, config constants, and OpenAPI schema registrat…
nicky-mezzina-lhc Aug 3, 2026
9f859db
chore: add domain-specific module placeholders
nicky-mezzina-lhc Aug 3, 2026
8dcea32
feat: add shared schemas module, and include API contract documentation
nicky-mezzina-lhc Aug 3, 2026
2115930
feat: update shared schemas to use UUIDv7 for `ResourceId` and enforc…
nicky-mezzina-lhc Aug 4, 2026
062ad88
chore: add .editorconfig for consistent code style settings
nicky-mezzina-lhc Aug 4, 2026
f70225f
chore: expand README with layout details for domain-specific modules
nicky-mezzina-lhc Aug 4, 2026
39cc34e
docs: add detailed API contract and data model documentation for `v4.…
nicky-mezzina-lhc Aug 4, 2026
0447ab5
feat: add OpenAPI security schemes and rate-limit response contract f…
nicky-mezzina-lhc Aug 4, 2026
b049c56
feat: implement RFC 9457-compliant `application/problem+json` error h…
nicky-mezzina-lhc Aug 4, 2026
1622775
feat: add cursor-based pagination dependency and schema for paginated…
nicky-mezzina-lhc Aug 4, 2026
908e958
feat: implement initial routers, schemas, and domain-specific modules…
nicky-mezzina-lhc Aug 4, 2026
c7eb7a5
feat(api/openapi.json): add OpenAPI contract for NC3 Testing Platform…
nicky-mezzina-lhc Aug 4, 2026
e021aa7
chore: update README and Makefile to streamline local development wit…
nicky-mezzina-lhc Aug 4, 2026
7b0cbc7
chore(ci): update checkout action to v7 in GitHub workflow
nicky-mezzina-lhc Aug 4, 2026
3da0d56
test: add contract tests for OpenAPI validation and consistency, upda…
nicky-mezzina-lhc Aug 4, 2026
6a05396
chore(ci): replace checkout action version with hash expression and r…
nicky-mezzina-lhc Aug 4, 2026
a3d2724
fix(notifications): move catch-all `dismiss_notification` endpoint in…
nicky-mezzina-lhc Aug 4, 2026
2924d97
refactor(api): remove 401 Unauthorized response from endpoints that a…
nicky-mezzina-lhc Aug 4, 2026
844aa49
chore(ci): replace `--frozen` with `--locked` in workflow commands fo…
nicky-mezzina-lhc Aug 4, 2026
5cce02d
fix(export-openapi): specify UTF-8 encoding for reading and writing O…
nicky-mezzina-lhc Aug 4, 2026
71791c4
refactor(api): canonicalize domain names to lowercase IDNA A-label fo…
nicky-mezzina-lhc Aug 5, 2026
16aa992
docs(api): clarify deletion constraints for assets and align with UUI…
nicky-mezzina-lhc Aug 5, 2026
fedfd9b
chore(deps): add `idna>=3.18` to dependencies in `pyproject.toml` and…
nicky-mezzina-lhc Aug 5, 2026
a8b5c55
docs: update README to include `make lint` in development routine
nicky-mezzina-lhc Aug 5, 2026
f358aeb
chore(ci): add Dependabot config for GitHub Actions and update checko…
nicky-mezzina-lhc Aug 5, 2026
4d9dea3
fix(schemas): handle trailing dots in domain names using `removesuffi…
nicky-mezzina-lhc Aug 5, 2026
c083f6a
feat(api): add verification challenge to verification data model to c…
nicky-mezzina-lhc Aug 5, 2026
ae4c841
docs(data-model): clarify constraint handling for user erasure and ac…
nicky-mezzina-lhc Aug 5, 2026
aba221d
chore(deps): add `httpx2>=2.9.1`, `httpcore2`, and `truststore` to de…
nicky-mezzina-lhc Aug 5, 2026
9bed783
feat(errors): add handler for unhandled exceptions and enforce RFC 94…
nicky-mezzina-lhc Aug 5, 2026
922eff1
test(api): add tests for case insensitivity and rejection of invalid …
nicky-mezzina-lhc Aug 5, 2026
637f1e8
chore(deps): move `httpx2` from dependencies to dev-dependencies and …
nicky-mezzina-lhc Aug 5, 2026
4f3991c
docs(api): remove confusion over API key revocation and password changes
nicky-mezzina-lhc Aug 7, 2026
c998885
docs(api): clarify pagination behavior for collection endpoints ("Som…
nicky-mezzina-lhc Aug 7, 2026
1ccfc60
docs(api): clarify `POST /reports` source field and domain target han…
nicky-mezzina-lhc Aug 7, 2026
e9417b5
docs(api): tighten semantics for `DELETE` behavior and mention MFA re…
nicky-mezzina-lhc Aug 7, 2026
6d636f9
docs(data-model): clarify constraint for file task upload targeting
nicky-mezzina-lhc Aug 7, 2026
3bb75da
feat(auth): add `OptionallyAuthenticated` dependency for conditional …
nicky-mezzina-lhc Aug 7, 2026
528b10a
docs(api): clarify alternative credential use for token-based operations
nicky-mezzina-lhc Aug 7, 2026
f93b6b2
docs(security): clarify behavior of `read_optional_credentials` for g…
nicky-mezzina-lhc Aug 7, 2026
8702c33
docs(api): clarify `DELETE /assets/{asset_id}` constraints for additi…
nicky-mezzina-lhc Aug 7, 2026
09fdd80
docs(api): specify `DELETE` constraint for schedule references in assets
nicky-mezzina-lhc Aug 7, 2026
541976a
docs(api): refresh openapi.json
nicky-mezzina-lhc Aug 7, 2026
ad03e54
docs(api, data-model): clarify challenge replacement behavior and MFA…
nicky-mezzina-lhc Aug 7, 2026
032fd23
feat(auth): enforce MFA requirement for API key management and verifi…
nicky-mezzina-lhc Aug 7, 2026
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
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true

[*.{json,yml,yaml}]
indent_size = 2

[{*.markdown,*.md}]
ij_markdown_wrap_text_if_long = false
ij_markdown_keep_line_breaks_inside_text_blocks = true
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
openapi.json linguist-generated=true
uv.lock linguist-generated=true
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly

- package-ecosystem: uv
directory: /
schedule:
interval: weekly
41 changes: 41 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
contract:
name: OpenAPI contract
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Set up uv
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
enable-cache: true

- name: Install dependencies
run: uv sync --locked

- name: Lint
run: uv run --locked ruff check .

- name: Type check
run: uv run --locked pyright

- name: Test
run: uv run --locked pytest
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.PHONY: dev export-openapi lint test

dev:
uv run fastapi dev src/nc3_testing_platform/main.py

export-openapi:
uv run export-openapi

lint:
uv run ruff check .
Comment thread
nicky-mezzina-lhc marked this conversation as resolved.

test:
uv run pytest
37 changes: 22 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Project repository for the NC3 Testing Platform backend (v4).

- Python 3.13, [uv](https://docs.astral.sh/uv/) (packaging + virtualenv)
- FastAPI + Pydantic — the app and its request/response models
- openapi-spec-validator (dev) — validates the generated 3.1 spec
- pytest + openapi-spec-validator (dev) — the contract test suite

**Projected** — planned:

Expand All @@ -28,7 +28,7 @@ No environment variables or config are required yet.
# Running the mock server

```bash
uv run fastapi dev app/main.py
make dev
```

- API base: http://localhost:8000/api/v1
Expand All @@ -40,36 +40,43 @@ Handlers return static stub data, so the running server doubles as a mock the fr

# Generating the OpenAPI contract

The OpenAPI 3.1 spec is generated from the FastAPI app (`app.main:app`) and written to `docs/openapi.json`.
The OpenAPI 3.1 spec is generated from the FastAPI app (`nc3_testing_platform.main:app`) and written to `api/openapi.json`.

```bash
uv run python -m app.tools.export_openapi # write docs/openapi.json
uv run openapi-spec-validator --schema 3.1 docs/openapi.json # validate (exits 0 if valid)
make export-openapi # write api/openapi.json
make lint # ruff over the source
make test # validate it, and check the committed file is current
```

Regenerate and re-validate after any change to a router or Pydantic schema. `docs/openapi.json` is the contract the
frontend interfaces with; commit it alongside the change that alters it.
The development routine after any change to a router or Pydantic schema is `make export-openapi && make lint`. `api/openapi.json` is the contract the frontend interfaces with; commit it alongside the change that alters it.

`make test` validates the generated document against OpenAPI 3.1 and fails if the committed file differs from it. CI runs the same command.
Comment on lines +51 to +53

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Include make test in the documented development routine.

Line 51 instructs contributors to run only make export-openapi && make lint. Line 53 states that make test validates OpenAPI 3.1 and detects contract drift. Add make test to the routine so local instructions perform the required checks.

Proposed documentation fix
-The development routine after any change to a router or Pydantic schema is `make export-openapi && make lint`.
+The development routine after any change to a router or Pydantic schema is `make export-openapi && make lint && make test`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
The development routine after any change to a router or Pydantic schema is `make export-openapi && make lint`. `api/openapi.json` is the contract the frontend interfaces with; commit it alongside the change that alters it.
`make test` validates the generated document against OpenAPI 3.1 and fails if the committed file differs from it. CI runs the same command.
The development routine after any change to a router or Pydantic schema is `make export-openapi && make lint && make test`. `api/openapi.json` is the contract the frontend interfaces with; commit it alongside the change that alters it.
`make test` validates the generated document against OpenAPI 3.1 and fails if the committed file differs from it. CI runs the same command.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 51 - 53, Update the documented development routine in
README.md to include make test alongside make export-openapi and make lint. Keep
the existing guidance about committing api/openapi.json and validation behavior
unchanged.


# Project structure

> **Current scope:** the only working functionality is the Pydantic schemas and OpenAPI spec generation. Route handlers
> return stub data so the app runs as a live mock; there is no persistence, auth backend, or scan logic yet.

```
app/
src/nc3_testing_platform/
main.py # FastAPI app; mounts every domain router under /api/v1
core/ # shared, cross-cutting building blocks
enums.py # canonical enums
schemas.py # base model config + shared field types
errors.py # RFC 9457 problem+json errors + handlers
pagination.py # cursor pagination
security.py # OpenAPI security schemes + rate-limit contract
domains/ # one vertical slice per domain (router + schemas together)
guest/ auth/ org/ assets/ scans/
schedules/ findings/ reports/ notifications/ health/
domains/ # one vertical slice per domain
scans/ # every slice follows this layout
models.py # SQLAlchemy models
schemas.py # Pydantic request and response models
repository.py # queries; session is the first argument
service.py # business logic and transaction boundaries
router.py # path operations
tools/
export_openapi.py # dumps app.openapi() -> docs/openapi.json
export_openapi.py # dumps app.openapi() -> api/openapi.json
api/
openapi.json # generated API contract (see "Generating the OpenAPI contract")
docs/
openapi.json # generated contract (see "Generating the OpenAPI contract")
reference/ # source design docs (data-model, ADRs)
```
reference/ # reference documentation
```
15 changes: 15 additions & 0 deletions api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# API contract

`openapi.json` is the generated OpenAPI 3.1 contract for the v4 backend.
It is committed so the frontend and client generators can consume it without a Python toolchain, and so contract changes
show up as reviewable PR diffs.

Do not edit it by hand.
The source of truth is the FastAPI app; regenerate after any schema or route change:

```bash
make export-openapi
```

Commit the regenerated file together with the code change that caused it.
CI validates the committed spec and fails if it drifts from what the app generates.
Loading