feat(analytics): retire Rybbit and add SEO/GEO discovery tracking

Document Umami as the sole analytics platform, remove Rybbit proxy and
tracker code, and classify public page traffic with discovery_channel for
adm SEO/GEO dashboards.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-12 01:34:05 +08:00
parent c58a23d155
commit c122bd5664
26 changed files with 466 additions and 449 deletions
+37
View File
@@ -0,0 +1,37 @@
# Memind 访问统计平台说明
## 当前唯一平台:Umami
Memind 公开页与生成页的真实用户访问统计 **仅使用 Umami**`memind-analytics` 独立部署,生产入口 `fxi.tkmind.cn`)。
- Portal 通过同源 `/analytics/*` 代理 Umami tracker
- 管理后台(memind_adm)通过 SSO 进入 Umami,并提供 **SEO / GEO 发现流量** 专用看板
- 生成页事件维度见 `mindspace-analytics.mjs`(含 `discovery_channel` / `discovery_source`
本地配置见 [local-analytics.md](local-analytics.md)。
## 已退役:Rybbit
**Rybbit 已于 2026-08 下线,不再部署、不再注入 tracker、不再提供 SSO。**
历史背景:Rybbit 曾作为 Umami 并行的行为分析方案(`/rybbit/*` 代理、`MEMIND_RYBBIT_*` 环境变量、memind_adm Rybbit SSO)。该方案已废弃。
**禁止**在新代码、文档、环境变量示例或运维脚本中重新引入 Rybbit 相关配置。若看到遗留引用,应删除而非「可选保留」。
## SEO / GEO 流量口径
| 字段 | 含义 |
|------|------|
| `discovery_channel` | `seo`(搜索引擎)/ `geo`(生成式引擎)/ `direct` / `referral` |
| `discovery_source` | 具体来源,如 `google``baidu``chatgpt``perplexity` |
| `referrer_host` | 外部 referrer 域名(不含路径) |
分类逻辑见 `mindspace-analytics-discovery.mjs`。Shell + iframe 场景会通过 `memind_discovery` 查询参数向内层传播来源。
## 相关仓库
| 仓库 | 职责 |
|------|------|
| **Memind** | tracker 注入、discovery 分类、Umami 代理 |
| **memind-analytics** | Umami 定制部署、`memind-pages` APIoverlay 在 `deploy/umami/overlay/` |
| **memind_adm** | Analytics 配置、SEO/GEO 看板、Umami SSO |
+3 -1
View File
@@ -17,6 +17,8 @@
**状态:禁止再次引用。改动已提交并进入 `origin/main`,该分支保留仅用于只读追溯,不是待合并开发分支。**
> **2026-08 补充**:该分支引入的 Rybbit tracking 已于 2026-08 全量下线并自代码库移除;当前访问统计 **仅 Umami**,见 [analytics-platform.md](analytics-platform.md)。勿再从本分支恢复 Rybbit 相关实现。
审计日期:2026-07-27
分支 HEAD`90ee4c3`
`origin/main` 对应提交:`90ee4c3`
@@ -40,7 +42,7 @@
本分支闭环前已通过:
- `node --test mindspace-rybbit.test.mjs server/portal-domain-services-bootstrap.test.mjs server/portal-published-page-delivery.test.mjs server/portal-publication-shell.test.mjs`
- `node --test mindspace-analytics.test.mjs mindspace-analytics-discovery.test.mjs server/portal-domain-services-bootstrap.test.mjs server/portal-published-page-delivery.test.mjs server/portal-publication-shell.test.mjs`(历史验证含 `mindspace-rybbit.test.mjs`Rybbit 已移除)
- `npm run verify:chat-finish-sync`
- `npm run verify:mindspace-publish-guards`
- `npm run verify:mindspace-publish-guards:full`
+15 -56
View File
@@ -1,79 +1,38 @@
# Local Memind analytics (Umami + Rybbit)
# Local Memind analytics (Umami)
## Umami (optional)
> **Rybbit 已退役**,见 [analytics-platform.md](analytics-platform.md)。下文仅描述 Umami。
Memind can still proxy `/analytics/*` to a local Umami service at
`http://127.0.0.1:3100`.
Memind 通过同源 `/analytics/*` 代理本地或远程 Umami 服务(默认 `http://127.0.0.1:3100`)。
```dotenv
MEMIND_ANALYTICS_ENABLED=true
MEMIND_ANALYTICS_URL=http://127.0.0.1:3100
MEMIND_ANALYTICS_WEBSITE_ID=<website-id>
MEMIND_ANALYTICS_ID_SECRET=<random-local-secret>
MEMIND_ANALYTICS_IDENTITY_MODE=raw
MEMIND_ANALYTICS_IDENTITY_MODE=pseudonymous
MEMIND_ANALYTICS_DOMAINS=127.0.0.1,localhost
```
`MEMIND_ANALYTICS_IDENTITY_MODE=raw` sends the stable Memind user ID to an
explicitly approved first-party analytics service. Omit it elsewhere to keep the
pseudonymous default.
`MEMIND_ANALYTICS_IDENTITY_MODE=raw` 仅在明确批准的第一方分析环境中使用;其他环境保持 pseudonymous 默认。
Create a second Umami Website for the Memind product shell. Keeping it separate
prevents chat, MindSpace, and feedback navigation from inflating generated-page
views. Do not create a Website per page or per user.
## Product shell(独立 Website
为 Memind 产品壳(H5 SPA)创建第二个 Umami Website,避免聊天与导航事件污染生成页 PV:
```dotenv
MEMIND_PRODUCT_ANALYTICS_ENABLED=true
MEMIND_PRODUCT_ANALYTICS_WEBSITE_ID=<product-website-id>
```
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 configured identity as generated pages while remaining in the separate
product Website.
产品壳 tracker 同样走 `/analytics/script.js`,记录 SPA 路由 PV、`product_click` 与 10/30 秒参与事件。
## Rybbit (recommended for behavior analytics)
## SEO / GEO 发现流量
Rybbit runs on 105 as `https://rybbit.tkmind.cn`. Local Memind does not talk to
103 for analytics. It proxies same-origin `/rybbit/*` to Rybbit `/api/*` so the
browser script stays first-party:
公开页 Umami 事件附带 `discovery_channel``seo` / `geo` / `direct` / `referral`)与 `discovery_source`。memind_adm **Analytics → SEO / GEO 流量** 看板按页展示 SEO 与 GEO 来源的浏览明细(口径与 Umami「生成页明细」一致)。
```text
Generated Page
-> /rybbit/script.js -> https://rybbit.tkmind.cn/api/script.js
-> /rybbit/track -> https://rybbit.tkmind.cn/api/track
```
## 管理后台
1. In Rybbit, create one Site for the local host you use (`127.0.0.1` or
`localhost`). Do not create a Site per page or per user.
2. Put the numeric Site ID and a local pseudonymization secret in Memind `.env`:
- **memind_adm → Analytics 配置**Umami Website ID、密钥、SSO 入口
- **memind_adm → SEO / GEO 流量**:按页监控搜索引擎 / 生成式引擎来源访问
```dotenv
MEMIND_RYBBIT_ENABLED=true
MEMIND_RYBBIT_URL=https://rybbit.tkmind.cn
MEMIND_RYBBIT_SITE_ID=2
MEMIND_RYBBIT_ID_SECRET=<random-local-secret>
```
If `MEMIND_RYBBIT_ID_SECRET` is omitted, Portal bootstrap reuses the
MindSpace analytics secret stored in `mindspace_config` (the same value
configured below in memind_adm → Analytics 配置).
3. Restart the local Memind server. Full generated HTML pages receive a
same-origin `/rybbit/script.js` tracker. Publication routes under
`/u/:owner/pages/:slug` and `/MindSpace/:user/public/...` both receive
the tracker. The tracker identifies the visitor
with a stable pseudonymous owner ID, then records engagement events such as
`page_click`, scroll depth, and dwell time. Initial pageviews come from
Rybbit's site setting `trackInitialPageView`.
4. Open Rybbit from local `memind_adm` → Analytics 配置 →「打开 Rybbit 分析后台」
(SSO). That path requires matching `MEMIND_RYBBIT_SSO_SECRET` /
`RYBBIT_SSO_EMAIL` with the 105 Rybbit deployment.
Both integrations are fail-open: missing configuration or a down analytics
service leaves page generation and page delivery unchanged. Do not expose the
Rybbit or Umami dashboards directly to end users.
Analytics 服务 fail-open:未配置或 Umami 不可用时,页面生成与交付不受影响。勿向终端用户暴露 Umami 控制台。