Skip to content

cutover-blog: import laddr blog_posts + minimum-viable viewer at /blog #84

@themightychris

Description

@themightychris

Why this exists alongside #45

#45 covers reviving blog posts as a content-typed gitsheets sheet (v1.2 markdown bodies, lazy body loading, full reader experience). That's substantial work and depends on the broader content-typed migration tracked in #44 — both scoped post-cutover.

The narrower problem: the existing laddr site has blog posts. Cutting over to next-v2 with no blog content visible is a regression at flip-time even though strictly nothing's broken. This issue is the minimum-viable bridge: import the content into a regular TOML sheet now so it's not lost or invisible.

Scope (intentionally narrow)

  1. Schema (regular TOML sheet, not content-typed)BlogPost entity in packages/shared/src/schemas/blog-post.ts. Fields per Revive blog posts as a content-typed gitsheets sheet (revises the deferred decision) #45's spec (id, legacyId, slug, title, summary, authorId, postedAt, editedAt, featuredImageKey, deletedAt, body, createdAt, updatedAt). body stays as a string field in the TOML for now; Revive blog posts as a content-typed gitsheets sheet (revises the deferred decision) #45 migrates it to content-typed later.
  2. Sheet config.gitsheets/blog-posts.toml in the data repo, regular path template ${{ slug }}.toml.
  3. Importer translator — extend apps/api/scripts/import-laddr/translators.ts with translateBlogPost; wire into the importer flow.
  4. API endpointsGET /api/blog-posts (paginated list, body included since not lazy-loaded) and GET /api/blog-posts/:slug (detail).
  5. SPA routes/blog index, /blog/:slug detail. Render the body via the existing server-side markdown pipeline.
  6. Spec files — minimum specs/api/blog.md, specs/screens/blog-index.md, specs/screens/blog-detail.md; note the deferred follow-up to Revive blog posts as a content-typed gitsheets sheet (revises the deferred decision) #45 in each.

Explicitly out of scope (lives in #45)

  • Content-typed migration (markdown files with TOML frontmatter)
  • Lazy body loading (queryAll({ withBody: false }))
  • Staff-side POST/PATCH/DELETE — writes happen via PR to the data repo
  • Comments, reactions, multi-author workflows
  • Tag filtering for the blog index

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions