Revive blog posts as a content-typed gitsheets sheet (revises the deferred decision)
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 35/100
- Issue 类型
- 功能
- 描述清晰度
- 基本清楚
- 活跃度
- 冷清
- 技术栈
- markdown, typescript
调研方向
先阅读 issue #44 和 specs/deferred.md 中推迟的决定,然后检查现有的 gitsheet 模式和 apps/api/scripts/import-laddr.ts。跟踪 apps/api/scripts/import-laddr/translators.ts,以及所引用的 BlogPost schema 和 routing 要求。完成的标准是:在不包含已排除 workflows 的情况下,实现 content-typed blog-post sheet、API、SPA routes、恢复 importer,并完成列出的 spec 更新。
由索引模型根据 Issue 内容生成。
描述
specs/deferred.md currently says blog posts get replaced by "staff-authored markdown files in the code repo at apps/web/src/content/blog/<slug>.md, shipped via PR." That decision predates gitsheets v1.2's content-typed records.
With v1.2 we can give blog posts their own gitsheets sheet — markdown bodies + TOML frontmatter — and get a better outcome than files-in-code-repo:
Why this beats the original deferral
| Concern | Files-in-code-repo | Content-typed sheet |
|---|---|---|
| PR-reviewable | ✅ | ✅ |
| Publish cadence | Tied to web deploys | Immediate on data-repo merge |
| Tags / cross-links | Ad-hoc frontmatter | Native TagAssignment |
| Author attribution | Hand-stamp in frontmatter | Native Person reference |
| Snapshot inclusion | Not in data snapshot | In the snapshot (pseudonymized) |
| API serving | Bespoke Vite handler | Existing read API pipeline |
/blog index cost |
Bundle every post into web build | queryAll({ withBody: false }) |
| laddr-import revival | Out of scope | Resurrect blog_posts table on the existing one-shot import |
Sheet shape
# .gitsheets/blog-posts.toml
[gitsheet]
root = 'blog-posts'
path = '${{ slug }}'
[gitsheet.format]
type = 'markdown'
body = 'body'
[gitsheet.schema]
$ref = './schemas/BlogPost.schema.json'
BlogPost entity (in packages/shared/src/schemas/blog-post.ts):
idUUIDv7legacyId(laddr'sBlogPost.ID, for the importer's idempotence)slug(kebab-case, slug-handle conventions)titlesummary(short markdown — stays in frontmatter)authorId→ PersonpostedAt(iso8601)editedAtnullablefeaturedImageKeynullable (attachment via gitsheets)deletedAtnullable (soft-delete)body(the markdown body — the designated content field)- standard
createdAt/updatedAt
Routing
Add to the SPA:
/blog— index (paginated, optional tag filter)/blog/:slug— detail/blog/tag/:namespace/:slug— tag-filtered (reuseTagsNamespacepattern)
API:
GET /api/blog-posts(list with facets, q, sort, page)GET /api/blog-posts/:slug(detail)POST/PATCH/DELETE— staff-only (per the original spec, blog wasn't a per-user-role CMS)
laddr-import revival
The existing one-shot importer at apps/api/scripts/import-laddr.ts currently skips blog_posts. Re-add it as another translator in apps/api/scripts/import-laddr/translators.ts:
- Map
BlogPost.Slug→slug(slugify-with-dedupe if invalid) - Map
BlogPost.Title→title - Map
BlogPost.Body→body - Map
BlogPost.AuthorID→ resolve via the existingidMaps.personByLegacy - Map
BlogPost.Published(and similar) →postedAt - Preserve
legacyIdso re-runs are idempotent
Sequencing
- Depends on #44 (content-typed gitsheets is the substrate) — or stand on its own as the first content-typed sheet in the project. Either order works since blog-posts is a brand-new sheet that doesn't conflict with the existing TOML-only ones.
- Sequenced after
cutover-prepso existing migration paths stay valid through cutover.
Spec updates needed
specs/deferred.md— update the "Blog (/blog) as a user-facing CMS" entry from "files in code repo" to "content-typed sheet, see this issue."- New spec files:
specs/api/blog.md,specs/screens/blog-index.md,specs/screens/blog-detail.md. specs/data-model.md— addBlogPostentity.specs/behaviors/legacy-id-mapping.md— note the newBlogPost.legacyIdaxis.
Out of scope: comments, reactions, the multi-author "posts under a topic" workflow — keep it as simple as the original deferral imagined.
- 主要语言
- TypeScript
- 星标
- 1
- 派生
- 1
- 平均合并
- 1 天 20 小时
- 30 天内合并 PR
- 25
贡献指南
这个仓库没有索引到贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
CodeForPhilly/codeforphilly-ng 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 84/100
-
MarkdownEditor toolbar: use Radix Toolbar from radix-ui instead of the hand-rolled roving tabindex 未关闭enhancement
难度 2/5 1-3 小时 新手友好度 82/100
-
难度 2/5 1-3 小时 新手友好度 76/100
-
难度 2/5 1-3 小时 新手友好度 88/100
-
难度 2/5 1-3 小时 新手友好度 74/100
查看 CodeForPhilly/codeforphilly-ng 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 70/100
-
难度 2/5 1-3 小时 新手友好度 75/100
mksglu/context-mode#1200 ·
-
难度 2/5 1-3 小时 新手友好度 75/100
jaegertracing/jaeger-ui#4506 ·
-
area:desktop area:ui bug platform:macos
难度 2/5 1-3 小时 新手友好度 75/100
anthropics/claude-code#96687 ·
-
good first issue
难度 1/5 1 小时以内 新手友好度 95/100
AOSSIE-Org/DebateAI#582 · 2 条评论 ·