d7c29c0883
- rewards: 激励视频实发改按 calculate_ad_reward_coin(eCPM, 当日第N次) 公式;AD_REWARD_COIN/MAX_AD_REWARD_COIN 降为历史兼容口径;新增 SIGNIN_BOOST_COIN=2000 - 签到膨胀: Day1-13 看完激励视频额外发固定金币、Day14 不允许 (signin.py / signin-boost) - ad_session_id 幂等: ad_ecpm/ad_reward/ad_feed_reward 记录加 ad_session_id 列 + 唯一索引(新迁移 coin_reward_phase2 / ad_feed_reward_session) - ad.py + schemas + repositories: ecpm-report / feed-reward / reward-status / test-grant 改造;config_schema 增 signin_boost_coin;admin stats overview 补充 - 同步 docs/api + docs/database + docs/integrations/pangle 及 tests(test_ad_reward / test_welfare) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: OuYingJun1024 <1034284404@qq.com> Reviewed-on: #28 Co-authored-by: ouzhou <ouzhou@wonderable.ai> Co-committed-by: ouzhou <ouzhou@wonderable.ai>
46 lines
3.3 KiB
Markdown
46 lines
3.3 KiB
Markdown
# coin_transaction — 金币流水账本
|
||
|
||
> 模型 `app/models/wallet.py` · 仓库 `app/repositories/wallet.py`(写入口 `grant_coins`) · 接口 [wallet-coin-transactions](../api/wallet-coin-transactions.md) · [← 索引](./README.md) · [总览](./OVERVIEW.md)
|
||
|
||
金币每变动一笔就记一行(记变动后余额 `balance_after`),用于对账与 App「金币明细」展示。**只增不改不删**——账本不可篡改。
|
||
|
||
## 用在哪 / 增删改查
|
||
- **C(插入)**:唯一来源是 `wallet.grant_coins`(发金币入口),被以下动作调用,每次写一笔:
|
||
|
||
| 动作 / endpoint | `biz_type` | `amount` | `ref_id` 指向 |
|
||
|---|---|---|---|
|
||
| 签到 `POST /signin/do` | `signin` | + | 当天日期串(= `signin_record.signin_date` ISO) |
|
||
| 签到后看广告膨胀 `POST /signin/boost` | `signin_boost` | + | 当天日期串(= `signin_boost_record.signin_date` ISO) |
|
||
| 领任务 `POST /tasks/claim` | `task_<key>`(如 `task_enable_notification`) | + | `user_task.task_key` |
|
||
| 普通激励视频 S2S 回调 `POST /ad/pangle-callback` | `reward_video`(历史兼容:`ad_reward`) | + | `ad_reward_record.trans_id` |
|
||
| 信息流广告结算 `POST /ad/feed-reward` | `feed_ad_reward` | + | `ad_feed_reward_record.client_event_id` |
|
||
| 金币兑现金 `POST /wallet/exchange` | `exchange_out` | − | null(配套 `cash_transaction.exchange_in`) |
|
||
| admin 手动加金币 | `admin_grant` | + | null(`remark`=`admin:<reason>`) |
|
||
| admin 手动扣金币 | `admin_deduct` | − | null |
|
||
|
||
> ⚠️ 比价里程碑 `comparison_milestone_claim` **当前不发币、不写本表**(产品定暂不真发,详见该表文档)。
|
||
- **U / D**:无。账本只追加。
|
||
- **R**:`GET /wallet/coin-transactions`(金币明细,`id` 倒序游标分页);admin 跨用户金币流水(可按 `biz_type` 筛)。
|
||
|
||
## 字段
|
||
| 列 | 类型 | 约束 / 默认 | 说明(取值 / join) |
|
||
|---|---|---|---|
|
||
| `id` | Integer | PK, autoincrement | |
|
||
| `user_id` | Integer | FK→user.id, index, NOT NULL | 归属用户 |
|
||
| `amount` | Integer | NOT NULL | 本笔变动金币;**正=入账(赚),负=出账(花/兑换)** |
|
||
| `balance_after` | Integer | NOT NULL | 本笔后金币余额(= 当时 `coin_account.coin_balance`,对账用) |
|
||
| `biz_type` | String(32) | NOT NULL | 取值见上表:`signin` / `signin_boost` / `task_<key>` / `reward_video` / `ad_reward`(历史) / `feed_ad_reward` / `exchange_out` / `admin_grant` / `admin_deduct`。无 DB 枚举约束,靠写入方约定 |
|
||
| `ref_id` | String(64) | nullable | **关联业务键,指向随 `biz_type` 变(见上表)**;无关联时为 null |
|
||
| `remark` | String(128) | nullable | 备注(如签到「每日签到 第N天」、admin「admin:<reason>」) |
|
||
| `created_at` | DateTime(tz) | server_default now(), index | 时间 |
|
||
|
||
## 关系 / Join Key
|
||
- `user_id` → `user.id`(多对一)。
|
||
- `ref_id` 是**软关联**(无 FK),目标表随 `biz_type`:`signin`→签到日 / `signin_boost`→`ad_reward_record.trans_id` / `task_<key>`→`user_task.task_key` / `reward_video`/`ad_reward`→`ad_reward_record.trans_id` / `feed_ad_reward`→`ad_feed_reward_record.client_event_id` / 其余 null。
|
||
|
||
## 索引与约束
|
||
- PK `id`;index `user_id`、`created_at`。
|
||
|
||
## 注意
|
||
- 流水与余额快照(`coin_account`)、与对应业务记录(signin/task/ad_reward/feed_ad_reward 等)在**同一事务**写,不会只发币不留痕。
|