feat: track Memind product analytics

This commit is contained in:
john
2026-07-20 20:19:52 +08:00
parent 91026882cb
commit 175095cbf3
8 changed files with 386 additions and 10 deletions
+14 -2
View File
@@ -9,8 +9,10 @@ local Umami service at `http://127.0.0.1:3100`; it does not contact 103/105.
curl --fail http://127.0.0.1:3100/api/heartbeat
```
2. Create one Umami Website for the local generated-page host. Do not create a
Website per page or per user.
2. Create two Umami Websites: one for generated pages and one for the Memind
product shell. Keeping them separate prevents chat, MindSpace, and feedback
navigation from inflating generated-page views. Do not create a Website per
page or per user.
3. Put the Website ID and a local-only pseudonymization secret in Memind's
`.env`:
@@ -21,6 +23,8 @@ local Umami service at `http://127.0.0.1:3100`; it does not contact 103/105.
MEMIND_ANALYTICS_WEBSITE_ID=<website-id>
MEMIND_ANALYTICS_ID_SECRET=<random-local-secret>
MEMIND_ANALYTICS_DOMAINS=127.0.0.1,localhost
MEMIND_PRODUCT_ANALYTICS_ENABLED=true
MEMIND_PRODUCT_ANALYTICS_WEBSITE_ID=<product-website-id>
```
4. Restart the local Memind server. Full generated HTML pages will receive a
@@ -31,6 +35,14 @@ local Umami service at `http://127.0.0.1:3100`; it does not contact 103/105.
operational analytics. Click, form, scroll, and engagement events retain the
pseudonymous `owner_id`, `page_id`, and `channel` dimensions.
5. The product shell loads its tracker from the same-origin
`/analytics/script.js` endpoint. It records one standard page view per SPA
route transition, `product_click` for links/buttons, and 10/30-second route
engagement events. Query strings are restricted to a small allowlist and
click labels never copy arbitrary chat or generated-page text. Authenticated
product events use the same pseudonymous identity as generated pages, while
remaining in the separate product Website.
The integration is fail-open: missing configuration, disabled analytics, or a
down Umami service leaves page generation and page delivery unchanged. User
facing analytics must be queried through a future Memind API that filters by