From 8c1926676054c36979ea25b491100c96a8a46c10 Mon Sep 17 00:00:00 2001 From: Jeffrey Hales Date: Fri, 6 Nov 2026 00:37:59 -0700 Subject: [PATCH] feat(blog): enable live likes and first-party views --- www/README.md | 20 ++- www/package.json | 2 + www/src/components/LikeViewCounter.astro | 12 +- www/src/layouts/BlogPostLayout.astro | 2 +- www/src/scripts/likes-views.ts | 205 +++++++++++++++++++++- www/src/utils/article-messages.ts | 2 + www/src/utils/counter-mode.ts | 6 +- www/tools/counters-browser.mjs | 132 ++++++++++++++ www/tools/counters.test.mjs | 209 +++++++++++++++++++++++ www/tools/deploy.mjs | 6 +- www/tools/phase10-artifact-verify.mjs | 32 +++- www/tools/phase10-artifact.test.mjs | 14 ++ www/tools/phase9-nonproduction.test.mjs | 19 ++- 13 files changed, 631 insertions(+), 30 deletions(-) create mode 100644 www/tools/counters-browser.mjs create mode 100644 www/tools/counters.test.mjs diff --git a/www/README.md b/www/README.md index 8277ff3..2854aff 100644 --- a/www/README.md +++ b/www/README.md @@ -83,6 +83,8 @@ The default values are: ```txt PUBLIC_AIA_API_BASE=https://api.azinstitute4autism.com +PUBLIC_COUNTERS_MODE=off +PUBLIC_COUNTERS_LIVE_APPROVED=false PUBLIC_ALLOW_INDEXING=false ``` @@ -94,6 +96,16 @@ not deploy anything or change environment files. Run `npm run build` afterward to restore staging output. Only explicitly authorized production deployments should publish indexing-enabled artifacts. +Ordinary local builds keep counters off. `npm run deploy` deliberately and +non-overridably builds the production artifact with live counters, the approved +API origin and `PUBLIC_COUNTERS_LIVE_APPROVED=true`. Article pages post one +first-party view per real navigation; Library cards only batch-read statistics. +Likes use the existing POST/DELETE API and store only the visitor's chosen slug +set in localStorage. No view cookies or visitor identifiers are created. Run +`npm run test:counters`, then build in live mode and run `npm run +verify:counters -- --browser=chromium` (or `firefox`) for a fully intercepted +browser regression that cannot write production counters. + ## View And Build ### Development Server @@ -600,16 +612,18 @@ Use `PUBLIC_AIA_FORMS_MODE=off npm run build` for an offline artifact, or `PUBLIC_AIA_FORMS_MODE=mock npm run dev` for synthetic fixtures. Missing/empty mode means live; obsolete `isolated-test` and other invalid values produce an explicit configuration error. Remove old approval/environment variables from -local settings. Indexing is independent of forms; counters remain off by default. +local settings. Indexing and form mode remain independent of counter mode. See the [current Form A guide](integrations/jotform/README.md) for the exact registry, safeguards, rollback and owner acceptance requirements. Form C remains inactive. Employee-portal private input retains its own separate gates. Verify matching output with -`node tools/phase10-artifact-verify.mjs --mode=staging --forms=live`; +`node tools/phase10-artifact-verify.mjs --mode=staging --forms=live --counters=off`; use `--mode=indexing` for indexing output and `--forms=off` or `--forms=mock` -for those explicit builds. No actual submissions run in automated tests. +for those explicit builds. Production counter artifacts require +`--counters=live`. No actual submissions or production counter writes run in +automated tests. ## Static releases and employee portal diff --git a/www/package.json b/www/package.json index 7a7b1c8..024fd79 100644 --- a/www/package.json +++ b/www/package.json @@ -27,6 +27,8 @@ "test:seo": "node --experimental-strip-types --test tools/seo.test.mjs", "test:library": "node --experimental-strip-types --test tools/library.test.mjs", "test:campaign": "node --test tools/campaign.test.mjs", + "test:counters": "node --experimental-strip-types --test tools/counters.test.mjs", + "verify:counters": "node tools/counters-browser.mjs", "verify:campaign": "node tools/campaign-browser.mjs", "generate:sitemap": "node tools/generate-sitemap.mjs", "generate:redirects": "node tools/generate-redirects.mjs" diff --git a/www/src/components/LikeViewCounter.astro b/www/src/components/LikeViewCounter.astro index 29ebe2e..f2eb5ea 100644 --- a/www/src/components/LikeViewCounter.astro +++ b/www/src/components/LikeViewCounter.astro @@ -1,8 +1,8 @@ --- import { articleMessages } from '../utils/article-messages'; import { counterModeForRuntime, resolveCounterConfig } from '../utils/counter-mode'; -interface Props { slug: string; lang: string } -const { slug, lang } = Astro.props; +interface Props { slug: string; lang: string; trackView?: boolean } +const { slug, lang, trackView = false } = Astro.props; const text = articleMessages(lang); const counterConfig = resolveCounterConfig( import.meta.env.PUBLIC_COUNTERS_MODE, @@ -15,21 +15,23 @@ const mockResult = import.meta.env.PUBLIC_COUNTERS_MOCK_RESULT === 'failed' || i : 'success'; const statusId = `counter-status-${slug.replace(/[^a-zA-Z0-9_-]/g, '-')}`; --- -
+