# 2026-07-21 工作记录

## 邀请成为开发者报错分析（UID:35739）
- 报错「该用户不是平台开发者，无法邀请为开发者角色」来源：`websopy-java` 项目（非 com.gxwebsoft.core）。
- 拦截点共 3 处，逻辑一致：邀请角色为 `developer` 时，跨库查 `gxwebsoft_core.sys_user.is_developer`，必须为 `1` 才放行：
  - `com/gxwebsoft/app/service/impl/AppUserServiceImpl.java:168-172`（API: POST /api/app/developer/.../invite）
  - `com/gxwebsoft/app/service/impl/AppInviteServiceImpl.java:257-261`
  - `com/gxwebsoft/app/controller/AppMpInviteController.java:179-183`（小程序邀请）
- 「平台开发者」定义：
  - `sys_user.type = 2`（见 AppUserController /check-access 判断）
  - `sys_user.is_developer = 1`（邀请 developer 角色的硬性门槛，由 SysUserCrossDbMapper.selectIsDeveloperByUserId 查询）
- 关键发现：websopy-java 与 com.gxwebsoft.core 后端代码中**没有任何写入 is_developer=1 / type=2 的逻辑**，即「成为开发者」的赋权由 websopy-pc 前端开发者门户注册/认证流程或数据库操作完成（后端仅做读取校验）。
- 结论：UID:35739 的 `sys_user.is_developer` 为 0 或 NULL → 报错。需先让其完成「成为开发者」注册使 is_developer=1（并建议同步 type=2）。
- 潜在 Bug：邀请门槛用 is_developer，而 /check-access 用 type=2。若两字段不一致，会出现「能进开发者中心但无法被邀请为开发者」的矛盾。

## 统一开发者身份判定为 is_developer=1（已实施）
- 用户选定方案：把开发者身份判定统一为「sys_user.is_developer = 1」。
- 改动（websopy-java 项目）：
  - `AppUserController.checkAccess()`：原 `selectUserType()==2` → 改为 `selectIsDeveloperByUserId()==1`，同步更新 Javadoc。
  - `AppProductServiceImpl` 转让应用所有权校验：原 `selectUserType()==2` → 改为 `selectIsDeveloperByUserId()==1`。
  - 三处邀请门槛（AppUserServiceImpl / AppInviteServiceImpl / AppMpInviteController）本就使用 is_developer=1，无需改。
- 结果：全站「平台开发者」判定统一为 is_developer=1 单一标准。
- 注意：此变更使 is_developer 成为唯一依据；存量仅 type=2、无 is_developer 的开发者将失去权限。需数据回填：`UPDATE gxwebsoft_core.sys_user SET is_developer=1 WHERE type=2 AND deleted=0;`（先备份）。UID:35739 仍需 is_developer=1 才能被邀请。

## Tenant 实体补充 superAdminUserId 字段
- 用户已在 `TenantMapper.xml` 的 `selectSql` 中 SELECT `u.user_id as superAdminUserId`（LEFT JOIN gxwebsoft_core.sys_user u ON u.tenant_id=a.tenant_id AND u.is_super_admin=1 AND u.deleted=0）。
- 在 `Tenant.java` 中补充 `private Integer superAdminUserId;` 并标注 `@TableField(exist = false)`，使 MyBatis 能映射该衍生字段（不是 sys_tenant 真实列，不参与增改）。
- `selectPageRel` / `selectListRel` 用 resultType=Tenant，可直接返回该字段。
