返回首页
最新
嗨,HN,
这是我第一次在这里分享一个应用。
我和我妻子一直在互相许下小承诺(“我请你吃晚餐”,“你选下部电影”,“我来计划周末”),但总是忘记这些承诺。
我们尝试过记事和提醒功能,但效果并不好。
于是我们开发了这个小应用,作为我们之间的一个游戏,其中:
- 一方创建一个“承诺”(一个承诺/请求)
- 另一方在想要的时候兑现它
- 伴侣标记为已完成
这个应用可以帮助你记录日期、庆祝活动、想法和回忆;它是你和你妻子的一个空间(至少到目前为止是我们的空间)。
这就是核心功能。
其他功能都是可选的。
随着时间的推移,我们添加了:
- 共享日历,用于记录约会和纪念日
- 简单的连续记录和里程碑(不社交,不竞争)
- 共享愿望清单和回忆
- 延时笔记(“6个月后打开”),你的伴侣不会看到
设计约束:
- 默认私密(仅限两位用户)
- 没有动态信息,没有公开资料
- 不比较情侣之间
这个应用是免费的,提供1美元的付费层级,可以无限制地创建承诺。
这主要是我们为自己想要的生活方式工具,但我们也很好奇其他人是否有同样的问题。
最初是使用纯 JavaScript 实现的(仍然是最快的 JavaScript 图像差异工具),但我希望进一步提升性能。因此,我将核心部分重写为 Rust,使其成为最快的开源单线程图像差异工具。在 4K 图像(5600×3200)上,性能表现为约 327 毫秒,而 odiff 则为约 1215 毫秒。生成的二进制文件也小了约 3 倍(约 700KB 对比约 2MB)。
核心思路是:让冷处理更智能,从而减少热处理的工作量。冷处理不是简单的像素相等检查,而是扫描动态大小的块并标记“问题”块——可能包含差异的块。热处理则仅在这些问题块上运行 YIQ 感知差异和抗锯齿检查,完全跳过其他部分。PNG 输入输出使用 spng(C 库)通过 Rust 绑定实现。整个过程使用 SIMD 加速——在 ARM 上使用 NEON,在 x86 上使用 SSE4.1。它是 odiff 的直接替代品,具有相同的 API。
嗨,HN,我是穆罕默德,一位热爱产品交付并回馈社区的技术创始人。我正在开源支持我的B2B产品apflow.co的全栈引擎。
<p>它是什么:一个生产级的B2B启动项目,后端使用Go,前端使用Next.js。两者都完全Docker化,使用独立的容器。没有Vercel,也没有Supabase。可以在一个6美元的VPS上部署整个项目,或者将前端和后端分开部署在不同的服务商上。你拥有基础设施的控制权。
<p>我所解决的问题:
<p>我评估的每个SaaS启动项目都有一个共同的问题:它们将我锁定在其他人的平台上。Vercel用于托管,PlanetScale用于数据库,按调用计费的无服务器函数。对于原型来说没问题,但在规模扩大时成本变得不可预测,迁移也很痛苦。
<p>我想要的是一个可以在任何Linux机器上通过docker-compose up进行部署的解决方案。可以选择将前端托管在Cloudflare Pages上,后端托管在Hetzner VPS上,而不需要在代码中埋入特定于供应商的API。
<p>为什么选择Go作为后端:
<p>Go正好满足我对SaaS后端的需求:
<p>小内存占用。后端运行时大约占用50MB内存。在一个便宜的VPS上,这样的内存余量让我可以在不升级的情况下运行更多服务。
<p>并发而不复杂。计费Webhook、文件上传和AI调用可以并发运行,而不会陷入回调地狱。
<p>编译时类型安全。使用SQLC,我的SQL编译为类型安全的Go。如果查询错误,它会在构建时失败,而不是在生产中出错。
<p>可预测的性能。没有在负载下让你惊讶的垃圾回收暂停。
<p>架构(模块化单体):
<p>我不想为一个小团队引入微服务的复杂性,但我需要清晰的分离。我构建了一个模块化单体:像身份验证、计费和AI这样的功能是独立的Go模块,具有明确的接口,但它们作为一个单一的二进制文件进行部署。
<p>这种结构还使得AI编码工具(Cursor、Claude Code)变得更加高效。因为每个模块都有严格的边界,AI确切知道新代码应该放在哪里,而不会破坏其他模块。
<p>全栈,而不仅仅是后端:
<p>后端:Go 1.25 + Gin + SQLC(类型安全的SQL,无ORM)+ PostgreSQL与pgvector
<p>前端:Next.js 16 + React 19 + Tailwind + shadcn/ui
<p>通信:前端使用干净的REST API。你可以将Next.js替换为任何支持HTTP的框架。
<p>基础设施:前端和后端分别有独立的Dockerfile。可以一起部署或单独部署。
<p>预构建的内容:
<p>基础设施问题已解决,以便你可以专注于实际产品:
<p>身份验证 + RBAC:Stytch B2B集成,支持组织、团队和角色。多租户数据隔离在查询级别强制执行。
<p>计费:Polar.sh作为记录商。处理订阅、发票和全球税/VAT。没有Stripe webhook的边缘案例。
<p>AI管道:使用pgvector的OpenAI RAG。检索服务强制执行严格的上下文边界,以最小化幻觉。
<p>OCR:集成Mistral进行文档提取。
<p>文件存储:Cloudflare R2集成。
<p>每个功能都是一个独立的模块。不需要OCR?可以移除它。想用Stripe替代Polar?计费接口是抽象的。
<p>现实世界的证明:
<p>这不是我为GitHub星星制作的模板。这是运行在apflow.co生产环境中的确切代码。当我添加文档OCR时,我将其作为一个新模块构建,而没有触及身份验证或计费。架构保持稳定。
<p>如何尝试:
<p>克隆代码库,阅读setup.md以检查先决条件,运行./setup.sh,你将在几分钟内在本地拥有一个工作中的B2B环境。
<p>我希望得到的反馈:
<p>我希望从Go开发者那里获得关于模块边界和跨模块接口的反馈。同时也想知道是否有人对生产部署中的Docker设置有建议。
<p>GitHub: <a href="https://github.com/moasq/production-saas-starter" rel="nofollow">https://github.com/moasq/production-saas-starter</a>
<p>在线演示: <a href="https://apflow.co" rel="nofollow">https://apflow.co</a>