7e-2: Compiled page API endpoint — GET /notes/{slug}/compiled #112

Closed
opened 2026-03-08 07:06:50 +00:00 by forgejo_admin · 0 comments
Contributor

Lineage

plan-2026-02-26-tf-modularize-postgres → Phase 7 (Block Content) → Phase 7e (Compiled Pages) → Phase 7e-2

Repo

forgejo_admin/pal-e-docs

User Story

As a consumer of pal-e-docs (sprint frontend, agent tools),
I want a single API call that returns pre-rendered HTML + TOC + metadata for a note,
So that I don't need multiple calls to assemble a complete page view.

Context

The compiled_pages table already exists (Phase 7a) with html, toc_json, content_hash, and compiled_at. The 7c backfill populated 274 compiled pages. The 7e-1 cutover (PR #110) ensures compiled_pages stay in sync on every note write. But there's no API endpoint to serve this data — consumers must use get_note() (no TOC) or get_note_toc() + multiple get_section() calls.

This phase adds the endpoint, then follow-on work adds the SDK method and MCP tool in pal-e-docs-sdk and pal-e-docs-mcp respectively.

File Targets

Files the agent should modify or create:

  • src/pal_e_docs/routes/blocks.py — add GET /{slug}/compiled endpoint to the existing blocks router. Returns compiled page data from the compiled_pages table.
  • src/pal_e_docs/schemas.py — add CompiledPageOut response model with fields: html (str), toc_json (list), content_hash (str), block_count (int), compiled_at (datetime), slug (str), title (str).

Files the agent should reference (read, don't modify):

  • src/pal_e_docs/models.pyCompiledPage model (has html, toc_json, content_hash, compiled_at, note_id)
  • src/pal_e_docs/routes/blocks.py — existing block endpoints for pattern reference

Files the agent should NOT touch:

  • src/pal_e_docs/routes/notes.py — note routes are unchanged
  • src/pal_e_docs/blocks/sync.py — sync logic is unchanged

Acceptance Criteria

  • GET /notes/{slug}/compiled returns JSON: {slug, title, html, toc_json, content_hash, block_count, compiled_at}
  • Returns 404 if note doesn't exist
  • Returns 404 (or empty compiled page) if note has no compiled page entry
  • block_count is computed from the blocks table (count of blocks for that note)
  • Response includes note slug and title for consumer convenience
  • Existing endpoints unchanged

Test Expectations

  • Unit test: compiled page returns correct fields for a note with blocks
  • Unit test: 404 for nonexistent slug
  • Unit test: verify block_count matches actual block count
  • Unit test: verify toc_json matches heading blocks
  • Integration test: create note → get compiled → verify content matches
  • Run command: pytest tests/ -v

Constraints

  • Add the endpoint to the existing routes/blocks.py router (prefix /notes, tags ["blocks"])
  • Follow the existing pattern: _get_note_or_404() helper, Pydantic response model
  • The block_count field should be a live count query, not stored — avoids maintaining another field
  • Keep it simple — this is a read endpoint, no write logic

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • PR #110 — 7e-1 source-of-truth cutover (prerequisite, merged)
  • phase-postgres-7e-compiled-pages — phase note
  • Follow-on: SDK method in pal-e-docs-sdk, MCP tool in pal-e-docs-mcp (separate issues)
### Lineage `plan-2026-02-26-tf-modularize-postgres` → Phase 7 (Block Content) → Phase 7e (Compiled Pages) → Phase 7e-2 ### Repo `forgejo_admin/pal-e-docs` ### User Story As a consumer of pal-e-docs (sprint frontend, agent tools), I want a single API call that returns pre-rendered HTML + TOC + metadata for a note, So that I don't need multiple calls to assemble a complete page view. ### Context The `compiled_pages` table already exists (Phase 7a) with `html`, `toc_json`, `content_hash`, and `compiled_at`. The 7c backfill populated 274 compiled pages. The 7e-1 cutover (PR #110) ensures compiled_pages stay in sync on every note write. But there's no API endpoint to serve this data — consumers must use `get_note()` (no TOC) or `get_note_toc()` + multiple `get_section()` calls. This phase adds the endpoint, then follow-on work adds the SDK method and MCP tool in pal-e-docs-sdk and pal-e-docs-mcp respectively. ### File Targets Files the agent should modify or create: - `src/pal_e_docs/routes/blocks.py` — add `GET /{slug}/compiled` endpoint to the existing blocks router. Returns compiled page data from the `compiled_pages` table. - `src/pal_e_docs/schemas.py` — add `CompiledPageOut` response model with fields: `html` (str), `toc_json` (list), `content_hash` (str), `block_count` (int), `compiled_at` (datetime), `slug` (str), `title` (str). Files the agent should reference (read, don't modify): - `src/pal_e_docs/models.py` — `CompiledPage` model (has `html`, `toc_json`, `content_hash`, `compiled_at`, `note_id`) - `src/pal_e_docs/routes/blocks.py` — existing block endpoints for pattern reference Files the agent should NOT touch: - `src/pal_e_docs/routes/notes.py` — note routes are unchanged - `src/pal_e_docs/blocks/sync.py` — sync logic is unchanged ### Acceptance Criteria - [ ] `GET /notes/{slug}/compiled` returns JSON: `{slug, title, html, toc_json, content_hash, block_count, compiled_at}` - [ ] Returns 404 if note doesn't exist - [ ] Returns 404 (or empty compiled page) if note has no compiled page entry - [ ] `block_count` is computed from the blocks table (count of blocks for that note) - [ ] Response includes note `slug` and `title` for consumer convenience - [ ] Existing endpoints unchanged ### Test Expectations - [ ] Unit test: compiled page returns correct fields for a note with blocks - [ ] Unit test: 404 for nonexistent slug - [ ] Unit test: verify block_count matches actual block count - [ ] Unit test: verify toc_json matches heading blocks - [ ] Integration test: create note → get compiled → verify content matches - Run command: `pytest tests/ -v` ### Constraints - Add the endpoint to the existing `routes/blocks.py` router (prefix `/notes`, tags `["blocks"]`) - Follow the existing pattern: `_get_note_or_404()` helper, Pydantic response model - The `block_count` field should be a live count query, not stored — avoids maintaining another field - Keep it simple — this is a read endpoint, no write logic ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes ### Related - PR #110 — 7e-1 source-of-truth cutover (prerequisite, merged) - `phase-postgres-7e-compiled-pages` — phase note - Follow-on: SDK method in pal-e-docs-sdk, MCP tool in pal-e-docs-mcp (separate issues)
Commenting is not possible because the repository is archived.
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/pal-e-api#112
No description provided.