Compare commits

..

4 Commits

Author SHA1 Message Date
202ee34ef3 chore: remove bootstrap scripts from main
The tools/seed-gitea.sh seeder + README reached main via an earlier chore
commit, but the agreed decision is to manage Gitea entirely with the tea
CLI and not keep bespoke scripts in the repo. Remove them; the backlog
they seeded already exists in Gitea.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 13:40:05 +02:00
dfbaf7640a feat(bff): placeholder BFF + /health endpoint (closes #28) (#34) 2026-06-03 11:38:08 +00:00
364d2eceb2 docs(backlog): split S-00 into sub-slices (refs #1) (#33) 2026-06-03 11:37:57 +00:00
c746648e5c chore(tools): add idempotent Gitea backlog seeder
Add tools/seed-gitea.sh, which bootstraps the Gitea repo from BACKLOG.md:
the label taxonomy, the seven iteration milestones, and all 26 slice
issues (S-00..S-25). Driven by curl/jq against the Gitea API; reads
GITEA_TOKEN from the environment. Idempotent — every item is matched
before creation, so a partial or failed run can be re-run safely.

Document it in tools/README.md (prerequisites, usage, what it creates,
verification). Overlaps part of S-00's "labels/milestones exist in
Gitea" acceptance; the authoritative runbook moves to docs/ under S-00.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 11:59:35 +02:00
12 changed files with 175 additions and 12 deletions

27
.gitignore vendored Normal file
View File

@@ -0,0 +1,27 @@
# .NET build output
bin/
obj/
[Dd]ebug/
[Rr]elease/
*.user
# Test results / coverage
[Tt]est[Rr]esults/
*.trx
coverage*.json
coverage*.xml
*.coverage
# Rider / VS / VS Code
.idea/
.vs/
.vscode/
# Node / Angular (added as the frontend lands)
node_modules/
dist/
.angular/
# OS
.DS_Store
Thumbs.db

View File

@@ -12,22 +12,41 @@ Each slice is **independently demoable** and meets the Definition of Done in `CL
## Iteration 0 — Foundations *(milestone: `Iteration 0 — Foundations`)* ## Iteration 0 — Foundations *(milestone: `Iteration 0 — Foundations`)*
### S-00 · Repository skeleton, Gitea Actions CI, contributor workflow > **S-00 was split** (CLAUDE.md §13) into the sub-slices below. The original
> outcome — a fresh clone + `docker compose up` reaching a green BFF health
> endpoint, with CI green and the contributor scaffolding in place — is the sum
> of S-00-a…e. The Gitea milestones, labels, and slice issues already exist —
> they are managed directly with the `tea` CLI.
**Outcome:** A fresh `git clone` from the Respellion Gitea remote, followed by `docker compose up`, produces a green "hello world" health endpoint from a placeholder BFF. Gitea Actions runs lint, build, unit tests, and the compose-up smoke test, all green. Issue templates, PR template, milestones, labels, and the first project board exist in Gitea. ### S-00-a · Placeholder BFF + health endpoint
**Acceptance:** **Outcome:** A minimal .NET BFF exposing `GET /health` returning green; runnable with `dotnet run`. TDD anchor for the slice.
- New developer follows `README.md` and reaches a green local environment in under 10 minutes. **Touches:** `services/bff/`, tests. **Out of scope:** Docker, CI, OIDC.
- Gitea Actions pipeline green on `main`.
- `git-cliff` produces an empty `CHANGELOG.md`.
- `docs/PRD.md`, `CLAUDE.md`, `BACKLOG.md`, `docs/architecture/adr-0001-loose-coupling.md`, `docs/gitea-workflow.md` all in repo.
- `.gitea/workflows/ci.yaml`, `.gitea/ISSUE_TEMPLATE/{slice,bug,adr-proposal}.md`, `.gitea/PULL_REQUEST_TEMPLATE.md` all in repo.
- Gitea milestone `Iteration 1 — Walking Skeleton` exists, populated with issues S-01 through S-09.
**Touches:** repo layout, Gitea Actions workflows, Dockerfile for placeholder BFF, `docker-compose.yml` skeleton, MkDocs scaffold, Gitea issue/PR templates. ### S-00-b · Dockerfile + compose skeleton + compose-up smoke
**Out of scope:** any business logic, frontend, OpenZaak. **Outcome:** BFF containerized; `infra/docker-compose.yml` brings it up; health green within 3 minutes from a fresh clone.
**Touches:** `services/bff/Dockerfile`, `infra/docker-compose.yml`, smoke script. **Out of scope:** other services, CI.
### S-00-c · Gitea Actions CI (lint, build, unit, compose-up smoke)
**Outcome:** `.gitea/workflows/ci.yaml` green on PRs and `main`: lint, build, unit, compose-up smoke. Actions pinned by absolute URL (§8.7/§15).
**Touches:** `.gitea/workflows/ci.yaml`, `docs/runbooks/ci.md`. **Out of scope:** mutation, e2e, container push.
### S-00-d · Contributor workflow: issue/PR templates, git-cliff, CHANGELOG
**Outcome:** Issue templates (`slice`/`bug`/`adr-proposal`), PR template, `git-cliff` → empty `CHANGELOG.md`, `docs/gitea-workflow.md`.
**Touches:** `.gitea/ISSUE_TEMPLATE/`, `.gitea/PULL_REQUEST_TEMPLATE.md`, `cliff.toml`, `CHANGELOG.md`, `docs/gitea-workflow.md`. **Out of scope:** app code.
### S-00-e · Docs scaffold: MkDocs + ADR-0001 + README quickstart
**Outcome:** MkDocs builds the `docs/` site; `docs/architecture/adr-0001-loose-coupling.md` exists; README has a sub-10-minute quickstart.
**Touches:** `mkdocs.yml`, `docs/` nav, `docs/architecture/adr-0001-loose-coupling.md`, `README.md`. **Out of scope:** Gitea Pages publish.
--- ---

View File

@@ -85,7 +85,7 @@ The five flows form the BDD acceptance backbone (Gherkin scenarios in `tests/acc
- **Source control & collaboration:** **Gitea** (Respellion self-hosted) — repository, issues, milestones, labels, projects, releases, container registry, wiki, packages. - **Source control & collaboration:** **Gitea** (Respellion self-hosted) — repository, issues, milestones, labels, projects, releases, container registry, wiki, packages.
- **CI/CD:** **Gitea Actions** running on Respellion-hosted `act_runner` instances. Workflow files live in `.gitea/workflows/`. Marketplace actions are referenced via absolute URLs (`uses: https://github.com/actions/checkout@v4` or Gitea-hosted equivalents where available) for reproducibility. - **CI/CD:** **Gitea Actions** running on Respellion-hosted `act_runner` instances. Workflow files live in `.gitea/workflows/`. Marketplace actions are referenced via absolute URLs (`uses: https://github.com/actions/checkout@v4` or Gitea-hosted equivalents where available) for reproducibility.
- **Backend:** .NET 9 (LTS at iteration time), C#, minimal APIs for BFF, MediatR for in-process messaging within Domain Service, EF Core for the projection store and domain DB. - **Backend:** .NET 10 (LTS at iteration time), C#, minimal APIs for BFF, MediatR for in-process messaging within Domain Service, EF Core for the projection store and domain DB.
- **Frontend:** Angular (latest LTS) + TypeScript, standalone components + signals, Nx monorepo, NL Design System component library, Angular Testing Library + Playwright. - **Frontend:** Angular (latest LTS) + TypeScript, standalone components + signals, Nx monorepo, NL Design System component library, Angular Testing Library + Playwright.
- **Workflow:** Flowable (BPMN + DMN) via Docker image; Postgres for engine store. - **Workflow:** Flowable (BPMN + DMN) via Docker image; Postgres for engine store.
- **Identity:** Keycloak with pre-seeded realms. - **Identity:** Keycloak with pre-seeded realms.

6
global.json Normal file
View File

@@ -0,0 +1,6 @@
{
"sdk": {
"version": "10.0.203",
"rollForward": "latestFeature"
}
}

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,12 @@
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();
var app = builder.Build();
app.MapGet("/", () => "BFF placeholder");
app.MapHealthChecks("/health");
app.Run();
// Exposed so the test host (WebApplicationFactory<Program>) can boot the app.
public partial class Program;

View File

@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5249",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7106;http://localhost:5249",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.8" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Bff.Api\Bff.Api.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,20 @@
using System.Net;
using Microsoft.AspNetCore.Mvc.Testing;
namespace Bff.Tests;
public class HealthEndpointTests(WebApplicationFactory<Program> factory)
: IClassFixture<WebApplicationFactory<Program>>
{
[Fact]
public async Task Health_endpoint_returns_200_and_reports_healthy()
{
var client = factory.CreateClient();
var response = await client.GetAsync("/health");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.Content.ReadAsStringAsync();
Assert.Contains("Healthy", body);
}
}

4
services/bff/Bff.slnx Normal file
View File

@@ -0,0 +1,4 @@
<Solution>
<Project Path="Bff.Api/Bff.Api.csproj" />
<Project Path="Bff.Tests/Bff.Tests.csproj" />
</Solution>