# App Build Protocol

Use this protocol when building a real app on the CASE 1EdTech surface.

## App Data Boundary

The CASE API is the data layer. Do not add a separate database for CFDocuments, CFItems, CFAssociations, CFPackages, or Alignments. Browser storage is acceptable for UI preferences, selected framework IDs, collapsed tree nodes, and temporary drafts.

## Minimum Standards-Browser Flow

1. Bootstrap a token.
2. List frameworks with `GET /ims/case/v1p1/CFDocuments`.
3. Let the user select a framework by `identifier`, `uri`, and `title`.
4. List items with `GET /ims/case/v1p1/CFItems?CFDocumentURI=<encoded-uri>`.
5. Fetch relationship context with `GET /ims/case/v1p1/CFItemAssociations/{sourcedId}`.
6. Use `GET /ims/case/v1p1/CFAssociations` only with documented filters when the app needs edge lists.
7. Link external app records through `POST /ims/case/v1p1/Alignments`.
8. Verify external links through `GET /ims/case/v1p1/Alignments?externalSystem=...&externalId=...`.
9. Before shipping, run `checks/case_surface_check.sh` and include its JSON output as evidence that the app's browser path reproduces the platform's package-export answer key.

If item discovery by `CFDocumentURI` cannot support the app's documented job, do not add publisher-hostname inference. Report the mismatch as a surface issue.

## Alignment Rules

Alignment is the only place for tenant-specific external IDs.

Use Alignment for:

- lesson IDs
- curriculum-resource IDs
- local assessment IDs
- external search index IDs
- app-owned labels or metadata about a resource-to-standard link

Do not put these values into:

- `CFAssociation`
- `CFItem.extensions`
- `CFPackage`
- copied local CASE tables

## CFPackage Rules

Use `POST /ims/case/v1p1/CFPackages` for transactional import.

Use `GET /ims/case/v1p1/CFPackages/{sourcedId}` for spec-pure export and post-import verification of one document graph. Do not verify large imports by running one `GET /ims/case/v1p1/CFItems/{id}` request per item; use package export for the full graph and paged `CFItems?CFDocumentURI=...` / `CFAssociations?CFDocumentURI=...` reads for spot checks.

Never expect Alignment rows or platform `_platform` sidecars in CFPackage export. If a user asks for a package that includes external lesson IDs, explain that those are Alignment data, then provide a separate Alignment report.

## Read-Edit-Write Rules

1. Detail GET the mutable resource.
2. Save the response `ETag`.
3. Send PUT, PATCH, or DELETE with `If-Match`.
4. For the next write, use `X-Case-ETag` from the previous successful write response or GET the resource again.
5. If the API returns `case:precondition_required`, fetch the resource and retry with `If-Match`.
6. If the API returns `case:precondition_failed`, refetch and ask whether to merge, replace, or discard the local draft.

## Evidence To Include In Final App/Report

Every app or report should expose:

- `CASE_BASE_URL`
- tenant mode: demo or real tenant
- endpoint names called
- request IDs or trace IDs for failures
- selected CFDocument identifier and URI
- selected CFItem identifier and URI
- Alignment external system and external ID, if created
- `checks/case_surface_check.sh` result, or the exact reason the check was not relevant
- a statement that no local CASE data store, parser, or graph-repair layer was used
