Commit Graph
8 Commits
Author SHA1 Message Date
andwati 02a7a6197f Add feeds, sitemap, search, tags, and per-post nav/TOC/series/related
- src/site.config.ts: minimal site metadata (title, description,
  base URL, nav, tag descriptions) ported from the legacy zola.toml
  as a placeholder pending real design/copy.
- RSS (@astrojs/rss) and JSON Feed endpoints, sitemap
  (@astrojs/sitemap), robots.txt.
- Base.astro: meta description (site-wide default or per-page
  override via llms_description/description), RSS/JSON feed
  <link rel=alternate>, and a webmention endpoint link (plumbing
  only — needs the domain registered on webmention.io to do
  anything).
- toml-content-loader.ts: marked renderer now assigns heading ids
  and collects them into rendered.metadata.headings, so
  render(entry) exposes headings the same way a built-in Markdown
  loader would.
- Writing detail page: table of contents, prev/next navigation,
  series-nav (uses the existing extra.series/series_index fields),
  and tag-overlap related posts.
- Tags index + per-tag pages, tag links wired in from writing cards.
- Pagefind: indexes the build output as part of `pnpm build`
  (astro build && pagefind --site dist), plus a /search/ page using
  Pagefind's default UI.

Verified: astro check clean, full build succeeds (feeds/sitemap/
pagefind all generate correctly), and manually exercised /search/
(real query, highlighted results) and /tags/ in a browser against
the built site.
2026-08-30 19:04:25 +03:00
andwati 62db772dad Add bookshelf ISBN/paper enrichment, fix status field name collision
apps/cms/src/utils/bookshelf-covers.ts fetches book covers from Open
Library by ISBN (real image, cached into apps/site/public/covers/)
and backfills missing title/authors for papers from Semantic Scholar
by DOI/arXiv id. Wired into the sync middleware in content-sync.ts:
runs once per entry (cover_image already set means "done"), and only
on live create/update through Strapi, not during the boot-time
import (so a restart doesn't hammer external APIs).

Also renames the bookshelf `status` field to `read_status`
everywhere (schema, content/README.md, seed content, Astro zod
schema, bookshelf page, sync mapping). Strapi's content-manager API
treats a top-level `status` key as its own reserved draft/publish
parameter even with draftAndPublish disabled, so an attribute
literally named `status` silently rejected every write — caught this
while testing the enrichment hook.

Verified end-to-end: created a book by ISBN with no cover_image,
confirmed a real cover image was downloaded and cached, cover_image
was set on the entry and written to the file, and the cover/file were
both removed on delete.
2026-08-30 18:52:39 +03:00
andwati 85efb824ae Wire Strapi to content/ via a two-way file sync provider
Adds slug (uid) fields to all four content types so Strapi documents
can be matched to files deterministically, plus:

- apps/cms/src/utils/content-file.ts: read/write/delete the +++ TOML
  frontmatter files, using smol-toml's TomlDate so dates round-trip as
  bare local dates (matching the legacy Zola format), not quoted
  datetime strings.
- apps/cms/src/utils/content-sync.ts: per-type frontmatter <-> Strapi
  field mappings, a boot-time importer that upserts every content/
  file into Strapi by slug, and a Document Service middleware that
  writes any create/update/delete made through Strapi straight back
  to the same files.

Strapi's SQLite DB is now genuinely a disposable cache: content/
stays buildable and readable with Strapi entirely absent, and
restarting Strapi rebuilds its DB from content/ with no duplicates
(matched by slug).

Verified end-to-end: fresh boot imports all seed files once; a second
boot re-imports idempotently (0 created, all matched by slug); create/
update/delete through the content-manager API all correctly write to
and remove the corresponding file on disk.
2026-08-30 18:45:44 +03:00
andwati 27efeb8b26 Add Docker setup for running Strapi locally
apps/cms/Dockerfile.dev + root docker-compose.yml give a one-command
way to run the CMS in a container for testing (docker compose up
cms), with the shared content/ directory mounted so it matches the
host dev setup. apps/cms/Dockerfile is a production multi-stage build
for later Dokploy deployment. Uses node:24-bookworm-slim to match the
local Node version and get glibc prebuilt binaries for better-sqlite3
without needing a native build toolchain in the final image.

Verified: both images build, the dev container boots Strapi
successfully, admin panel and API routes are reachable, and the
mounted content/ volume resolves at the same relative path the future
sync provider will expect.
2026-08-30 18:36:31 +03:00
andwati 9d6d78b31f Define Strapi content types matching the content/ schema
Adds writing, portfolio-entry, bookshelf-entry, and curated-blog
collection types with attributes mirroring the TOML frontmatter
fields in content/README.md exactly, so the future sync provider has
a direct field mapping. draftAndPublish is disabled on all four since
our own `draft` boolean (synced to the file) is the source of publish
state, not Strapi's built-in workflow. Verified Strapi boots and
registers all four REST routes (api/writings, api/portfolio-entries,
api/bookshelf-entries, api/curated-blogs).
2026-08-30 18:23:42 +03:00
andwati 16c8dff5d5 Wire Astro content collections to the shared content/ directory
Adds a custom Astro loader that reads the Zola-style TOML frontmatter
(+++ ... +++) directly, so content/ stays the single source of truth
with no YAML conversion step. Defines writings/portfolio/bookshelf/
blogs collections and basic list/detail pages for each, rendering the
seed entries end-to-end (verified in-browser via `pnpm --filter site
dev`). This is the first runnable MVP: home, writings list + post
detail, portfolio, bookshelf (books and papers), and curated blogs
all render from real content/ files.
2026-08-30 18:14:34 +03:00
andwati cae62d4a66 Apply Biome formatting across the workspace
Fixes the formatting deltas from the initial Astro/Strapi scaffold
and brings the legacy generate-og-images/generate-llms/validate-post
scripts in line with Biome's style. No behavioral changes.
2026-08-30 17:59:30 +03:00
andwati 80e1d55ea1 Scaffold Astro/Strapi monorepo for the site rebuild
Set up a pnpm workspace with apps/site (Astro) and apps/cms (Strapi,
SQLite-backed) as the foundation for the new digital-legacy site.
Switches package management to pnpm and adds Biome for linting/
formatting, replacing npm/no-linter setup. Existing Zola site stays
in place for now and will be migrated/removed progressively.
2026-08-30 17:56:36 +03:00