Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

179 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PistonPost

PistonPost is a small social feed for sharing art, images, videos, jokes, and everyday posts with familiar people. It uses TanStack Start, React 19, shadcn/ui on Base UI, Bun, Effect, Drizzle, and Cloudflare.

The implementation roadmap is in PLAN.md. Agents and contributors must read AGENTS.md before changing the repository.

Repository layout

PistonPost is one Bun package and one deployable Cloudflare Worker:

  • src: application routes, components, server code, auth, domain logic, database code, email, and shared utilities.
  • src/components/ui: shadcn/ui components and Base UI primitives.
  • wasm/image-sanitizer: the Rust source for client and Worker image sanitization.
  • drizzle: generated D1 migrations and Drizzle metadata.
  • tests: shared browser and DOM test setup.
  • docs: operator and architecture documentation.

The folders under src keep architectural concerns visible without creating separate workspace packages.

Development

Install dependencies and start the application:

bun install
bun run dev

The Cloudflare Vite development server runs on port 3000. Add shadcn components from the repository root:

bunx --bun shadcn@latest add <component>

Run the complete local CI gate with:

bun run ci

Useful focused commands include:

bun run test:web
bun run typecheck:web
bun run cf:typegen
bun run db:check
bun run wrangler:dry-run

The generated image sanitizer is checked in so normal Bun installs do not require Rust. After changing wasm/image-sanitizer, install the wasm32-unknown-unknown Rust target and regenerate it:

rustup target add wasm32-unknown-unknown
bun run wasm:build

The Worker exposes a shallow GET /health endpoint. Anonymous public documents use Cache-Control: no-cache so browsers and Cloudflare revalidate HTML before using it. Authenticated, mutation, auth, admin, draft, preview, and unlisted responses stay private or no-store.

Push notifications

Web Push uses one VAPID key pair per deployed environment. Generate a pair once:

bunx --bun web-push generate-vapid-keys --json

Put the public key in VAPID_PUBLIC_KEY for the relevant wrangler.jsonc environment. Put the private key in the ignored .dev.vars file as VAPID_PRIVATE_KEY; production uses a Secrets Store secret with the same name. The two values must come from the same pair. Keep VAPID_SUBJECT=mailto:support@pistonmaster.net unless the monitored contact address changes.

Push stays unavailable in the interface when the public key is blank. After changing a binding, run bun run cf:typegen. The existing JOBS Queue handles push delivery, retries, and expired subscription cleanup without another Worker.

Browser analytics

Post views and aggregate operational events use Cloudflare Analytics Engine. PistonPost also supports consent-gated PostHog page analytics using the same provider pattern as the EnderDash website. The tracked .env file enables PostHog in development and production with its public project token and managed reverse proxy. Use .env.local when you need a personal override. The client uses memory-only persistence and sends anonymous route categories without dynamic post IDs, usernames, tag names, page titles, referrers, or query strings. Update .env and redeploy when either public value changes.

See Cloudflare resource provisioning before creating staging or production resources. The email compliance controls document records message classification, unsubscribe behavior, sender configuration, key rotation, and the live mailbox verification runbook.

Production releases use the manually approved Deploy production GitHub Actions workflow. The workflow loads non-secret deployment configuration from .env.production, reads only the Cloudflare API token from the protected GitHub environment, builds the Worker with the production environment selected, applies D1 migrations, deploys the Worker, and runs smoke tests. Complete the provisioning and backup guides before triggering it.

Contributors

Languages