Record completed internal CMS rollout

This commit is contained in:
Kevin
2026-09-04 22:25:57 -04:00
parent dc3ec3ff30
commit 5652339676
5 changed files with 234 additions and 142 deletions
+67 -32
View File
@@ -1,24 +1,66 @@
# Happy Tails Astro pilot
# Happy Tails Astro sites and internal CMS
This repository is a static Astro pilot for `3031023.xyz`. The existing
Cloudflare Pages site remains the rollback target while this branch is tested.
This repository backs the production Happy Tails sites at `3031023.xyz` and
`blog.3031023.xyz`. Both are static Astro builds deployed as separate
Cloudflare Workers. The retained Cloudflare Pages project remains the primary
site rollback target.
The planned preview-only editing experiment is documented in the [Decap CMS
Gitea pilot](docs/decap-cms-pilot.md). It does not authorize CMS activation, a
production merge, or a domain change.
The Decap CMS workflow is operational for internal SloanOps use. It is not a
public feature or a client-editing offer. The approved internal editor is
`sloanops.admin`; do not invite additional editors without a separate access,
support, and security review.
## Repository layout
- `sites/www/` is the primary-site content location; it serves `3031023.xyz`.
- `sites/blog/` is the separate `blog.3031023.xyz` sample site.
- `sites.json` is the operator-controlled manifest. It is not public intake.
- `sites/www/` contains primary-site Markdown and site data.
- `sites/blog/` contains the Journal Markdown and site data.
- `public/admin/` contains the shared, no-index Decap admin shell and config.
- `public/images/uploads/` is the only CMS-writable media directory.
- `sites.json` is the operator-controlled build manifest, not public intake.
- `src/` contains shared Astro presentation code.
- `schemas/` and `fixtures/` provide the Phase 1 JSON contract proof.
- `schemas/`, `scripts/`, and `fixtures/` enforce the content and deployment
contracts.
Blog posts and primary-site FAQs are now static Markdown collections with
validated frontmatter and draft filtering. Production CMS publishing, public
sign-up changes, n8n changes, and onboarding-worker changes remain out of
scope; the linked Decap plan is a preview-only editing experiment.
## Internal CMS workflow
Use `https://3031023.xyz/admin/` for normal internal editing. Decap commits
content and approved raster media directly to the protected `cms` staging
branch; it never writes to `main`.
1. Make and review content changes on `cms`.
2. Confirm the `cms` Worker version previews and content validation results.
3. Open a pull request from `cms` to `main`.
4. Merge only after the required CMS validation, both site builds, and SloanOps
review pass.
5. Relevant `main` changes deploy the production primary and/or blog Worker.
6. Synchronize the resulting `main` merge commit back into `cms` through a
protected-branch pull request before the next editing cycle.
Operator-authored CMS application or configuration work also starts from the
current `cms` state. Use a short branch and a pull request into protected
`cms`, then promote the reviewed `cms` state to `main`. Direct protected-file
pushes to `cms` and all direct pushes to `main` are intentionally rejected.
Only the stable CMS and production admin origins are registered with Gitea.
Logging in from a branch-specific Worker preview alias therefore produces
`Unregistered Redirect URI`; this is expected. Never solve it with a wildcard
OAuth redirect or wildcard CORS origin. Use branch previews to inspect rendered
site output and an approved admin origin to test editing.
See the [CMS operating record](docs/decap-cms-pilot.md) and
[Gitea settings](docs/decap-cms-gitea-setup.md) for the complete boundaries.
## Content and media behavior
The CMS exposes primary FAQs, services, team members, fixed primary page
images, and Journal posts. Draft content is excluded from pages and sitemaps.
Journal publish and optional updated dates use Decap's supported `datetime`
widget in date-only UTC mode; new posts default the publish date to the current
UTC date.
CMS image sources must be approved JPG, PNG, WebP, or AVIF files in the flat
uploads directory and may be at most 25 MiB. Every build re-encodes public
copies to at most 1920 pixels and 500 KiB and strips embedded metadata.
## Local checks
@@ -37,25 +79,18 @@ Each selected site builds to `dist/<site-key>/`. The Worker configurations use
only static assets and a custom 404 page. They contain no custom domains,
routes, account IDs, or secrets.
`npm run verify:cms` checks the fixed Gitea branch/backend, the four Markdown
content contracts, the fixed page-image record, the bounded raster-media boundary, the pinned admin
shell, and the stable secret-free pull-request status context. The live steps
remain unapplied; see the [Gitea pilot settings](docs/decap-cms-gitea-setup.md)
for the exact review checklist.
`npm run verify:cms` checks the fixed Gitea backend and `cms` branch, all CMS
content contracts, media boundaries, the pinned admin shell, supported
widgets, and the stable secret-free pull-request status context.
## Preview deployment
The Gitea workflows upload scoped non-production preview versions of the
production Workers from every non-`main` branch. Cloudflare assigns each branch
a readable `workers.dev` preview alias without changing production traffic.
Relevant primary-site pushes to `main` deploy `3031023-xyz-www`, and relevant
blog pushes to `main` deploy `3031023-xyz-blog`, automatically. Both production
workflows deploy static assets only.
It uses the existing `CF_API_TOKEN` and `CF_ACCOUNT_ID`. The token retains the
Pages permissions needed for the `main` rollback target and now also permits
the non-production Worker preview deployment.
Routine jobs do not configure DNS or custom domains.
Non-`main` pushes upload no-index Cloudflare Worker versions with readable
branch aliases; they do not move production traffic. Relevant `main` pushes
deploy `3031023-xyz-www` and/or `3031023-xyz-blog` automatically after building
and verifying the selected site. Routine workflows contain no DNS, custom
domain, route, account ID, or token configuration.
Production hostname attachment and the `www` redirect are manual,
operator-controlled cutover steps. See `docs/pilot-baseline.md` for the
rollback record.
The production domain bindings, `www` redirect, retained Pages rollback, and
recovery steps are recorded in the [primary cutover runbook](docs/cutover-runbook.md)
and [blog production runbook](docs/blog-production-runbook.md).