Business Requirements Specification (BRS)
Pharmagin Speaker Platform - 业务需求规格说明书
Version: 1.0 Date: 2026-02-19 Status: Draft Purpose: 为平台重写提供完整的业务需求定义
Table of Contents
- 1. Executive Summary
- 2. User Roles & Access Control
- 3. Core Business Domains
- 4. External Integration Requirements
- 5. Configuration Requirements
- 6. Non-Functional Requirements
- 7. Data Model Requirements
- Appendix A: Feature Flags Inventory
- Appendix B: Business Rules Catalog
1. Executive Summary
1.1 平台定位
Pharmagin Speaker Platform 是一个面向制药行业的演讲者项目管理平台。平台支持制药公司组织教育活动(如晚宴、研讨会、圆桌讨论),由医疗保健专业人员(HCPs)担任演讲者,面向 HCP 受众进行学术宣讲。平台管理参会者注册、预算追踪、法规合规及报告生成等完整业务流程。
1.2 目标用户
| 用户角色 | 应用 | 核心职责 |
|---|---|---|
| Agency Planner | Plannerview | 创建和管理 Program,配置注册站点,管理预算、合规文档,生成报告 |
| Sales Representative | Salesview | 提交 Program 请求,管理参会者,查看预算分配和报告 |
| Speaker (HCP) | Speakerview | 管理个人档案,签署合同,完成培训,提交费用报销 |
1.3 核心业务能力
- Program 全生命周期管理 - 从创建、审批、执行到关闭的完整流程
- Speaker 全生命周期管理 - 提名、入职、合同签署、培训认证、项目分配
- 参会者注册管理 - 多渠道注册、NPI/Target 调和、频率检查、签到签名
- 层级化预算管理 - 公司到项目级别的预算分配、上限控制与追踪
- 法规合规 - Aggregate Spend 报告、Transfer of Value 追踪、合规文档审计(满足 Sunshine Act 要求)
- 多渠道通信 - 邮件邀请、定时邮件、提醒通知、告警系统
- Zoom 虚拟会议 - 虚拟 Meeting/Webinar 创建、参会者注册、Webhook 事件处理
- 多维度报告 - Program 活动、参会者分析、Speaker 利用率、预算花费、Ad-hoc 报告构建器
- 多租户配置 - 按 Agency/Company/Product 三层动态配置,165+ Feature Flags
- 外部系统集成 - Salesforce/Veeva CRM、Zoom、SendGrid、SFTP、NPI Registry、Google Geocoding、SSO/SAML
1.4 系统规模
| 维度 | 目标 |
|---|---|
| 业务实体 | ~140 个核心实体 |
| Feature Flags | ~165 个(活跃) |
| 外部集成 | 12 个 |
| 前端应用 | 3 个(Plannerview、Salesview、Speakerview) |
2. User Roles & Access Control
2.1 角色层级模型
系统采用多维度 RBAC 权限模型,用户在 Instance / Company / Product 三个维度分别拥有不同角色和权限:
Instance (部署实例)
└── Company (制药公司)
└── Product (药品/品牌)
└── Role (角色)
└── Permission (权限)权限格式: {SCOPE}-{ID}-{PERMISSION} (如 PRODUCT-25-PROGRAMS)
2.2 预定义角色
Plannerview 角色 (Instance 级别):
- ADMIN - 完整管理权限:用户管理、配置管理、所有 Program 操作
- PLANNER - Program 管理、注册站点管理、预算管理、合规文档管理
- MULTI_MODULE_USER_ADMIN - 跨模块用户管理员
Salesview 角色 (Product 级别):
| 角色 | 数据可见范围 | 核心权限 |
|---|---|---|
| SALES_ADMIN | 全产品线 | 用户管理、预算分配、地理管理、所有报告、Program 管理 |
| UPPER_MANAGER | 全产品线 | 所有 Program、全部报告、审批查看 |
| REGIONAL_MANAGER | 所属 Region | Region 级 Program、预算分配(如启用)、报告 |
| DISTRICT_MANAGER | 所属 District | District 级 Program、预算分配(如启用)、报告 |
| SALES_PERSON | 仅本人数据 | 创建 Program、查看已安排/已完成的 Program、日历 |
| PLANNER | 全产品线 | 所有 Program、文档模板下载 |
Speakerview 角色 (Company 级别):
- Admin - Speaker 管理员:管理内容库、合同、培训
- Speaker - 普通 Speaker:管理个人档案、查看合同/培训、提交费用
- Sales - 销售代表视角(有限访问)
2.3 认证要求
| 认证方式 | 描述 | 应用场景 |
|---|---|---|
| 密码认证 | BCrypt 加密,支持密码历史检查 | 全部三个应用 |
| SSO/SAML 2.0 | 对接 Azure AD / Okta,签发 JWT | 企业用户登录 |
| API Token | JWT(RS256 签名),包含 userId、authorities、exp 等 claims | API 调用 |
BR-001: 系统应使用标准 JWT 替代内存 UUID Token,支持无状态认证和水平扩展。
BR-002: SSO 认证成功后直接签发 JWT,Cookie 必须设置 HttpOnly=true, Secure=true, SameSite=Strict。
BR-003: 密码重置 Token 应持久化存储(数据库或 Redis),包含过期时间,支持多实例部署。
BR-004: Speaker 认证应统一纳入 UnifiedUser 体系,移除 Speaker 实体中的密码相关字段。
2.4 授权模型
BR-005: 所有 API 端点应使用 @PreAuthorize 注解进行权限控制。
BR-006: 权限变更应通过短有效期 Access Token(15 分钟)+ 长有效期 Refresh Token 机制实时生效。
BR-007: 用户数量限制应按视图(SalesView/SpeakerView/PlannerView)控制活跃用户上限,白名单域名用户不受数量限制。
3. Core Business Domains
3.1 Program Lifecycle
3.1.1 领域描述
Program 是平台的核心业务实体,表示一个制药公司 Speaker 演讲项目(如晚宴、研讨会、圆桌讨论)。新系统中统一使用 Program 命名替代旧系统中的 MeetingRequest/Meeting 双实体。
3.1.2 Program 状态工作流
创建
|
+--> 预算充足 --> ASSIGNED(0)
| |
| 需要审批?
| | |
| 是 否
| | |
| v |
| PENDING_APPROVAL(12)
| | |
| 通过 拒绝
| | |
| v v
| ASSIGNED DENIED(13)
| |
+--> 预算不足 --> WAITLISTED(11) (可配置: 预算达限时直接拒绝)
|
v
PLANNING(6) --> REGISTERED(9) --> BILLING(1) --> CLOSED(4)
| |
v v
CANCELLED(2) --> CANCELLED_CLOSED(3) REOPENED(14) --> CLOSED
|
POSTPONED(7) --> POSTPONED_CLOSED(8)
其他: ESTIMATE(5), VOID(10)BR-008: Program 状态流转应使用状态机引擎(如 Spring Statemachine),替代硬编码 if/else 逻辑。
BR-009: 所有状态变更应使用命令模式 API:PUT /programs/{id}/status { action, reason }。
3.1.3 审批流程
审批配置来源于 ProgramType 的 approvals 配置(JSON),支持两种审批路径:
- 常规路径: DM (District Manager) -> RM (Region Manager) -> UM (Upper Management)
- Field Exhibit 路径: RBD -> Marketing -> Legal
每级审批支持基于成本阈值的自动审批规则:
- 如果 meetingCost < exceedsCost,该级自动通过
- 如果 meetingCost >= exceedsCost,需要该级手动审批
BR-010: 审批配置应使用强类型数据模型(ApprovalConfig),替代松散的 JSON Map 结构。
BR-011: 部分审批(Partial Approval)应支持逐级通知下一审批人。
BR-012: 审批超过 2 天的 Program 应自动发送提醒给 District Manager(可配置产品范围和时间阈值)。
3.1.4 Program 创建流程
Sales Rep 提交 Program 请求时,系统执行以下步骤:
- 检查
disallowProgramSubmission配置 - 检查 Zoom 时间冲突(如为虚拟项目)
- 获取 ProductUser 权限信息
- 计算 meetingCost
- 检查预算充足性(
hasEnoughBudget) - 执行审批流程(如需要)
- 分配 Planner
- 生成 Program 名称(meetingIdPrefix + sequence)
- 保存并发布
ProgramCreatedEvent - 自动生成:Registration Site、Budget Items、Project Tasks
BR-013: Program 创建应验证 Topic 有效期,过期 Topic 禁止使用。
BR-014: Program 关闭需满足以下前置条件:ACT 预算版本已创建、参会者列表已关闭、ToV 计算已完成。
3.1.5 Project Task 管理
每个 Program 可关联基于模板的任务清单,用于追踪 Program 执行过程中的待办事项。
BR-015: 系统应支持 Project Task 模板管理,创建 Program 时自动根据 ProgramType 生成任务清单。
3.1.6 数据模型(目标状态)
Program (核心)
├── id, name, productId, programTypeId, serviceTypeId
├── status, approvalStatus
├── meetingStartTime, meetingEndTime, timezoneId
├── plannerId, userId, teamId
└── createdAt, updatedAt
ProgramLocation (地理信息 - 1:1)
ProgramRequestor (请求者信息 - 1:1)
ProgramSpeaker (演讲者关联 - 1:N)
ProgramApproval (审批记录 - 1:N)
ProgramFinancial (财务信息 - 1:1)
ProgramCustomField (动态字段 - 1:N)
RegistrationSite (注册站点 - 1:1)3.2 Speaker Management
3.2.1 领域描述
Speaker Management 管理制药行业演讲者(HCP)的完整生命周期,包括 Profile 管理、合同管理、培训认证、内容/演示文稿管理、费用报销、Speaker Group 管理、提名管理等。
3.2.2 Speaker Onboarding 流程
Sales Rep 提名 Speaker
--> Admin/Planner 审核
--> Speaker 账户创建(门户注册)
--> 合同创建(Contract Creation Pending, status=3)
--> Speaker 签署合同(Contract Signature Pending, status=4)
--> W9 提交(W9 Pending, status=2)
--> Active(status=1)
--> Topic 培训 + Content 培训
--> Speaker 已认证(可被分配到项目)BR-016: Speaker 创建时应检查邮箱唯一性(忽略大小写,按 companyId 范围)。
BR-017: Speaker 删除应使用软删除(设置 deleted 标记),保留数据审计能力。
3.2.3 合同管理 (Contract)
- 支持多种合同类型,每个合同关联一个或多个 ProgramType
- 合同包含报酬条款(honoraria),新系统应使用
contract_honoraria_items表替代 15+ 个硬编码字段 - 合同签署流程:Not Signed(0) -> Speaker 签署 -> Signed(1)
- 支持下载合同文档(DOCX/PDF 格式,XDocReport 模板引擎生成)
BR-018: 合同报酬模型应使用结构化的 {contractId, honorariaType, amount} 表,替代硬编码字段和 JSONB 混用。
BR-019: Speaker 签署合同时应验证身份所有权(checkOwnerPermission)。
BR-020: 如启用 programQuantityLimit,系统应在 Speaker 搜索时检查该 Speaker 的已用配额并在超限时禁用选择。
3.2.4 演示文稿管理 (Presentation)
- Admin 上传 Core 演示文稿(PPT 文件),设置 Slide Detail 和插入点
- Admin 上传 Module/Case Study 内容
- Speaker 按 SpeakerGroup 可见性查看可用内容
- Speaker 创建个人演示文稿,选择 Module 填充插入点
- 系统使用 Aspose Slides 合并生成最终 PPTX
BR-021: 演示文稿生成应异步处理(消息队列或异步任务),避免阻塞请求线程。
BR-022: Content 可见性应通过 SpeakerGroup 关联控制。
3.2.5 报酬计算
BR-023: 系统应提供独立的 HonorariaCalculationService,统一管理 Speaker 的报酬余额计算,涵盖 honorariaCap、meetingHonoraria、speakerExpense、includeTeInHonorariaCalculation 等维度。
3.2.6 数据模型(目标状态)
Speaker (核心身份)
├── id, firstName, lastName, suffix, npiNumber, type, level, status
SpeakerAddress (地址 - 1:N, 类型: Office/Home/W9/NPI)
SpeakerContact (联系方式 - 1:N)
SpeakerCredential (医疗执照/认证 - 1:N)
SpeakerPreference (偏好设置 - 1:1)
SpeakerNomination (提名信息 - 独立表)
SpeakerContract (合同 - 1:N)
ContractHonorariaItem (合同报酬项 - 1:N per contract)
SpeakerTraining (培训记录 - 1:N, 合并 topic 和 module 培训)3.3 Attendee & Registration
3.3.1 领域描述
管理参会人员从添加、邀请、注册、签到到合规审查的完整生命周期。核心子功能包括:参会人员管理、注册工作流、HCP 合规调和(NPI/Target/Salesforce)、出席频率检查、签到签名、住宿管理、注册站点配置、Transfer of Value 追踪。
3.3.2 注册状态工作流
Pending(0) --邀请--> Invited(10) 或 RepInvited(70)
|
v
Accepted(20) 或 Declined(60) 或 Canceled(50)
|
v
Registered(40)
|
v
Check-In (signInStatus: 0->1 或 3)注册来源(RegistrationSource): 1=Open Reg, 2=Email Invitation, 3=Sales Rep(Quick Reg), 4=Planner(Contact Import), 6=Walk-In, 7=Copy Attendees, 8=Auto Reg, 9=Sales Rep(Batch Reg), 10=Set Registration Status
BR-024: 注册状态流转应使用状态机框架管理,每个 Product 可配置允许的状态转换矩阵(RegistrationWorkflow)。
BR-025: 注册时应检查最大参会人数限制(meeting.expectedAttendees),已注册人数 + guest 数不能超过上限。
3.3.3 HCP 调和 (Reconciliation)
系统支持 3 种调和类型(由 Product.npiTarget 配置决定):
| 类型 | 数据源 | 匹配方式 |
|---|---|---|
| NPI (type=1) | NPPES NPI 数据库 | NPI 号码、姓名、城市、州 |
| TARGET (type=2) | 客户上传的 Target HCP 列表 | companyId + productId 过滤 |
| SALESFORCE (type=3) | Salesforce Force API | CRM 联系人匹配 |
BR-026: 系统应提供统一的 ReconciliationService 作为所有调和操作的入口,替代当前分散的 3 个独立方法。
BR-027: 批量自动调和应通过 NPI + Name + City + State 搜索,仅当精确匹配到 1 条时自动合并。
3.3.4 频率检查 (Frequency Check)
BR-028: 系统应在参会者注册时自动执行频率检查,控制 HCP 在特定时间范围内参加 Speaker Program 的次数。
BR-029: 频率检查支持以下配置:
frequencyPeriodType=0: 按月数范围检查frequencyPeriodType=1: 按 FiscalYear 范围检查- 支持按 Topic 过滤(
topicEnabled) - 特定 attendeeCategory 可白名单跳过检查(
bypassedFrequencyCheckCategories)
BR-030: 触发频率限制时应自动发送通知邮件给 Planner。
3.3.5 签到与签名
BR-031: 系统应支持参会者现场签到(signInStatus 更新)、电子签名采集和地理位置记录。
3.3.6 住宿管理 (Sleeping Room)
BR-032: 系统应支持酒店房间管理(SleepingRoom CRUD)、房型库存按日期管理(SleepingRoomInventory)、参会者住宿关联和库存自动更新。
BR-033: 系统应支持住宿报表下载:Rooming List、Pickup Report、未预订参会者列表。
3.3.7 数据模型改进
BR-034: Attendee 主键应使用 Long 自增,保留 UUID 作为公开标识符(externalId)。
BR-035: registrationStatus / hcpStatus / signInStatus 应使用 PostgreSQL ENUM 类型,增加数据库层约束。
3.4 Budget & Financial
3.4.1 领域描述
管理从 Admin -> Region -> District 的预算逐级分配,按品牌维度的预算管理,单个 Program 的预算行项目(含 SOW/EST/BILL/ACT/CXL 五个版本),预算上限控制和财务年度管理。
3.4.2 预算层级
Company -> Product -> Brand -> Region -> District -> Territory -> Program
每个层级可设置分配金额和上限3.4.3 预算分配流程
- Admin 录入 Region 预算 - 创建 BudgetAllocationHistory (ADMIN_TO_REGION)
- RM 分配到 District - 支持平均分配(EVERY)或指定分配(SINGLE),创建 BudgetAllocationHistory (REGION_TO_DISTRICT)
- District 间转移 - 验证源 District 余额充足,创建双向 BudgetCapItem 记录
- 取消分配 - District 预算退回 Region
BR-036: 分配预算时,allocatedBudget 不能超过 Region 的 unallocatedBudget。
BR-037: 取消分配时,releaseBudget 不能超过 District 当前预算。
BR-038: 转移预算时,allocatedBudget 不能超过源 District 的余额。
3.4.4 预算上限方法 (Cap Method)
| Cap 方法 | 检查逻辑 |
|---|---|
| SharedAmountPool (0) | 所有 ProgramType 共用一个 $ 池,检查 locale.balance >= meetingCost |
| ProgramTypeCap (4) | 每个 ProgramType 有独立 $ 上限,检查 programType.balance >= meetingCost |
| ProgramTypeQty (2) | 只限制数量,检查 totalQuantity - programQuantity > 0 |
BR-039: hasEnoughBudget 检查应基于 Program 实际 BudgetItem 成本,而非模板估算值。
3.4.5 Program 预算版本管理
每个 Program 有 5 个预算版本:
| 版本 | 用途 |
|---|---|
| SOW (1) | Scope of Work - 工作范围估算 |
| EST (2) | Estimate - 预算估计 |
| BILL (3) | Billing - 账单 |
| ACT (4) | Actual - 实际花费 |
| CXL (5) | Cancellation - 取消费用 |
BR-040: 版本复制操作应将源版本的 items 复制到目标版本,已有对应 item 时更新,没有时插入。
3.4.6 成本计算公式
Total = BaseCost + TaxCost + GratuityCost
BaseCost = quantity * unitCost
TaxCost:
固定金额 (taxMethod=1): tax
百分比 (taxMethod=0): quantity * unitCost * tax / 100
GratuityCost:
含税 (gratuityIsTaxed=1): 根据 taxMethod 和 gratuityMethod 组合计算
不含税: 根据 gratuityMethod 计算 (固定金额或百分比)BR-041: 成本计算应统一为独立的 BudgetCalculator 服务,Java 和 SQL 使用同一计算逻辑。
3.4.7 财务年度
BR-042: 系统应支持按 Product 配置 Fiscal Year 的起止日期,同一 productId 不允许重叠的 fiscal year。
BR-043: Fiscal Period 年份列表应动态生成(当前年份 -5 到 +2),不得硬编码。
3.5 Compliance & Regulatory
3.5.1 领域描述
追踪和报告制药公司向 HCPs 的价值转移(Transfer of Value, TOV),满足美国 Sunshine Act 的透明度报告要求。包含三个核心子领域:Aggregate Spend 报告、TOV 追踪、Compliance Document Audit。
3.5.2 Aggregate Spend Report
- 按 Product 配置导出哪些字段
- 支持多种报告格式:标准格式、Porzio 格式、自定义格式
- 包含两部分数据:F&B TOV per attendee + Speaker expenses from budget items
- 仅包含已关闭会议(CLOSED / CANCELLED_CLOSED)的数据
- 仅计算已签到参会者(signInStatus IN (1,3))
BR-044: Aggregate Spend 报告配置应按 Product 管理字段选择,支持运行时动态配置。
BR-045: 报告格式应配置化管理,消除 Porzio、Verona 等客户特定格式的硬编码。
3.5.3 Transfer of Value (TOV) 计算
TOV 计算触发条件(全部满足时触发通知):
- Budget Version = BILL(4)
- Meeting Status = CLOSED 或 CANCELLED_CLOSED
- Attendee List Status = CLOSE
enableTOVCalculationNotification= true
TOV 计算逻辑:
headcount = allocationHeadcount ?? actual consumed food headcount
budget = usedTov ?? foodBeverageBudget
attendeeTov = budget / headcount (HALF_UP, 4 位小数)BR-046: TOV 计算前置条件:Budget Version 必须为 ACT,Attendee List 必须关闭。
BR-047: 系统应支持 TOV 手动调整(批量和单个),并记录调整原因(tovChangeReason, headcountChangeReason)。
BR-048: PLID 匹配应抽取为独立的 PLIDMatchingService,使用枚举而非魔术字符串表示匹配结果。
3.5.4 Compliance Document Audit
- 按 Program 的 ServiceType 匹配适用的合规文件模板清单
- 每个文件支持上传、下载、标记"Ready for Audit"
- Planner 可启用/关闭 Program 的审计状态
- Sales Rep 只读查看审计数据
BR-049: Admin/Planner 管理文件模板和审计状态,Sales Rep 只读查看。
BR-050: 合规文件清单应按 Product 和 ServiceOption 筛选。
3.6 Communication & Notification
3.6.1 领域描述
管理平台全部通信和通知功能:邮件通信、邮件邀请、定时邮件、调查问卷邮件、提醒系统、告警系统、退订管理、SendGrid 集成、iCalendar 生成。
3.6.2 邮件发送
- 支持 40+ 模板变量替换(如
%%FIRST_NAME%%、%%MEETING_NAME%%、%%SPEAKER_FIRST_NAME%%) - 支持 Email Sandbox 模式(测试环境重定向到指定邮箱)
- 支持附件、内联图片、iCalendar 日历附件
- 发送前自动过滤退订名单
BR-051: 邮件发送应引入消息队列,支持发送状态追踪(pending/sent/failed/bounced)和失败重试(指数退避)。
BR-052: 退订检查应在所有邮件发送路径统一执行,包括确认邮件和取消邮件。
BR-053: 邮件模板变量替换应抽取为独立的 EmailTemplateEngine,支持变量注册、验证和缺失变量报告。
3.6.3 邮件邀请系统
- 基于 ServiceType 配置邀请模板
- 支持邀请追踪(tracking pixel + invitationId)
- 支持快速邀请和批量邀请
BR-054: 邀请发送需满足前置条件:对应 ServiceType 有邀请模板、注册站点为 Active 状态。
3.6.4 定时邮件
- 支持"立即发送"和"定时任务"两种模式
- 定时规则:X 天前(sendType=0)、X 天后(sendType=1)、日期范围内每 X 天(sendType=2)
- 按参会者类型、注册状态、签到状态过滤收件人
BR-055: 定时邮件任务应支持激活/停用,逻辑删除。
3.6.5 统一告警系统
系统应使用统一的 Notification 模型替代当前分散的 4 种告警表:
Notification
├── id, type, category, title, description
├── targetUserType, targetUserId
├── sourceType, sourceId
├── actionUrl, actionType
├── status (unread/read/dismissed)
└── createdAt, readAtBR-056: 告警系统应统一存储、统一查询、统一已读管理,替代 t_alert、t_custom_alert、t_meeting_alert、t_budget_alert 及其 view_history 表。
3.6.6 提醒系统
| 提醒类型 | 频率 | 描述 |
|---|---|---|
| 注册提醒 | 每天 7AM ET | 向 Invited 但未注册的参会者重发邀请 |
| 邀请提醒(Planner) | 每周日 8AM ET | 向 Planner 发送未注册参会者汇总 |
| 邀请提醒(Attendee) | 每周二 8AM ET | 向参会者重发邀请 |
| 待审批提醒 | 每天 2AM | 超过 2 天的待审批 Program 提醒 DM |
| Speaker 提醒 | 查询驱动 | 未培训模块、未签合同、新视频标记 |
BR-057: 提醒时间和频率应可配置,不得硬编码产品 ID 或时间参数。
3.6.7 SendGrid 集成
BR-058: SendGrid 用于邮件活动追踪(opens, clicks 等),每日增量同步。未来可考虑通过 SendGrid Webhook 替代定时轮询实现实时事件通知。
3.7 Geographic & Territory
3.7.1 领域描述
管理制药企业销售组织的地理层级结构,是平台预算分配和数据可见性控制的基础设施。
3.7.2 层级结构
Product
└── SalesForce (销售部队)
└── Region (大区) - 关联 RegionManager
└── District (区域) - 关联 DistrictManager
└── Territory (辖区) - 关联 Sales Rep
Team (跨地理团队)
├── 关联 SalesForce (1:1)
├── 关联 Brand[] (M:N)
└── 关联 ProgramType[] (M:N)3.7.3 Planner 分配
Planner 分配支持层级继承:从最低层级(Territory)向上查找第一个非 null 的 plannerId。
BR-059: Planner 分配到 Region 级别时,应级联更新该 Region 下所有 District 和 Territory 的 plannerId。
3.7.4 地理节点重分配
BR-060: District 重分配前应检查预算是否已反分配(当 brandBudgetAllocationEnabled 时)。
BR-061: 重分配操作应在事务中级联更新 UserProduct 和 MeetingRequest 的地理关联字段。
3.7.5 用户地理绑定
BR-062: 用户数据可见范围由地理绑定决定:
- Sales Person -> 仅本人 Territory
- District Manager -> 所属 District 下所有 Territory
- Regional Manager -> 所属 Region 下所有 District/Territory
- 支持 Secondary Geography(附加可查看的 Region/District)
3.7.6 验证规则
BR-063: 同一层级下节点名称不能重复(如同一 productId 下 Region 名称唯一)。
BR-064: 节点下有关联数据时不可删除(有子节点、关联用户、关联 Program)。
3.7.7 自定义标签
BR-065: 地理层级标签(Region/District/Territory)应支持客户自定义(通过 CustomLabelConfiguration)。
3.8 Reporting & Analytics
3.8.1 领域描述
为三类用户提供多维度数据可视化、统计分析和数据导出能力,覆盖 Program 活动报告、Attendee 分析、At a Glance 仪表板、Ad-hoc 报告构建器、Custom Reports 和 Data Extract 等。
3.8.2 标准报告体系
Program Activity 报告:
- Program Summary(项目汇总下载)
- Fiscal YTD Spend by Brand(按品牌年度至今花费)
- Programs by Budget Status(按预算状态)
- Program Activity by Geography and Spend(按地理和花费)
- Program Activity by Sales Representatives(按销售代表)
- Speaker Utilization(Speaker 利用率)
Attendee Analytics 报告:
- Attendee Tracker(参会者追踪下载)
- Registration Summary(注册摘要)
- Registration by Specialty / Geography / Program
BR-066: 所有报告应统一 Product/Region/District 三级权限过滤,抽取为通用的 ReportPermissionFilter。
BR-067: 大报告应采用异步模式:提交报告任务 -> 后台生成 -> 完成后通知用户下载。
3.8.3 Ad-hoc 报告构建器
- 支持 34 个系统字段 + 自定义字段选择
- 用户拖拽排序字段构建报告
- 支持运行、分页查看和 Excel 下载
BR-068: Ad-hoc 报告字段应从数据库配置加载,支持动态扩展。同一 Program 下报告名称唯一。
3.8.4 导出引擎
系统应提供注解驱动的通用导出框架:
- 支持
@ExcelColumn注解定义导出字段元数据 - 支持按 AgencyConfig / ProductConfig 动态控制列的显示/隐藏
- 支持 DynamicField 运行时列
- 支持 XLSX、CSV、TXT 格式
BR-069: 导出引擎应统一在 ReportExporter 中,支持 Excel、CSV、PDF(未来扩展)格式。
3.8.5 Custom Reports
BR-070: 系统应将 R/Python 脚本报告迁移到 Java 服务端或沙箱化报告模板引擎,消除服务器环境依赖和安全风险。
3.9 Content & Document
3.9.1 领域描述
管理平台全部文档和内容资产,包括文档模板管理(XDocReport Velocity 模板引擎)、通用文件上传/下载服务、内容库管理(演示文稿、模块、案例研究)。
3.9.2 文档模板生成
- 使用 XDocReport + Velocity 模板引擎
- 支持 DOCX、PDF、XHTML 三种输出格式
- 模板匹配优先级:serviceType > programType > productId > 全局
- 上下文变量:meetingrequest、speaker、planner、salesrep、attendees、regQRCode 等
文档类型:签到表、纸质邀请、参会者问卷回复、签名报告、酬金发票、Speaker 费用报销、项目后认证、酬金附函
BR-071: PDF 转换策略应配置驱动,不得硬编码模板文件名来决定使用 Docx4J 还是 CloudConvert。
BR-072: 文档模板上传应验证文件扩展名和大小限制。
3.9.3 文件管理
- 支持 26 种文件类型分类存储
- 文件使用 MD5 哈希命名实现去重
- 目标:迁移到对象存储服务(S3/MinIO),支持水平扩展
BR-073: 文件上传应添加类型白名单、大小限制和恶意内容扫描。
BR-074: 文件搜索必须使用参数化查询,禁止 SQL 拼接。
3.9.4 内容库
- Content 类型:Core Presentation(type=0, sub=0)、Module(type=0, sub=1)、Case Study(type=0, sub=2)、Other Content(type=1)
- 内容关联 Topic 和 SpeakerGroup
- Speaker 按 SpeakerGroup 可见性查看内容
BR-075: Content 和 Document 概念应统一为 Asset 模型,使用枚举替代魔法数字。
3.10 Survey & Feedback
3.10.1 领域描述
管理药品演讲项目相关的问卷调查功能:问卷模板创建、问卷与产品/项目类型绑定、问卷填写(Attendee/Speaker/Sales Rep)、结果统计分析和 Excel 下载。
3.10.2 问卷类型
| 类型 | 填写者 | 触发方式 |
|---|---|---|
| Attendee Survey | 参会者 | 项目结束后邮件通知 |
| Sales Rep Survey | Sales Rep | 项目结束后在 Salesview 填写 |
| Speaker Survey | Speaker | 在 Speakerview 填写 |
| Attendee In Program Survey | 参会者 | 在特定 Program 中填写 |
3.10.3 问卷流程
- Planner 创建问卷模板(SurveyBuilder 可视化编辑器)
- 配置问卷的产品/项目类型绑定
- 激活问卷
- 参会者/Speaker/Sales Rep 填写问卷
- 查看统计分析和下载结果
BR-076: 问卷模板应使用统一的动态模板系统,废弃 Speakerview 中按 companyId 硬编码的 Speaker Survey 字段定义。
BR-077: 问卷名称唯一性检查;更新已有回答的问卷时需确认(forceUpdate=true),更新后自动停用。
BR-078: Attendee Survey 按 attendeeId 去重,其他类型按 meetingRequestId 去重。
BR-079: 如启用 enableCloseOutProgram 且项目已关闭,禁止提交问卷。
3.10.4 数据模型改进
BR-080: products JSONB 字段应拆分为 t_survey_product 和 t_survey_program_type 关联表。
BR-081: 为 content 和 response 定义强类型 DTO。
3.11 Expense Management
3.11.1 领域描述
管理 Speaker 在演讲项目中产生的费用报销流程:费用报告创建、明细管理、收据上传、提交审批、审批/拒绝、历史记录。
3.11.2 费用状态工作流
DRAFT(0) --> PENDING_APPROVED(3) --> APPROVED(1)
--> REJECTED(2) --> DRAFT(0)3.11.3 费用报告流程
- Speaker 选择会议,创建费用报告(初始状态 DRAFT)
- 添加费用明细(交通、住宿、餐饮等)+ 上传收据
- 提交费用报告(状态 -> PENDING_APPROVED)
- Planner 审批或拒绝
BR-082: 费用报告和明细应使用软删除,保留数据审计能力。
BR-083: 提交时后端应自动从 ExpenseItem 合计 amount,不接受前端传入的 amount。
BR-084: 每个操作应验证 Speaker 权限(checkSpeakerPermission)。
BR-085: 费用分类支持层级结构(parentCategoryId)。
3.11.4 收据上传
BR-086: 收据上传应统一使用 File Module,先上传获取 fileId 再关联到 ExpenseItem,添加文件类型和大小限制。
3.12 Virtual Programs
3.12.1 领域描述
管理药品演讲项目的虚拟会议功能,支持 Zoom Virtual Meeting、Zoom Webinar 和第三方虚拟会议。
3.12.2 虚拟会议类型
| 类型 | 代码 | 描述 |
|---|---|---|
| Zoom Virtual Meeting | 1 | 标准 Zoom 会议 |
| Zoom Webinar | 2 | Zoom 网络研讨会 |
| Third-Party | 3 | 第三方虚拟会议(手动管理 URL) |
3.12.3 创建流程
- Planner 选择 Zoom 用户(Host)
- 系统通过 Zoom API 创建 Meeting/Webinar
- 保存虚拟会议信息到独立数据表
- 参会者注册时自动注册到 Zoom 会议
- 发送虚拟会议邀请
BR-087: 虚拟会议信息应存储在独立数据表(t_virtual_meeting、t_virtual_meeting_attendee),替代 JSONB 字段。
BR-088: Zoom Host 选择顺序:指定的 zoomUser > Sales Rep email > Planner email > 默认配置。
3.12.4 Webhook 处理
participant.join- 记录参会者加入时间participant.leave- 记录参会者离开时间meeting.ended- 获取会议报告,更新参会记录
BR-089: Webhook 签名验证使用 HMAC-SHA256,时间戳容差 5 分钟。
3.12.5 Token 管理
BR-090: Zoom Access Token 应按 productId 缓存,支持多产品使用不同 Zoom 账号。
4. External Integration Requirements
4.1 集成清单
| 外部系统 | 方向 | 协议 | 用途 |
|---|---|---|---|
| Salesforce | 双向 | REST API(迁移自 SOAP) | CRM 联系人/活动同步 |
| Veeva CRM | 双向 | SOAP Partner API | Veeva 多渠道活动同步 |
| Zoom | 双向 | REST API + Webhook | 虚拟会议管理 |
| SendGrid | 入向 | REST API / Webhook | 邮件活动追踪 |
| iCal4j | 出向 | iCalendar 标准 | 日历邀请生成 |
| Google Maps | 出向 | REST API | 地理编码 |
| SFTP | 出向 | SSH/SFTP | 文件传输 |
| CloudConvert | 出向 | REST API | DOCX 到 PDF 转换 |
| SSO/SAML | 入向 | SAML 2.0 | Azure AD/Okta SSO |
| NPI Registry | 入向 | 数据库查询 | 医疗人员标识验证 |
| Mosaic | 出向 | 数据库 + Excel | 合规数据导出 |
| Podio | 出向 | REST Webhook | Program 创建通知 |
4.2 统一集成架构
BR-091: 所有外部集成应使用统一的集成基础设施层:
IntegrationClient (统一抽象)
├── RetryPolicy (指数退避 + 抖动, 使用 Resilience4j)
├── CircuitBreaker (断路器)
├── TimeoutPolicy (超时控制)
├── RateLimiter (限流)
├── Metrics (Micrometer 指标)
└── CredentialProvider (密钥管理)4.3 Salesforce 集成要求
BR-092: 从 SOAP Partner API 迁移到 REST API。
BR-093: 消除 SOQL 拼接,使用参数化查询。
BR-094: 按产品隔离连接,每个产品拥有独立的 Salesforce 连接。
BR-095: 大批量同步使用消息队列异步处理。
4.4 Zoom 集成要求
BR-096: 合并 Meeting 和 Webinar 服务的公共逻辑到基类,通过策略模式差异化。
BR-097: 处理 429 Rate Limit 响应,实现指数退避。
4.5 凭据管理
BR-098: 所有集成凭据应迁移到密钥管理服务(如 AWS Secrets Manager 或 HashiCorp Vault),支持自动轮换和访问日志审计。
4.6 SSO 统一
BR-099: 合并 pharmagin-sso 和 pharmagin-login 为单一服务,使用 Spring Security SAML2(5.x+),SSO 成功后直接签发 JWT。
5. Configuration Requirements
5.1 配置层级
Agency Config (实例级)
└── Company Config (公司级 - 面向 Speaker 品牌定制)
└── Product Config (产品级 - 最细粒度功能开关)5.2 配置存储
BR-100: 所有 Feature Flags 应从 YAML 迁移到数据库表,支持运行时动态切换:
t_feature_flag (
flag_key VARCHAR,
scope ENUM('AGENCY', 'PRODUCT', 'COMPANY'),
scope_id INTEGER,
value JSONB,
description TEXT,
updated_at TIMESTAMP,
updated_by INTEGER
)BR-101: YAML 仅保留基础设施配置(数据库连接、端口、外部服务 URL 等)。
5.3 Feature Flag 命名规范
BR-102: 全部使用正向命名 xxxEnabled(boolean, true = enabled),消除 disable* 反向命名的混淆。
5.4 配置 API 安全
BR-103: 公共 API 只返回前端需要的配置子集,严格排除 API Keys、Passwords 等敏感信息。
5.5 字典数据管理
系统应管理以下字典数据:Products、Brands、Topics、ProgramTypes、ServiceTypes、Regions、Districts、Territories、Teams、Venues、PLIDs、Speaker Levels、Medical Specialties(60+)等。
BR-104: 字典数据应支持 CRUD 操作和下拉框查询两种模式。
5.6 主题/品牌系统
BR-105: 系统应支持客户自定义视觉风格(primaryColor, secondaryColor, logo, footer),由 Nginx 注入的客户 ID 头驱动品牌配置加载。
6. Non-Functional Requirements
6.1 性能要求
BR-106: 标准列表查询响应时间 < 500ms,报告生成 < 5s(小报告)或异步(大报告)。
BR-107: 支持水平扩展,无状态认证(JWT),Redis 或数据库持久化会话相关数据。
6.2 安全要求
BR-108: 所有 API 端点添加 RBAC 权限控制。
BR-109: 文件上传添加白名单、大小限制、恶意内容扫描。
BR-110: 消除所有 SQL 注入风险,使用参数化查询。
BR-111: 密码使用 BCrypt 加密,移除所有明文密码机制。
BR-112: 登录接口添加 Rate Limiting 防暴力破解。
6.3 审计要求
BR-113: 所有关键业务操作应记录审计日志:Program 状态变更、审批操作、预算分配、合规文档状态变更、配置变更。
BR-114: 审计日志应包含:操作人、操作时间、操作类型、变更前值、变更后值。
6.4 可观测性
BR-115: 所有外部集成操作使用 MDC 记录 correlation ID、集成名称、操作类型。
BR-116: 每次外部调用记录延迟、成功/失败计数(Micrometer 指标)。
BR-117: 暴露 /actuator/health 中各集成的连通性检查。
6.5 数据迁移
BR-118: 系统应提供从旧系统(MeetingRequest/Meeting 双实体模型)到新系统(统一 Program 模型)的数据迁移方案。
BR-119: ID 类型统一策略:Attendee 主键从 UUID String 改为 Long 自增,保留 UUID 作为公开标识符。
7. Data Model Requirements
7.1 核心实体(目标状态)
Program Domain
| 实体 | 描述 | 主键 |
|---|---|---|
| Program | 项目核心信息 | Long (auto-increment) |
| ProgramLocation | 项目地理信息 | Long, FK: programId |
| ProgramRequestor | 请求者信息 | Long, FK: programId |
| ProgramSpeaker | 项目演讲者关联(一对多) | Long, FK: programId + speakerId |
| ProgramApproval | 审批记录 | Long, FK: programId |
| ProgramFinancial | 财务信息 | Long, FK: programId |
| ProgramCustomField | 动态字段 | Long, FK: programId |
| ProgramTask | 项目任务 | Long, FK: programId |
| RegistrationSite | 注册站点 | Long, FK: programId |
| ProgramType | 项目类型 | Long |
| ServiceType | 服务类型 | Long |
Speaker Domain
| 实体 | 描述 | 主键 |
|---|---|---|
| Speaker | 核心身份信息 | Long |
| SpeakerAddress | 地址(一对多) | Long, FK: speakerId |
| SpeakerContact | 联系方式 | Long, FK: speakerId |
| SpeakerCredential | 医疗执照 | Long, FK: speakerId |
| SpeakerContract | 合同 | Long, FK: speakerId |
| ContractHonorariaItem | 合同报酬项 | Long, FK: contractId |
| SpeakerTraining | 培训记录(统一) | Long, FK: speakerId |
| SpeakerGroup | 分组 | Long |
Attendee Domain
| 实体 | 描述 | 主键 |
|---|---|---|
| Attendee | 参会者 | Long (UUID 作为 externalId) |
| AttendeeType | 参会者类型 | Long |
| AttendeeSignature | 电子签名 | Long, FK: attendeeId |
| SleepingRoom | 住宿 | Long |
| SleepingRoomInventory | 房型库存 | Long, FK: sleepingRoomId |
Budget Domain
| 实体 | 描述 | 主键 |
|---|---|---|
| BudgetVersion | 预算版本 | Long |
| BudgetCategory | 预算分类 | Long |
| BudgetItem | 预算行项目 | Long |
| BudgetCapLocale | 区域预算上限 | Long |
| BudgetAllocationHistory | 分配历史 | Long |
| FiscalYear | 财务年度 | Long |
Virtual Meeting Domain
| 实体 | 描述 | 主键 |
|---|---|---|
| VirtualMeeting | 虚拟会议信息 | Long, FK: programId |
| VirtualMeetingAttendee | 虚拟参会者 | Long, FK: virtualMeetingId |
7.2 命名统一规则
| 旧名称 | 新名称 |
|---|---|
| MeetingRequest | Program |
| Meeting | RegistrationSite |
| MeetingProgramType | ProgramType |
| ProgramServiceType | ServiceType |
| MeetingProjectTask | ProgramTask |
| SalesTeam | SalesForce |
7.3 数据完整性规则
BR-120: 所有实体使用统一的软删除策略(deleted 标记字段)。
BR-121: 所有 JSONB 字段应定义强类型 Java DTO,使用 JSON Schema 验证结构。
BR-122: 数据库表名统一使用 t_ 前缀。
BR-123: 所有外键关系应在数据库层面定义约束。
Appendix A: Feature Flags Inventory
A.1 Agency Level Flags (14 个)
| Flag | 描述 |
|---|---|
projectTaskEnabled | 启用项目任务功能 |
enableScheduledReports | 启用定时报告 |
enableApprovalFlow | 启用可配置审批流 |
enableAutomatedEmail | 启用自动化邮件 |
enablePreferredSpeakersList | 启用首选 Speaker 列表 |
enableForceTargetInvitation | 启用强制目标邀请 |
enableHonorariaAmount | 启用酬金金额设置 |
enableCloseOutProgram | 启用关闭项目功能 |
enableUnsubscribedEmail | 启用退订邮件管理 |
enableDataExceptions | 启用数据异常追踪 |
enableAttendeeTrackerDataToSftp | 启用参会者数据 SFTP 传输 |
enableMosaicIntegration | 启用 Mosaic 集成 |
enablePorzioAggSpendReport | 启用 Porzio 聚合支出报告 |
enableGoogleGeocodeAPI | 启用 Google 地理编码 |
A.2 Product Level Flags (按类别)
Program Configuration (9 个): editProgram, editProgramOnlyApproved, approvalEnabled, attachmentsEnabled, shareProgramEnabled, cancelProgramEnabled, enableApproverComment, lunchAndLearnProgram, enableProgramPresentations
Program List (7 个): brandEnabled, topicEnabled, teamEnabled, venueEnabled, locationEnabled, districtManagerEnabled, regionalManagerEnabled
Registration (19 个): openRegistrationEnabled, registrationSiteEnabled, closeAttendeeListEnabled, closeAttendeeListPendingStatusCheckEnabled, copyAttendeesEnabled, updateCRMAttendeesEnabled, setRegistrationStatusEnabled, unreconcileEnabled, deleteAttendeeEnabled, addToSalesforceEnabled, enableEmailInvitation, allowSalesRepChangeEmailAlias, useDefaultStatusAsNextStatusForInvitedStatus, enableRegistrationSiteStatus, enableLookUpNPI, enableBatchRegistrationBasedOnAffiliation, enableBatchRegistration, enableCustomizedBrandPrefix, disableQuickRegistration
Speaker Search (17 个): filterEnabled, stateEnabled, specialityEnabled, regionReadOnly, honorariaCapEnabled, availableAmountEnabled, continueWithoutSpeakerEnabled, ratingEnabled, trainingEnabled, requiredNoticeEnabled, unavailableDaysEnabled, otherLanguageEnabled, localHonorariaEnabled, travelHonorariaEnabled, disableNotes, enableSpeakerCategory, enableSpeakerLevel
Document Template (8 模板 x 4 子 flag = 32 个): 每个模板(signInSheet, paperInvitation, attendeeSurveyResponses, signatureReport, honorariaInvoice, speakerExpenseReimbursement, postProgramCertification, honorariaCoverLetter)包含:enabled, restricted, permitAll, enableDocx/enablePdf
其他 Product Level (41 个): plannerIdFromProgramType, brandBudgetAllocationEnabled, disallowProgramIfBudgetReached, disallowProgramSubmission, switchProductEnabled, presentationsEnabled, enableNewSurvey, enableCustomReport, enableSpeakerNomination, enablePLID, enableTOVCalculationNotification, enableSpeakerRandomization, enableSignInAttendees, enableQuickEmailInvitation, enableMultipleEmailInvitation 等
Survey (2 个): salesRepSurveyEnabled, attendeeSurveyEnabled
Alert (1 个): salesRepSurveyEnabled
A.3 Company Level Flags (19 个)
disableSurveyAlerts, speakerSurveyEnabled, disablePresentationDelete, surveyReport, disableUserGroup, enableEditProfile, enableSignUp, enablePresentationMergeField, disablePresentationOnTraining, enableContractAdvanced, enableLEIECheck
Navigation (8 个): disableTopics, disableTraining, disableExpenseReports, disableNominations, disableReports, disableScheduledPrograms, disableCompletedPrograms, enableAdmin
A.4 Database Config Flags (4 个)
topicEnabled, speakerEnabled, prohibitTrainedSpeaker, frequencyCheckEnabled
A.5 统计汇总
| 类别 | 数量 |
|---|---|
| Agency Level | 14 |
| Product Level (全部) | ~128 |
| Company Level | 19 |
| Database Config | 4 |
| Active Total | ~165 |
| 已移除 | 18 |
Appendix B: Business Rules Catalog
Program Domain
| ID | 规则描述 |
|---|---|
| BR-001 | 系统应使用标准 JWT 替代内存 UUID Token,支持无状态认证和水平扩展 |
| BR-002 | SSO Cookie 必须设置 HttpOnly=true, Secure=true, SameSite=Strict |
| BR-003 | 密码重置 Token 应持久化存储,包含过期时间,支持多实例部署 |
| BR-004 | Speaker 认证统一纳入 UnifiedUser 体系 |
| BR-005 | 所有 API 端点应使用 @PreAuthorize 注解进行权限控制 |
| BR-006 | 权限变更通过短有效期 Access Token + Refresh Token 实时生效 |
| BR-007 | 用户数量限制按视图控制,白名单域名用户不受限 |
| BR-008 | Program 状态流转使用状态机引擎 |
| BR-009 | 状态变更使用命令模式 API |
| BR-010 | 审批配置使用强类型数据模型 |
| BR-011 | 部分审批支持逐级通知下一审批人 |
| BR-012 | 审批超时自动提醒(可配置产品范围和时间阈值) |
| BR-013 | Program 创建时验证 Topic 有效期 |
| BR-014 | Program 关闭需满足:ACT 版本已创建、参会者列表已关闭、ToV 已完成 |
| BR-015 | 支持 Project Task 模板管理,自动生成任务清单 |
Speaker Domain
| ID | 规则描述 |
|---|---|
| BR-016 | Speaker 创建时邮箱唯一性检查(忽略大小写,按 companyId 范围) |
| BR-017 | Speaker 删除使用软删除 |
| BR-018 | 合同报酬使用结构化的 honoraria items 表 |
| BR-019 | 合同签署时验证身份所有权 |
| BR-020 | programQuantityLimit 超限时禁用 Speaker 选择 |
| BR-021 | 演示文稿生成异步处理 |
| BR-022 | Content 可见性通过 SpeakerGroup 控制 |
| BR-023 | 独立的报酬计算服务统一管理 balance 计算 |
Attendee & Registration Domain
| ID | 规则描述 |
|---|---|
| BR-024 | 注册状态流转使用状态机,每个 Product 可配置状态转换矩阵 |
| BR-025 | 注册时检查最大参会人数限制 |
| BR-026 | 统一的 ReconciliationService 作为调和操作入口 |
| BR-027 | 批量自动调和仅当精确匹配 1 条时自动合并 |
| BR-028 | 注册时自动执行频率检查 |
| BR-029 | 频率检查支持按月/FiscalYear、按 Topic 过滤、白名单跳过 |
| BR-030 | 频率限制触发时自动通知 Planner |
| BR-031 | 支持签到、电子签名和地理位置记录 |
| BR-032 | 支持酒店房间管理和库存自动更新 |
| BR-033 | 支持住宿报表下载 |
| BR-034 | Attendee 主键改为 Long,保留 UUID 作为公开标识符 |
| BR-035 | 状态字段使用 PostgreSQL ENUM 类型 |
Budget & Financial Domain
| ID | 规则描述 |
|---|---|
| BR-036 | 分配预算不超过 Region unallocatedBudget |
| BR-037 | 取消分配不超过 District 当前预算 |
| BR-038 | 转移预算不超过源 District 余额 |
| BR-039 | 预算充足检查基于实际 BudgetItem 成本 |
| BR-040 | 版本复制:已有对应 item 更新,没有则插入 |
| BR-041 | 成本计算统一为独立的 BudgetCalculator 服务 |
| BR-042 | 同一 productId 不允许重叠的 fiscal year |
| BR-043 | FiscalPeriod 年份列表动态生成 |
Compliance & Regulatory Domain
| ID | 规则描述 |
|---|---|
| BR-044 | Aggregate Spend 报告按 Product 配置字段,支持运行时动态配置 |
| BR-045 | 报告格式配置化管理,消除客户特定硬编码 |
| BR-046 | TOV 计算前置:Budget Version = ACT,Attendee List 已关闭 |
| BR-047 | TOV 支持手动调整并记录调整原因 |
| BR-048 | PLID 匹配抽取为独立服务,使用枚举表示匹配结果 |
| BR-049 | Admin/Planner 管理审计状态,Sales Rep 只读 |
| BR-050 | 合规文件清单按 Product 和 ServiceOption 筛选 |
Communication Domain
| ID | 规则描述 |
|---|---|
| BR-051 | 邮件发送引入消息队列,支持状态追踪和失败重试 |
| BR-052 | 退订检查在所有邮件发送路径统一执行 |
| BR-053 | 邮件模板变量替换抽取为独立的 EmailTemplateEngine |
| BR-054 | 邀请发送需有对应模板且注册站点 Active |
| BR-055 | 定时邮件支持激活/停用,逻辑删除 |
| BR-056 | 告警系统统一为 Notification 模型 |
| BR-057 | 提醒时间和频率可配置,不硬编码 |
| BR-058 | SendGrid 用于邮件活动追踪,考虑 Webhook 替代定时轮询 |
Geographic & Territory Domain
| ID | 规则描述 |
|---|---|
| BR-059 | Planner 分配支持层级级联 |
| BR-060 | District 重分配前检查预算反分配 |
| BR-061 | 重分配在事务中级联更新关联数据 |
| BR-062 | 用户数据可见范围由地理绑定决定 |
| BR-063 | 同层级节点名称唯一 |
| BR-064 | 有关联数据的节点不可删除 |
| BR-065 | 地理层级标签支持客户自定义 |
Reporting Domain
| ID | 规则描述 |
|---|---|
| BR-066 | 统一三级权限过滤 |
| BR-067 | 大报告异步生成 |
| BR-068 | Ad-hoc 字段从数据库配置加载,报告名唯一 |
| BR-069 | 统一导出引擎,支持 Excel/CSV/PDF |
| BR-070 | R/Python 脚本迁移到 Java 或沙箱化模板引擎 |
Content & Document Domain
| ID | 规则描述 |
|---|---|
| BR-071 | PDF 转换策略配置驱动 |
| BR-072 | 模板上传验证文件扩展名和大小 |
| BR-073 | 文件上传添加白名单、大小限制、恶意内容扫描 |
| BR-074 | 文件搜索使用参数化查询 |
| BR-075 | Content 和 Document 统一为 Asset 模型 |
Survey Domain
| ID | 规则描述 |
|---|---|
| BR-076 | 统一动态问卷模板系统,废弃硬编码 Speaker Survey |
| BR-077 | 问卷名唯一,更新已有回答时需确认并自动停用 |
| BR-078 | Attendee Survey 按 attendeeId 去重,其他按 meetingRequestId 去重 |
| BR-079 | 关闭的项目禁止提交问卷(可配置) |
| BR-080 | products JSONB 拆分为关联表 |
| BR-081 | 定义强类型 DTO |
Expense Domain
| ID | 规则描述 |
|---|---|
| BR-082 | 费用报告和明细使用软删除 |
| BR-083 | 提交时后端自动合计 amount |
| BR-084 | 每个操作验证 Speaker 权限 |
| BR-085 | 费用分类支持层级结构 |
| BR-086 | 收据上传统一使用 File Module |
Virtual Program Domain
| ID | 规则描述 |
|---|---|
| BR-087 | 虚拟会议信息存储在独立数据表 |
| BR-088 | Zoom Host 选择按优先级顺序 |
| BR-089 | Webhook HMAC-SHA256 签名验证,5 分钟时间戳容差 |
| BR-090 | Zoom Token 按 productId 缓存 |
Integration Domain
| ID | 规则描述 |
|---|---|
| BR-091 | 统一集成基础设施层(重试、断路器、超时、限流、指标) |
| BR-092 | Salesforce 从 SOAP 迁移到 REST API |
| BR-093 | 消除 SOQL 拼接 |
| BR-094 | 按产品隔离 Salesforce 连接 |
| BR-095 | 大批量同步使用消息队列 |
| BR-096 | Zoom Meeting/Webinar 服务合并公共逻辑 |
| BR-097 | 处理 429 Rate Limit |
| BR-098 | 凭据迁移到密钥管理服务 |
| BR-099 | SSO 服务统一 |
Configuration Domain
| ID | 规则描述 |
|---|---|
| BR-100 | Feature Flags 迁移到数据库,支持运行时切换 |
| BR-101 | YAML 仅保留基础设施配置 |
| BR-102 | 统一正向命名 xxxEnabled |
| BR-103 | 公共 API 排除敏感信息 |
| BR-104 | 字典数据支持 CRUD 和下拉查询 |
| BR-105 | 客户自定义品牌样式 |
Non-Functional
| ID | 规则描述 |
|---|---|
| BR-106 | 标准查询 < 500ms,大报告异步 |
| BR-107 | 无状态认证,支持水平扩展 |
| BR-108 | 所有端点 RBAC 权限控制 |
| BR-109 | 文件上传安全限制 |
| BR-110 | 消除 SQL 注入 |
| BR-111 | BCrypt 加密,移除明文密码 |
| BR-112 | 登录 Rate Limiting |
| BR-113 | 关键操作审计日志 |
| BR-114 | 审计日志包含操作人、时间、类型、变更值 |
| BR-115 | 外部集成 MDC correlation ID |
| BR-116 | 外部调用 Micrometer 指标 |
| BR-117 | 集成健康检查端点 |
| BR-118 | 旧系统到新系统数据迁移方案 |
| BR-119 | Attendee ID 类型统一策略 |
| BR-120 | 统一软删除策略 |
| BR-121 | JSONB 字段强类型 DTO |
| BR-122 | 表名统一 t_ 前缀 |
| BR-123 | 外键约束数据库层定义 |
Document End
Total Business Rules: 123 (BR-001 to BR-123) Total Feature Flags (Active): ~165 Total Domains: 12 Core + Configuration + Integration = 14