Files
Genarrative/.hermes/skills/genarrative-profile-invite-flow/SKILL.md
历冰郁-hermes版 7e35231dfe
Some checks failed
CI / verify (pull_request) Has been cancelled
docs: sync genarrative shared skills
2026-05-08 17:39:49 +08:00

7.3 KiB
Raw Blame History

name, description, version, author, license, metadata
name description version author license metadata
genarrative-profile-invite-flow 在 Genarrative 中排查或修改邀请码、邀请好友、首次登录后填写邀请码、我的页签邀请码兑换链路时使用。 1.0.0 Hermes Agent MIT
hermes
tags related_skills
Genarrative
邀请码
referral
auth
profile
query-params
前端

Genarrative 邀请码与邀请好友流程

用于排查或修改 Genarrative 的邀请码读取、填写、兑换、邀请中心与“我的”页签相关能力。

适用场景

  • 判断 URL query 参数中的邀请码是否被读取。
  • 修改邀请码填写入口、首次登录后引导或“我的”页签兑换入口。
  • 排查邀请码预填、兑换、已填写状态、邀请好友复制链接。
  • 修改邀请中心 API client 或前端 referral UI。
  • 回答用户关于“邀请码在哪里填 / 从哪里配置 / query 是否支持”的问题。

先做代码核对,不要只凭旧记忆回答

邀请码流程近期发生过迁移:不要默认认为登录窗口可填写邀请码。回答前优先搜索并核对当前代码,尤其是:

cd <repo-root>
python3 - <<'PY'
from pathlib import Path
root=Path('src')
terms=['RegistrationInviteModal','readInviteCodeFromLocation','referralRedeemCode','redeemRpgProfileReferralInviteCode','邀请码','inviteCode']
for term in terms:
    print('\n---', term)
    for p in root.rglob('*'):
        if p.is_file() and p.suffix in ['.ts', '.tsx']:
            try:
                txt=p.read_text('utf-8')
            except Exception:
                continue
            if term in txt:
                for i, line in enumerate(txt.splitlines(), 1):
                    if term in line:
                        print(f'{p}:{i}:{line.strip()[:180]}')

当前前端链路口径

1. AuthGate 中仍有旧 query 读取逻辑

文件:

  • src/components/auth/AuthGate.tsx

重点函数 / 状态:

  • readInviteCodeFromLocation()
  • pendingInviteCode
  • showRegistrationInviteModal
  • RegistrationInviteModal

当前旧逻辑会读取:

  • ?inviteCode=...
  • ?invite_code=...

并把值清洗为大写字母数字形式。

2. 登录窗口本身不再填写邀请码

不要回答“登录窗口可填写邀请码”。当前登录弹窗 LoginScreen 只负责登录 / 注册账号;邀请码填写已迁移到登录后的流程。

3. 新版“我的”页签兑换入口在 RpgEntryHomeView

文件:

  • src/components/rpg-entry/RpgEntryHomeView.tsx

重点常量 / 函数 / 状态:

  • PROFILE_INVITE_QUERY_KEYS:新版 query 支持 inviteCode / invite_code
  • normalizeProfileInviteQueryCode():去掉非字母数字并转大写。
  • readProfileInviteCodeFromLocationSearch():从 window.location.search 读取并 normalize。
  • pendingProfileInviteCode:组件初始化时读取 query 邀请码。
  • referralCenter
  • referralRedeemCode
  • setReferralRedeemCode
  • openProfilePopupPanel('redeem')
  • submitReferralRedeemCode()
  • canShowReferralRedeemShortcut
  • isWithinProfileInviteRedeemWindow(authUi?.user?.createdAt)

UI 中“填邀请码”面板会使用 referralRedeemCode 作为输入值,并通过 submitReferralRedeemCode() 提交。当前新版实现会在首次打开“填邀请码”面板时用 pendingProfileInviteCode 预填输入框;例如 /?inviteCode=spring-2026 会预填为 SPRING2026

4. 新版兑换 API client

文件:

  • src/services/rpg-entry/rpgProfileClient.ts

函数:

  • getRpgProfileReferralInviteCenter() -> GET /profile/referrals/invite-center
  • redeemRpgProfileReferralInviteCode(inviteCode) -> POST /profile/referrals/redeem-code

判断 query 参数是否真正接入新版流程

回答这类问题时要区分两层:

  1. “是否存在旧 query 读取代码”:看 AuthGate.tsxreadInviteCodeFromLocation()
  2. “query 是否接到新版填写入口”:看 RpgEntryHomeView.tsx 是否存在 pendingProfileInviteCode / readProfileInviteCodeFromLocationSearch(),以及打开 openProfilePopupPanel('redeem') 时是否把该值写回 referralRedeemCode

当前新版流程已经支持 inviteCode / invite_code query 预填“我的”页签的“填邀请码”弹窗;登录窗口仍不填写邀请码。

如果未来代码只看到 AuthGate 读 query但没有看到 RpgEntryHomeViewreferralRedeemCode 从 query 初始化,就应回答:

代码里仍支持读取 inviteCode / invite_code,但新版“第一次登录后 / 我的页签”的填写入口未必已经完整接入该 query 值;需要继续把 query 值传入新版 profile referral redeem 流程。

修改建议顺序

如果要把 query 邀请码完整接入新版流程,建议按这个顺序做:

  1. 先确定 query 参数规范:继续支持 inviteCode / invite_code,并统一 normalize。
  2. RpgEntryHomeView.tsx 内用 readProfileInviteCodeFromLocationSearch(window.location.search) 初始化 pendingProfileInviteCode
  3. pendingProfileInviteCode 初始化 referralRedeemCode,并在 openProfilePopupPanel('redeem') 时重新写回,避免关闭后再次打开被清空。
  4. 如产品要求自动弹出:
    • pendingProfileInviteCode 且未登录时,自动调用 authUi?.openLoginModal() 打开登录窗口;登录窗口仍不承接邀请码输入。
    • pendingProfileInviteCode 且已登录时,自动将 referralRedeemCode 设为该 query 邀请码,并 setProfilePopupPanel('redeem') 直接打开“填邀请码”面板。
    • useRef 记录是否已处理过当前 query避免组件重渲染或 authUi 对象变化导致重复弹窗。
    • 当前项目实现已从“只预填、不自动弹”调整为上述行为。
  5. 兑换成功后清理输入态;是否清理 URL query 需由产品决定,避免破坏分享链接归因。
  6. 补测试覆盖:未登录访问带 query、已登录访问带 query 自动打开填写面板、我的页签手动打开、已填写邀请码、过期窗口、空/非法 query。当前已有 RpgEntryHomeView.recharge.test.tsx 覆盖:
    • invite query opens login modal for logged out users
    • invite query opens redeem modal directly for logged in users
    • profile redeem invite modal reads query invite code after login

常见坑

  1. 不要把旧 RegistrationInviteModal 误认为当前唯一入口。
  2. 不要说“登录窗口可以填写邀请码”,除非当前代码重新把邀请码输入放回 LoginScreen
  3. AuthGate 读到 query 不等于新版 RpgEntryHomeView 已经预填。
  4. “第一次登录后”与“我的页签”可能是两个入口;修改时要同时检查自动引导和手动入口。
  5. canShowReferralRedeemShortcut 受登录态、创建时间窗口、邀请中心初始化、已兑换状态共同影响。
  6. 邀请码 URL 通常由 inviteLinkPath 生成,复制逻辑在 copyInviteInfo(),不要只改兑换入口而忘记分享链接格式。

参考资料

  • references/query-invite-code-flow-2026-05-07.md:本次会话确认的邀请码 query 与新版 profile referral 入口关系。

验证标准

  • 能明确回答当前 query 参数读取位置与参数名。
  • 能区分旧 AuthGate 邀请弹窗与新版“我的”页签 referral redeem。
  • 若实现改动,测试覆盖带 query 的登录后预填/弹窗行为,以及已填写邀请码时不再提示。