Skip to content

在公司内部落地了我的第一个全栈项目,收获满满 #85

@coderPerseus

Description

@coderPerseus

大家好,我是 luckySnail ,上上周结束的时候,我的 leader 告诉我:下周把一个简单的前后端项目交给我来开发,我当时听到非常开心,虽然我自己有从 1 到 1 开发过前后端完整项目:SVG 秀,但是是这是个人的实验项目,相比较真实的企业环境下,真实的业务需求,还是有很大区别的。经过一周的时间,我在上周周四的晚上成功部署上线了第一版,周五进行了优化。目前服务稳定运行,想记录分享一下这次开发的过程和我的收获,希望对你有所帮助!

接手需求

leader 在交给我任务的时候,就把需求文档给我了!大致看了一下是一个简单的用户权限管理 + 问卷收集 + 标签使用管理的系统,可以说是最常见的管理系统,确认了业务流程后,我简单梳理了一下需求,方便我更快更好的开发

客户:

  • 通过运营分享的链接,填写问卷

运营:

  • 创建表单收集链接(携带自己的用户 id)
  • 将客户填写的问卷完成,然后将状态扭转到财务
  • 可以给问卷打标签

财务

  • 根据问卷进行确认信息进行驳回(返回给运营),或者打款(完成)

管理员

  • 可以查看这些所有信息
  • 可以管理问卷,标签,用户

leader 说了,这个服务要集成在现有系统中,希望可以快速上线,目前现有的系统是前后端分离的,这个项目的前端是我来负责的,我可以很快接入。但是目前的后端是 fastify 并且已经是有复杂度的项目,我突然开发肯定是来不及了,因为熟悉项目规范什么都需要时间,刚好我的后端服务和当前项目后端的服务本身就可以分离,于是我心里已经想好了后端不会在当前后端服务里集成

技术选择

在企业的真实项目开发中,系统的稳定性是最重要的,所以在技术选择上,肯定是选择成熟,使用人多,并且自己能 cover 的住的技术,当然还有一点也很重要,那就是选择你所在公司使用的技术栈,我这次的开发也是基于上面综合决定了下面的技术栈:

  • supabase:因为我们的登录服务是依赖它,最近购买了他们的高级服务,但是很多资源都还没有使用,这次刚好发挥一下这个服务的价值,不能白花这个钱
  • honojs:极小的体积,能适配各种环境,原生的 typescript 支持,并且社区活跃,使用的人也很多

这里使用 supabase 提供数据库和数据库对应后端接口的能力,是完全能够实现我的需求的。下面简单介绍一下 supabase,它是开源 Firebase 的替代方案,它基于 PostgreSQL 构建,提供了一套完整的后端即服务(Backend-as-a-Service, BaaS)功能,帮助开发者快速构建全栈应用,而无需从零搭建后端。那它具体提供了什么呢?

  • 实时数据库(Realtime Database): 基于 Pg 的逻辑复制和 WebSocket,支持监听数据变更
  • 身份认证(Auth):提供用户注册、登录、第三方登录(如 Google、GitHub)、密码重置等功能,支持 JWT 令牌和行级安全策略(RLS)。
  • 存储(Storage) :支持文件上传与管理(如图片、视频),权限可通过 RLS 控制,类似云存储服务。
  • 自动生成 API:Supabase 会自动为你的数据库表生成 RESTful 和 GraphQL API
  • 行级安全(Row Level Security, RLS) :通过 Pg 原生的 RLS 机制,实现细粒度的数据访问控制,无需写额外的后端逻辑。
  • CLI 工具:提供了 supabase cli ,能更方便的进行 本地开发、调试和部署管理将云端 Supabase 项目的能力带到本地环境,提升开发效率与一致性。尤其是数据库迁移部分,在团队协作和 CI/CD 上非常实用
  • 开源 & 可自托管 :Supabase 100% 开源(MIT 协议),支持在自己的服务器上部署
    再简单介绍一下 honojs :是一个为边缘运行时(如 Cloudflare Workers、Deno、Bun 等)和 Node.js 设计的超轻量、高性能的 Web 框架,如果你想了解更多,可以去官方看文档

数据库设计

确定了技术,就可以开始进行数据库设计,把表创建好了,其实一半的代码也就写出来了!因为我们使用 supabase 服务,它会自动根据表生成对应的接口,有了表,对应的接口也就有了!下面是我借助 AI 设计的数据库:

表 1: user 表

create table public.user (
  id text not null,
  created_at timestamp with time zone not null,
  email text null,
  role public.userType null,
  is_banned text null,
  constraint user_pkey primary key (id),
  constraint user_email_key unique (email),
  constraint user_id_key unique (id)
) TABLESPACE pg_default;
表 2: tag 表
  
create table public.user (
  id text not null,
  created_at timestamp with time zone not null,
  email text null,
  role public.userType null,
  is_banned text null,
  constraint user_pkey primary key (id),
  constraint user_email_key unique (email),
  constraint user_id_key unique (id)
) TABLESPACE pg_default;

  表 3: payout_requests 表
  
create table public.payout_requests (
  id bigint generated by default as identity not null,
  created_at timestamp with time zone not null default now(),
  owner_operator_id uuid null,
  kol_account text null,
  real_name text null,
  pay_account text null,
  sfz_name text null,
  sfz_account text null,
  phone text null,
  pay_amount numeric null,
  form_source_id uuid null,
  tags json null,
  status public.payout_status null,
  notes text null,
  "isDelete" boolean not null default false,
  from_user_email text null,
  constraint payout_requests_pkey primary key (id),
  constraint payout_requests_id_key unique (id),
  constraint payout_requests_form_source_id_fkey foreign KEY (form_source_id) references auth.users (id) on update CASCADE on delete CASCADE,
  constraint payout_requests_owner_operator_id_fkey foreign KEY (owner_operator_id) references auth.users (id) on update CASCADE on delete CASCADE
) TABLESPACE pg_default;

这里我先在 supabase 后台创建了两个枚举:

image.png

userType:operations, finance, admin

payout_status: wait_sure, pendingPayment, paid, reject

其实这个数据库表设计和命名都存在问题,不知道你能发现多少?但是在我做的途中才知道的,为了保证准时上线,我打算先上线,还有一个原因是这个服务是服务内部,可能开发一次后面不用再管了,所以打算就暂时先这样

后端开发

有了数据库表,下面就可以进行后端开发了,其实是否使用 honojs 我还纠结了一会,理论上我完全可以使用 supabase 提供的能力完成需求,但是有两点让我不得不自己进行接口开发:

  1. 我对 supabase 不是很熟悉,害怕自己无法能在短时间实现需求
  2. 这个业务是希望国内用户可以调通后端服务的接口,但是 supabase 的服务国内肯定访问不了
    最终导致我打算自己使用 honojs 更快的进行接口开发,来提供后端接口服务。开发完成后可以将服务部署在任何位置
    首先就是参考: https://supabase.com/docs/guides/getting-started/quickstarts/hono 搭建出后端项目。搭建完成项目后,就启动 Codex,如果你在使用 Claude Code 或者 Cursor 也可以使用你自己的 AI 编程工具
    第一步:初始化项目和初始化数据库
    运行 codex 的 /init,生成 AGENT.md ,然后让AI 来帮我们安装 supabase CLI ,提示词如下 :
参考 https://supabase.com/docs/guides/local-development ,文档,安装 supabase cli 到当前电脑
---
等待安装完成后 supabase --version 进行校验

然后我们使用 supabase 先连接上我们在线的 supabase 项目(这里你应该已经创建好你的项目了),然后进行初始化数据库,有了 CLI 之后我们就不需要在 web 端一个个创建数据库表,直接使用 CLI 生成即可,它还会生成对应的迁移记录,在 CI / CD 的时候这非常有用

# CLI 和你的在线项目关联起来 SUPABASE_URL:https://your_project_ref.supabase.co
supabase link --project-ref your_project_ref
# 验证连接成功
supabase status
# 初始化:会创建一个 supabase 文件夹,你的相关操作都会在这里进行记录
supabase init
# 创建一个新的迁移文件
supabase migration new init_tables
# 运行后,你会看到类似:
supabase/migrations/20251027_init_tables.sql
# 编辑迁移文件
也就是将上面的创建表语句放入迁移文件,这一步可以让 AI 帮你弄
# 同步迁移文件到云端,然后去 supabase 后台会看到你的三个表
supabase db push
# 这条命令会:
# - 检查 SQL 语法;
# - 在云端 Supabase 项目执行;
# - 自动记录迁移历史。
# 验证结果: supabase db pull。 会把最新数据库结构拉回来。

第二步:配置环境变量,并验证是否成功连接上 Supabase

# Get your keys at https://supabase.com/dashboard/project/_/settings/api
SUPABASE_URL=xxx
SUPABASE_ANON_KEY=xx
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

这个过程中,如果遇到任何报错,都可以问 Codex ,辅助修复 bug,初始化数据库后,对应的数据库接口也就有了!

image.png
image.png

我们可以看到对应的接口文档,下面就在本地使用 supabase 提供的包来开发对应的接口,首先创建一个 /user 接口,这个接口很简单,就是获取请求的鉴权信息,调 supabase 的 auth 服务,返回用户信息

 app.get('/user', async (c) => {
    const supabase = getSupabase(c);

    const { data: { user }, error } = await supabase.auth.getUser();

    if (error || !user) {
      return c.json({ message: 'Not logged in' }, 401);
    }

    return c.json({
      id: user.id,
      email: user.email,
      message: 'Logged in'
    });
  });

如果这个接口调通了,下面就可以让 AI 进行疯狂的接口开发了!所有接口大体逻辑基本相同,都是权限校验 => 数据处理 => 返回数据和状态,下面给一个示例的提示词:

现在开发payout_requests 表相关的接口,有增删改查,注意删除是逻辑删除,设置 isDelete 为 true,这个删除接口仅仅管理员可以使用,还需要开发一个状态修改接口,这个接口是所有角色都可以使用,创建接口是不需要登录即可调用,遵循 Restful 规范进行开发

基本上,都是这样的提示词,然后开发完成后进行代码校验 + 测试,等后端接口开发完成后,下面来开发前端

前端开发

根据需求,前端需要两个页面,一个是给客户使用的表单收集页面,另外一个是后台管理页面,给运营,财务和管理员使用。所以也是很简单,只需要关注权限校验正确即可,下面是让 AI 开发示例提示词:

基于当前的 payout_requests 表相关的接口 ,开发对应的页面,使用 ant design 的 list 组件展示数据,最后面有一列操作栏,展示:修改,删除,注意删除按钮仅仅运营和管理员可见,还需要一个设置状态的下拉框,状态枚举有三个值,你需要创建一个常量保持,并生成对应中文展示状态

和后端一样,我负责代码 review + 验证效果,这里需要注意的是,你需要告诉你的 AI 已经完成的后端代码,这样它才能够更好的工作

部署上线

当我们本地开发测试完成后,就可以上线我们的服务了!后端是 honojs 的服务,是可以轻松进行部署到 cloudflare,vercel 等平台。如果你要部署到自己的服务器也是非常简单,安装一个 node 环境即可。
这里有一个需要注意的是,如果你是部署到 docker 上,需要使用 hono/adapter 来动态获取环境变量,并且需要在 docker 里面配置好对应的环境变量

小小总结

虽然这是一个不能再简单的项目。但是从接手到上线,还是学到了新的知识。例如:在数据库设计的时候 payout_requests 表的 tags 字段更合理的方式是新建一个关联表。

而且,当我在开发前端和后端的服务的时候,会更加了解什么事情应该在前端做,什么事情应该在后端去实现。

最后就是在开发过程中,我基本上都是作为一个需求下达,代码校验和结果验证的人,如果不是还需要 code review,我觉得我更像一个测试开发

另外我打算做一个 0 基础小白 AI 编程的教程。所以想调研一下,你是否了解 AI 编程,是否想将你的想法通过编程转为真实的产品

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions