"""邮件组 / Google 账号域通知模板。 覆盖的流程: * **邮件组自助**(``app/domains/email_group/service.py``)—— 建组、成员自行退出、 owner 转交、申请加入、被移出。 * **Google 账号**(同上 + ``app/domains/google_workspace/account_provisioner.py``) —— 密码重置、新账号首登临时密码信。 * **动态邮件组**(``app/domains/email_group/dynamic_service.py`` + ``app/scheduled_jobs/google_handlers.py``)—— 规则变更的 IT 管理员播报、 规则漂移日报。 三条与其它域不同的约束,改这个文件之前先读: 1. ``password_reset`` / ``mail_group_created`` / ``mail_group_owner_transfer`` 在迁移 ``043_hr_finance_roles_and_email_groups`` 里被种成 **只有中文 subject/body_text** 的 ``email_template.*`` 覆盖行。运行时是逐字段合并 (``NotificationService._load_template``),中文字段永远取种子、``_en`` / ``_ja`` 取这里的 builtin。所以这三个 key 的中文文案 **必须与迁移种子逐字 一致** —— 否则线上中文用户看到的是种子,维护者看到的是这里的版本。 2. ``google_account_password`` 是唯一一封携带明文临时密码的信,它 **不走 dispatch**:``account_provisioner._send_password_email`` 直接调 email driver 发到个人邮箱,再用 ``record_external_email`` 记一条终态 outbox 行。因此这里 的模板是那封信的 **唯一文案来源**,由调用点自己 ``pick_localized`` + format。 该 key 属于 ``SECRET_TEMPLATE_KEYS``,永不 resend / retry / revive,也不进 收件人自己的站内信,所以不存在「重渲染时 context 缺失」的风险。 3. 可选值(退出原因、组描述)由调用点兜底成 ``—`` 再放进 ``context``,而不是在 模板里做条件分支 —— format 字符串没有条件语法,空字符串会渲染成 「退出原因:」这样的悬空标签。 """ from __future__ import annotations TEMPLATES: dict[str, dict[str, str]] = { # ── 邮件组 ──────────────────────────────────────────────────── # 中文 subject/body_text 与迁移 043 的 _MAIL_GROUP_CREATED_TEMPLATE 逐字一致。 "mail_group_created": { "subject": "邮件组 {group_email} 已创建", "subject_en": "Mail group {group_email} created", "subject_ja": "メーリングリスト {group_email} を作成しました", "body_text": ( "Hi {person_name},\n\n" "你申请的 Google 邮件组已创建成功。\n\n" " · 邮件组名称:{group_name}\n" " · 邮件地址:{group_email}\n" " · 描述:{group_description}\n" " · Owners:{group_owners}\n\n" "管理邮件组:https://groups.google.com/a/{group_domain}/g/{group_local}\n\n" "你可以到上面的链接查看/添加成员、修改设置。注意:你作为 owner," "在离职时需要先把这个邮件组转交给其他同事,才能完成离职。\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "The Google mail group you requested has been created.\n\n" " · Group name: {group_name}\n" " · Address: {group_email}\n" " · Description: {group_description}\n" " · Owners: {group_owners}\n\n" "Manage the group: https://groups.google.com/a/{group_domain}/g/{group_local}\n\n" "Use the link above to review or add members and change settings. " "Note: as an owner you must hand this group over to a colleague " "before your offboarding can complete.\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "お申し込みいただいた Google メーリングリストを作成しました。\n\n" " · グループ名:{group_name}\n" " · アドレス:{group_email}\n" " · 説明:{group_description}\n" " · オーナー:{group_owners}\n\n" "管理ページ:https://groups.google.com/a/{group_domain}/g/{group_local}\n\n" "上記のリンクからメンバーの確認・追加や設定の変更ができます。" "なお、オーナーの方は退職手続きを完了する前に、このグループを" "他の同僚へ引き継ぐ必要があります。\n\n" "— Helix IT プラットフォーム" ), }, "mail_group_member_left": { "subject": "{leaver_name} 已退出邮件组 {group_email}", "subject_en": "{leaver_name} left mail group {group_email}", "subject_ja": "{leaver_name} さんがメーリングリスト {group_email} から退出しました", "body_text": ( "Hi {person_name},\n\n" "{leaver_name}({leaver_email})已自行退出邮件组" "「{group_name}」({group_email})。\n\n" " · 退出原因:{reason}\n\n" "你是该邮件组的 owner 之一。如需重新添加该成员," "请到 Google Groups 管理页操作。\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "{leaver_name} ({leaver_email}) left the mail group " "\"{group_name}\" ({group_email}) on their own.\n\n" " · Reason: {reason}\n\n" "You are one of the group's owners. Re-add the member from the " "Google Groups admin page if that was not intended.\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "{leaver_name}({leaver_email})さんがメーリングリスト" "「{group_name}」({group_email})から自分で退出しました。\n\n" " · 退出理由:{reason}\n\n" "あなたはこのグループのオーナーの一人です。再度追加が必要な場合は " "Google Groups の管理ページから操作してください。\n\n" "— Helix IT プラットフォーム" ), }, "mail_group_join_requested": { "subject": "{requester_name} 申请加入邮件组 {group_email}", "subject_en": "{requester_name} requested to join mail group {group_email}", "subject_ja": "{requester_name} さんがメーリングリスト {group_email} への参加を申請しました", "body_text": ( "Hi {person_name},\n\n" "{requester_name}({requester_email})申请加入邮件组" "「{group_name}」({group_email}),等待你审批。\n\n" " · 申请理由:{reason}\n\n" "请在 Helix「邮件组目录 → 待审批」中通过或拒绝。\n" "你也可以直接到 Google Groups 管理该组:{manage_link}\n\n" "{cta_line}\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "{requester_name} ({requester_email}) asked to join the mail group " "\"{group_name}\" ({group_email}) and is waiting for your decision.\n\n" " · Reason: {reason}\n\n" "Approve or reject it in Helix under \"Mail groups → Pending review\".\n" "You can also manage the group directly in Google Groups: {manage_link}\n\n" "{cta_line}\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "{requester_name}({requester_email})さんがメーリングリスト" "「{group_name}」({group_email})への参加を申請し、" "あなたの承認をお待ちしています。\n\n" " · 申請理由:{reason}\n\n" "Helix の「メーリングリスト一覧 → 承認待ち」から承認または却下してください。\n" "Google Groups から直接グループを管理することもできます:{manage_link}\n\n" "{cta_line}\n\n" "— Helix IT プラットフォーム" ), "card_button_label": "去审批", "card_button_label_en": "Review request", "card_button_label_ja": "承認画面を開く", }, # ── 加入申请的裁决结果:通知申请人 ──────────────────────────── # ``email_group/service.py`` 用 f"mail_group_join_{req.status}" 拼 key, # 所以 approved / rejected 两个成员必须都在这里注册 —— 之前只注册了 # ``requested``,裁决结果对英文/日文读者一直是中文。 # context: person_name, group_email, group_name, decider_name, note "mail_group_join_approved": { "subject": "你已加入邮件组 {group_email}", "subject_en": "You have been added to mail group {group_email}", "subject_ja": "メーリングリスト {group_email} に追加されました", "body_text": ( "Hi {person_name},\n\n" "你的加入申请已通过,现在你是邮件组「{group_name}」" "({group_email})的成员。\n\n" " · 审批人:{decider_name}\n" " · owner 备注:{note}\n\n" "{cta_line}\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "Your join request was approved — you are now a member of the mail " "group \"{group_name}\" ({group_email}).\n\n" " · Approved by: {decider_name}\n" " · Owner note: {note}\n\n" "{cta_line}\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "参加申請が承認され、メーリングリスト「{group_name}」" "({group_email})のメンバーになりました。\n\n" " · 承認者:{decider_name}\n" " · オーナーのコメント:{note}\n\n" "{cta_line}\n\n" "— Helix IT プラットフォーム" ), "card_button_label": "查看我的邮件组", "card_button_label_en": "View my mail groups", "card_button_label_ja": "自分のメーリングリスト", }, "mail_group_join_rejected": { "subject": "加入邮件组 {group_email} 的申请被拒绝", "subject_en": "Your request to join mail group {group_email} was declined", "subject_ja": "メーリングリスト {group_email} への参加申請が却下されました", "body_text": ( "Hi {person_name},\n\n" "你申请加入邮件组「{group_name}」({group_email})的请求" "已被 owner 拒绝。\n\n" " · 审批人:{decider_name}\n" " · owner 备注:{note}\n\n" "{cta_line}\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "Your request to join the mail group \"{group_name}\" " "({group_email}) was declined by an owner.\n\n" " · Decided by: {decider_name}\n" " · Owner note: {note}\n\n" "{cta_line}\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "メーリングリスト「{group_name}」({group_email})への参加申請は、" "オーナーにより却下されました。\n\n" " · 判断者:{decider_name}\n" " · オーナーのコメント:{note}\n\n" "{cta_line}\n\n" "— Helix IT プラットフォーム" ), "card_button_label": "查看我的邮件组", "card_button_label_en": "View my mail groups", "card_button_label_ja": "自分のメーリングリスト", }, # 被 HR / IT 直接加进邮件组时通知本人。收件人是被加的那个人(不是 # 管理员),所以三语齐全 —— 员工触达面必须按人均语言渲染。外部地址没有 # identity_persons 行、也没有通知通道,service 层会跳过。 "mail_group_member_added": { "subject": "你已被加入邮件组 {group_email}", "subject_en": "You were added to mail group {group_email}", "subject_ja": "メーリングリスト {group_email} に追加されました", "body_text": ( "Hi {person_name},\n\n" "你已被加入邮件组「{group_name}」({group_email})。\n\n" " · 你的身份:{role}\n" " · 操作人:{actor_name}\n" " · 操作原因:{reason}\n\n" "从现在起,发往该地址的邮件你会收到。如果这与你的预期不符," "请联系操作人或 IT 团队。\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "You were added to the mail group \"{group_name}\" " "({group_email}).\n\n" " · Your role: {role}\n" " · Performed by: {actor_name}\n" " · Reason: {reason}\n\n" "You will now receive mail sent to that address. If this was " "not expected, contact the person above or the IT team.\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "メーリングリスト「{group_name}」({group_email})に" "あなたが追加されました。\n\n" " · あなたの役割:{role}\n" " · 操作者:{actor_name}\n" " · 理由:{reason}\n\n" "今後このアドレス宛のメールが届きます。心当たりがない場合は、" "操作者または IT チームへお問い合わせください。\n\n" "— Helix IT プラットフォーム" ), }, # 被取消负责人身份时通知本人。和「被移出邮件组」不是一回事:那是 # 收不到邮件了,这是不再对这个组负责 —— 不告诉他,前负责人会一直以为 # 组里的事还有人管。所以这条通知的是「职责变化」,三语齐全。 # 被取消负责人身份时通知本人。和「被移出邮件组」不是一回事:那是收不到 # 邮件了,这是不再对这个组负责 —— 不告诉他,前负责人会一直以为组里的事 # 还有人管。所以这条通知的是「职责变化」,三语齐全。 # # 拆成两个 key,而不是一个 key 加一个 {still_member} 变量:两种情况唯一 # 的差别是个布尔值,而用 ``是``/``否`` 去填它,会把一个中文字塞进英文和 # 日文正文的中间(「Still a plain member: 是」)—— 收件人是普通员工, # 这正是必须按人均语言渲染的那一面。 # owner 被别人转走时通知「被转走的那一方」。转交本身通知的是接手人; # HR / 管理员可以替别人转,所以不通知前任等于让他一直以为组还归自己管。 "mail_group_owner_transferred_away": { "subject": "你已不再是邮件组 {group_email} 的负责人", "subject_en": "You are no longer an owner of mail group {group_email}", "subject_ja": "メーリングリスト {group_email} の管理者から外れました", "body_text": ( "Hi {person_name},\n\n" "邮件组「{group_name}」({group_email})的负责人已转交给 " "{new_owner}。\n\n" " · 操作原因:{reason}\n\n" "从现在起,该组的成员变更、权限申请等事项不再需要你处理。" "如果这与你的预期不符,请联系 IT 团队。\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "Ownership of the mail group \"{group_name}\" " "({group_email}) has been transferred to {new_owner}.\n\n" " · Reason: {reason}\n\n" "You are no longer responsible for this group's membership or " "access requests. If this was not expected, contact the IT " "team.\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "メーリングリスト「{group_name}」({group_email})の管理者権限が " "{new_owner} に移管されました。\n\n" " · 理由:{reason}\n\n" "今後、このグループのメンバー変更や権限申請の対応は不要です。" "心当たりがない場合は、IT チームへお問い合わせください。\n\n" "— Helix IT プラットフォーム" ), }, "mail_group_owner_revoked_demoted": { "subject": "你已不再是邮件组 {group_email} 的负责人", "subject_en": "You are no longer an owner of mail group {group_email}", "subject_ja": "メーリングリスト {group_email} の管理者から外れました", "body_text": ( "Hi {person_name},\n\n" "你已不再是邮件组「{group_name}」({group_email})的负责人," "但仍然是该组的普通成员。\n\n" " · 操作人:{actor_name}\n" " · 操作原因:{reason}\n\n" "从现在起,该组的成员变更、权限申请等事项不再需要你处理;" "发往该地址的邮件你仍然会收到。" "如果这与你的预期不符,请联系操作人或 IT 团队。\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "You are no longer an owner of the mail group " "\"{group_name}\" ({group_email}). You are still a plain " "member of it.\n\n" " · Performed by: {actor_name}\n" " · Reason: {reason}\n\n" "You are no longer responsible for this group's membership or " "access requests, and you will keep receiving mail sent to " "the address. If this was not expected, contact the person " "above or the IT team.\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "メーリングリスト「{group_name}」({group_email})の管理者から" "外れました。一般メンバーとしては残っています。\n\n" " · 操作者:{actor_name}\n" " · 理由:{reason}\n\n" "今後、このグループのメンバー変更や権限申請の対応は不要です。" "このアドレス宛のメールは引き続き届きます。" "心当たりがない場合は、操作者または IT チームへお問い合わせ" "ください。\n\n" "— Helix IT プラットフォーム" ), }, "mail_group_owner_revoked_removed": { "subject": "你已不再是邮件组 {group_email} 的负责人", "subject_en": "You are no longer an owner of mail group {group_email}", "subject_ja": "メーリングリスト {group_email} の管理者から外れました", "body_text": ( "Hi {person_name},\n\n" "你已不再是邮件组「{group_name}」({group_email})的负责人," "并且已不在该组中。\n\n" " · 操作人:{actor_name}\n" " · 操作原因:{reason}\n\n" "从现在起,该组的成员变更、权限申请等事项不再需要你处理," "发往该地址的邮件你也不会再收到。" "如果这与你的预期不符,请联系操作人或 IT 团队。\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "You are no longer an owner of the mail group " "\"{group_name}\" ({group_email}), and you have been " "removed from it.\n\n" " · Performed by: {actor_name}\n" " · Reason: {reason}\n\n" "You are no longer responsible for this group's membership or " "access requests, and you will no longer receive mail sent to " "the address. If this was not expected, contact the person " "above or the IT team.\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "メーリングリスト「{group_name}」({group_email})の管理者から" "外れ、グループからも削除されました。\n\n" " · 操作者:{actor_name}\n" " · 理由:{reason}\n\n" "今後、このグループのメンバー変更や権限申請の対応は不要です。" "このアドレス宛のメールも届かなくなります。" "心当たりがない場合は、操作者または IT チームへお問い合わせ" "ください。\n\n" "— Helix IT プラットフォーム" ), }, "mail_group_member_removed": { "subject": "你已被移出邮件组 {group_email}", "subject_en": "You were removed from mail group {group_email}", "subject_ja": "メーリングリスト {group_email} から削除されました", "body_text": ( "Hi {person_name},\n\n" "你已被移出邮件组「{group_name}」({group_email})。\n\n" " · 操作人:{actor_name}\n" " · 操作原因:{reason}\n\n" "如果这与你的预期不符,请联系操作人或 IT 团队。\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "You were removed from the mail group \"{group_name}\" " "({group_email}).\n\n" " · Performed by: {actor_name}\n" " · Reason: {reason}\n\n" "If this was not expected, contact the person above or the IT team.\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "メーリングリスト「{group_name}」({group_email})から" "あなたが削除されました。\n\n" " · 操作者:{actor_name}\n" " · 理由:{reason}\n\n" "心当たりがない場合は、操作者または IT チームへお問い合わせください。\n\n" "— Helix IT プラットフォーム" ), }, # 中文 subject/body_text 与迁移 043 的 _MAIL_GROUP_TRANSFER_TEMPLATE 逐字一致。 # 种子文案不含转交原因,``{reason}`` 因此三语一律不出现 —— 中文被种子覆盖, # 只在 en/ja 里带上会造成同一封信各语言信息量不同。 "mail_group_owner_transfer": { "subject": "邮件组 {group_email} 的 owner 权限已转交给你", "subject_en": "You are now an owner of mail group {group_email}", "subject_ja": "メーリングリスト {group_email} のオーナー権限が移管されました", "body_text": ( "Hi {person_name},\n\n" "{previous_owner} 把 Google 邮件组 {group_email}(「{group_name}」)" "的 owner 权限转交给了你。你现在是这个邮件组的负责人之一。\n\n" "管理邮件组:https://groups.google.com/a/{group_domain}/g/{group_local}\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "{previous_owner} transferred ownership of the Google mail group " "{group_email} (\"{group_name}\") to you. You are now one of the " "people responsible for this group.\n\n" "Manage the group: https://groups.google.com/a/{group_domain}/g/{group_local}\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "{previous_owner} さんから Google メーリングリスト {group_email}" "(「{group_name}」)のオーナー権限が移管されました。" "あなたはこのグループの責任者の一人になりました。\n\n" "管理ページ:https://groups.google.com/a/{group_domain}/g/{group_local}\n\n" "— Helix IT プラットフォーム" ), }, # ── 动态邮件组(收件人只有 IT 管理员)─────────────────────────── "dynamic_email_group_changed": { "subject": "动态邮件组变更:{group_email}", "subject_en": "Dynamic mail group changed: {group_email}", "subject_ja": "動的メーリングリストの変更:{group_email}", "body_text": ( "Hi {person_name},\n\n" "动态邮件组「{group_name}」({group_email})发生变更。\n\n" " · 操作人:{actor_name}\n" " · 变更详情:{change_detail}\n\n" "请在 Helix「动态邮件组」管理页核对。\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "The dynamic mail group \"{group_name}\" ({group_email}) was " "changed.\n\n" " · Performed by: {actor_name}\n" " · Details: {change_detail}\n\n" "Review it on the Helix \"Dynamic mail groups\" admin page.\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "動的メーリングリスト「{group_name}」({group_email})が" "変更されました。\n\n" " · 操作者:{actor_name}\n" " · 変更内容:{change_detail}\n\n" "Helix の「動的メーリングリスト」管理ページでご確認ください。\n\n" "— Helix IT プラットフォーム" ), }, "dynamic_email_group_drift": { "subject": "动态邮件组规则漂移:{drift_count} 个组需核对", "subject_en": "Dynamic mail group rule drift — groups to review: {drift_count}", "subject_ja": "動的メーリングリストのルール乖離:{drift_count} 件の確認が必要です", "body_text": ( "Hi {person_name},\n\n" "以下动态邮件组的成员规则出现漂移,可能导致成员静默缺失," "请在 Helix「动态邮件组」管理页核对:\n\n" "{drift_lines}\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "The membership rules of the dynamic mail groups below have " "drifted, which can silently drop members. Please review them on " "the Helix \"Dynamic mail groups\" admin page:\n\n" "{drift_lines}\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "以下の動的メーリングリストのメンバールールに乖離が発生しています。" "メンバーが知らないうちに欠落する可能性がありますので、Helix の" "「動的メーリングリスト」管理ページでご確認ください:\n\n" "{drift_lines}\n\n" "— Helix IT プラットフォーム" ), }, # ── Google 账号 ─────────────────────────────────────────────── # 中文 subject/body_text 与迁移 043 的 _PASSWORD_RESET_TEMPLATE 逐字一致。 "password_reset": { "subject": "你的 Google 账号密码已重置", "subject_en": "Your Google account password has been reset", "subject_ja": "Google アカウントのパスワードをリセットしました", "body_text": ( "Hi {person_name},\n\n" "你发起的 Google Workspace 密码重置已完成。\n\n" "临时密码:{temp_password}\n\n" "重要提醒\n" "-----------\n" "• 此密码由系统随机生成,过程中没有任何人看到明文\n" "• 为了安全,强烈建议你尽快登录后自行修改为一个只有你自己知道的密码\n" "• 登录地址:https://accounts.google.com/\n\n" "如果这次重置不是你本人发起的,请立即联系 IT 团队。\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "The Google Workspace password reset for your account is done.\n\n" "Temporary password: {temp_password}\n\n" "Important\n" "-----------\n" "• This password was generated at random — nobody saw it in plaintext\n" "• For your own safety, sign in and change it to a password only " "you know as soon as you can\n" "• Sign-in URL: https://accounts.google.com/\n\n" "If you did not ask for this reset, contact the IT team immediately.\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "Google Workspace アカウントのパスワードリセットが完了しました。\n\n" "仮パスワード:{temp_password}\n\n" "重要なお知らせ\n" "-----------\n" "• このパスワードはシステムが自動生成したもので、" "担当者が平文を見ることはありません\n" "• 安全のため、ログイン後できるだけ早くご自身だけが知る" "パスワードへ変更してください\n" "• ログイン URL:https://accounts.google.com/\n\n" "お心当たりのないリセットの場合は、直ちに IT チームへご連絡ください。\n\n" "— Helix IT プラットフォーム" ), }, # 唯一一封携带明文首登密码的信。走的是 driver.send 直投个人邮箱, # 由 ``account_provisioner._send_password_email`` 自己取本模板并渲染。 "google_account_password": { "subject": "[Helix] 你的 Google Workspace 账号已就绪:{work_email}", "subject_en": "[Helix] Your Google Workspace account is ready: {work_email}", "subject_ja": "[Helix] Google Workspace アカウントの準備が整いました:{work_email}", "body_text": ( "{person_name} 你好,\n\n" "你的公司 Google Workspace 账号已经创建。请使用下方临时密码" "首次登录,Google 会要求你立即修改密码。\n\n" " · 账号:{work_email}\n" " · 临时密码:{temp_password}\n" " · 登录入口:https://accounts.google.com\n\n" "安全要求:\n" " - 临时密码仅供首次登录,登录后请立即修改\n" " - 修改密码后请尽快开启两步验证\n" " - 切勿向任何人转发此邮件中的密码\n\n" "如有疑问请联系 IT 团队。\n\n" "— Helix IT 平台" ), "body_text_en": ( "Hi {person_name},\n\n" "Your corporate Google Workspace account has been created. " "Sign in once with the temporary password below; Google " "will prompt you to change it on first login.\n\n" " · Account: {work_email}\n" " · Temporary password: {temp_password}\n" " · Sign-in URL: https://accounts.google.com\n\n" "Security:\n" " - Use this password ONCE then change it immediately\n" " - Enable two-step verification right after first login\n" " - Never share this password\n\n" "Questions? Contact IT.\n\n" "— Helix IT Platform" ), "body_text_ja": ( "{person_name} 様\n\n" "会社の Google Workspace アカウントを作成しました。" "下記の仮パスワードで初回ログインしてください。" "ログイン時に Google からパスワードの変更を求められます。\n\n" " · アカウント:{work_email}\n" " · 仮パスワード:{temp_password}\n" " · ログイン URL:https://accounts.google.com\n\n" "セキュリティ上のお願い:\n" " - 仮パスワードは初回ログインのみに使用し、直後に変更してください\n" " - パスワード変更後、できるだけ早く 2 段階認証を有効にしてください\n" " - このメールに記載されたパスワードは誰にも転送しないでください\n\n" "ご不明な点は IT チームへお問い合わせください。\n\n" "— Helix IT プラットフォーム" ), }, # ── Google 租户对账告警 ──────────────────────────────────────── # app/scheduled_jobs/google_handlers.py::_warn_active_employee_dark_accounts # —— 坐席同步发现「Helix 说在职、Google 说账号不 active」的人。IT-only, # 每人 30 天内只告警一次(按 audit 去重)。 # context: count / person_list(语言中立:``· 姓名 <邮箱>``,超 20 人时 # 追加一行 ``· ... (+N more)``)。 "google.active_employee_account_dark": { "subject": "[账号异常] {count} 位在职员工的 Google 账号已不活跃", "subject_en": ( "[Account anomaly] {count} active employees have a dark Google " "account" ), "subject_ja": ( "[アカウント異常] 在職中の従業員 {count} 名の Google アカウントが" "無効になっています" ), "body_text": ( "以下 [b]{count}[/b] 位[b]在职[/b]员工的 Google 账号在租户里已不是 " "active(被挂起或删除),但 HRIS / Helix 仍显示他们在职:\n\n" "{person_list}\n\n" "常见原因:① 有人在 Google 管理台手工挂起了账号(离职流程还没在 " "Helix 里跑起来);② HRIS 离职数据延迟。\n" "为什么要告诉你:Helix 的离职数据交接是走 Google Workspace 坐席这条" "链路的。账号先暗下来,坐席就会被回收,等离职流程真正开始时已经没有" "坐席可扫 —— 这正是历史上出现过的「无交接删除」的成因。\n" "请确认这些人是否已经离职,并在 Helix 里把离职流程跑起来。\n\n" "{cta_line}\n\n— Helix IT 平台" ), "body_text_en": ( "[b]{count}[/b] employees Helix and the HRIS still list as [b]active" "[/b] no longer have an active Google account in the tenant (it was " "suspended or deleted):\n\n" "{person_list}\n\n" "Usual causes: (1) somebody suspended the account by hand in the " "Google admin console before the offboarding process was started in " "Helix; (2) the HRIS termination record is late.\n" "Why this matters: Helix moves a leaver's data through the Google " "Workspace seat. Once the account goes dark the seat is revoked, so " "by the time offboarding really starts there is no seat left to " "scan — the way accounts have been deleted without a handover " "before.\n" "Please confirm whether these people have left, and start their " "offboarding process in Helix.\n\n" "{cta_line}\n\n— Helix IT Platform" ), "body_text_ja": ( "Helix と HRIS では[b]在職中[/b]となっている以下の [b]{count}[/b] 名" "について、テナント上の Google アカウントが active ではありません" "(停止または削除済み):\n\n" "{person_list}\n\n" "よくある原因:① Helix で退職プロセスを開始する前に、Google 管理" "コンソールで手動停止された;② HRIS の退職データの反映遅れ。\n" "重要な理由:Helix は退職者のデータ引き継ぎを Google Workspace の" "シート経由で行います。アカウントが先に無効になるとシートが回収され、" "退職プロセス開始時にはスキャンすべきシートが残っていません —— " "過去に「引き継ぎなしの削除」が起きた原因がこれです。\n" "これらの方が退職済みかどうかをご確認のうえ、Helix で退職プロセスを" "開始してください。\n\n" "{cta_line}\n\n— Helix IT プラットフォーム" ), "card_button_label": "查看离职管理", "card_button_label_en": "Open offboarding", "card_button_label_ja": "退職管理を開く", }, } __all__ = ["TEMPLATES"]