Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

190 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pack 170 — Cub Scouts of Macon, Georgia

Deploy status Built with Astro Deployed on Cloudflare Workers Bun

Version 0.1.0 MIT License

Pack 170 is the source for macon170.com — the official website of Cub Scout Pack 170 in Macon, Georgia, built with Astro and a Cloudflare Workers backend.

macon170.com home page: a notebook-styled hero reading 'Cub Scout Pack 170 — Build confidence. Find friends. Get outside. Do your best.' with a den grid and family calendar preview below it

✨ Features

  • 🏕️ Family-first static siteAstro pages for the calendar, adventures, joining, and volunteering, built to answer "is this pack for us?" in under two minutes on a phone
  • ✉️ Turnstile-verified contact form — parent inquiries are checked server-side with Cloudflare Turnstile and land in a private, D1-backed volunteer desk, never a public inbox
  • 📅 Draft → publish → archive calendar — volunteers manage events with a full audit trail; the public API only ever exposes published family logistics
  • 🔐 Zero-trust admin desk — every request to admin.macon170.com is verified against a Cloudflare Access JWT server-side, not just trusted at the edge
  • 🧪 Real Workers-runtime testsVitest unit and integration coverage (against actual D1 migrations) plus Playwright e2e coverage of the full contact-to-admin flow
  • 🧹 One-command CI parityjust ci runs the exact lint/check/format/ test/e2e battery GitHub Actions runs before every deploy

🚀 Quick Start

bun install --frozen-lockfile
cp .dev.vars.example .dev.vars
bun run db:migrate:local
bun run dev:worker

Open http://localhost:8787 — this runs the full Worker (contact API, admin desk, D1) in front of the built site. For frontend-only iteration without the API, bun run dev starts just the Astro dev server.

Table of Contents

🤔 Why This Exists

Pack 170 previously ran its web presence on a Square site. This project replaces it as the pack's primary web presence, serving two audiences equally: prospective families who need to answer "what is this, does my kid qualify, when/where do you meet, how do I join" in under two minutes, and current pack families looking up the calendar, event details, and volunteer contacts.

Two constraints shaped the architecture more than anything else:

  • Youth protection. Youth are identified by first name and last initial only, no photos without consent, and every contact channel is parent-framed and reaches multiple adults — there's no one-to-one adult–youth messaging path.
  • Scouting America brand rules. Official marks are used unmodified only, sourced from the Brand Center, with no ads, no merchandise sales, and a required non-endorsement disclaimer — this site is run by pack volunteers, not Scouting America or the Central Georgia Council.

Those constraints are why the admin desk is Access-gated rather than a public CMS, and why the data model tracks an audit trail for every submission and event change.

📦 Installation

Prerequisites: Bun and a Cloudflare account with Wrangler authenticated (bunx wrangler login).

git clone https://github.com/kerryhatcher/macon170.com.git
cd macon170.com
bun install --frozen-lockfile
cp .dev.vars.example .dev.vars
bun run db:migrate:local

.dev.vars holds TURNSTILE_SECRET, set by default to Cloudflare's documented always-pass test secret — safe for local development, never used in production.

Environment variables reference
Variable Where Purpose
TURNSTILE_SECRET .dev.vars (Worker secret in prod) Server-side Turnstile verification
TURNSTILE_SITE_KEY wrangler.jsonc vars Client-side Turnstile widget key
ACCESS_TEAM_DOMAIN wrangler.jsonc vars Your https://TEAM.cloudflareaccess.com domain
ACCESS_AUD wrangler.jsonc vars Cloudflare Access application audience tag
ADMIN_ORIGIN / PUBLIC_SITE_ORIGIN wrangler.jsonc vars Expected origins for CORS and redirects

Full production setup, including Access policy configuration and GitHub Actions secrets, is documented in docs/CLOUDFLARE-DEPLOYMENT.md.

🔧 Usage

Command What it does
bun run dev Astro dev server only (no API, no D1)
bun run dev:worker Full Worker + static site + local D1, at :8787
bun run build Type-checks and builds to dist/
bun run test Vitest unit + integration
bun run test:e2e Playwright e2e coverage
bun run lint / format ESLint and Prettier
just ci The full local battery, same as CI

Run just ci before every commit — it's the same battery GitHub Actions runs before it will deploy.

📖 API Reference

One Worker serves both the static Astro output and the API:

  • POST /api/contact — Turnstile-verified, rate-limited parent inquiries, written to D1
  • GET /api/events — public, read-only, published-only calendar data
  • admin.macon170.com/* — the volunteer desk; every request requires a Cloudflare Access JWT verified server-side against Cloudflare's rotating JWKS, and every view or status change is written to an audit log tied to the verified email

See docs/CLOUDFLARE-DEPLOYMENT.md for the full request/response and data-safety model.

🏗️ Architecture

src/               Astro pages, layouts, and components (the public site)
src/data/pack.ts   The single editable file for pack-specific facts
worker/            Cloudflare Worker: contact API, admin desk, calendar CRUD
migrations/        D1 schema (contact_submissions, calendar_events, audit)
e2e/               Playwright coverage of the contact-to-admin flow
docs/              Deployment runbook and pack research/reference material

🤝 Contributing

This is a small, volunteer-maintained pack site, but pull requests, bug reports, and content corrections are welcome. See CONTRIBUTING.md for local setup, the PR process, and code standards. Please also read our Code of Conduct.

💬 Support

  • Bugs or feature ideas: open a GitHub issue
  • Security or data-safety concerns: see SECURITY.md — please don't file these as public issues
  • Pack questions (meeting times, joining, events): use the contact page on the live site, not this repository

License

MIT — see LICENSE.

🙏 Acknowledgements

  • Cub Scout Pack 170 is chartered by Highland Hills Baptist Church in Macon's Shirley Hills neighborhood, part of the Central Georgia Council, Scouting America.
  • This is a volunteer-run site, not an official Scouting America or council communication channel. Scouting trademarks and design marks belong to Scouting America; no endorsement of this site or its non-Scouting activities is implied.
  • Built with Astro and Cloudflare Workers.

About

Scout Pack 170 Macon GA website

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages