设计¶
xiangqin 把交友 app 的信息不对称戳破:排序规则公开 + 匹配算法在用户端。
三原则¶
- 查询权在用户:服务端只提供受限 WHERE DSL,不做推荐 / 排序算分。
- 排序规则公开:
ORDER BY exposure_remaining>0 DESC, updated_at DESC,没有暗箱。 - 付费 = 可见性:付费用户在被命中时置顶 + 🔥 标记,每次命中扣 1。
数据层(sqlite)¶
6 张表:
| 表 | 作用 |
|---|---|
users |
user_id (ULID) / phone_hmac / created_at |
auth_requests |
request_id / phone_hmac / code / expires_at |
sessions |
session_token / user_id / expires_at |
profiles |
user_id / gender / age / city / tags / bio |
exposure_orders |
order_id / user_id / count / amount_cents / paid / provider |
exposure_usage |
user_id / remaining(被命中原子 -1) |
WAL 模式 + 全部外键索引。
受限 WHERE DSL¶
- 字段白名单:
gender/age/city/tags - 操作符白名单:
= != >= <= > </IN/CONTAINS(tags 专用) - 值白名单:字符串 / 整数 / 逗号列表;禁
OR/JOIN/ 子查询 - LIMIT 默认 50,最大 100
- WHERE 不能为空
示例:
付费排序语义¶
SELECT ... FROM profiles p
LEFT JOIN exposure_usage e ON p.user_id=e.user_id
WHERE <user-dsl>
ORDER BY (e.remaining>0) DESC, p.updated_at DESC
LIMIT <N>;
-- 对每条命中且 e.remaining>0 的记录,原子:
UPDATE exposure_usage SET remaining = remaining - 1
WHERE user_id=? AND remaining>0;
余额为 0 就回落到普通池,不退款。
组件¶
┌─ client ────────────┐ ┌─ server (epsilon) ────┐
│ xq CLI (Click) │ HTTP │ FastAPI + sqlite │
│ xiangqin skill │─────▶│ auth / profile / query │
└─────────────────────┘ │ exposure + webhook │
└────────────────────────┘
│
├─▶ aliyun SMS(注册验证码)
└─▶ alipay 当面付(曝光付款)
凭证:vault.json 声明 → vault install → .vault/secrets.json → 代码读
非目标(宪法)¶
- ❌ 不做推荐算法
- ❌ 不做聊天 / 消息
- ❌ 不做 UGC 社区
- ❌ 不做匹配评分 / 相似度
- ❌ 不存手机号明文
自治单体实验¶
- 唯一对外 CLI 依赖:vault
- 不依赖:生态里 matchmaker / cashier / backup / membership / host / oss / hitch
- 背景:跑通 0.1 验证付费意愿后才决定拆不拆;拆不拆看 O2 指标