# 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 quotes, compliance items, and Sign of the Week selector
- community organizations
- vocational opportunities
- emotional intelligence assessment content, personality quiz questions, weekly focus, and team content
- ESA funding content

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

- 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.

`safety-qbs-quiz` is organization-scoped. Organization users with `MANAGE_CONTENT_CATALOG` can manage the quiz through the QBS safety editor; school, campus, and classroom users read the organization-owned payload and only complete the quiz.

## 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.

`classroom-strategies` is organization-scoped. Organization managers with `MANAGE_CONTENT_CATALOG` can add, edit, delete, and upload images for the shared strategy library; school, campus, and classroom views read the same organization-owned payload and can only persist per-user favorites when the user is in their own scope.

## 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.

`sign-language-items` is organization-scoped. Organization users with `MANAGE_CONTENT_CATALOG` can add, edit, delete, upload media for, and select Sign of the Week from the shared organization sign library. School, campus, and classroom users read the same organization-owned sign cards and persist only personal learned progress when they are in their own scope.

## Editable Zones Of Regulation Content

Regulation zone records, behaviors, strategies, matching signs, and QBS safety connection copy are part of the `regulation-zones` and `zones-of-regulation-page-content` content catalog payloads. The frontend renders these payloads and keeps the stable Quick Behavior Management Flow as static component content because it is not tenant-editable.

## Editable Dashboard Content

Dashboard quotes and compliance items are part of the `dashboard-encouraging-quotes` and `dashboard-compliance-items` content catalog payloads. `dashboard-sign-of-week` stores the selected sign card id, current Sunday-start `weekOf`, and fallback display fields; the dashboard business layer resolves it against `sign-language-items` instead of duplicating sign-card content.
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 school impact items, staff role guidance, FAQ items with per-question audience visibility, parent conversation Q&A references, and resource records are part of the campus-scoped `esa-funding-content` content catalog payload. Users with `MANAGE_ESA_FUNDING_CONTENT` can edit that payload only from a campus effective scope; organization/school/platform users manage it by drilling into a campus.

Static ESA intro copy, the state-variation notice/checklist, key points, and approved-use cards live in `frontend/src/shared/constants/esaFunding.ts` because they are stable training copy, not editable runtime records. Student and guardian views read the same campus content but hide staff-only FAQ entries, staff role guidance, parent conversation references, and the staff acknowledgment card.

Editing `esa-funding-content` sends the changed section name to the backend. The content catalog service bumps the linked campus `policy_documents` row tagged `ESA Funding`, which resets current-version staff acknowledgment state and drives header notifications plus leadership acknowledgment reporting.

## 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.
