# lotterLaravel — Agent 须知

## 数据库：禁止擅自清空

**未经用户明确同意，不得执行：**

| 禁止 | 说明 |
|------|------|
| `php artisan migrate:fresh` | 删表重建，业务数据全失 |
| `php artisan db:wipe` | 清空所有表 |
| `php -r` / 脚本中的 `migrate:fresh`、`db:wipe` | 易误连 `.env` 开发库（如 `pgsql` / `lottery`） |

**可以做的：** `php artisan migrate`（增量）、`php artisan test`（走 `phpunit.xml` 的 SQLite 内存库）。

用户明确要求 `migrate:fresh` 时：先说明目标库名与数据将全部丢失，待用户确认后再执行。

详见 `.cursor/rules/database-destructive-commands.mdc`。

## 后台 RBAC

改 `app/Support/AdminAuthorizationRegistry.php` 后，在已有库执行 `php artisan lottery:admin-auth-sync --audit`（见 `docs/admin-rbac.md`）。`migrate:fresh --seed` 会走迁移内的 resync，一般不必再手动 sync。玩家写接口（`admin.players.store/update/destroy`）须**仅**绑 `service.players.manage`，勿扩进 `service.wallet.view`/`service.tickets.view` 等 view slug（middleware OR 会令仅 view 的财务账号误过写操作）；读接口 view/manage 分开。

## 双模式玩家（主站钱包 / 代理信用）

- `players.auth_source`：`main_site_sso`（主站 JWT）与 `lottery_native`（彩票端账号密码）。
- `players.funding_mode`：`wallet`（主站划转）与 `credit`（授信下注）；**禁止**仅用整站 `credit_line_mode` 代替玩家级判断，用 `PlayerFundingMode::usesCredit($player)`。
- 生产环境配置独立 `LOTTERY_NATIVE_JWT_SECRET`（勿与主站 SSO 混用）。

## 信用占成盘（代理账期结算）

- 业务真理源：`docs/信用占成盘代理系统设计说明文档.md`；实施路线：`docs/信用占成盘代理体系改造计划.md`。
- **代理账期**代码包：`App\Services\AgentSettlement\`（勿与彩票开奖 `App\Services\Settlement\` / `SettlementBatch` 混用）。
- **禁止**在生产关账路径使用 `DesignDocExample12` 硬编码账单；仅单元/Feature 测试可引用。
- 非 `testing` 环境关账受 `AGENT_SETTLEMENT_ALLOW_PRODUCTION_CLOSE`（默认 `true`）控制；预发可设为 `false` 门禁。
- 占成账单聚合必须读注单**快照**（`share_snapshot`），禁止按当前 `agent_profiles` 重算历史。

## 接入站点与超管

- 超管身份：`admin_users.is_super_admin`；**禁止**经 `admin_user_site_roles` 绑站；全库仅一名（DB partial unique index）。
- 零站点：`admin_sites` 可为 0；`defaultAdminSiteId()` 无站返回 null；超管仍可登录；需站点的写操作用 `requireDefaultAdminSiteId()` 抛 `no_integration_site`。
- 删接入站：DELETE API/UI；默认站亦可删（含最后一个）；仅删除仅绑 `site_admin_{code}` 的自动账号，**不得**删超管。

## Learned User Preferences

- 排障/上线评估时用 MCP（postgres）直查库验证数据与权限，勿仅凭代码推断生产态。

## Learned Workspace Facts

- 期号 `close_time`/`draw_time` UTC 存储；下注由 `DrawHallSnapshotBuilder` 实时判定；列表展示 DB `status`，详情 API 有 `hall_preview_status`。
- `AgentProfileCapabilityFilter` 仅作用于**已绑定代理节点**的经营账号（按档案 `can_create_*` 收紧权限）；**禁止**对无代理绑定的平台账号（如 `site_admin`）套用，否则会误剥 `prd.agent.manage` 等权限。`can_create_child_agent=false` 剥 `agent.node.manage` 时，**勿**用 `nodeManageableBy()` 门控 `agent.role.manage`（会误挡本节点角色创建）。绑定经营代理主账号统一绑 `slug=agent`，模板仅含 `prd.settlement.agent.view`；登录态对绑定代理主账号自动补足 `settlement.agent.manage`，实际操作仍受直属边 + 收款方校验。
- 代理数据范围：有 `admin_user_agents` 绑定须先按 `AdminAgentScope::primaryAgentNode()` 限子树，**禁止**因 `accessibleAdminSiteIds() !== null` 跳过代理过滤（兼站点角色亦然）。纯站点运营 = `admin_user_site_roles` 且**无**代理绑定，用 `AdminAgentScope::isSiteOnlyOperator()`。站点运营（`site_admin|site_finance|site_cs`）看本站资金+信用；`site_admin`：代理树/玩家/信用结算/注单 + 钱包流水·对账·经营报表（可导出）·期号只读；`site_finance`：财务工作台 + 对账/报表/结算收付；`site_cs`：客服工作台 + 单玩家查询；开通一级代理线路仅超管（`prd.agent-line.provision`）。
- 结算中心登记收付/确认/坏账/补差 UI 需 `prd.settlement.agent.manage`（`canManage`）；仅 view 时操作区静默隐藏。另需账单 `status` ∈ confirmed/partial_paid/overdue 且 `unpaid_amount > 0`。**坏账核销 / 补差冲正** 另需未绑定代理（站点财务，`canFinanceAdjustments`），绑定代理仅有收付/确认。绑定代理账单可见范围：**玩家账单**仅直属玩家；**代理账单**仅 `owner=本节点` 或 `counterparty=本节点`；登记收付/确认仅可操作 **收款方**。
- 收付/调账/坏账后端落库 `payment_records`、`settlement_adjustments`；账期详情 **收付与调账** Tab 查操作台账，**账务流水** 仅玩家信用变动；单张账单详情内另有该账单的收付列表。
- 线上生产：已有库用 `php artisan lottery:db-init --no-demo`（含 RBAC sync）；缺根 `agent_profiles` 可跑迁移 `2026_06_17_120000_backfill_root_agent_profiles.php`；常驻 `schedule:work`、`queue:work redis --queue=broadcasts:countdown,broadcasts,default`、`reverb:start`；`CACHE_STORE`/`QUEUE_CONNECTION` 须 Redis；先部署 lotterLaravel 再前端。
- `AgentProfileService::upsertForNode` PATCH 缺省键会写 0（占成/回水等），须按 `array_key_exists` 合并既有 profile；`settlement_cycle` 空串归一化为 `weekly`；建子代理前根节点 profile 须存在（`rebate_limit`/`default_player_rebate` 校验依赖）。
- `CreditAmountScale::minorToMajor` 占用授信向上取整（ceiling），与 `assertCreditPreflight` 按 major 校验一致。
- 代理仪表盘/账期「输赢」用本级 `share_profit`；开/关账期仅未绑定代理站点财务；根节点（`depth=0`）profile 仅超管可改。
- SSO/接入：首次有效 JWT 调 `GET /api/v1/player/me` 按 `(site_code, site_player_id)` 自动建档；`username`/`nickname` 彩票生成 `nlotto******`；建站生成 `sso_jwt_secret`/`wallet_api_key`，`main-site/` 须手动对齐；`wallet_api_url` 填主站钱包根 URL；8005=站点不存在/停用或玩家冻结（生产按 `admin_sites` 验站）。
- 报表 `AdminReportQueryService`：未传日期默认近 30 天；玩家/玩法/回水按 `draws.business_date`；SQLite 对 `business_date` 用 `whereDate` 勿 `whereBetween`（列可能带时间戳）；日盈利过滤零活动日。
