diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 34af9eeda..31e7a2484 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -5,14 +5,10 @@ updates:
versioning-strategy: "increase"
schedule:
interval: "weekly"
- open-pull-requests-limit: 20
+ open-pull-requests-limit: 4
labels:
- "type: dependencies 🔗"
- "automerge 🤞"
- # Ignore list: pin packages that should not be updated automatically
- ignore:
- - dependency-name: "zod"
- update-types: ["version-update:semver-patch", "version-update:semver-minor", "version-update:semver-major"]
- package-ecosystem: "github-actions"
directory: "/"
schedule:
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index 91fe76892..476ba88ea 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -20,7 +20,6 @@ jobs:
# Define environment variables once at the job level
# These will be available to ALL steps in this job
- # @TODO: Same issue with type-check.yml. These are real keys set on GitHub. But the production build only occurs on Vercel, and it's the only place that needs real keys. Once we set up a test framework using Docker containers for Suprabase, Upstash, etc., we should replace these keys with test keys.
env:
CONVERTKIT_API_KEY: ${{ secrets.CONVERTKIT_API_KEY }}
CONVERTKIT_FORM_ID: ${{ secrets.CONVERTKIT_FORM_ID }}
@@ -94,6 +93,9 @@ jobs:
- name: Start Supabase stack
run: npm run containers:supabase:start
+ - name: Apply Supabase migrations
+ run: npm run containers:supabase:db-push
+
- name: Run Playwright E2E tests
run: npx playwright test
env:
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 389b95cad..30f7b3dfa 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -44,6 +44,7 @@
"Joomla",
"jscoverage",
"Karamov",
+ "keyup",
"KHTML",
"koko",
"labelledby",
@@ -69,9 +70,11 @@
"oklch",
"Onest",
"optin",
+ "PGRST",
"pids",
"pleroma",
"Poslovski",
+ "Postg",
"Qualys",
"registrator",
"repost",
diff --git a/@types/window.d.ts b/@types/window.d.ts
index dd4b7fac4..d224c716a 100644
--- a/@types/window.d.ts
+++ b/@types/window.d.ts
@@ -52,6 +52,11 @@ declare global {
*/
isPlaywrightControlled?: boolean
+ /**
+ * Allows Playwright tests to disable PWA service worker registration
+ */
+ __disableServiceWorkerForE2E?: boolean
+
/**
* Snapshot of environment-client results for Playwright assertions
*/
diff --git a/README.md b/README.md
index 15ce98db8..74e69a76e 100644
--- a/README.md
+++ b/README.md
@@ -36,6 +36,40 @@ git push -u origin feature/your-feature-name
- Branch name must follow conventions
- Cannot commit directly to main
+### Local Development Server
+
+Use the helper script below to start Astro with `.env.development` automatically loaded:
+
+```bash
+npm run dev:env
+```
+
+The underlying `npm run dev` command remains unchanged for CI and Vercel; `dev:env` is just a convenience for local shells so API routes that depend on `process.env` (cron handlers, email providers, etc.) behave the same way they do in production.
+
+## Supabase Production Initialization
+
+Provisioning the hosted Supabase project uses the same SQL migrations that back local development. When you need to initialize (or update) the production database:
+
+1. Authenticate the Supabase CLI (only required once per machine):
+
+ ```bash
+ npx supabase login
+ ```
+
+1. Link the CLI to the production project (replace the placeholder reference):
+
+ ```bash
+ npx supabase link --project-ref your-production-project-ref --workdir suprabase
+ ```
+
+1. Apply the latest migrations and RLS policies:
+
+ ```bash
+ npm run supabase:db:push
+ ```
+
+The `supabase:db:push` script runs `supabase db push` against the linked project, ensuring every table, index, and policy in `suprabase/migrations` is kept in sync with production.
+
## Coding Standards
### Component Architecture
diff --git a/_TODO.md b/_TODO.md
index 49117b8c0..677af9f25 100644
--- a/_TODO.md
+++ b/_TODO.md
@@ -4,6 +4,12 @@
Implement mitigations in test/e2e/specs/07-performance/PERFORMANCE.md
+## GitHub
+
+- Make sure actions workflows are working correctly after performance tests pass and whole suite is green
+- Change Dependabut to open a single PR with all dependency updates
+- Add 'hotfix' branch and add branch protection rules
+
## Analytics
Vercel Analytics
@@ -11,27 +17,43 @@ Vercel Analytics
## Themepicker tooltips, extra themes
- Add additional themes
-- @TODO: add tooltip that makes use of the description field
+- Add tooltip that makes use of the description field
## Sentry feedback, chat bot tying into my phone and email
See note in src/components/scripts/sentry/client.ts - "User Feedback - allow users to report issues"
-## src/pages/api next steps
+## Uppy file uploads from contact form
+
+docs/CONTACT_FORM.md
+
+## Search
+
+Add Upstash Search as a Vercel Marketplace Integration.
+
+Lunr is a JS search library using an inverted index. Client-side search for statically hosted pages.
+
+### [`@jackcarey/astro-lunr`](https://www.npmjs.com/package/@jackcarey/astro-lunr)
+
+### [`@siverv/astro-lunr`](https://www.npmjs.com/package/@siverv/astro-lunr)
+
+## Email Templates
-E2E Starting Point
+Right now we're using string literals to define HTML email templates for site mails. We should use Nunjucks with the rule-checking for valid CSS in HTML emails like we have in the corporate email footer repo.
-Stabilize infra first: run npm run containers:up, npm run containers:wait, npm run containers:supabase:start, and the dev server. Keep containers:logs and containers:supabase:logs tailing in another terminal so every mock failure is visible before Playwright runs.
+## @TODO: Provide button to turn off animation in Hero
-Create a shared Playwright "mocks ready" fixture: add a helper that checks process.env.E2E_MOCKS === '1' and pings `http://127.0.0.1:8079/` plus the two WireMock endpoints before each suite. That gives quick feedback if someone forgets the setup commands.
-Implementation order
+"Scaling/zooming animations are problematic for accessibility, as they are a common trigger for certain types of migraine. If you need to include such animations on your website, you should provide a control to allow users to turn off animations, preferably site-wide. Also, consider making use of the prefers-reduced-motion media feature — use it to write a media query that will turn off animations if the user has reduced animation specified in their system preferences. "
-08-api: start with these since their success hinges entirely on the mocks. For each test, assert the HTTP response and inspect the mock's request logs (WireMock /__admin/requests) to prove the backend call happened. Adding the cron tests here makes sense—just exercise the GET endpoints via page.request or Playwright's API testing capability so you don't need UI plumbing.
+## Color vars
+
+brand primary: #001733
+brand secondary: #0062B6
-Cron coverage: write three tests that hit cleanup-confirmations, newsletter-reminders, etc., using the mock stack. Seed Supabase/Redis with known values before each test (scripts in containers) and assert the mocks see the expected outbound traffic.
+ring (1px), ring-2, ring-4
+accent
-03-forms: once the API layer is stable, wire the UI flows. Use Playwright to submit each form, but assert success by checking the mock mappings were triggered, not just the UI toast.
-Consent Preferences (@wip): convert it to use the same helper that verifies mocked Upstash REST and Supabase responses. This test should (1) toggle UI controls, (2) check the outbound request via the mock logs, and (3) read back seeded data to confirm persistence.
+text-white, other default Tailwind colors
## Typing client-side API calls and SSR API endpoints
@@ -43,12 +65,12 @@ Shared Types vs Swagger / Keeping Docs in Sync
- Cons: no generated docs/SDKs; discipline is required to keep manual docs current.
- How to enforce: treat the contract files as the single source of truth, add lint rules banning request/response literal types outside _contracts, and add lightweight contract tests that instantiate each type against the endpoint handler (failing if fields diverge).
-2. Code-first OpenAPI (Zod or TS schemas → OpenAPI)
+1. Code-first OpenAPI (Zod or TS schemas → OpenAPI)
- Define schemas in Zod/Valibot (or ts-rest) alongside the endpoint. Generate OpenAPI JSON plus TypeScript types from those schemas. Docs (Swagger UI/Redoc) and any client SDKs come from the generated spec, so they're always in sync.
- Guarantees: CI regenerates the spec and fails when the checked-in artifact is stale; endpoint handlers reuse the same schema for runtime validation, so a mismatch cannot compile.
-3. Spec-first OpenAPI + Swagger Codegen
+1. Spec-first OpenAPI + Swagger Codegen
- Maintain an OpenAPI YAML/JSON file as the source of truth, run Swagger Codegen (or openapi-typescript) to produce both server stubs and client SDKs.
- Guarantees: developers edit the spec, run codegen (enforced via a pre-commit/CI task), and the generated server stubs remind you to implement every path/verb. Documentation pages (Swagger UI) are rendered straight from the same spec, so they inherently match the implementation.
@@ -67,24 +89,6 @@ Lighthouse audits (6) - Integration pending
Newsletter double opt-in (6) - Email testing infrastructure
Axe accessibility (2) - axe-core integration
-## Search
-
-Add Upstash Search as a Vercel Marketplace Integration.
-
-## Email Templates
-
-Right now we're using string literals to define HTML email templates for site mails. We should use Nunjucks with the rule-checking for valid CSS in HTML emails like we have in the corporate email footer repo.
-
-## Color vars
-
-brand primary: #001733
-brand secondary: #0062B6
-
-ring (1px), ring-2, ring-4
-accent
-
-text-white, other default Tailwind colors
-
## Axe tags
cat.aria: Rules related to Accessible Rich Internet Applications (ARIA) attributes and roles.
@@ -100,6 +104,12 @@ cat.structure: Rules related to the document's overall structure, like the prope
cat.tables: Rules for data tables, including headers and associations.
cat.text-alternatives: Rules for ensuring that text alternatives are provided for non-text content, such as images.
+## @TODO: Add Check HTML Links to test workflow
+
+npm i -D check-html-links
+npx check-html-links _site
+`https://github.com/modernweb-dev/rocket/tree/main/packages/check-html-links`
+
## Social Media Preview Cards
Looking at the social-card endpoint implementation, it's designed to work with third-party screenshot services, not the social networks themselves.
@@ -117,7 +127,7 @@ Social networks like Twitter, Facebook, LinkedIn, etc. don't screenshot HTML pag
- Direct image URLs (PNG, JPEG, etc.)
- Standard dimensions (1200x630px for most platforms)
-The Intended Workflow
+**The Intended Workflow**
This endpoint is designed to integrate with screenshot services like:
@@ -127,7 +137,7 @@ This endpoint is designed to integrate with screenshot services like:
- ScreenshotOne or ApiFlash - Dedicated screenshot APIs
- Satori - Convert HTML/CSS to SVG/PNG
-Current Limitation
+**Current Limitation**
As implemented, this endpoint would need an additional step to be useful for social sharing:
@@ -141,71 +151,67 @@ For a production Astro site, you'd typically:
- Pre-generate images at build time for static content
- Use a screenshot service that can be called from your endpoint to return actual images
-## @TODO: Use Confetti on CTA forms
+**Social Media Preview Generators**
-`canvas-confetti`
-https://github.com/catdad/canvas-confetti
-https://www.kirilv.com/canvas-confetti/
+There are several integrations available that vary based on the library they use to create an image file to snapshot, whether they allow the template for generating the image to be modified, and what options they provide for output.
-## @TODO: Use the Page Visibility API to pause videos, image carousels, and animations
+[`astro-og-canvas`](https://www.npmjs.com/package/astro-og-canvas)
-Stop unnecessary processes when the user doesn't see the page or inversely to perform background actions.
+- Most popular option (~660 weekly d/l). Generates images at **run time**.
+- Uses **`canvaskit-wasm`** for rendering
+- Uses plain color or gradient background. Provide title, description, and logo (displayed at top left of card).
+- Can't set size of final card.
-## @TODO: "Add to Calendar" button
+[`astro-satori`](https://www.npmjs.com/package/astro-satori)
-Google Calendar, Apple Calendar, Yahoo Calender, Microsoft 365, Outlook, and Teams, and generate iCal/ics files (for all other calendars and cases).
+- Moderately popular option (~230 weekly d/l). Generates images at **run time**.
+- Uses Vercel's **Satori** library for rendering (entirely done in JS with limitations on what CSS can be used). Satori is a library for generating SVG strings from pure HTML and CSS.
+- Size of final card can be set.
+- Seems opinionated, but it might be possible to have a lot of control (not sure).
+- Output format?
-https://github.com/add2cal/add-to-calendar-button
-https://add-to-calendar-button.com/
+[`astro-opengraph-image`](https://www.npmjs.com/package/@altano/astro-opengraph-image#fn-filename-change)
-## @TODO: Add Check HTML Links to test workflow
+- Uses **Satori**. Has dependencies on [`@resvg/resvg-wasm`](https://www.npmjs.com/package/@resvg/resvg-wasm) and Sharp. Middleware integration. Generates images at **run time**.
+- Provides element to add OG tags in document `
`.
+- Very flexible, you can provide the Astro template to generate the card.
-npm i -D check-html-links
-npx check-html-links _site
-https://github.com/modernweb-dev/rocket/tree/main/packages/check-html-links
+[Astro Open Graph Image](https://www.npmjs.com/package/astro-og-image)
-## @TODO: Provide button to turn off animation in Hero
+- Uses **Puppeteer**. Generates images at **build time**.
+- You can provide the Astro template to generate the card.
+- Requires providing a `baseHead` property in page templates.
-"Scaling/zooming animations are problematic for accessibility, as they are a common trigger for certain types of migraine. If you need to include such animations on your website, you should provide a control to allow users to turn off animations, preferably site-wide. Also, consider making use of the prefers-reduced-motion media feature — use it to write a media query that will turn off animations if the user has reduced animation specified in their system preferences. "
+[Astro Open Graph Image Generator](https://www.npmjs.com/package/@cyberkoalastudios/og-image-generator)
-## Fix offline page
+- Uses **Puppeteer**. Has dependencies on [`canvaskit-wasm`](https://www.npmjs.com/package/@resvg/resvg-wasm) and Sharp.
+- You can set the background image. No option to set the size of the card.
+- Manually add OF properties on `` element. Flexible.
-- It should look like any other page, but have interactivity like navigation and other links disabled.
-- The test cases should check for if they're on the offline page, and return passed for an inverse. Like the smoke test that makes sure navigation is available, it would return true if navigation is present but disabled in the same test case.
+## @TODO: Use Confetti on CTA forms
-## @TODO: Handle `@media (prefers-reduced-motion: reduce)`
+`canvas-confetti`
+`https://github.com/catdad/canvas-confetti`
+`https://www.kirilv.com/canvas-confetti/`
-Stop the Hero Greensocks animation when `@media (prefers-reduced-motion: reduce)`, using `window.mediaQuery()`. Handle user preference for reduced motion on animations, doing this also with a listener like for browser theme preference
+## @TODO: Use the Page Visibility API to pause videos, image carousels, and animations
-```css
-@media (prefers-reduced-motion) {
- /* styles to apply if the user's settings are set to reduced motion */
-}
-```
+Stop unnecessary processes when the user doesn't see the page or inversely to perform background actions.
-```typescript
-const mediaQueryList = window.matchMedia('(prefers-reduced-motion)') // not sure what the inverse is to match for so that there's a listener for both the prefers-reduced-motion state and the doesn't-care state
-mediaQueryList.addEventListener(event => {
- if (event.type === 'change') {}
-})
-```
+## @TODO: "Add to Calendar" button
-## @TODO: Set up webmentions
+Google Calendar, Apple Calendar, Yahoo Calender, Microsoft 365, Outlook, and Teams, and generate iCal/ics files (for all other calendars and cases).
-This code goes in `_layouts/layouts/base.njk` after the last `
-
-{%- endif -%}
-```
+## @TODO: Set up webmentions
-There's a filter roughed out for the webmentions.
+Needs to add real API key and test
## @TODO: SCSS Use clothoid corners with border-radius
-https://onotakehiko.dev/clothoid/
+`https://onotakehiko.dev/clothoid/`
`@TODO: SCSS Make sure accent-color or styling for checkboxes/radio button groups is set up. Sets the colour used by checkboxes and radio buttons, as well as range fields and progress indicators. The accent colour is inherited`
@@ -215,95 +221,10 @@ https://onotakehiko.dev/clothoid/
}
```
-## @TODO: SCSS Replace all `:focus pseudoselectors` with `:focus-visible`
-
-```css
-/* Focusing the button with a keyboard will show a dashed black line. */
-button:focus-visible {
- outline: 4px dashed black;
-}
-
-/* Focusing the button with a mouse, touch, or stylus will show a subtle drop shadow. */
-button:focus:not(:focus-visible) {
- outline: none;
- box-shadow: 1px 1px 5px rgba(1, 1, 0, .7);
-}
-```
-
## @TODO: Refactor modals
Modals should be wrapped in the `