Contributing to The Pool
Getting Started
Prerequisites
- Podman for the recommended local path, or:
- Ruby + Bundler (for host Jekyll)
- Node.js 24 preferred, Node.js 22 minimum for Wrangler 4 (for Worker + scripts)
- Wrangler CLI (for host Worker development)
- optional: Stripe CLI (for webhook testing)
Local Development
npm run podman:doctor
./scripts/dev.sh --podman
That is the default local development path. It keeps the standard local ports and local state files, but runs Jekyll and Wrangler inside containers so new forks do not need host Ruby or host Wrangler just to boot the app.
The Podman Worker container runs Node 24, matching GitHub Actions. Host-only Worker development should use Node 24 when possible; Node 22 is the minimum supported runtime for Wrangler 4.
If you need the host-only path instead:
bundle install
bundle exec jekyll serve --config _config.yml,_config.local.yml
If you want to run the checkout helper or browser suite against the same Podman-backed stack:
./scripts/test-checkout.sh --podman
./scripts/test-e2e.sh --podman
./scripts/test-worker.sh --podman
./scripts/smoke-pledge-management.sh --podman
./scripts/pledge-report.sh --podman --local
./scripts/fulfillment-report.sh --podman --local
npm run test:e2e:headless:podman
npm run podman:doctor
npm run podman:self-check
./scripts/test-e2e.sh --podman is now fully automated browser coverage. ./scripts/test-checkout.sh --podman remains the manual interactive helper when you want to step through a real checkout in your own browser.
Clear cache if styles don’t update:
bundle exec jekyll clean
Read the Docs (in order)
- Root
README.md— High-level purpose & architecture docs/PROJECT_OVERVIEW.md— How all parts fit togetherdocs/WORKFLOWS.md— Pledge lifecycle, magic links & charge flowdocs/DEV_NOTES.md— Integration notes, content model & gotchasdocs/TESTING.md— Full testing guide (includes secrets setup)docs/ROADMAP.md— Planned featuresdocs/DASHBOARD.md— Admin dashboard editing and operations
For dashboard UI changes, also skim docs/ACCESSIBILITY.md, docs/I18N.md, docs/SECURITY.md, and docs/SEO.md; the admin shell has explicit requirements for keyboard access, Spanish strings, input normalization, and noindex.
GitHub Pages Setup
- Create repo and add files
- Add a
CNAMEfile for your public site domain - DNS (Cloudflare):
| Type | Name | Value |
|---|---|---|
| CNAME | pool | <username>.github.io |
- Enable HTTPS in repo settings
- Verify the first-party cart loads and campaigns render
- Verify Worker-backed checkout boot config is present
Current Status (June 2026)
✅ Completed:
- Jekyll + first-party cart site structure
- Sass styling system (shared modular partials, 8px grid)
- Money formatting plugin (
$3,800style) - Campaign cards, two-column layout, hero variants
- Production phases, community decisions, production diary
- Pledge UX, cart icon, first-party checkout review
- Native first-party Stripe payment flow in the existing checkout sidecar
- No-account pledge management (magic links,
/manage/page) - On-site
Update Cardflow in/manage/ - Supporter-only community page with voting
- Non-stackable tier support (hide quantity controls in cart)
- Mobile hamburger/cart overlay handling
- Cloudflare Worker (pledge storage, stats, inventory, emails)
- Worker scheduled task for auto-settle at midnight in the configured platform timezone
- Aggregated charging (one charge per supporter per campaign)
- Support items and custom amounts data flow (cart → Worker → KV → stats)
- Countdown timer pre-rendering (no “00 00 00 00” flash)
- Multi-tier pledge support (
additionalTiers) - Unit tests (Vitest) and E2E tests (Playwright)
- Fully automated checkout E2E coverage
- Production campaign launch (Hand Relations)
- Podman-backed local dev/testing path
- More explicit inventory overselling protection via Durable Object coordination
- Private admin dashboard for role-scoped campaign editing, settings, add-ons, analytics, reports, supporters, marketing links, and user management
- Completed typography, elements, and layouts redesign across public pages, campaign surfaces, checkout, and Manage Pledge
- Configurable platform timezone for campaign deadlines, countdowns, reports, lifecycle automation, and settlement checks
- Upcoming-campaign launch reminders with Turnstile, dedupe, unsubscribe, and shared Resend delivery
- Public-page performance hardening, generated asset minification, conservative same-origin prefetching, and responsive media derivatives
- Dashboard media workflow hardening for image/video optimization dispatch, publish-time media cleanup, and diary anchor/rendering fixes
🚧 Active focus:
- Merge-gate discipline and release-readiness audits across accessibility, customization, dashboard, i18n, performance, security, and SEO
- Tax calculator depth, net revenue analytics, richer campaign marketing tools, add-on variant pricing, and protected campaign preview pages
Branching & PRs
Branch Naming
- Feature branches:
feat/<short-name>(e.g.,feat/pledge-hook) - Fix branches:
fix/<short-name> - Docs branches:
docs/<short-name>
Commit Style
- Conventional prefixes:
feat,fix,docs,chore,infra
Pull Requests
- Keep PRs focused and under ~300 lines when possible
- Fill out the PR template, include screenshots for UI changes, and include desktop/tablet/mobile screenshots for admin dashboard layout changes
- Link issues with
Closes #123
Labels
feature,bug,task,infra,docs,security
First Contribution Checklist
- Clone repo, run
npm run podman:doctor - Start local dev with
./scripts/dev.sh --podman - Confirm Worker local dev is running on Node 24 through the Podman path
- Only use the host-only Jekyll/Wrangler path if you intentionally need it
- Skim
_layouts/&_includes/to see first-party cart integration - Review
assets/js/cart & pledge scripts - Read
worker/src/to understand the backend (pledge storage, stats, charging) - Open
/admin/locally with the default dev admin email path and understand the dashboard publish vs KV-save split - Verify
CNAMEis set to your public site domain
Secrets & Config (Test Mode First)
- GitHub Actions: Add test
STRIPE_SECRET_KEY+CHECKOUT_INTENT_SECRET - Cloudflare Worker: Same secrets as env vars; set
SITE_BASE - Stripe: For hosted environments, create a webhook to
https://worker.example.com/webhooks/stripe - Local custom checkout: add
STRIPE_PUBLISHABLE_KEY_TESTtoworker/.dev.vars - Admin dashboard: local dev grants bootstrap super-admin access through
ADMIN_BOOTSTRAP_EMAILSin ignoredworker/.dev.vars; fork admins should put production access in_config.ymladmin.users,ADMIN_USERS_JSON, or the dashboard Users screen. The Users screen saves to KV, not GitHub.
See TESTING.md for full secrets reference.
Security Notes
- Secrets live only in GitHub Actions + Cloudflare vars; never in repo
- The dashboard Secrets & credentials section is read-only status. Do not add secret editing or secret persistence to
_config.yml, campaign YAML, KV user records, or dashboard drafts. - Validate Stripe webhook signatures
- Never commit API keys or tokens
Glossary
| Term | Definition |
|---|---|
| Pledge | Order placed with no immediate charge; card saved via Stripe SetupIntent |
| All-or-Nothing | Cards charged only if pledged_amount >= goal_amount at deadline |
| SetupIntent | Stripe object to save a payment method for later off-session charges |
| Magic Link | HMAC-signed URL sent via email for accountless pledge management |
| The Pool | Platform name for the crowdfunding site |
| Platform operator | Company or studio name for your deployment |
Contact & Ownership
Use the project docs and existing git history for context, and keep changes scoped and well-tested before opening a PR.