Hernoem packages endpoint naar /api/v1/offerings
Continuous Integration / config (pull_request) Successful in 9s
Continuous Integration / prepare (pull_request) Successful in 1m14s
Continuous Integration / build-production (pull_request) Skipped
Continuous Integration / build (pull_request) Successful in 2m1s
Continuous Integration / test (pull_request) Successful in 2m7s
Continuous Integration / deploy-production (pull_request) Skipped
Deploy / deploy (pull_request) Successful in 35s
Continuous Integration / deploy-test (pull_request) Successful in 36s

De frontend haalt de pakketten-data nu op via /api/v1/offerings i.p.v.
/api/v1/packages.
This commit is contained in:
2026-08-01 22:20:31 +02:00
parent cdec908d53
commit 99abf5dff0
4 changed files with 8 additions and 8 deletions
@@ -1,4 +1,4 @@
# Hand-off: Packages API (`GET /api/v1/packages`) # Hand-off: Packages API (`GET /api/v1/offerings`)
**Audience**: whoever implements the CMS/backend that will serve package content. **Audience**: whoever implements the CMS/backend that will serve package content.
**Status**: frontend is already wired up and waiting on this endpoint to exist. **Status**: frontend is already wired up and waiting on this endpoint to exist.
@@ -19,10 +19,10 @@ it yet.
### Endpoint ### Endpoint
``` ```
GET /api/v1/packages GET /api/v1/offerings
``` ```
- **Same domain as the site, relative path.** The frontend calls `fetch('/api/v1/packages')` - **Same domain as the site, relative path.** The frontend calls `fetch('/api/v1/offerings')`
with no protocol/host — it relies on the API being reachable under the *same* origin the with no protocol/host — it relies on the API being reachable under the *same* origin the
React app is served from, both on `test.slpsoftware.nl` and on production React app is served from, both on `test.slpsoftware.nl` and on production
(`slpsoftware.nl`). Today, both Pis only serve the static React build (see (`slpsoftware.nl`). Today, both Pis only serve the static React build (see
@@ -27,7 +27,7 @@ describe('PackagesSection', () => {
vi.unstubAllGlobals(); vi.unstubAllGlobals();
}); });
it('fetches packages from /api/v1/packages and renders one PackageCard per package', async () => { it('fetches packages from /api/v1/offerings and renders one PackageCard per package', async () => {
mockFetchOnce(new Response(JSON.stringify(packages), { status: 200 })); mockFetchOnce(new Response(JSON.stringify(packages), { status: 200 }));
renderWithQueryClient(); renderWithQueryClient();
@@ -36,7 +36,7 @@ describe('PackagesSection', () => {
expect(screen.getByTestId('packages-grid').children.length).toBe(packages.length); expect(screen.getByTestId('packages-grid').children.length).toBe(packages.length);
}); });
expect(fetch).toHaveBeenCalledWith('/api/v1/packages'); expect(fetch).toHaveBeenCalledWith('/api/v1/offerings');
for (const pkg of packages) { for (const pkg of packages) {
expect(screen.getByTestId(`package-card-${pkg.id}`)).toBeInTheDocument(); expect(screen.getByTestId(`package-card-${pkg.id}`)).toBeInTheDocument();
expect(screen.getByText(pkg.title)).toBeInTheDocument(); expect(screen.getByText(pkg.title)).toBeInTheDocument();
+1 -1
View File
@@ -7,7 +7,7 @@
* *
* This module is the source of truth for content that isn't (yet) API-backed * This module is the source of truth for content that isn't (yet) API-backed
* (requirements FR-1/FR-6). `packages` is the exception: it now also doubles as * (requirements FR-1/FR-6). `packages` is the exception: it now also doubles as
* the reference/seed data for the `/api/v1/packages` contract consumed via * the reference/seed data for the `/api/v1/offerings` contract consumed via
* src/features/landing/hooks/usePackagesQuery.ts (requirements FR-5) — see * src/features/landing/hooks/usePackagesQuery.ts (requirements FR-5) — see
* aidlc-docs/features/react-frontend/construction/react-frontend-app/functional-design/packages-api-handoff.md. * aidlc-docs/features/react-frontend/construction/react-frontend-app/functional-design/packages-api-handoff.md.
*/ */
@@ -5,10 +5,10 @@ import type { PackageCardData } from '../data/content';
// (test.slpsoftware.nl / slpsoftware.nl) — see aidlc-docs/features/react-frontend/ // (test.slpsoftware.nl / slpsoftware.nl) — see aidlc-docs/features/react-frontend/
// construction/react-frontend-app/functional-design/packages-api-handoff.md // construction/react-frontend-app/functional-design/packages-api-handoff.md
// for the API contract this endpoint must implement. // for the API contract this endpoint must implement.
const PACKAGES_ENDPOINT = '/api/v1/packages'; const OFFERINGS_ENDPOINT = '/api/v1/offerings';
async function fetchPackages(): Promise<PackageCardData[]> { async function fetchPackages(): Promise<PackageCardData[]> {
const response = await fetch(PACKAGES_ENDPOINT); const response = await fetch(OFFERINGS_ENDPOINT);
if (!response.ok) { if (!response.ok) {
throw new Error(`Failed to fetch packages: ${response.status} ${response.statusText}`); throw new Error(`Failed to fetch packages: ${response.status} ${response.statusText}`);
} }