98 lines
4.4 KiB
Markdown
98 lines
4.4 KiB
Markdown
# Happy Tails Astro sites and internal CMS
|
|
|
|
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 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/` 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/`, `scripts/`, and `fixtures/` enforce the content and deployment
|
|
contracts.
|
|
|
|
## 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. If `main` contains file changes that are not already in `cms`, synchronize
|
|
them back through a protected-branch pull request before the next editing
|
|
cycle. A merge commit whose tree already matches `cms` needs no no-op sync.
|
|
|
|
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
|
|
|
|
Use Node 22.12 or newer within the Node 22 release line.
|
|
|
|
```bash
|
|
npm ci
|
|
npm run verify:cms
|
|
SITE_KEY=www npm run build:site
|
|
SITE_KEY=www npm run verify:build
|
|
SITE_KEY=blog npm run build:site
|
|
SITE_KEY=blog npm run verify:build
|
|
```
|
|
|
|
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 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
|
|
|
|
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.
|
|
|
|
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).
|