500+ коммитов за пять месяцев: как я в одиночку запустил RetroPoint
500+ Commits in Five Months: How I Launched RetroPoint Solo
500+ коммитов за пять месяцев: как я в одиночку запустил RetroPoint
On April 5, 2026, I began testing a hypothesis: is it possible to build a functional SaaS MVP in one month using a $20 Cursor subscription, working three to four hours, four evenings a week? A month later, the MVP was ready. On September 2, I rolled out release 2026.09.2. Between those dates, there were over 500 commits, 61 development phases, and seven modules in production. In this article, I’ll cover why I had to build my own tool, how the stack is structured, how splitting tasks between AI models enabled such speed, and what didn’t work as planned.
2026年4月5日,我开始验证一个假设:是否可以在一个月内,利用每月20美元的Cursor订阅,通过每周四个晚上、每晚三到四小时的工作,构建出一个可用的SaaS MVP?一个月后,MVP完成了。9月2日,我发布了2026.09.2版本。在这两个日期之间,包含了超过500次提交、61个开发阶段以及7个上线模块。接下来,我将按顺序说明:为什么我必须自己开发工具、技术栈是如何构建的、模型间的工作分配如何带来如此高的效率,以及哪些设想最终没能实现。
I should clarify two things right away. I am the one making RetroPoint, so read this as a story from an interested party. And while there is indeed only one developer, I didn’t start from scratch. I commissioned the RetroPoint design from a designer named Natalia on December 10, 2022. She only worked on the retrospective module, but that was enough to establish the product’s visual language. I never quite found the time for full-scale development. I returned to the shelved idea in the spring of 2026, when the development of AI models and agents made such a solo launch realistic. With the help of Claude Design and modern AI models, I continued the original system without further designer involvement and ported it to the remaining modules.
首先说明两点。RetroPoint是我开发的,所以请将其视为当事人的自述。虽然确实只有一名开发者,但我并非从零开始。2022年12月10日,我委托设计师Natalia完成了RetroPoint的设计。她当时只完成了回顾(Retrospective)模块,但这足以确立产品的视觉语言。由于一直没时间进行全面开发,我将这个想法搁置了。直到2026年春天,随着AI模型和智能体的发展,这种单人启动项目变得切实可行,我才重新拾起这个想法。在Claude Design和现代AI模型的帮助下,我延续了最初的系统,并在没有设计师进一步参与的情况下,将其扩展到了其余模块。
Why I had to build my own
I have been in development for 17 years, 12 of which I have spent managing teams ranging from three to thirty people. For retrospectives, task estimation, goals, and one-on-one meetings, there were always tools available, but they didn’t fit into a unified workflow. Context was scattered across services, spreadsheets, calendars, chats, and personal notes, and I had to link it all manually. Then, the usual set of work services became less predictable. Payment and access terms changed, bringing the risk of losing years of meeting history. I didn’t want to build team processes around tools whose availability I couldn’t control. Russian services are still around and working, but when I looked for replacements as a team lead, the available products covered individual processes well but failed to connect their results into a single work cycle.
为什么我必须自己开发
我从事开发工作已有17年,其中12年担任管理职务,团队规模从3人到30人不等。在回顾、任务评估、目标设定和一对一会议方面,虽然都有现成的工具,但它们无法整合进统一的工作节奏中。上下文分散在各种服务、表格、日历、聊天记录和个人笔记中,我不得不手动进行关联。后来,常用的工作服务变得不再那么稳定。支付和访问条款的变更,带来了丢失多年会议记录的风险。我不想再围绕无法掌控可用性的工具来构建团队流程。虽然俄罗斯本土服务依然可用,但当我作为团队负责人寻找替代方案时,现有的产品虽然能很好地覆盖单一流程,却无法将结果串联成一个完整的工作闭环。
What was missing
A good retrospective ends with agreements. That’s the whole point of the meeting. But after decisions are recorded, work in these tools usually ends. In the teams I managed, the process usually broke down in three places:
- Context fragmentation: Goals live in a spreadsheet, meetings in a calendar, agreements in chat, and personal notes are separate from everything else.
- Lost agreements: Recording a decision isn’t enough. You need to understand which goal it leads to, who is responsible, how important it is, and the deadline.
- Manual workflow stitching: Before every meeting, the team lead has to re-gather facts and move action items between services. I didn’t need a board; I needed a “meeting-decision-action with owner and deadline” link so that the next cycle starts where the last one ended.
我缺少什么
一场好的回顾会议应以达成共识告终,这正是会议的目的所在。但一旦决策记录完毕,这些工具的工作也就结束了。在我管理的团队中,流程通常在三个环节断裂:
- 上下文碎片化: 目标在表格里,会议在日历里,共识在聊天记录里,而领导的个人笔记又与这一切完全隔离。
- 共识丢失: 仅仅记录决策是不够的。你需要明确它指向哪个目标、谁负责、重要性如何以及截止日期。
- 手动串联工作流: 在每次会议前,团队负责人必须重新收集事实,并在不同服务间迁移待办事项。我需要的不是一个看板,而是一个“会议-决策-带负责人和截止日期的行动”的关联机制,这样下一个周期就能从上一个周期结束的地方开始。
What I achieved
Currently, there are seven independent modules in production: retrospectives with 19 ready-made techniques, Planning Poker, OKR, 1-on-1 meetings, Performance Review, work meetings, and an absence calendar with birthdays. What I did and don’t regret:
- Modules connect one by one. An unused module doesn’t appear in the menu, so the workspace isn’t cluttered with buttons no one uses.
- Participants join a public board via a link without registration or mandatory names. An account is only needed for the organizer.
- An agreement turns into an action with an owner, deadline, and a link to the original meeting.
- The AI assistant collects topics, prepares summaries, and suggests next steps, but applies nothing without human confirmation.
- Data is stored in Russia, payments are in rubles, and on July 27, the product was included in the registry of personal data operators. For some Russian teams, this is an entry requirement for new services.
成果如何
目前,生产环境中已有7个独立模块:包含19种现成技巧的回顾、规划扑克(Planning Poker)、OKR、一对一会议、绩效评估、工作会议以及带有生日提醒的请假日历。 我所做且不后悔的决定:
- 模块按需连接。未启用的模块不会出现在菜单中,因此工作区不会被没人使用的按钮堆满。
- 参与者通过链接即可进入公共看板,无需注册,也无需强制填写姓名。只有组织者需要账号。
- 共识会转化为带有负责人、截止日期和原始会议链接的行动项。
- AI助手负责收集主题、准备摘要并建议后续步骤,但在未经人工确认前不会执行任何操作。
- 数据存储在俄罗斯,使用卢布支付。7月27日,该产品被列入个人数据运营商名录。对于部分俄罗斯团队而言,这是引入新服务的准入门槛。
How it’s built
The backend runs on Python 3.12 and FastAPI, with data in PostgreSQL 16 via SQLAlchemy 2.0 and Alembic. The layers are standard: api, service, repository, and adapters. The board updates for all participants via SSE, PDFs are generated by reportlab, and files go to S3-compatible storage. The frontend is React 18 with TypeScript, built on Vite. Drag-and-drop uses dnd-kit, text fields use TipTap, and charts use ECharts. The infrastructure is simple: Docker Compose, GitLab CI, VDS on Ubuntu, and nginx.
技术架构
后端运行在Python 3.12和FastAPI上,数据通过SQLAlchemy 2.0和Alembic存储在PostgreSQL 16中。分层结构很标准:api、service、repository和adapters。看板通过SSE(服务器推送事件)实时更新,PDF由reportlab生成,文件存储在兼容S3的存储中。前端使用React 18和TypeScript,基于Vite构建。拖拽功能使用dnd-kit,文本框使用TipTap,图表使用ECharts。基础设施很简单:Docker Compose、GitLab CI、Ubuntu上的VDS以及nginx。
I spent the most time on SEO for the SPA. The public part of the site lives on the same React router, and by default, a search bot gets an empty <div id="root">. The solution is unfashionable but works. During the build, I create a second, server-side bundle via vite build --ssr, run all public routes through it, and place the generated HTML next to the static files. The sitemap.xml is generated from the same data as the pages themselves, so the sitemap never diverges from reality. The build fails if a page has an empty <title>, missing description, or suspiciously little HTML inside #root. There is another file in public, llms.txt. It contains a map of the public part of the site with clear boundaries for AI agents: where to look for current pricing and why this file is not an API. It is important to me that a bot asked about retrospective services reads the current terms, not a summary of a two-year-old article. Checking such a file by eye is pointless, so it has a contract test. If prices or module composition change in the code and llms.txt isn’t updated, the test turns red.
我花在SPA(单页应用)SEO上的时间最多。网站的公共部分运行在同一个React路由上,默认情况下,搜索引擎爬虫只会抓取到一个空的 <div id="root">。这个解决方案虽然不时髦,但很有效。在构建过程中,我通过 vite build --ssr 生成第二个服务端包,遍历所有公共路由,并将生成的HTML放置在静态文件旁边。sitemap.xml 是从与页面相同的数据源生成的,因此网站地图永远不会与实际内容脱节。如果页面缺少 <title>、描述,或者 #root 内部的HTML内容过少,构建就会失败。在 public 目录下还有一个 llms.txt 文件。它包含了网站公共部分的地图,并为AI智能体划定了明确边界:去哪里查看当前定价,以及为什么这个文件不是API。对我来说,当机器人被问及回顾服务时,读取的是当前条款,而不是两年前文章的摘要,这一点至关重要。人工检查这种文件毫无意义,所以我为它编写了契约测试。如果代码中的价格或模块构成发生了变化而 llms.txt 未更新,测试就会报错。
How one person handles 61 phases
I wouldn’t have managed this volume alone without AI agents, but the “just ask to write code” approach doesn’t work at all. In my scheme, a strong model makes decisions, and a more accessible one executes them. Claude Opus inside Cursor removed uncertainty: it chose the product and architectural solution, then turned it into a detailed technical specification with acceptance criteria. Implementation based on the ready-made contract was handled by more accessible models. The main saving wasn’t in the cost of requests, but in the fact that the decision was made once. More accessible models received a ready-made spec and didn’t waste time re-choosing the approach. When a spec can be handed to an executor… yes, along the way, I invented my own bicycle — but that’s a story for another time.
一个人如何应对61个开发阶段
如果没有AI智能体,我不可能独自完成如此大的工作量,但“直接让AI写代码”的方法根本行不通。在我的方案中,由强大的模型负责决策,由更轻量的模型负责执行。Cursor中的Claude Opus消除了不确定性:它负责选择产品和架构方案,然后将其转化为带有验收标准的详细技术规格书。基于现成契约的实现工作则由更轻量的模型完成。主要的节省不在于请求成本,而在于决策只需做一次。轻量模型接收到现成的规格书,无需浪费时间重新选择方案。当规格书可以直接交给执行者时……没错,在开发过程中,我发明了自己的“自行车”(指自创的流程/工具)——但这又是另一个故事了。