# Content Catalog Integration

## Purpose

Editable frontend content catalogs are loaded from the backend through the shared content catalog API.

Editable runtime product/content records must not live in `frontend/src/shared/constants/`. The frontend may keep only non-secret config, query keys, labels, timing values, stable training copy, product-static catalogs, and style tokens.

## Files

- Constants: `frontend/src/shared/constants/contentCatalog.ts`
- API: `frontend/src/shared/api/contentCatalog.ts`
- API type: `frontend/src/shared/types/contentCatalog.ts`
- Business hook: `frontend/src/business/content-catalog/hooks.ts`
- API test: `frontend/src/shared/api/contentCatalog.test.ts`

## API

Runtime read:

- `GET /api/content-catalog/read/:contentType`

Authenticated management:

- `GET /api/content-catalog`
- `POST /api/content-catalog`
- `GET /api/content-catalog/:contentType`
- `PUT /api/content-catalog/:contentType`
- `DELETE /api/content-catalog/:contentType`

`useContentCatalogPayload(contentType, empty, { enabled })` accepts an optional
`enabled` flag for **lazy** loads — used by the header search to fetch a
catalog only once the user types (see `top-bar-integration.md`).

## Current Consumers

- classroom support strategies
- QBS safety quiz
- sign language catalog
- sign language page content
- regulation zones
- zones of regulation page content
- dashboard quote, compliance items, and sign of the week
- community organizations
- vocational opportunities
- emotional intelligence assessment content, weekly focus, and team content
- ESA funding content

Product-static content that intentionally does **not** use content catalog:

- personality quiz questions, personality type directory, quiz intro feature cards, and workplace sidebar content (`frontend/src/shared/constants/personalityStaticContent.ts`)
- classroom timer backgrounds, built-in sound metadata, presets, and tips (`frontend/src/shared/constants/classroomTimerContent.ts`)

## Error Handling

Views must render explicit loading and error states when content catalog requests are pending or fail.

Do not treat an empty payload default as a fallback for a failed request. The default payload exists only to keep rendering code type-safe while the query is loading.

## Test Data

Frontend tests should use local test fixtures in test files or `frontend/src/test-seeds/`. Do not import backend product content payloads into frontend runtime code.

Runtime testing should use database seeds through backend APIs. Frontend runtime code should not carry production seed records as fallback data.

## Backend-Seeded E2E Coverage

Backend-seeded content browser tests are separate from the backend-free app shell smoke tests.

Commands:

```bash
cd backend
npm run db:migrate
npm run db:seed
npm run watch
```

In another terminal:

```bash
cd frontend
VITE_BACKEND_API_URL=http://localhost:8080/api npm run test:e2e:content
```

`VITE_BACKEND_API_URL` must match the running backend API. If it is omitted, the frontend default is `http://localhost:8080/api`.

The content e2e suite lives in `frontend/tests/e2e/content-catalog.seeded.e2e.ts` and runs through `frontend/playwright.content.config.ts`. The default `npm run test:e2e` config ignores `*.seeded.e2e.ts` so backend-free smoke tests stay deterministic.

Minimum backend seed set for content e2e:

- `classroom-strategies`
- `sign-language-items`
- `sign-language-page-content`
- `regulation-zones`
- `zones-of-regulation-page-content`
- `dashboard-encouraging-quotes`
- `dashboard-compliance-items`
- `dashboard-sign-of-week`

The seeded e2e suite first verifies this minimum set through `GET /api/content-catalog/read/:contentType`, then renders high-value content-backed routes and asserts UI text taken from the live backend response. The classroom timer check renders product-static content and does not require backend content-catalog rows. The suite does not import backend seed files or duplicate seed records in frontend tests.

## Editable Quiz Content

QBS quiz title, weekly focus, key reminders, questions, answer choices, correct answers, and explanations are part of the `safety-qbs-quiz` content catalog payload. The frontend renders this payload and does not keep quiz content or reminder copy in shared constants.

## Editable Classroom Strategy Content

Classroom strategy titles, descriptions, images, categories, age groups, regulation zones, and implementation tips are part of the `classroom-strategies` content catalog payload. The frontend may keep filter labels and style tokens, but it must not keep strategy records or implementation copy in shared constants.

## Editable Sign Language Content

Sign records, teaching tips, video URLs, GIF URLs, step instructions, and page-level teaching reminders are part of the `sign-language-items` and `sign-language-page-content` content catalog payloads. The frontend renders these payloads and does not keep sign content or reminder copy in shared constants.

## Editable Zones Of Regulation Content

Regulation zone records, behaviors, strategies, matching signs, QBS safety connection copy, and quick de-escalation flow content are part of the `regulation-zones` and `zones-of-regulation-page-content` content catalog payloads. The frontend renders these payloads and does not keep zone content or flow copy in shared constants.

## Editable Dashboard Content

Dashboard quotes, compliance items, and sign-of-week content are part of the `dashboard-encouraging-quotes`, `dashboard-compliance-items`, and `dashboard-sign-of-week` content catalog payloads. The dashboard business layer renders these payloads and does not keep dashboard content records in shared constants.
These dashboard catalog rows are seeded per tenant at organization, school, and campus scope so owner/superintendent/principal/registrar/director dashboards and platform-admin drill-down views all read backend-owned content.

## Editable ESA Funding Content

ESA funding approved uses, key points, state checklist items, school impact items, staff role guidance, parent conversation script, and resource records are part of the `esa-funding-content` content catalog payload. Static ESA intro copy and FAQs live in `frontend/src/shared/constants/esaFunding.ts` because they are stable training copy, not editable runtime records.

## Editable Community Organization Content

Community organization records are part of the `community-organizations` content catalog payload. The frontend may keep partnership labels/classes, age group labels, category icon keys, and style tokens, but it must not keep organization records in shared constants.

## Editable Vocational Opportunity Content

Vocational opportunity records are part of the `vocational-opportunities` content catalog payload. The frontend may keep zip search timing, category preview labels, category icon keys, and style tokens, but it must not keep opportunity records in shared constants.
