feat: 更新后端文档位置
This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||
|
||||
## Git Hooks
|
||||
|
||||
项目使用 `.githooks/` 目录存放**仓库内**的 git hooks(**不**在 `.git/hooks/`)。**clone 后需手动启用**:
|
||||
|
||||
```bash
|
||||
git config core.hooksPath .githooks
|
||||
```
|
||||
|
||||
### 启用的 Hook
|
||||
|
||||
#### `post-receive`
|
||||
|
||||
**触发场景**:`git push` 到本仓库时(在 **bare repo** 或 `receive.denyCurrentBranch=updateInstead` 的非 bare repo 上)。
|
||||
|
||||
**行为**:自动执行 `pnpm run build:start`,即 `next build && next start`。
|
||||
|
||||
**注意事项**:
|
||||
|
||||
- 本仓库的 `.githooks/post-receive` **不**会**自动**生效 —— 必须在每个工作副本上跑一次上面的 `git config` 命令
|
||||
- `core.hooksPath` 是**本地** git config(写入 `.git/config`),**不**随仓库提交
|
||||
- `post-receive` 在**接收端**触发 —— 即 push 目标机器(生产 / 测试服务器)的 hook,不是本地开发机的
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||
modify
|
||||
@@ -0,0 +1,206 @@
|
||||
# Elio Proactive Wakeup API
|
||||
|
||||
Target environment: `pro` pre-release.
|
||||
|
||||
Base URL:
|
||||
|
||||
```text
|
||||
https://proapi.banlv-ai.com
|
||||
```
|
||||
|
||||
All endpoints require:
|
||||
|
||||
```http
|
||||
X-Admin-Token: <admin token>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
`ADMIN_VIEW_TOKEN` can only read rules. Updating rules or running scans requires `ADMIN_TOKEN`.
|
||||
|
||||
## Status
|
||||
|
||||
The proactive wakeup scheduler is deployed on `pro`, but real sending is guarded by environment flags:
|
||||
|
||||
```text
|
||||
ENABLE_PROACTIVE_WAKEUP=false
|
||||
PROACTIVE_WAKEUP_DRY_RUN=true
|
||||
```
|
||||
|
||||
With the current default, the hourly scheduler skips sending. The admin UI can still manually call dry-run for monitoring.
|
||||
|
||||
## Rule Model
|
||||
|
||||
```ts
|
||||
type ProactiveRule = {
|
||||
id: string;
|
||||
rule_key:
|
||||
| "global_anti_harassment"
|
||||
| "festival"
|
||||
| "social_post_share"
|
||||
| "dormant_wakeup";
|
||||
category: "guardrail" | "festival" | "social_post" | "dormant";
|
||||
enabled: boolean;
|
||||
priority: number;
|
||||
trigger_conditions: Record<string, unknown>;
|
||||
behavior_strategy: Record<string, unknown>;
|
||||
frequency_limit: Record<string, unknown>;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
```
|
||||
|
||||
Default rules:
|
||||
|
||||
| Rule | Purpose | Main Limits |
|
||||
| --- | --- | --- |
|
||||
| `festival` | Valentine, Christmas, birthday personalized wakeup | Max 1 per festival cycle |
|
||||
| `social_post_share` | Share Elio latest Facebook post | Max 1 per FB post event |
|
||||
| `dormant_wakeup` | 48h inactivity wakeup | Max 1 per dormant cycle |
|
||||
| `global_anti_harassment` | Stop waking users after 7 idle days | Global suppression |
|
||||
|
||||
## List Rules
|
||||
|
||||
```http
|
||||
GET /api/admin/proactive/rules
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
curl -H "X-Admin-Token: $ADMIN_TOKEN" \
|
||||
https://proapi.banlv-ai.com/api/admin/proactive/rules
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"id": "8b14a3bf-6c01-4d0c-85b5-613399cb8f14",
|
||||
"rule_key": "dormant_wakeup",
|
||||
"category": "dormant",
|
||||
"enabled": true,
|
||||
"priority": 30,
|
||||
"trigger_conditions": {
|
||||
"min_idle_hours": 48,
|
||||
"min_user_messages": 5
|
||||
},
|
||||
"behavior_strategy": {
|
||||
"mode": "ai_dormant_wakeup",
|
||||
"tone": "soft_missing",
|
||||
"send_channel": "cozsweet"
|
||||
},
|
||||
"frequency_limit": {
|
||||
"cycle_scope": "dormant_period",
|
||||
"max_per_cycle": 1
|
||||
},
|
||||
"created_at": "2026-06-29T07:38:46.155433+00:00",
|
||||
"updated_at": "2026-06-29T10:52:11.041169+00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Update Rule
|
||||
|
||||
```http
|
||||
PATCH /api/admin/proactive/rules/{rule_key}
|
||||
```
|
||||
|
||||
Allowed request fields:
|
||||
|
||||
```ts
|
||||
type UpdateProactiveRuleRequest = {
|
||||
enabled?: boolean;
|
||||
priority?: number;
|
||||
trigger_conditions?: Record<string, unknown>;
|
||||
behavior_strategy?: Record<string, unknown>;
|
||||
frequency_limit?: Record<string, unknown>;
|
||||
};
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
curl -X PATCH \
|
||||
-H "X-Admin-Token: $ADMIN_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"enabled":true}' \
|
||||
https://proapi.banlv-ai.com/api/admin/proactive/rules/dormant_wakeup
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"rule_key": "dormant_wakeup",
|
||||
"enabled": true,
|
||||
"priority": 30,
|
||||
"trigger_conditions": {
|
||||
"min_idle_hours": 48,
|
||||
"min_user_messages": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Run Scan
|
||||
|
||||
```http
|
||||
POST /api/admin/proactive/run?dry_run=true
|
||||
```
|
||||
|
||||
Query parameters:
|
||||
|
||||
| Name | Type | Default | Meaning |
|
||||
| --- | --- | --- | --- |
|
||||
| `dry_run` | boolean | `true` | `true` previews eligible candidates; `false` sends and writes delivery records only when `ENABLE_PROACTIVE_WAKEUP=true`. |
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "X-Admin-Token: $ADMIN_TOKEN" \
|
||||
"https://proapi.banlv-ai.com/api/admin/proactive/run?dry_run=true"
|
||||
```
|
||||
|
||||
Current pro response with no eligible users:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"enabled": false,
|
||||
"dryRun": true,
|
||||
"candidates": 0,
|
||||
"sent": 0,
|
||||
"items": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When candidates exist, `items` contains rule/cycle context and, in dry-run mode, generated preview messages.
|
||||
|
||||
## Frontend States
|
||||
|
||||
Handle these states in the admin UI:
|
||||
|
||||
| State | How to detect | UI suggestion |
|
||||
| --- | --- | --- |
|
||||
| Unauthorized | HTTP `403`, `message=admin token required` | Ask operator to enter an admin token. |
|
||||
| No candidates | `success=true`, `data.candidates=0` | Show an empty state. |
|
||||
| Dry-run preview | `data.dryRun=true`, `items.length>0` | Show candidate list and preview text. |
|
||||
| Sending disabled | `data.enabled=false` | Display that real sending is off in environment config. |
|
||||
| Send executed | `data.dryRun=false`, `data.sent>0` | Show sent count and delivery rows. |
|
||||
| Partial failure | Any item with `status="failed"` | Show per-user failure reason and keep successful rows. |
|
||||
|
||||
## Notes
|
||||
|
||||
- User eligibility requires cozsweet/web user messages `>= 5` and last interaction older than the rule threshold.
|
||||
- The global anti-harassment rule suppresses wakeups once the user has been idle for 7 days.
|
||||
- Birthday wakeups require birthday data. The migration includes `users.birthday`; if the column is not present yet, birthday matching is skipped without breaking other rules.
|
||||
- Facebook post sharing requires inserting an `elio_fb_post` row into `proactive_message_events`.
|
||||
@@ -0,0 +1,206 @@
|
||||
# Elio 主动唤醒 API
|
||||
|
||||
目标环境:`pro` 预发布环境。
|
||||
|
||||
基础地址:
|
||||
|
||||
```text
|
||||
https://proapi.banlv-ai.com
|
||||
```
|
||||
|
||||
所有接口都需要:
|
||||
|
||||
```http
|
||||
X-Admin-Token: <admin token>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
`ADMIN_VIEW_TOKEN` 只能读取规则。更新规则或运行扫描需要使用 `ADMIN_TOKEN`。
|
||||
|
||||
## 状态
|
||||
|
||||
主动唤醒调度器已经部署在 `pro` 环境,但真实发送受环境变量控制:
|
||||
|
||||
```text
|
||||
ENABLE_PROACTIVE_WAKEUP=false
|
||||
PROACTIVE_WAKEUP_DRY_RUN=true
|
||||
```
|
||||
|
||||
在当前默认配置下,每小时调度器会跳过真实发送。管理后台仍然可以手动调用 dry-run,用于监控和预览。
|
||||
|
||||
## 规则模型
|
||||
|
||||
```ts
|
||||
type ProactiveRule = {
|
||||
id: string;
|
||||
rule_key:
|
||||
| "global_anti_harassment"
|
||||
| "festival"
|
||||
| "social_post_share"
|
||||
| "dormant_wakeup";
|
||||
category: "guardrail" | "festival" | "social_post" | "dormant";
|
||||
enabled: boolean;
|
||||
priority: number;
|
||||
trigger_conditions: Record<string, unknown>;
|
||||
behavior_strategy: Record<string, unknown>;
|
||||
frequency_limit: Record<string, unknown>;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
```
|
||||
|
||||
默认规则:
|
||||
|
||||
| 规则 | 用途 | 主要限制 |
|
||||
| --- | --- | --- |
|
||||
| `festival` | 情人节、圣诞节、生日等个性化唤醒 | 每个节日周期最多 1 次 |
|
||||
| `social_post_share` | 分享 Elio 最新 Facebook 帖子 | 每个 Facebook 帖子事件最多 1 次 |
|
||||
| `dormant_wakeup` | 48 小时未活跃用户唤醒 | 每个沉睡周期最多 1 次 |
|
||||
| `global_anti_harassment` | 用户闲置 7 天后停止唤醒 | 全局抑制规则 |
|
||||
|
||||
## 获取规则列表
|
||||
|
||||
```http
|
||||
GET /api/admin/proactive/rules
|
||||
```
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
curl -H "X-Admin-Token: $ADMIN_TOKEN" \
|
||||
https://proapi.banlv-ai.com/api/admin/proactive/rules
|
||||
```
|
||||
|
||||
响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"id": "8b14a3bf-6c01-4d0c-85b5-613399cb8f14",
|
||||
"rule_key": "dormant_wakeup",
|
||||
"category": "dormant",
|
||||
"enabled": true,
|
||||
"priority": 30,
|
||||
"trigger_conditions": {
|
||||
"min_idle_hours": 48,
|
||||
"min_user_messages": 5
|
||||
},
|
||||
"behavior_strategy": {
|
||||
"mode": "ai_dormant_wakeup",
|
||||
"tone": "soft_missing",
|
||||
"send_channel": "cozsweet"
|
||||
},
|
||||
"frequency_limit": {
|
||||
"cycle_scope": "dormant_period",
|
||||
"max_per_cycle": 1
|
||||
},
|
||||
"created_at": "2026-06-29T07:38:46.155433+00:00",
|
||||
"updated_at": "2026-06-29T10:52:11.041169+00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 更新规则
|
||||
|
||||
```http
|
||||
PATCH /api/admin/proactive/rules/{rule_key}
|
||||
```
|
||||
|
||||
允许的请求字段:
|
||||
|
||||
```ts
|
||||
type UpdateProactiveRuleRequest = {
|
||||
enabled?: boolean;
|
||||
priority?: number;
|
||||
trigger_conditions?: Record<string, unknown>;
|
||||
behavior_strategy?: Record<string, unknown>;
|
||||
frequency_limit?: Record<string, unknown>;
|
||||
};
|
||||
```
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
curl -X PATCH \
|
||||
-H "X-Admin-Token: $ADMIN_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"enabled":true}' \
|
||||
https://proapi.banlv-ai.com/api/admin/proactive/rules/dormant_wakeup
|
||||
```
|
||||
|
||||
响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"rule_key": "dormant_wakeup",
|
||||
"enabled": true,
|
||||
"priority": 30,
|
||||
"trigger_conditions": {
|
||||
"min_idle_hours": 48,
|
||||
"min_user_messages": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 运行扫描
|
||||
|
||||
```http
|
||||
POST /api/admin/proactive/run?dry_run=true
|
||||
```
|
||||
|
||||
查询参数:
|
||||
|
||||
| 名称 | 类型 | 默认值 | 含义 |
|
||||
| --- | --- | --- | --- |
|
||||
| `dry_run` | boolean | `true` | `true` 表示预览符合条件的候选用户;`false` 仅在 `ENABLE_PROACTIVE_WAKEUP=true` 时执行真实发送并写入投递记录。 |
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "X-Admin-Token: $ADMIN_TOKEN" \
|
||||
"https://proapi.banlv-ai.com/api/admin/proactive/run?dry_run=true"
|
||||
```
|
||||
|
||||
当前 `pro` 环境在没有符合条件用户时的响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"enabled": false,
|
||||
"dryRun": true,
|
||||
"candidates": 0,
|
||||
"sent": 0,
|
||||
"items": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
当存在候选用户时,`items` 会包含规则、周期上下文;在 dry-run 模式下,还会包含生成的预览消息。
|
||||
|
||||
## 前端状态
|
||||
|
||||
管理后台需要处理以下状态:
|
||||
|
||||
| 状态 | 检测方式 | UI 建议 |
|
||||
| --- | --- | --- |
|
||||
| 未授权 | HTTP `403`,`message=admin token required` | 提示操作人员输入 admin token。 |
|
||||
| 无候选用户 | `success=true`,`data.candidates=0` | 展示空状态。 |
|
||||
| Dry-run 预览 | `data.dryRun=true`,`items.length>0` | 展示候选用户列表和预览文本。 |
|
||||
| 真实发送已禁用 | `data.enabled=false` | 提示当前环境配置已关闭真实发送。 |
|
||||
| 已执行发送 | `data.dryRun=false`,`data.sent>0` | 展示发送数量和投递记录行。 |
|
||||
| 部分失败 | 任意 item 的 `status="failed"` | 展示每个用户的失败原因,同时保留成功记录。 |
|
||||
|
||||
## 备注
|
||||
|
||||
- 用户符合条件的前提是 cozsweet/web 用户消息数 `>= 5`,并且最后一次互动时间早于规则阈值。
|
||||
- 全局反骚扰规则会在用户闲置 7 天后抑制唤醒。
|
||||
- 生日唤醒需要生日数据。迁移中包含 `users.birthday`;如果该列尚不存在,生日匹配会被跳过,但不会影响其他规则。
|
||||
- Facebook 帖子分享需要向 `proactive_message_events` 插入一条 `elio_fb_post` 记录。
|
||||
Reference in New Issue
Block a user