Article

Tinder 开发笔记——随想象一路前进,于前进探索未知

开发笔记发布于·更新于
#开发#Tinder#Python#FastAPI#数据库#pgsql

如果你关注我的 Github 号的话(好吧我赌你没关注,但欢迎互关),你应该会注意到我新近几天一直在给某个项目开 PR,疯狂 release,就是这玩意儿(话说你愿意给star 吗?)。

https://github.com/jsshmzx/Tinder

先大概介绍一下这个项目吧:给我们海中人做一个互联平台(航海家计划,将于今年 6 月正式发布,预计开发周期一年,明年同期公测并上线),而 Tinder 就是这个互联平台的后端。采用 FastAPI + pgsql + redis 为框架。

想象H1#

虽然说高三的学业其实非常繁忙,但我依然抽出很多时间去构想,如下部分(数据库架构设计图、API 目录设计图):

可以看到如果你单纯去绘制下蓝图,整个系统还是非常简单的,但如果你真的着手去实践,你就会发现,哇,我其实很菜(对,反正我很菜)。

前进H1#

我始终贯彻的一个开发理念是:先有后端才有前端,后端围绕数据,前端则着重用户体验。

所以首先要做的就是后端和数据部分!

数据库迁移H2#

在开发 Tinder 之前,我其实拥有相当稀少的 FastAPI 开发基础,所以构建出一个基本框架(导入 App,设置 CORS,启动应用)不成问题,但这之后呢?我的评价是我就像从零开始学,在此欢迎各位大佬指出值得改进的地方与问题。

因为 Tinder 使用 Python 开发,所以我并不能直接使用 prisma 来实现数据迁移与操作,但并不是什么大问题对吧。Tinder 的数据迁移思路源自于 Mix-Space 中的迁移方法(遍历已存在的记录并在 MongoDB 中检查是否有相应的记录,如果发现有则执行对应的文件,然后写入代码中防止后期重复执行),Tinder 使用了相同的思路,只不过将其迁移到了 Python+pysql

你可以使用 excalidraw 来大致的了解整个流程,应当很好理解:

excalidraw
https://gist.trfox.top/teror/aab25a1e3b6e44e7bd7fd726dd8f46d3/download/HEAD/db-migration.excalidraw

自定义 Log 打印H2#

算是个没多少用的功能,没什么意义,只是为了取代原有的print( ),美化下日志输出,方便查找错误日志云云。

代码写在下面

python
# ANSI 颜色代码
_GREEN = "\033[92m"
_ORANGE = "\033[38;5;208m"
_RED = "\033[91m"
_RESET = "\033[0m"

_LEVEL_CONFIG = {
    "SUCCESS": (_GREEN, "[SUCCESS]"),
    "WARNING": (_ORANGE, "[WARNING]"),
    "ERROR": (_RED, "[ERROR]"),
}


def custom_log(log_level: str, log_content: str) -> None:
    """打印自定义颜色日志。

    Args:
        log_level: 日志级别,支持 'SUCCESS'、'WARNING'、'ERROR'(不区分大小写)。
        log_content: 日志内容。
    """
    level_key = log_level.upper()
    color, label = _LEVEL_CONFIG.get(level_key, (_RESET, f"[{level_key}]"))
    print(f"{color} {label} {log_content}{_RESET}")

未知H1#

这是我开发了几天下来最大的感受:我是菜鸡,我其实啥也不会。毕竟第一次去着手写这种相对较为大型的 API 来说,很多问题与标准我都要问AI 和交给 Agent 解决。

目录结构H2#

这是一个小细节,然而值得去打磨,以给后期开发奠定基础。

目前的目录结构是这样的,那天我问了ds很多问题:比如数据库连接器算不算 helper?firewall 应该放哪里?经过几次打磨,最终成了这样一个相对较为清晰的架构:

text
Tinder/
├── .github/                          # GitHub 配置目录
│   └── workflows/                    # GitHub Actions 工作流
│       ├── codeql.yml                # CodeQL 代码安全扫描工作流
│       ├── docker-build.yml          # Docker 镜像构建工作流
│       └── test.yml                  # 自动化测试工作流
├── core/                             # 核心功能模块
│   ├── database/                     # 数据库相关
│   │   ├── connection/               # 数据库连接管理
│   │   │   ├── db.py                 # SQLAlchemy 引擎与会话工厂(ORM 基类 Base)
│   │   │   └── redis.py              # Redis 连接管理
│   │   ├── dao/                      # 数据访问对象(Data Access Object)
│   │   │   ├── base.py               # BaseDAO 基类,提供通用 CRUD 操作
│   │   │   ├── comments.py           # 评论表 ORM 模型与 DAO
│   │   │   ├── favourites.py         # 收藏表 ORM 模型与 DAO
│   │   │   ├── illegal_requests.py   # 违规请求表 ORM 模型与 DAO
│   │   │   ├── personal_logs.py      # 个人日志表 ORM 模型与 DAO
│   │   │   ├── relations.py          # 用户关系表 ORM 模型与 DAO
│   │   │   ├── request_logs.py       # 请求日志表 ORM 模型与 DAO
│   │   │   ├── song_arrangements.py  # 歌曲编排表 ORM 模型与 DAO
│   │   │   ├── songs.py              # 歌曲表 ORM 模型与 DAO
│   │   │   ├── stores_and_restaurants.py # 商店与餐厅表 ORM 模型与 DAO
│   │   │   ├── system_logs.py        # 系统日志表 ORM 模型与 DAO
│   │   │   ├── system_reports.py     # 系统报告表 ORM 模型与 DAO
│   │   │   ├── tags.py               # 标签表 ORM 模型与 DAO
│   │   │   ├── tasks.py              # 任务表 ORM 模型与 DAO
│   │   │   ├── tokens.py             # 令牌表 ORM 模型与 DAO
│   │   │   ├── users.py              # 用户表 ORM 模型与 DAO
│   │   │   ├── vote.py               # 投票表 ORM 模型与 DAO
│   │   │   ├── wall_looking_for.py   # 寻找墙贴表 ORM 模型与 DAO
│   │   │   └── wall_sayings.py       # 说说墙贴表 ORM 模型与 DAO
│   │   └── migrations/               # 数据库迁移管理
│   │       ├── SQL/                  # SQL 迁移脚本目录
│   │       │   ├── alter_users_add_password.sql      # 用户表新增密码字段
│   │       │   ├── initial_comments.sql              # 评论表初始化
│   │       │   ├── initial_favourites.sql            # 收藏表初始化
│   │       │   ├── initial_illegal_requests.sql      # 违规请求表初始化
│   │       │   ├── initial_migration_user.sql        # 用户表初始化
│   │       │   ├── initial_personal_logs.sql         # 个人日志表初始化
│   │       │   ├── initial_relations.sql             # 用户关系表初始化
│   │       │   ├── initial_request_logs.sql          # 请求日志表初始化
│   │       │   ├── initial_song_arrangements.sql     # 歌曲编排表初始化
│   │       │   ├── initial_songs.sql                 # 歌曲表初始化
│   │       │   ├── initial_stores_and_restaurants.sql # 商店与餐厅表初始化
│   │       │   ├── initial_system_logs.sql           # 系统日志表初始化
│   │       │   ├── initial_system_reports.sql        # 系统报告表初始化
│   │       │   ├── initial_tags.sql                  # 标签表初始化
│   │       │   ├── initial_tasks.sql                 # 任务表初始化
│   │       │   ├── initial_tokens.sql                # 令牌表初始化
│   │       │   ├── initial_vote.sql                  # 投票表初始化
│   │       │   ├── initial_wall_looking_for.sql      # 寻找墙贴表初始化
│   │       │   └── initial_wall_sayings.sql          # 说说墙贴表初始化
│   │       └── migration_history.py  # 迁移脚本执行顺序列表
│   ├── helper/                       # 通用辅助工具
│   │   └── ContainerCustomLog/       # 自定义日志模块
│   │       └── index.py              # 带颜色与时间戳的控制台日志工具
│   └── middleware/                   # 中间件
│       └── firewall/                 # 防火墙/访问控制中间件
│           ├── config.py             # 防火墙规则配置
│           ├── helpers.py            # 防火墙辅助函数
│           ├── index.py              # 对外暴露 FirewallMiddleware
│           └── middleware.py         # 防火墙中间件实现(IP 封禁、限流等)
├── docs/                             # 项目文档
│   └── database/                     # 数据库相关文档
│       ├── db-migration.excalidraw   # 数据库迁移流程图(Excalidraw 格式)
│       └── readme.md                 # 数据库说明文档
├── modules/                          # 业务功能模块
│   └── index/                        # 根路由模块
│       └── index.py                  # 根路由(GET /),返回系统信息
├── tests/                            # 测试目录
│   ├── integration/                  # 集成测试
│   │   ├── conftest.py               # pytest 集成测试夹具配置
│   │   ├── test_api.py               # API 接口集成测试
│   │   └── test_firewall.py          # 防火墙中间件集成测试
│   └── unit/                         # 单元测试
│       ├── test_custom_log.py        # 自定义日志模块单元测试
│       ├── test_firewall_helpers.py  # 防火墙辅助函数单元测试
│       └── test_index_router.py      # 根路由单元测试
├── .env.example                      # 环境变量示例文件(数据库/Redis 配置模板)
├── .gitignore                        # Git 忽略规则
├── Dockerfile                        # Docker 镜像构建文件
├── LICENSE                           # 开源许可证
├── README.md                         # 项目说明文档(本文件)
├── db_migrate.py                     # 数据库迁移入口脚本(使用 psycopg2 执行 SQL)
├── docker-entrypoint.sh              # Docker 容器启动脚本
├── pytest.ini                        # pytest 配置文件
├── requirements.txt                  # Python 依赖列表
└── server.py                         # FastAPI 应用入口,配置中间件与路由

数据层H2#

ORMH3#

ORM 这个东西我经常在一些项目上见过,主打一个安全,预防 SQL 注入(我之前那个项目甚至手动拼接 sqlcommand,想想还是有点怕的),然而我对此并不熟悉,所以交给AI解决了。

DAO 与 DTOH3#

DTO 我先前在 Mx-Space 的源码里见过,然而当时没有仔细了解。

DAO 则是我在与 ds聊天过程中了解的。

那么二者有什么区别呢:

DAO(数据访问对象)负责封装数据库的增删改查操作,关注的是“如何存储”数据;DTO(数据传输对象)则是一个简单的容器,用于封装需要传输的数据,关注的是“如何传递”数据。

好吧实际上我在正式开发之前是打算在某个 API 文件里直接调用数据库的,但实际开发如此正式,也算学到了。

Controller 与 HelperH2#

这二者也是我先前很模糊的概念,现在大概明白了点,就是“餐厅里值班经理与服务”的关系。后者仅是前者调用的一种。

开发规范H2#

太好笑了,我一个人竟然需要查看AI写的《数据库使用指南》,好吧,我是菜鸡,我确实得学。

测试系统的搭建H2#

不想自己写,所以交给 AI 去写了,后期有文件要 Test 也交给 AI 吧。

H1#

目前 Tinder 已更新到了 V0.2.3,但实际建起的部分更多是辅助,API 部分除了/以外都没开发,任重而道远啊。

下次commit应当是高考完了

距离高考还剩 105 天,祝一切顺利。

Copyright & License
© 2026 Teror Fox
Tinder 开发笔记——随想象一路前进,于前进探索未知
CC知识共享许可
BY署名:必须保留原作者署名
NC非商业:禁止用于商业目的
SA相同方式共享:以同协议发布
许可协议:署名-非商业性使用-相同方式共享
Teror Fox
Teror Fox离线