Cannabivo.com
Cannabivo 吉祥物站在霓虹灯照耀的大麻社交俱乐部内,手持展示 Cannabivo 应用和俱乐部目录的手机。

内部

阅读约 13 分钟

Cannabivo:构建 Cannabis Social Club 的国际基础设施

Cannabivo 是面向合法 Cannabis Social Club、荷兰咖啡馆和吸烟休闲厅的国际信息目录与新闻中心——一个可通过透明、最新且多语言的信息进行搜索、发现和连接的地方。下面是这一故事的完整版本:Cannabivo 从何而来、如今成为什么,以及它究竟是如何构建起来的。

我们在 2024 年看到的缺口

一个“更适合德国和西班牙的目录”如何演变成一个横跨十个国家、十八种语言、拥有二十五万页的生产平台——以及支撑它运转的前沿工程。

目录可以不只是名单。把它做成合法、多语言、经过核验、注重隐私且技术严谨的产品,它就不再只是名单,而会变成基础设施。

“Cannabis social clubs、咖啡馆与吸烟休闲厅——一个国际目录与新闻中心。” 这是我们的一句话承诺,而且我们是有意把它说得朴素直白。Cannabivo 不是消费倡议,不是 Cannabis 市场,也不是又一个把复制来的地址拼凑起来的薄弱列表网站。它是一个面向合法 Cannabis Social Club、荷兰咖啡馆和吸烟休闲厅的国际信息目录——其设计目标是让人们能够通过搜索 → 发现 → 连接,获取透明、最新、并且以自己语言提供的信息。

我们的目标远不止于一个目录。Cannabivo 正在成为 CSC 社区的基础设施:从设计上就是私密的、范围上是国际化的、由社区驱动的,并以 18 种语言在线运行。平台目前已覆盖 225,792 个页面211,397 个地理位置页面,以及横跨 10 个国家的 13,573 条俱乐部列表。此外,还配有一个深入的 Cannabis 维基、教育与预防页面、新闻系统、自动俱乐部更新、社区论坛,以及一个连接真实工具的 AI 支持代理。底层则运行着一套完全自主、无框架核心的架构:现代 Web 标准、持久化 PHP 工作进程、HTTP/3、我们能配置到的最严格静态分析、第一方分析,以及 web 与移动端共用的一份类型化 PHP → TypeScript → Dart 合约。

这就是那个故事的长版本:Cannabivo 从何而来,如今是什么,以及——细节层面——它是如何构建的。

德国在 2024 年初的合法化让一个原本容易被忽视的事实暴露出来:Cannabis Social Club 的在线覆盖,远远没有准备好迎接按计划到来的现实。对有经验的 Web 开发者来说,现有的大多数内容都显得半成品——碎片化、不完整、本地化糟糕、技术过时,而且太单薄,根本帮不上真正的人。

人们提出的问题其实并不难。合法俱乐部在哪里?哪些信息是最新的?新来者在联系俱乐部前需要了解什么?哪些是事实,哪些已经过时,哪些只是从别处复制过来的?太多时候,答案散落在薄弱的列表、机器翻译的碎片和那些显然从未为其声称服务的社区而建的页面里。

最初的想法很朴素:做一个更适合德国和西班牙的目录。但我们越看,模式就越清楚。CSC 社区需要的不是另一份场所清单。它需要的是一层多语言、法律上谨慎、技术上可靠的信息层——一层能够按国家扩展、同时又能在城市、地区、单个俱乐部、文章、FAQ 条目乃至语言这个粒度上保持精确。

全面的内部开发始于 2024 年夏末/秋季。Cannabivo 于 2026 年 2 月上线,从第一天起就提供全部 18 种语言,并且此后几乎每天都在改进。这个时序本身就是重点:多语言支持从来不是上线后才补上的功能,而是从第一条提交开始就被倒入地基——数据库、URL、路由、SEO 层——之中。

最初只是目录构想的项目,在 AI 辅助开发的推动下,成长为一个覆盖 阿根廷、哥伦比亚、德国、马耳他、荷兰、南非、西班牙、瑞士、泰国和乌拉圭 的国际平台。每个国家的覆盖仍在完善中,这一点我们说得很明确。但生产规模已经真实存在,而中期目标也毫无悬念:覆盖所有 Cannabis 已经合法化,或至少已去刑事化的国家,包括像瑞士这样的试点项目国家;瑞士目前已经收录。

Cannabivo 现在是什么

Cannabivo 已在生产环境中运行并持续维护。于 2026-06-13 经过验证的生产快照,描述的是一个早已走出原型阶段的平台。

一个宽阔的现代运维工作空间,多个大屏幕上显示着地图、列表和仪表盘,界面沉稳、偏深色主题。
Cannabivo 作为一个庞大而活跃的平台运行——把目录、维基、新闻编辑部和支持层整合在同一产品中。
生产指标当前数量
总页面数225,792
地理位置页面211,397
俱乐部列表13,573
专属俱乐部详情页13,573
Cannabis 维基文章106
维基分类9
FAQ 条目82
FAQ 分类11
已发布编辑文章15
自动俱乐部更新新闻条目275
注册用户1,216
论坛主题170

这些数字没有一个是虚荣指标。每一个都对应着一个产品决策。

一个大型目录需要地理页面,因为人们会按本地搜索。它需要详情页,因为每个俱乐部都值得拥有背景,而不是列表里的一行。它需要多语言 URL,因为国际用户不该总被当成事后补充。它需要持续维护,因为列表一旦没人打理就会迅速失真。它需要教育页面,因为信息质量才是核心。它还需要论坛,因为 CSC 社区不只是一个搜索问题——它也是一场对话。

一个经过核验的国际目录

目录目前列出横跨 10 个国家的 13,573 家俱乐部

一幅大型发光世界地图,墙面上密集分布着地标针,覆盖欧洲、南美、非洲和亚洲。
每一条俱乐部列表都会经过审核并地理编码到自己的页面上,因此这个目录就像一张经过核验的真实世界场景地图,覆盖十个国家。
国家俱乐部
泰国9,489
西班牙1,081
乌拉圭810
德国710
荷兰673
阿根廷495
南非243
哥伦比亚41
马耳他18
瑞士13

按国家划分的经核验俱乐部列表 (俱乐部)

按国家划分的经核验俱乐部列表按国家划分的经核验俱乐部列表 — values in 俱乐部泰国9,489西班牙1,081乌拉圭810德国710荷兰673阿根廷495南非243哥伦比亚41马耳他18瑞士13

今天,泰国占数据库份额最大,这种规模本身就是实打实的优势。西班牙、德国、荷兰、乌拉圭、阿根廷以及其他国家,都拥有不同的法律语境、不同的本地期待和不同的发现模式。一个严肃的国际目录必须同时容纳这一切复杂性,而不能让它们变成噪音。

Cannabivo 将其列表呈现为“已核验”,而核验是平台的核心承诺——不是一个我们轻易贴上的标签。在这种规模下,维持这一承诺既是系统问题,也是编辑纪律问题。我们持续保持列表准确和最新:新开业、关闭、搬迁、细节变更。目标不是把目录冻结在某个时点,而是让它随着现实世界的变化持续跟进。一个在发布当天就过时的目录,比没有目录还糟。

在这些列表周围,是一个可搜索的交互式地图、专门的俱乐部搜索,以及一个为“新鲜度”而设计的首页——最近新增的俱乐部、热门城市、各国入口,以及新闻和俱乐部更新的实时流。

维基、教育与预防——不带广告式信息

一个普通的列表网站只能告诉你东西在哪里。Cannabivo 的设计目标,是告诉你它意味着什么。

Cannabis 维基收录了106 篇文章,分属 9 个分类,内容深入涵盖植物学、历史、法律以及与消费相关的知识。它不是一份为了显得内容充实而拼凑出来的术语表;它经过研究和写作,能够独立成立。与之并列的是教育与预防页面——它们基于事实、没有广告、旨在支持理解,而不是推销某种产品。

这一点不是装饰性的。Cannabivo 是一个信息目录。我们不作医疗声明,也不鼓励消费。我们所做的是,为结构化、多语言、合法的信息建立访问通道,并且有意维护这条边界,因为整个平台的可信度正建立在这上面。维基以及教育和安全使用板块都还会继续扩展——更多文章、更多图片、更多视频。

新闻、自动更新与社区

新闻版块是新的,而且已经相当活跃。它将经过研究的编辑文章与自动俱乐部更新新闻相结合。在当前生产快照中,Cannabivo 拥有 15 篇已发布编辑文章275 条自动俱乐部更新新闻条目

这种组合是有意为之的。编辑文章提供更广泛的背景——政策变化、法律发展、文化时刻。自动俱乐部更新新闻之所以存在,是因为目录从来都不是静止的:俱乐部会开业,信息会被更正,地址会发生变化。一个活的新闻流能让人们看到这些变化,而不是把静态数据库放在那里,任其在底下悄悄变形。

此外还有一个社区论坛,而且它也在增长——目前已有 1,216 名注册用户170 个论坛主题。论坛不是后加上去的附件。CSC 文化本身就同时具有本地性、合法性、实用性和社交性。目录帮助人们找到信息;社区则帮助他们就这些信息展开讨论、互相对照笔记,并彼此学习。二者理应共处一屋。

AI 支持聊天有真实工具

Cannabivo 的支持聊天不是一个装饰性的聊天机器人,被随意贴在页面角落里。它是一个经过 Cannabivo 训练的 AI 支持代理,运行在网页和应用中,连接的是平台的真实工具,而不是任其自由发挥。

在实际使用中,这个代理可以:

1. 找到某个特定的 Cannabivo 页面,并返回真实的、规范的链接——使用用户的语言,而不是幻觉出来的 URL。 2. 搜索俱乐部,可按名称、城市、地区或距离查找,包括某个俱乐部是否此刻开放。 3. 从 FAQ 知识库中回答。 4. 在它无法帮助时开出真实的支持工单——包含分类、标题和描述——这样就能由人工接手。

区别就在这里:代理不是猜,而是在定义好的平台边界内工作,并返回确实存在的链接和俱乐部。随着 FAQ 增长,它自身也会不断变强,因为 FAQ 系统是动态维护且自我改进的——我们补上的每一个空缺,下一次都会成为代理可调用的知识。幕后,这个聊天系统通过 WebSocket 中继运行,配合 Redis pub/sub 和流式响应,模型也可按部署进行配置。

我们的理念很简单:AI 应该减轻摩擦,但不能变成黑箱。如果代理能基于 Cannabivo 自己的数据可靠回答,就应该回答。如果不能,就应该把问题交给真实的支持流程——而不是为了填补沉默而编造答案。

一个平台,十八种语言

Cannabivo 在上线首日就支持全部 18 种语言。这不是更容易的路线,但这是正确的路线。

一面整齐排列的小型相同标牌墙,每块牌子上都用不同的世界语言写着问候语,排成工整网格。
同一页面以十八种语言原生存在,每种语言都有自己干净的 URL——本地化是基础设施的一部分,而不是后加的附属功能。

网站目前运行 225,792 个页面,每一个页面都以全部 18 种语言存在。在数据库层面,这大约意味着 400 万条页面翻译行——一个基础 `pages` 表,加上 17 个按语言划分的表,并且彼此完全同步、经验证。平台还拥有 211,397 个地理位置页面——城市和地区——每一个都完整翻译成全部 18 种语言。

这不是 URL 前缀式翻译。我们不会在英文 URL 前面随便加上 `/de/`,就称之为本地化。每种语言的每一页都有自己本地化的 URL slug。例如:

  • `/news/2`
  • `/de/nachrichten/2`

这一结构配套完整的 `hreflang` 支持,以及真正适用于阿拉伯语的从右到左布局。这里的阿拉伯语不是“用阿拉伯文字显示的英文”——它获得的是符合该语言的 RTL 布局,并贯穿页面、SEO 头部和 UI。

平台在精神和结构上都是以英语为先,但绝不是只服务英语。完整的语言面覆盖英语、德语、法语、西班牙语、意大利语、波兰语、阿拉伯语、捷克语、印地语、匈牙利语、日语、韩语、葡萄牙语、葡萄牙语(巴西)、俄语、土耳其语和中文——其中阿拉伯语采用从右到左布局。

为什么这件事如此重要?因为 CSC 社区并不局限于一种语言、一个国家或一种法律模式。德国的用户、西班牙的俱乐部主理人、比较瑞士试点方案的读者、查看乌拉圭法律语境的旅行者——他们都不该被迫进入只提供英文的体验,才能得到一个直接答案。

多语言基础设施还会改变俱乐部能做什么。俱乐部负责人可以先写一段说明,若愿意再用 AI 写作助手润色,保存后只需一键就能把它翻译成全部 18 种语言。这不仅仅是便利。它还意味着国际可发现性——而这对一个小型本地俱乐部来说,原本可能根本触及不到。

翻译不是一个被放在 Cannabivo 边缘的功能。它贯穿数据库、URL、SEO 层、UI,以及俱乐部主理人的工作流程。

面向俱乐部:Club Manager 已经上线

Cannabivo 是为社区而建的,而这个社区也包括那些真正运营俱乐部的人。Club Manager 已经上线——它是会员账户中的一套完整自助编辑器,俱乐部负责人无需任何技术知识,就能管理自己的列表。

一双手正在木质桌面上的笔记本电脑前操作,屏幕显示干净的俱乐部管理仪表板,室内温暖。
俱乐部组织者通过已上线的自助仪表板管理自己的列表、营业时间和信息——没有表格,没有中间人。

它以移动端优先为原则,因为大多数俱乐部负责人不会坐在办公桌后打理公开形象。他们需要能在一分钟内修正一个细节,而且要用手边已经拿着的手机完成。

Club Manager 覆盖的是让一个列表真正有用的实用细节:

  • 说明和标语,配有一个 AI 写作助手 用于起草和润色
  • 一键翻译成全部 18 种语言
  • Logo、主视觉图,以及可重新排序的图库,并支持裁剪
  • 营业时间
  • 位置和可拖动的地图标记
  • 联系方式
  • 大约 11 个社交渠道字段
  • 会员信息
  • 一个 22 项设施选择器

每个部分都会单独保存——无需原始 JSON、无需 SEO 作业、也不要求负责人自己计算图片比例。所有权在每次保存时都由服务器端强制执行,而且平台绝不会信任客户端传来的标识符,因此一个负责人永远无法进入另一个俱乐部。

这正是 Cannabivo 的目录与其多语言架构,和俱乐部日常运营现实相遇的地方。一个好的列表不应要求雇佣网站代理商。它也不应该要求负责人理解 SEO、图片比例、翻译流水线或结构化数据。编辑器的存在,就是为了让好的展示成为默认状态,而不是技术能力的奖赏。

高级俱乐部微站点仍在待办中

这一愿景的下一层是 高级俱乐部微站点——目前仍在待办中,尚未构建。

想法很简单:每一个高级、已认领的俱乐部,都应该能够在自己独有的 Cannabivo 子域名上,认领一个经过打磨的第一方主页。

{club}.cannabivo.com

我们希望达到的标准是“默认就惊艳”:精心策划的预设、18 种语言的完整 SEO,以及与同一份列表数据直接连通的网站,而不是一个俱乐部必须手动同步的独立系统。只需更新一次信息,目录和微站点都会反映同一个事实源。

这里我们特别注意时态。Club Manager 已经上线。高级俱乐部微站点是计划中的愿景。把这条界线划清,本身就是产品的一部分,因为可信度本身就是产品的一部分。

在底层:为什么 Cannabivo 确实处于前沿

一个如此庞大的平台,不会偶然变得快速、保持多语言、保护隐私并驱动原生应用。Cannabivo 从零开始、在内部构建,采用的是对一个公共目录而言异常严格的工程决策。

开发者工作台的近景特写,深色屏幕上显示代码,旁边一小组网络硬件柔和发光。
友好表面之下,是一套手工打造、类型安全的技术栈——持久化 PHP、HTTP/3、原生应用,以及贯穿所有平台的一份类型化合约。

我们谨慎使用“前沿”这个词。它并不意味着追逐本季度最流行的库;它的意思是:在现代标准确实能解决真实产品问题的地方采用它们,然后用足够严格的质量控制,确保系统能持续扩展,而不是在内部悄悄腐烂。

从零构建,没有 Web 框架核心

Cannabivo 是一个完全内部开发的系统,没有 Web 框架核心。它底下并没有 Laravel 或 Symfony 的应用基础;Symfony 只以少数几个独立库的形式出现,而且仅在确实值得时才会使用。

这一决定让我们能完全掌控路由、渲染、缓存、本地化、合约、安全策略以及运行时行为。前期成本更高。作为回报,平台会顺着产品而弯曲,而不是让产品去迎合某个框架的默认行为和生命周期。

这种架构是一个代码库,多个产品——一个共享核心,配合按项目划分的层级,内部称为 Common/Projects 模型。这一点很重要,因为 Cannabivo 不是一套被反复复制成几千份的页面模板。它同时是目录、维基、FAQ 系统、新闻系统、支持系统、俱乐部负责人编辑器、社区界面、分析平台、自动化引擎,以及原生应用后端。共享核心在各处执行通用规则;按项目划分的层则承载产品特定行为,而不需要任何人把整个平台复制粘贴一遍。

现代运行时:持久化 PHP、HTTP/3,以及为速度而生的压缩

后端运行在 PHP 8.5.7工作进程模式的 FrankenPHP 上,这是一项真实的架构选择,而不是默认配置。传统 PHP 通常意味着按请求生命周期运行:启动应用、处理一个请求、全部销毁、再来一次。Cannabivo 则通过 Unix socket 保持持久化工作进程持续热身,因此应用不必为每一次访问都支付冷启动成本。

数据库是 MariaDB 12.3.2。前端工具链是 TypeScript 7,由 Go 原生编译器(`tsgo`)编译,并由 Vite 8 打包;系统的部分后端逻辑也会在服务器端运行 Node 和 TypeScript。

在 Web 服务器和边缘层,Cannabivo 使用 带 HTTP/3(QUIC)的 nginxTLS 1.3 与 0-RTT、动态 zstd 压缩,以及预压缩的 brotli 静态资源,并由 Cloudflare 承接公共域名。每一部分都承担着明确的职责:

  • 基于 QUIC 的 HTTP/3 降低了在现代、易丢包的移动网络上的传输摩擦。
  • TLS 1.3 与 0-RTT 在安全条件允许时减少握手成本。
  • zstd 为动态响应提供高效的在线压缩。
  • brotli(静态) 把预生成资源压到尽可能小。
  • FrankenPHP 工作进程模式 让 PHP 不会在每个请求上都像一个冷脚本一样启动。

这里没有单一的魔法技巧。这里只有一叠小小的延迟决策,而它们会相互叠加。

瞬时 SPA:Navigation API、View Transitions 与渐进增强

产品层面的问题很直接:谁会喜欢点开链接然后等待?

Cannabivo 在能改善体验的地方表现得像现代单页应用,同时仍然以服务端渲染为先。我们使用现代的 Navigation APIView Transitions API,让页面切换显得原生——连贯、动画化、即时——而不是整个文档被彻底拆掉。只要浏览器支持,浏览 Cannabivo 的感觉就像在使用应用。

但这不是一个“要么用 JavaScript,要么什么都没有”的架构。Cannabivo 建立在真正的渐进增强之上。关闭 JavaScript,或者在没有现代 API 的浏览器中打开页面,朴素的服务端渲染链接依然可用。这一点对可访问性、韧性、SEO,以及最基本的技术诚实都很重要。渲染从服务器开始;交互只是增强已经存在的内容。

对于缓存页面,Cannabivo 还更进一步:一个四种主题变体的预渲染静态 HTML 缓存(自动、深色、浅色和纯黑模式),由 nginx 直接提供,完全绕过 PHP。缓存命中时不会唤醒应用层——nginx 直接返回已经渲染好的 HTML,并将其标记为静态命中。之所以有四个变体,是因为展示并不是一种通用形态;分别预渲染它们能在不把设计系统压扁成单一折中方案的前提下保持页面速度。这些页面只在渲染时写入一次,并由一个监视文件系统的守护进程在带外压缩,因此请求路径无需为此付费。

前端性能层还包括:

  • 内联关键 CSS,并通过哈希固定进 Content Security Policy
  • 带明确尺寸的 AVIF 图像,实现零布局偏移
  • 首屏主视觉图采用高优先级立即加载;其下内容则延迟、低优先级加载
  • 悬停与触摸预取可能的下一次导航
  • Early Hints 作为加载策略的一部分

在常规路径上,Early Hints 由 Cloudflare 介入提供——这是描述大多数访问者实际如何接触到它们的诚实方式——而真正的 HTTP 103 会在动态缓存未命中的路径上发出。我们并不声称每位访问者在每条网络路径上都会收到字面意义上的 103。我们确实主张,系统围绕现代提示模型而设计,甚至在边缘注入了按页配置的 LCP 图像预加载。

值得强调的是:这里的性能并不是外包给某个 bundle 大小仪表盘。它被写进了渲染、缓存、传输、图像、CSS、预取和渐进增强之中——每一层都朝着同一个方向发力。

多语言 URL 是基础设施,不是装饰

从工程角度再提一次多语言层,是因为它是大规模系统中最难做对的事情之一。Cannabivo 的本地化不只是内容翻译。它还包括本地化 slug、同步的页面行、`hreflang` 和 RTL 布局,并把它们当作平台的第一等维度,而不是收尾装饰。

225,792 个页面 × 18 种语言 这个规模上,任何薄弱之处都不再只是美观问题,而会变成结构问题。缺失一条翻译行不是一个小错别字——它可能破坏 SEO、导航、站内链接,或者用户对整个网站的信任。这就是为什么基础 `pages` 表和 17 个按语言划分的表会保持完美、经验证的一致同步,也因此俱乐部页面、地理位置页面、维基文章、FAQ 条目和新闻都生活在同一个国际结构里,而不是挂在侧边的一个附加翻译表中。

代码质量:最高级别 PHPStan、超严格 TypeScript,以及将政策写进规则

Cannabivo 在 PHPStan Level 10——最高级别 上运行,并配合 121 条自定义静态分析规则。在前端,TypeScript 以超严格模式运行,配有 14 条自定义 lint 规则 和 9 个错误级插件。

这不是审美洁癖。它是在让整类错误从一开始就不可能发出去。

这些自定义规则就是写进代码的政策。几个真实例子:

  • `RequireRateLimitOnEveryRouteRule`——如果某条 API 路由没有声明速率限制,构建就会失败。安全姿态不依赖于某个人在审查时记住一份清单。
  • `NoRawIdInResponseDtoRule`——对外响应必须使用 UUID,绝不能使用原始整数数据库 ID,这样内部标识符就不会泄漏给客户端。
  • `NoInlineStylesRule`——内联样式会在构建时被拒绝,从而让严格的 Content Security Policy 始终可执行。
  • DTO 纪律——处理器必须接收一个类型化请求 DTO,并返回一个类型化响应 DTO;裸数组会被拒绝,这正是下面那条跨平台类型流水线得以成立的前提。

同样的理念贯穿整个代码库:生成出来的合约不能手工编辑,后端和前端的数据形状不能悄悄分叉,而所有安全敏感假设,只要机器能检查,就都会被机械化地检查。静态分析并不华丽,但它是一个快速演进的平台之所以还能保持可信的重要原因。我们几乎每日发版;严格分析正是让我们能够快速移动、而不假装“快”就一定等于“接受混乱”的原因。

一份类型化合约:1,518 个 PHP DTO → 1,518 个 TypeScript 类型 → 1,518 个 Dart 类型

Cannabivo 最强的工程决策之一,就是类型化 API 合约。

后端数据形状只定义一次,作为 PHP DTO,然后自动生成到 TypeScript 和 Dart 中。映射是一一对应的:

1,518 个 PHP DTO ↔ 1,518 个 TypeScript 类型 ↔ 1,518 个 Dart 类型

网站和原生应用使用的,是与后端相同的那份生成合约。当后端形状发生变化时,TypeScript 和 Dart 的消费者不会滑向另一套平行现实——生成文件被锁定为只读,因此没有人能手工编辑它们,而源 DTO 与生成类型之间的任何偏差,都会变成构建失败的错误,而不是用户在运行时才发现的意外。

这一点很重要,因为 Cannabivo 不只是一个网站。原生应用正在并行开发,而 web 与移动端共享 API 形状,避开了一个经典故障模式:后端演进了,web 团队修补了它的一种解释,移动应用保留了另一种,最后 bug 在接缝处悄悄堆积。我们有意选择更严格的模型——只定义一次事实源,从它生成平台合约,把偏差变成构建时问题,而不是面向用户的问题。

隐私优先的分析:没有 Google Analytics,没有第三方跟踪器

Cannabivo 不使用 Google Analytics,也不使用任何第三方跟踪器。作为替代,我们构建了一套完全自定义的第一方分析系统——包括真实用户 Core Web Vitals——并配有自己的摄取流水线,以及数十张专门设计的数据表,用于原始事件、按小时和按日汇总,以及经机器人过滤后仅保留人类访问视图。访客数据不会离开 Cannabivo 去往那些科技巨头。

这既是隐私决定,也是产品决定。我们仍然需要知道页面在真实场景中是否真的快,而不只是测试台上看起来快。我们只是选择自己来测量,而不是把访客行为喂给别人的监控机器。一个面向合法 CSC 信息的目录,理应认真对待隐私;任何人都不应该为了基本功能而牺牲自己的浏览上下文。

银行级安全:可测量、可执行

Cannabivo 运行的是一套银行级、多层安全架构:

  • Content Security Policy,除非逐一按哈希白名单,否则不允许内联脚本或样式
  • Trusted Types,以中和整类 DOM 注入
  • 多级速率限制,按 IP 和按用户分别控制——并且构建规则要求:任何没有速率限制的路由都会编译失败
  • 敏感内部端点的 HMAC 请求签名
  • 认证后、会改变状态的请求上的 CSRF 保护
  • HSTS preload
  • AI 辅助安全测试

平台在 Mozilla Observatory 上得分为 A+——135/100 分。这是已确认的结果,也是极少数网站才能达到的等级。

Content Security Policy 值得更细看。很多网站会宣传自己有 CSP,但底下仍然允许宽泛的内联执行。Cannabivo 的姿态更严格:内联脚本和样式根本不被广泛允许——每一项都必须经过哈希白名单——再加上 Trusted Types,就让浏览器侧注入的整类攻击更难实施。速率限制也采用同样的处理:它不是可有可无的中间件,而是构建环节若没有它就拒绝发布的架构。贯穿其中的想法始终如一——把安全假设编码进系统本身,这样它就不会被悄悄遗忘。

端到端加密的直接消息

Cannabivo 包含端到端加密的直接消息,采用零知识服务器设计:服务器只存储公钥和不可读的密文,从不存储消息内容。

这种加密达到 Signal 级别,支持多设备,并基于 libsodium。已验证的原语集合包括:

  • X25519 密钥交换
  • XChaCha20-Poly1305 认证加密
  • Ed25519 签名
  • BLAKE2b 密钥派生
  • BIP-39 助记词密钥备份
  • 用于群聊的 Sender Key 方案

多设备模型才是其中最有意思的部分。一条消息先用每条消息专用的内容密钥加密一次;然后通过临时密钥交换,为接收者的每台设备分别包裹该密钥并分发——这样,同一条消息就可以抵达手机、平板和网页端,而服务器从不接触明文。实现方式在各个平台间是共享的:在网页端,所有加密、密钥存储和套接字工作都通过 Web Worker 在主线程之外运行,密钥保存在 IndexedDB 中;在原生应用中,同样的原语通过 sodium FFI 绑定运行,密钥则存于安全的设备存储中。

我们对术语非常谨慎。这是 Signal 级别、基于 libsodium 的多设备 E2E 加密。我们把它称为“Signal Protocol”,也不声称实现了 Double Ratchet 或每条消息的前向保密。它的强度仍然相当可观:服务器无法读取消息,而且在所有客户端上的加密模型是相同的。对于一个 CSC 社区平台来说,私密通信不是装饰性功能——如果消息功能存在,它从第一行代码开始就必须建立在严肃的隐私边界之上。

原生应用:Flutter、离线优先、高刷新纪律

原生应用基于 Flutter 构建——三个应用共享一个通用核心——建立在离线优先的本地数据库之上,并使用与网站相同的类型化生成合约。状态管理和本地存储的设计,面向的是响应迅速、可离线运行的体验,而不是披在 WebView 上的一层薄壳。

性能纪律非常严格,并通过自定义 lint 规则执行:目标是高刷新、120fps 行为,lint 会禁止那些已知会造成卡顿的模式——不受限制的图像解码、代价高昂的模糊效果、非 builder 的列表渲染——这样规则就能在人工察觉之前先捕获回归。这一点很重要,因为移动性能不只是平均加载时间。它还包括触控响应、动画稳定性、列表流畅度,以及应用在一个人整天随身携带的设备上是否让人觉得可靠。

应用愿景很务实:你身边最好的俱乐部,很快只需点一下按钮就能打开,永远在你的口袋里。Android 应用先行,iOS 随后跟进。

自动化:内容、翻译、更新、媒体与站点地图

Cannabivo 包含一个可由运营者启用的自主内容引擎。这个措辞是有实际意义的:这不是在声称一个机器人会不加审核、全天候自动发布。它是一套运营者可以开启,也可以关闭的系统。

在启用后,这个引擎可以从多个来源研究 Cannabis 新闻,依据自身的故事记忆去重,避免同一事件被报道两次,生成结构化文章,在发布前把它翻译成另外 17 种语言——而且是原子化完成,因此半翻译状态的文章永远不会上线——并把它分发到 16 个社交和广播渠道:Telegram、X、Bluesky、Mastodon、LinkedIn、Reddit、Discord、Matrix、Facebook、Instagram、Threads、WhatsApp、Web Push、新闻简报、通用 webhook,以及一个浏览器自动化渠道。公开命名的首轮上线从 Telegram、Instagram 和 X 开始,后续还会继续。

自动化层还在运行那些看起来不起眼、却维持一个大型多语言目录活力的机器:

  • 自动俱乐部更新新闻
  • 图片和视频优化工作流(响应式 AVIF/WebP/JPEG 分层;自适应视频)
  • 每夜多语言站点地图重建
  • 一组由 systemd 定时器驱动的计划任务,而不是脆弱的 cron 作业

这就是一个拥有几十万页面的平台如何保持更新的方式。内容需要结构。翻译需要顺序。站点地图必须反映多语言现实,而不是英语现实。俱乐部更新必须在编辑逐条审核每个小变动之前就浮现出来。自动化在这里并不取代判断——它只是清掉重复性的摩擦,让人能够把精力留给那些真正需要人的部分。

我们现在所处的位置

Cannabivo 的 web 平台已投入生产并持续维护。当前阶段同时沿着两条轨道推进。

第一条是稳定、微调和验证:更新现有俱乐部内容、修正细节,并持续收紧平台。一个拥有 13,573 条俱乐部列表211,397 个地理页面、且我们一直在保持其准确和最新的目录,绝不能被当作“已经完成”。信息会变化,本地细节会变化,平台必须跟上。

第二条是并行开发原生移动端——同样的 Flutter 核心、离线优先、同样的类型化合约、同样的性能纪律。目标既简单又雄心勃勃:你身边最好的俱乐部,很快只需点一下按钮就能打开,永远在你的口袋里。

与此同时,我们正在通过社交媒体渠道和 Cannabivo 新闻简报推出自动化俱乐部信息。首页已经展示出平台的生命力——最近新增的俱乐部、热门城市、国家入口,以及新闻和俱乐部更新流。

全部 10 个国家仍处于持续完善中。这不是需要道歉的弱点;这是诚实的范围管理。国际覆盖不是一个可以钉在静态数据库上的徽章。它是一项运营承诺,而且必须每天都重新兑现。

下一步是什么

Cannabivo 的路线图是分阶段推进的,我们始终把已经上线、计划中和仍在讨论中的内容划清界限。

一部现代智能手机被举起,屏幕显示 Cannabis 俱乐部目录应用,背景是明亮窗景和柔和虚化的城市天际线。
接下来是原生应用和会员工具——先上线 Android,然后是 iOS,随后是面向更广泛生态的管理与市场。
时间范围路线图
1–2 个月Android 应用上架 Play Store;更多社交渠道,包括 Telegram、Instagram、X 等更多平台
2–3 个月iOS 应用上架 App Store
3–12 个月及以后为每个俱乐部提供俱乐部与会员管理;以及面向设备、种植空间和相关需求的市场
待办中位于 `{club}.cannabivo.com` 的高级俱乐部微站点,配有精心策划的预设和 18 种语言的 SEO
讨论中通过应用快速俱乐部签到的 Cannabivo-ID
讨论中变现模式

先 Android,后 iOS

Android 应用计划在 1–2 个月内上架 Play Store,iOS 应用则会在 2–3 个月内上架 App Store。二者都属于同一技术策略:共享一个核心的 Flutter 应用、离线优先的本地数据库、高刷新性能纪律,以及与网站相同的生成型类型化合约。由于它们共享那份合约,应用继承的是后端的正确性,而不是重新实现它——而重实现,正是大多数跨平台 bug 的诞生之地。

俱乐部与会员管理

在 3–12 个月及更长的时间范围内,Cannabivo 的目标是为每个俱乐部提供俱乐部与会员管理——把已经上线的 Club Manager 从公共列表编辑延伸到更深入的运营工具。其目的,是去回应俱乐部本来就要面对的行政现实,而不是让每个俱乐部都从零重新发明自己的软件。

市场愿景

一个市场也被放在 3–12 个月的时间范围内,目标是服务于设备、种植空间以及 CSC 运营所需的相关需求。为了准确说明这是什么、又不是什么:这不是 Cannabis 销售声明,也不是消费号召。它是一个面向平台方向的规划,关注的是生态系统运转所依赖的基础设施与供给。

Cannabivo-ID 正在积极评估中

Cannabivo-ID 仍在讨论中:这是一种数字身份,或许可以让会员通过应用快速签到俱乐部——俱乐部更少 bureaucracy,会员到场更顺畅。我们认为它在技术上和法律上都可行,并且正在积极评估中。它尚未上线,我们也会保持这一界线清晰。

变现仍未定案

变现仍然是一个开放问题。摆在桌面上的可能性包括限制免费俱乐部浏览、付费会员、广告、与 vape 或 CSC 设备商店合作,以及让俱乐部用 Cannabivo 来管理其会员。我们现在还不会给出最终模式。无论最后定成什么,都必须忠实于平台的角色:一个透明、合法、多语言、并且真正对 CSC 社区有用的国际信息目录。

Cannabivo 的目标,是成为 CSC 社区从未拥有过的国际基础设施——透明、合法、多语言,并且经久耐用。 目录是前门。其余一切则是门后的建筑:维基、教育与预防页面、新闻系统、FAQ、论坛、Club Manager、AI 支持代理、原生应用、加密消息、自动化引擎、类型化合约、第一方分析,以及安全架构。它们没有一样是孤立存在的;它们共同存在,只为让合法 Cannabis 信息更容易被找到,也更不容易出错。 我们从德国和西班牙的一个显而易见的缺口开始。如今,我们正以生产级规模、在一个设计为持续扩展的工程基础之上,横跨十个国家、以十八种语言推进建设。这里没有任何东西是完成的——而我们宁愿把这一点坦白告诉你,也不愿假装一个目录会有真正“做完”的那一天。 最容易说出口的雄心是这一句:成为世界上同类中最好的门户。 挑战接受。敬请关注。

Install · one tap

Cannabivo.com
Clubs, coffeeshops & news — on your home screen.
Instant load
Saved offline
News alerts
Adds to your home screen — no store needed
Tap Share, then Add to Home Screen to install Cannabivo.
or get the native app
Google PlayApp StoreSoon