Business Domain Overview
Pre-rewrite analysis - Layer 1: Overview Generated: 2026-02-19
Table of Contents
- 1. Executive Summary
- 2. Business Domain Map
- 3. Domain Details
- 3.1 Program & Meeting Management
- 3.2 Speaker Management
- 3.3 Attendee & Registration
- 3.4 Budget & Financial Management
- 3.5 Compliance & Regulatory
- 3.6 User & Permission Management
- 3.7 Communication & Notification
- 3.8 Reporting & Analytics
- 3.9 Configuration & Feature Management
- 3.10 Geographic & Territory Management
- 3.11 Content & Document Management
- 3.12 Survey & Feedback
- 3.13 External Integrations
- 3.14 Virtual Program Management
- 3.15 Expense Management
- 4. Domain Dependency Map
- 5. Cross-cutting Concerns
- 6. Initial Problem Identification
- 7. Deep Dive Priority
1. Executive Summary
The Pharmagin Speaker Platform is a comprehensive system for managing pharmaceutical industry speaker programs. It enables pharmaceutical companies to organize educational events where healthcare professionals (HCPs) serve as speakers, manage attendee registrations, track budgets, ensure regulatory compliance, and generate reports.
Platform Users
| User Group | Frontend App | Purpose |
|---|---|---|
| Agency Planners | plannerview (port 3000) | Create and manage programs, meetings, registrations, budgets, compliance |
| Sales Representatives | salesview (port 3200) | Request programs, manage attendees, view reports and budgets |
| Speakers (HCPs) | speakerview (port 3100) | Manage profiles, contracts, training, view scheduled programs |
System Scale
| Dimension | Count |
|---|---|
| Backend Modules (v1) | 37 |
| Database Entities | 138 |
| Frontend Applications | 3 |
| External Integrations | 13 |
| Feature Flags | 100+ |
2. Business Domain Map
┌─────────────────────────────────────────────────────────────────────┐
│ PHARMAGIN SPEAKER PLATFORM │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ CORE BUSINESS DOMAINS │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │
│ │ │ Program & │ │ Speaker │ │ Attendee & │ │ │
│ │ │ Meeting │←→│ Management │←→│ Registration │ │ │
│ │ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │ │
│ │ │ │ │ │ │
│ │ ┌──────┴───────┐ ┌─────┴────────┐ ┌───────┴──────────┐ │ │
│ │ │ Budget & │ │ Compliance │ │ Survey & │ │ │
│ │ │ Financial │ │ & Regulatory│ │ Feedback │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ SUPPORTING DOMAINS │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │
│ │ │ User & │ │ Communication│ │ Reporting & │ │ │
│ │ │ Permission │ │ & Notification│ │ Analytics │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │
│ │ │ Content & │ │ Geographic │ │ Virtual │ │ │
│ │ │ Document │ │ & Territory │ │ Program │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Expense │ │ Configuration│ │ │
│ │ │ Management │ │ & Features │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ EXTERNAL INTEGRATIONS │ │
│ │ Salesforce │ SendGrid │ Zoom │ SFTP │ NPI │ Google │ SSO │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘3. Domain Details
3.1 Program & Meeting Management
The central domain of the platform. Programs represent pharmaceutical speaker engagements (dinners, symposiums, roundtables) where speakers present to healthcare professional audiences.
Backend Modules
| Module | Path | Purpose |
|---|---|---|
meeting | /v1/meetings | Meeting container, listing, search, alerts |
program | /v1/programs | Program lifecycle (create → approve → execute → close) |
calendar | /v1/calendar | Calendar integration for scheduling |
project | /v1/tasks | Project task tracking for program execution |
Database Entities (18 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
| MeetingRequest | t_meeting_request | id, productId, meetingStatusId, approvalStatus | 120+ fields - the primary program entity |
| Meeting | t_meeting | id, meetingRequestId, registrationUrl | 90+ fields - registration/event details |
| MeetingAlert | t_meeting_alert | meetingRequestId, alertType | Meeting-specific alerts |
| MeetingAttachment | t_meeting_attachment | meetingRequestId, fileId | File attachments |
| MeetingChangeLog | t_meeting_changelog | meetingRequestId, fieldName, oldValue, newValue | Audit trail |
| MeetingComplianceDocument | t_meeting_compliance_document | meetingRequestId, documentId | Compliance docs |
| MeetingProgramType | t_meeting_program_type | meetingRequestId, programTypeId | Multi-type support |
| MeetingProjectTask | t_meeting_project_task | meetingRequestId, taskId | Task tracking |
| MeetingRequestStatus | t_meeting_request_status | id, name | Status definitions |
| MeetingRequestWorkflow | t_meeting_request_workflow | id, statusId, nextStatusId | State transitions |
| MeetingSharedUser | t_meeting_shared_user | meetingRequestId, userId | Access control |
| Location | t_location | id, address, city, state, zip | Meeting venues |
| Venue | t_venue | id, name, address | Venue master data |
| ProjectTask | t_project_task | id, name, description | Task definitions |
| ProjectTaskTemplate | t_project_task_template | id, templateName | Task templates |
| PLID | t_plid | id, name | Program/License identifiers |
| FiscalYear | t_fiscal_year | id, startDate, endDate | Financial year tracking |
| Workflow | t_workflow | id, name | Workflow definitions |
Frontend Pages
Plannerview:
/meetings- Meeting list/dashboard (MeetingTable)/meetings/:id(/:productId)- Meeting detail with tabs: Profile, Budget, Documents, ChangeLog, Summary, Assign, Tasks, Workflow, Virtual Setup/calendar- Calendar view/data-exceptions- Data exception tracking/plids- PLID management
Salesview:
/programs- Program list with status tabs (Pending, Approved, Scheduled, Completed)/programs/add- Create program form/programs/:programId/:type- Program detail (Information, Attendees, Surveys, Evaluation)/programs/:programId/sign-in-attendees- Sign-in page/calendar- Calendar view
Key Business Flows
Program Lifecycle:
Draft → Pending Approval → Approved → Scheduled → In Progress → Completed → Closed
↑ │
└──── Rejected ←─── (at any approval step) ──────────────┘
Meeting vs MeetingRequest:
MeetingRequest = the program request (business workflow)
Meeting = the registration/event instance (attendee-facing)
One MeetingRequest typically maps to one MeetingInitial Issues Identified
- MeetingRequest vs Meeting duality: Two massive entities (120+ and 90+ fields) represent overlapping concepts. The boundary between "program" and "meeting" is unclear and leads to confusion.
- MeetingRequest used as Program entity: The MeetingRequest table serves as the Program entity despite the name suggesting it's just a request. Misleading naming.
- Field bloat: Both entities have grown organically and contain 100+ fields, many of which are nullable flags or config overrides.
- Dual status tracking: MeetingRequestStatus and approval workflow concepts overlap.
3.2 Speaker Management
Manages healthcare professional speakers who are contracted to deliver presentations at pharmaceutical industry events.
Backend Modules
| Module | Path | Purpose |
|---|---|---|
speaker | /v1/speakers | Speaker CRUD, profile, status, login, bulk upload |
| (sub) contracts | /v1/speakers/{id}/contracts | Speaker contract management |
| (sub) presentations | /v1/speakers/{id}/presentations | Presentation content |
| (sub) reminders | /v1/speakers/{id}/reminders | Speaker notifications |
Database Entities (8 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
| Speaker | t_speaker | id, firstName, lastName, npiNumber, speakerStatus | 100+ fields - profile, credentials, financial rates, geographic data |
| SpeakerContract | t_speaker_contract | id, speakerId, contractStatus, honorariaRate | Contract terms and compensation |
| SpeakerGroup | t_speaker_group | id, name | Speaker segmentation |
| SpeakerTraining | t_speaker_training | speakerId, trainingId, completionDate | Training completion tracking |
| SpeakerSlide | t_speaker_slide | speakerId, slideId | Presentation materials |
| MappingTopicSpeaker | t_mapping_topic_speaker | topicId, speakerId | Speaker-topic expertise |
| MappingSpeakerDistrict | t_mapping_speaker_district | speakerId, districtId | Geographic assignment |
| MappingSpeakerGroup | t_mapping_speaker_group | speakerId, groupId | Group membership |
Frontend Pages
Speakerview (speaker-facing portal):
/speakers/speakers- Speaker list (admin view)/speakers/speakers/:speakerId/profile- Speaker profile management/speakers/speakers/:speakerId/documents- Document management/speakers/speakers/:speakerId/contracts- Contract viewing/signing/speakers/speakers/:speakerId/training- Training modules/speakers/speakers/:speakerId/scheduled-programs- Upcoming programs/speakers/speakers/:speakerId/completed-programs- Past programs/speakers/speakers/:speakerId/expenses- Expense reports/speakers/contracts- Contracts list/speakers/content- Content library/speakers/topics- Topics/expertise/speakers/nominations- Speaker nominations/speakers/training- Training library
Plannerview:
- Admin > Preferred Speakers List
Salesview:
/speakersor/speaker-list- Speaker roster
Key Business Flows
Speaker Lifecycle:
Nominated → Profile Created → Contracts Signed → Training Completed → Active → Deactivated
Speaker Engagement:
Assigned to Program → Confirm Availability → Present → Submit Expenses → ReimbursedInitial Issues Identified
- Speaker entity bloat: 100+ fields covering profile, credentials, financial rates, and geographic data in a single entity.
- Speaker login/auth mixed into speaker module: Speaker authentication is handled within the speaker module rather than the unified auth system.
- Topic management scattered: Topics appear in both speaker and dictionary modules.
3.3 Attendee & Registration
Manages healthcare professional attendees who register for and attend speaker programs.
Backend Modules
| Module | Path | Purpose |
|---|---|---|
site | /v1/sites | Registration site management (public-facing) |
registration | /v1/registration | Registration workflow processing |
npi | /v1/npis | NPI (National Provider Identifier) validation |
target | /v1/targets | Target audience (HCP) management |
Database Entities (15 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
| Attendee | t_attendee | attendeeId (UUID), meetingId, npiNumber, registrationStatus | 70+ fields - registration, compliance, sign-in |
| AttendeeType | t_attendee_type | id, name | HCP, Student, Compliance Officer, etc. |
| AttendeeResponse | t_attendee_response | attendeeId, responseType | RSVP tracking |
| AttendeeSignature | t_attendee_signature | attendeeId, signatureData | E-signature capture |
| AttendeeSurvey | t_attendee_survey | attendeeId, surveyId | Survey responses |
| AttendeeChangeLog | t_attendee_changelog | attendeeId, fieldName | Audit trail |
| AttendeeInfoField | t_attendee_info_field | id, fieldName | Custom attendee fields |
| AttendanceConfig | t_attendance_config | id, configType | Attendance rules |
| Target | t_target | targetId (Long), npiNumber, firstName, lastName | Target HCP audience |
| SecondaryTarget | t_secondary_target | id, targetId | Secondary target list |
| NpiData | t_npi_data | npi, providerName, specialty | NPI registry data |
| RegistrationStatus | t_registration_status | id, name | Status definitions |
| RegistrationWorkflow | t_registration_workflow | id, statusId, nextStatusId | State transitions |
| SleepingRoom | t_sleeping_room | id, meetingId, hotelName | Accommodation |
| SleepingRoomInventory | t_sleeping_room_inventory | roomId, date, available | Room availability |
Frontend Pages
Plannerview:
/registrations- Registration site list/registrations/:id(/:type)- Registration detail (Contacts, Accommodation, Communication, Workflow, Reports)/reg/:url(/:planner)- Public registration form/confirmation/:attendeeId- Attendance confirmation page/invitations/:attendeeId- Invitation display/decline/:attendeeId- Decline invitation form/unsubscribe/:attendeeId- Email unsubscribe
Salesview:
/programs/:programId/attendees- Attendee management within program/programs/:programId/sign-in-attendees- Sign-in page
Key Business Flows
Attendee Registration:
Invited/Self-Register → NPI Validated → Frequency Checked → Registered → Confirmed → Signed In → Attended
Target Reconciliation Types:
Type 1: NPI-based (match against NPI database)
Type 2: Target list (match against uploaded target lists)
Type 3: Salesforce (match against Salesforce contacts)Initial Issues Identified
- Site vs Meeting vs Registration confusion: "Site" represents a registration portal tied to a Meeting, but the naming is unintuitive. The relationship between Site, Meeting, and Registration is convoluted.
- Attendee ID type inconsistency: Attendee uses UUID (String) while most other entities use Integer. This creates friction in joins and queries.
- Dual reconciliation paths: NPI and Target reconciliation use different flows but should ideally be unified.
- SleepingRoom in site module: Accommodation management is bundled with registration but could be its own domain.
3.4 Budget & Financial Management
Hierarchical budget allocation and tracking from company level down to individual programs.
Backend Modules
| Module | Path | Purpose |
|---|---|---|
budget | /v1/budget/allocation, /v1/budgets/* | Budget allocation, categories, items, templates, caps |
Database Entities (11 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
| BudgetVersion | t_budget_version | id, meetingRequestId, versionNumber | Budget snapshot versions |
| BudgetCategory | t_budget_category | id, productId, name | Expense categories |
| BudgetItem | t_budget_item | id, budgetVersionId, categoryId, amount | Line items |
| BudgetItemTemplate | t_budget_item_template | id, templateName | Reusable templates |
| BudgetCapItem | t_budget_cap_item | id, productId, capType, capAmount | Spending caps |
| BudgetAlert | t_budget_alert | id, productId, threshold | Budget threshold alerts |
| BudgetAlertViewHistory | t_budget_alert_view_history | alertId, userId | Alert read tracking |
| BudgetAllocationHistory | t_budget_allocation_history | id, allocationType, amount | Allocation audit |
| AllocationTov | t_allocation_tov | id, attendeeId, amount | Transfer of Value |
| FiscalYear | t_fiscal_year | id, startDate, endDate | Fiscal period |
| Brand | t_brand | id, productId, name | Brand-level budgets |
Frontend Pages
Plannerview:
- Meeting detail > Budget tab (MTBudget, MTBudgetForm)
- Admin > Budget Categories
- Admin > Budget Templates
Salesview:
/budget-allocation- Budget allocation overview/budget-allocation/region-budget- Region-level allocation/budget-allocation/district-budget- District-level allocation- Reports > Programs by Budget Status
- Reports > Fiscal YTD Spend by Brand
Budget Hierarchy
Company → Product → Brand → Region → District → Territory → Program
Each level can have allocated amounts and spending capsInitial Issues Identified
- Budget spread across modules: Budget entities are in common persistence, but budget allocation logic touches program, meeting, and compliance modules.
- AllocationTov (Transfer of Value) mixes compliance and budget concerns in a single entity.
- Complex versioning: BudgetVersion per meeting creates many rows and complicates reporting.
3.5 Compliance & Regulatory
Pharmaceutical regulatory compliance - tracks payments to HCPs (Transfer of Value), manages required documentation, and generates aggregate spend reports for regulatory reporting (e.g., Sunshine Act).
Backend Modules
| Module | Path | Purpose |
|---|---|---|
compliance | /v1/compliance | Compliance records, document checklists, field mappings, exports |
Database Entities (5 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
| ComplianceDocument | t_compliance_document | id, name, required | Document checklist definitions |
| MeetingComplianceDocument | t_meeting_compliance_document | meetingRequestId, documentId | Per-meeting compliance docs |
| AggregateSpendReport | t_aggregate_spend_report | id, productId | Spend report configuration |
| AggregateSpendReportField | t_aggregate_spend_report_field | reportId, fieldName | Report field definitions |
| AggregateSpendFieldMapping | aggregate_spend_field_mapping | id, fieldName, mappedTo | Data mapping rules |
Frontend Pages
Plannerview:
/compliance/0- Compliance by Attendees (Aggregate Spend)/compliance/1- Compliance by Programs- Admin > Compliance Document Checklist
- Admin > Aggregate Spend Report Configuration
- Meeting detail > Compliance Documents tab
Salesview:
/reports/compliance-audit- Compliance audit reports/reports/compliance-audit/:meetingRequestId- Per-meeting compliance
Initial Issues Identified
- Compliance is tightly coupled to attendee and program: Hard to test or reason about compliance logic independently.
- Aggregate Spend reporting is configuration-heavy: Complex field mapping system that could benefit from simplification.
- Document checklist logic is duplicated: Similar patterns in meeting compliance docs and general compliance docs.
3.6 User & Permission Management
Multi-level RBAC system supporting user access at instance, company, and product levels with granular permissions.
Backend Modules
| Module | Path | Purpose |
|---|---|---|
user | /v1/users | User CRUD, activation, password management |
| (sub) auth | /v1/users/login | Authentication |
| (sub) roles | /v1/users/roles | Role management |
| (sub) permissions | - | Permission checking |
Database Entities (11 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
| UnifiedUser | t_unified_user | id, username, email, active | Central user profile |
| UserRole | t_user_role | userId, roleId | User-role mapping |
| UserProduct | t_user_product | userId, productId | User-product access |
| UserProductRole | t_user_product_role | userId, productId, roleId | Product-level roles |
| UserCompany | t_user_company | userId, companyId | Company access |
| UserInstance | t_user_instance | userId, instanceId | Instance access |
| Permission | t_permission | id, name, code | Permission definitions |
| RolePermission | t_role_permission | roleId, permissionId | Role-permission mapping |
| RoleGroup | t_role_group | id, name | Role grouping |
| UserAuthToken | user_auth_token | email, token | Auth tokens |
| UserPasswordHistory | t_user_password_history | userId, passwordHash | Password history |
Frontend Pages
Plannerview:
- Admin > Users (Planner View)
- Admin > Pharmagin Users (system-level users)
- Admin > Pharmagin Roles (role management)
- Admin > Users Limit
Salesview:
/users- User management (sales rep users)
Speakerview:
/speakers/admin- Speaker admin panel/speakers/login- Speaker login/speakers/forgotPwd/:uuid- Password reset
Access Control Model
Instance (deployment)
└── Company (pharmaceutical company)
└── Product (drug/brand)
└── Role (ADMIN, PLANNER, SALES_REP, SPEAKER, etc.)
└── Permission (PROGRAMS_VIEW, BUDGET_EDIT, etc.)
Authority Pattern (Salesview): PRODUCT-{productId}-{AUTHORITY_KEY}
e.g., PRODUCT-1-PROGRAMS, PRODUCT-1-BUDGET_ALLOCATIONInitial Issues Identified
- Speaker auth is separate: Speaker login/authentication exists in the speaker module, not in the user module.
- Two SSO services: pharmagin-sso (production) and pharmagin-login (next-gen) create maintenance burden.
- Complex multi-level permissions: Instance → Company → Product → Role → Permission hierarchy is powerful but complex to manage and debug.
- UserQuantityLimit: Licensing enforcement is mixed with user management.
3.7 Communication & Notification
Multi-channel communication system for emails, alerts, and notifications to speakers, attendees, and planners.
Backend Modules
| Module | Path | Purpose |
|---|---|---|
mail | /v1/mails | Email sending, templates, sandbox |
communication | /v1/communications | Communication tracking/history |
sendgrid | /v1/sendgrid | SendGrid integration and analytics |
alert | /v1/customAlerts | Alert rules configuration |
reminder | /v1/speakers/{id}/reminders | Automated reminders |
invitationtemplate | /v1/invitation-templates | Email invitation templates |
Database Entities (10 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
t_mail | id, subject, body, templateType | Email templates | |
| MailServiceType | t_mail_service_type | id, name | Service type definitions |
| ScheduledEmail | t_scheduled_email | id, scheduledDate, status | Scheduled campaigns |
| ScheduledEmailInstance | t_scheduled_email_instance | emailId, recipientEmail | Individual deliveries |
| SendGridEmailActivity | sendgrid_email_activity | id, email, event | Delivery tracking |
| Alert | t_alert | id, type, message | System alerts |
| CustomAlert | t_custom_alert | id, name, condition | User-defined alerts |
| CustomAlertViewHistory | t_custom_alert_view_history | alertId, userId | Alert read tracking |
| InvitationHistory | t_invitation_history | id, attendeeId, sentDate | Invitation audit trail |
| UnsubscribedEmail | t_unsubscribed_email | id, email | Email opt-out list |
Frontend Pages
Plannerview:
- Registration detail > Communication tab (ScheduledEmails)
- Admin > Email Invitation Templates
- Admin > Email Sandbox
- Admin > Push Alerts
- Admin > Unsubscribed List
/unsubscribe/:attendeeId- Public unsubscribe/resubscribe/:attendeeId- Public resubscribe
Initial Issues Identified
- Alert vs CustomAlert duality: Two separate alert systems exist, creating confusion about which to use.
- Mail module is overloaded: Handles templates, sending, sandbox, unsubscribe, and calendar invites.
- Communication tracking is separate from mail: Communication history and actual email sending are in different modules.
3.8 Reporting & Analytics
Business intelligence and reporting for program performance, budget utilization, speaker utilization, and attendee demographics.
Backend Modules
| Module | Path | Purpose |
|---|---|---|
report | /v1/reports, /v1/products/{productId}/reports | Standard and custom reports |
adhoc | /v1/adhoc | Ad-hoc report generation |
Database Entities (6 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
| AdhocReport | t_adhoc_report | id, name, query | Ad-hoc report definitions |
| AdhocReportDetail | t_adhoc_report_detail | reportId, fieldName | Report field details |
| ReportField | t_report_field | id, fieldName, displayName | Configurable report fields |
Frontend Pages
Plannerview:
/custom-reports- Custom report builder- Admin > Download Change Log
- Admin > Scheduled Reports
Salesview (extensive reporting):
/reports/glance- At A Glance Dashboard/reports/program-activity/dashboard- Program Activity Dashboard/reports/program-activity/program-summary- Program Summary (download)/reports/program-activity/fiscal-ytd-spend-by-brand- Fiscal YTD Spend/reports/program-activity/fiscal-ytd-operated-future-programs- Future Programs/reports/program-activity/programs-by-budget-status- Budget Status/reports/program-activity/program-activity-by-geography-and-spend- Geographic Analysis/reports/program-activity/program-activity-by-sales-representatives- Sales Rep Analysis/reports/program-activity/speaker-utilization- Speaker Utilization/reports/attendee-analytics/dashboard- Attendee Analytics Dashboard/reports/attendee-analytics/attendee-tracker- Attendee Tracker (download)/reports/attendee-analytics/registration-summary- Registration Summary/reports/attendee-analytics/registration-by-specialty- By Specialty/reports/attendee-analytics/registration-by-geography- By Geography/reports/attendee-analytics/registration-by-program- By Program/reports/custom-reports- Custom Reports
Speakerview:
/speakers/reports- Speaker reports dashboard
Initial Issues Identified
- Reporting logic is scattered: Report generation happens in the report module, adhoc module, compliance module, and inline in other modules.
- No unified reporting framework: Custom reports, adhoc reports, and standard reports all have different architectures.
- Heavy frontend reporting: Salesview has 15+ report pages, many with complex chart configurations hardcoded in the frontend.
3.9 Configuration & Feature Management
Centralized configuration system using Spring Cloud Config for multi-tenant, per-client feature management.
Backend Modules
| Module | Path | Purpose |
|---|---|---|
config | /v1/configuration/* | Instance and product configuration |
dict | /v1/dictionary | Reference data/lookup values |
Configuration Layers
1. Agency Config (agency-{env}.yml)
- Feature flags: projectTaskEnabled, enableScheduledReports, enableApprovalFlow, etc.
- Notification settings
- Optional meeting fields
2. Company Config (company-{env}.yml)
- Branding: logo, theme, footer
- Navigation: disableTopics, disableTraining, disableExpenseReports, etc.
- Labels: customLabel for speaker/product
- Contract form configuration
3. Product Config (product-{env}.yml)
- Reconciliation type (NPI, TARGET, SALESFORCE)
- SSO settings
- Custom labels for geography hierarchy
- Speaker search filters
- Program settings: approval, sharing, cancellation
- Registration settings: open, site, close, copy, sync
- Document templates: sign-in sheet, invitation, survey, etc.
- Virtual program settings (Zoom)
- Report permissions
4. Dictionary (dictionary.yml)
- Speaker levels
- Medical specialties (60+ values)Database Entities (7 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
| ProductConfiguration | t_product_configuration | productId, configKey, configValue | Product-level settings |
| Topic | t_topic | id, name, serviceTypeId | Educational topics |
| Product | t_product | id, name, companyId | Product master |
| Brand | t_brand | id, name, productId | Brand hierarchy |
| Theme | t_theme | id, primaryColor, secondaryColor | UI branding |
Frontend Pages
Plannerview Admin:
- Program Types, Budget Categories, Budget Templates
- Brand Configuration, Upload Logos
- Team Setup, Attendance Frequency
- Registration Workflow, Force Target Invitation
- Program Task Templates
- SFTP Configuration
Initial Issues Identified
- 100+ feature flags: Too many flags make configuration complex and error-prone. Many may no longer be needed.
- 3-layer config hierarchy: Agency → Company → Product configuration creates override complexity.
- Config values in both YAML and database: ProductConfiguration table duplicates some YAML settings, making it unclear which source of truth wins.
- Dictionary module is a catch-all: Contains reference data for many different domains (products, brands, regions, districts, topics, venues, etc.).
3.10 Geographic & Territory Management
Hierarchical geographic structure for sales territory management, synchronized with Salesforce CRM.
Backend Modules
| Module | Path | Purpose |
|---|---|---|
geography | /v1/geographies | Geographic hierarchy management |
| (dict) regions/districts/territories | /v1/dictionary/* | Reference data |
Database Entities (11 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
| Region | t_region | id, productId, name | Sales regions |
| District | t_district | id, regionId, name | Sales districts |
| Territory | t_territory | id, districtId, name | Sales territories |
| Team | t_team | id, name | Organizational teams |
| SalesTeam | t_sales_team | id, teamId, userId | Team membership |
| RegionManager | t_region_manager | regionId, userId | Region management |
| DistrictManager | t_district_manager | districtId, userId | District management |
| TeamBrand | t_team_brand | teamId, brandId | Team-brand assignments |
| TeamProgramType | t_team_program_type | teamId, programTypeId | Team-type assignments |
| Country | t_country | id, name, code | Country reference |
| State | t_state | id, name, countryId | State/province reference |
Frontend Pages
Salesview:
/geography- Geography management/reassign-program-geography- Reassign program territories
Geographic Hierarchy
Product → Region → District → Territory
↓
SalesTeam → SalesRep (User)3.11 Content & Document Management
Document generation, template management, and content library for presentations, agreements, and compliance documents.
Backend Modules
| Module | Path | Purpose |
|---|---|---|
xdoc | /v1/xdocreport/*, /v1/templates | Document generation (XDocReport) |
file | /v1/files | File upload/download/storage |
Database Entities (8 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
| Template | t_template | id, name, type, body | Document templates |
| Content | t_content | id, title, type | Content library items |
| ContentGroup | t_content_group | id, name | Content organization |
| ContentTopic | t_content_topic | contentId, topicId | Content-topic mapping |
| SiteTemplate | t_site_template | id, meetingId | Registration site templates |
| SiteTemplatePage | t_site_template_page | templateId, pageName | Template pages |
| SiteTemplateField | t_site_template_field | pageId, fieldName | Template fields |
| File | t_file | id, fileName, mimeType, path | File storage metadata |
| Document | t_document | id, name, type | Document records |
Document Types
- Sign-in sheets
- Paper invitations
- Attendee survey responses
- Signature reports
- Honoraria invoices
- Speaker expense reimbursement forms
- Post-program certifications
Frontend Pages
Speakerview:
/speakers/content- Content library/speakers/presentation/:slideId/:accessToken- Presentation viewer/speakers/speakers/:speakerId/documents- Speaker documents
Plannerview:
- Admin > Document Templates
- Meeting detail > Documents tab
Salesview:
/presentations- Presentation management
3.12 Survey & Feedback
Post-event survey system for collecting feedback from attendees and evaluating program effectiveness.
Backend Modules
| Module | Path | Purpose |
|---|---|---|
survey | /v1/surveys | Survey CRUD, responses, statistics |
Database Entities (2 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
| AttendeeSurvey | t_attendee_survey | attendeeId, surveyId, responses | Survey response data |
| (Survey definition likely stored as JSON or in config) |
Frontend Pages
Plannerview:
/survey/builder(/:surveyId)- Survey builder/meeting/:meetingRequestId/survey- Meeting survey results- Admin > Surveys
Salesview:
/programs/:programId/surveys- Program surveys/programs/:programId/evaluation- Program evaluation/reports/survey- Survey results reports/reports/survey/:surveyId- Survey detail/reports/other-survey- Other survey reports
3.13 External Integrations
13 external service integrations connecting the platform to CRM, email, video, and data services.
| Integration | Type | Package/Module | Purpose | Status |
|---|---|---|---|---|
| Salesforce | CRM | plus.integration.sf | Contact/Account/Event sync | Active |
| SendGrid | modules.v1.sendgrid | Email delivery & analytics | Active | |
| Zoom | Video | modules.v1.virtualProgram | Virtual meeting management | Active |
| SFTP | File Transfer | modules.v1.sftp | Batch data exchange | Active |
| NPI Registry | Data | modules.v1.npi | Provider validation | Active |
| Google Geocoding | Location | common.service.GoogleAPIService | Address-to-GPS conversion | Active (flag) |
| iCal4j | Calendar | modules.v1.mail | Calendar invite generation | Active |
| CloudConvert | Document | modules.v1.xdoc | Format conversion | Active |
| XDocReport | Document | modules.v1.xdoc | Mail merge/templates | Active |
| Aspose Slides | Document | (dependency) | PowerPoint processing | Active |
| Mosaic | Data | modules.v1.mosaic | Event/attendee data | Optional (flag) |
| SAML 2.0 | Auth | pharmagin-sso | Azure AD/Okta SSO | Active |
| OAuth2/JWT | Auth | common.security | API authentication | Active |
3.14 Virtual Program Management
Virtual/hybrid event support via Zoom integration for webinars and virtual meetings.
Backend Modules
| Module | Path | Purpose |
|---|---|---|
virtualProgram | /v1/virtualPrograms | Virtual event management, Zoom webhooks |
Configuration (product-dev.yml)
virtualPrograms:
zoomVirtualMeeting:
issuer: "<Zoom Client ID>"
secretKey: "<Zoom Client Secret>"
url: "https://api.zoom.us/v2"
users: [userId1, userId2] # Host accounts
programSettings:
join_before_host: true
mute_upon_entry: true
auto_recording: "NONE"
waiting_room: true
zoomWebinar: (similar config)Frontend Pages
Plannerview:
- Meeting detail > Virtual Program Setup tab
Salesview:
- Virtual meeting join URL within program detail
Note
PVM (Pharmagin Virtual Meeting) using Agora has been removed. Only Zoom and third-party integrations remain.
3.15 Expense Management
Speaker expense tracking and reimbursement for travel, meals, and other program-related costs.
Backend Modules
Part of the speaker module - expenses are managed as a sub-resource of speakers.
Database Entities (4 entities)
| Entity | Table | Key Fields | Notes |
|---|---|---|---|
| Expense | t_expense | id, speakerId, meetingRequestId, status | Expense header |
| ExpenseItem | t_expense_item | id, expenseId, category, amount | Line items |
| ExpenseCategory | t_expense_category | id, name | Expense categories |
| ExpenseHistory | t_expense_history | expenseId, action, timestamp | Audit trail |
Frontend Pages
Speakerview:
/speakers/expenses(/:expenseId)- Expense report submission/speakers/speakers/:speakerId/expenses- Speaker expense history
4. Domain Dependency Map
┌──────────────┐
│ Configuration│
│ & Features │
└──────┬───────┘
│ (feature flags govern all modules)
▼
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ User & │────→│ Program & │←────│ Geographic │
│Permission│ │ Meeting │ │ & Territory │
└──────────┘ └──────┬───────┘ └──────────────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────────┐
│ Speaker │ │ Attendee │ │ Budget & │
│Management│ │& Registr.│ │ Financial │
└────┬─────┘ └────┬─────┘ └──────────────┘
│ │
▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────────┐
│ Expense │ │ Survey │ │ Compliance │
│Management│ │& Feedback│ │ & Regulatory │
└──────────┘ └──────────┘ └──────┬───────┘
│
▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│Communication │ │ Reporting │ │ Content & │
│& Notification│ │ & Analytics │ │ Document │
└──────────────┘ └──────────────┘ └──────────────┘
│
▼
┌──────────────────────────────────────────┐
│ External Integrations │
│ Salesforce│SendGrid│Zoom│SFTP│NPI│SSO │
└──────────────────────────────────────────┘Key Dependency Chains
- Program → Speaker + Attendee + Budget + Compliance: A program cannot exist without speakers, attendees, a budget, and compliance rules.
- Attendee → NPI + Target + Registration: Attendee registration requires NPI validation and target matching.
- Budget → Product + Geography: Budget allocation follows the product and geographic hierarchy.
- Compliance → Attendee + Program + Budget: Compliance reporting aggregates data from multiple domains.
- Communication → All domains: Email notifications are triggered by events in every domain.
5. Cross-cutting Concerns
5.1 Event/Bus System
The bus module provides internal event publishing for decoupling:
- ProgramCreatedEvent, ProgramUpdatedEvent, ProgramCanceledEvent
- ApprovalStatusChangedEvent
- AttendeeListClosedEvent, RegistrationStatusChangedEvent
- CreateAttendeeEvent, UpdateAttendeeEvent
- AssignProgramPlannerEvent
5.2 Audit Trail
Multiple audit mechanisms exist:
- JaVers for entity-level change tracking
- ChangeLog entities (MeetingChangeLog, AttendeeChangeLog)
- History entities (ExpenseHistory, BudgetAllocationHistory, InvitationHistory)
- ViewHistory entities (AlertViewHistory, BudgetAlertViewHistory)
5.3 Cron Jobs
The cronjobs module manages scheduled background tasks:
- Automated reminders
- SendGrid email activity sync
- Data export to SFTP
- Scheduled email campaigns
5.4 File Storage
Centralized file service (file module) with abstract FileServer supporting storage operations for all modules.
6. Initial Problem Identification
6.1 Architectural Issues
| Issue | Severity | Description |
|---|---|---|
| MeetingRequest/Meeting duality | HIGH | Two massive entities (120+ / 90+ fields) with unclear boundaries. MeetingRequest is actually the "Program" entity but the name is misleading. |
| Entity bloat | HIGH | Speaker (100+), MeetingRequest (120+), Meeting (90+), Attendee (70+) fields indicate God objects that should be decomposed. |
| Scattered reporting | MEDIUM | Report logic exists in report, adhoc, compliance, and inline in other modules with no unified framework. |
| Dual alert systems | MEDIUM | Alert and CustomAlert are separate systems with overlapping functionality. |
| Speaker auth isolation | MEDIUM | Speaker authentication is separate from the unified user/auth system. |
| Config source ambiguity | MEDIUM | Configuration lives in YAML files AND database tables with unclear precedence rules. |
6.2 Data Model Issues
| Issue | Severity | Description |
|---|---|---|
| ID type inconsistency | MEDIUM | Most entities use Integer IDENTITY, but Attendee uses UUID String and Target uses Long. |
| Table naming inconsistency | LOW | Most tables use t_ prefix, but some don't (noven_attendee_history, sendgrid_email_activity, aggregate_spend_field_mapping). |
| Dual status/workflow | MEDIUM | MeetingRequestStatus + MeetingRequestWorkflow and RegistrationStatus + RegistrationWorkflow have overlapping concerns. |
| JSON/Object columns | LOW | productConfig, virtualProgramInfo use dynamic JSON which bypasses schema validation. |
6.3 Module Organization Issues
| Issue | Severity | Description |
|---|---|---|
| Dictionary as catch-all | MEDIUM | Dictionary module serves as a lookup for 15+ different reference data types. |
| Site module overloaded | MEDIUM | Site module manages registration portals, attendees, accommodations, contacts, and signatures. |
| Mail module overloaded | MEDIUM | Handles templates, sending, sandbox, unsubscribe, and calendar invites. |
| Feature flag proliferation | MEDIUM | 100+ feature flags across 3 config layers make behavior hard to predict. |
6.4 Integration Issues
| Issue | Severity | Description |
|---|---|---|
| Dual SSO services | MEDIUM | pharmagin-sso (production) and pharmagin-login (next-gen) both exist, creating maintenance burden. |
| Salesforce tightly coupled | MEDIUM | Salesforce integration is in the plus package with deep dependencies on core entities. |
| No integration abstraction | LOW | Each external service has its own integration pattern with no unified adapter layer. |
7. Deep Dive Priority
Based on the initial analysis, the recommended order for Layer 2 deep dives:
| Priority | Domain | Document | Reason |
|---|---|---|---|
| 1 | Program & Meeting | 02-program-meeting-domain.md | Core domain with the most complexity and issues (MeetingRequest/Meeting duality) |
| 2 | Speaker Management | 03-speaker-domain.md | Second core domain, 100+ field entity, auth concerns |
| 3 | Attendee & Registration | 04-attendee-registration-domain.md | Third core domain, NPI/Target reconciliation complexity |
| 4 | Budget & Financial | 05-budget-domain.md | Financial critical, complex hierarchy |
| 5 | Compliance & Regulatory | 06-compliance-domain.md | Regulatory risk, cross-domain dependencies |
| 6 | User & Permission | 07-user-permission-domain.md | Security critical, multi-level RBAC |
| 7 | Communication & Notification | 08-communication-domain.md | Overloaded modules, multiple systems |
| 8 | External Integrations | 09-integration-domain.md | Salesforce, Zoom, SendGrid dependencies |
| 9 | Reporting & Analytics | 10-reporting-domain.md | Scattered architecture, heavy frontend logic |
| 10 | Configuration & Features | 11-configuration-domain.md | 100+ flags, 3-layer hierarchy |
| 11 | Geographic & Territory | 12-geographic-domain.md | Salesforce sync, hierarchy management |
| 12 | Content & Document | 13-content-document-domain.md | Multiple document systems |
| 13 | Survey & Feedback | 14-survey-domain.md | Relatively contained domain |
| 14 | Expense Management | 15-expense-domain.md | Relatively contained domain |
| 15 | Virtual Programs | 16-virtual-program-domain.md | Simplified after PVM removal |
Appendix A: Complete Backend Module Index
| # | Module | Base Path | Entity Count | Frontend Coverage |
|---|---|---|---|---|
| 1 | meeting | /v1/meetings | 11 | PV, SV |
| 2 | program | /v1/programs | (shared with meeting) | PV, SV |
| 3 | speaker | /v1/speakers | 8 | SPV, SV |
| 4 | site | /v1/sites | 15 | PV |
| 5 | user | /v1/users | 11 | PV, SV, SPV |
| 6 | budget | /v1/budget/* | 11 | PV, SV |
| 7 | config | /v1/configuration/* | 7 | All |
| 8 | compliance | /v1/compliance | 5 | PV, SV |
| 9 | dict | /v1/dictionary | (reference data) | All |
| 10 | registration | /v1/registration | 4 | PV |
| 11 | npi | /v1/npis | 1 | - |
| 12 | target | /v1/targets | 2 | - |
| 13 | /v1/mails | 5 | PV | |
| 14 | communication | /v1/communications | - | PV |
| 15 | sendgrid | /v1/sendgrid | 1 | - |
| 16 | file | /v1/files | 2 | All |
| 17 | report | /v1/reports | 3 | PV, SV, SPV |
| 18 | adhoc | /v1/adhoc | 2 | PV |
| 19 | xdoc | /v1/xdocreport/* | 3 | PV, SPV |
| 20 | survey | /v1/surveys | 1 | PV, SV |
| 21 | virtualProgram | /v1/virtualPrograms | - | PV, SV |
| 22 | calendar | /v1/calendar | - | PV, SV |
| 23 | geography | /v1/geographies | 11 | SV |
| 24 | product | /v1/products | 2 | All |
| 25 | planner | /v1/planners | - | PV |
| 26 | plid | /v1/plids | 1 | PV |
| 27 | alert | /v1/customAlerts | 4 | PV |
| 28 | project | /v1/tasks | 3 | PV |
| 29 | reminder | /v1/speakers/*/reminders | - | SPV |
| 30 | sftp | /v1/sftp | - | PV |
| 31 | invitationtemplate | /v1/invitation-templates | 1 | PV |
| 32 | external | /v1/external | - | SV |
| 33 | bus | (internal) | - | - |
| 34 | cronjobs | /v1/cronjobs | - | - |
| 35 | mosaic | (internal) | - | - |
| 36 | view | (internal) | - | - |
| 37 | attendance | (via config) | 1 | - |
Legend: PV = Plannerview, SV = Salesview, SPV = Speakerview
Appendix B: Entity Count by Domain
| Domain | Entity Count | Largest Entity (fields) |
|---|---|---|
| Meeting Management | 18 | MeetingRequest (120+), Meeting (90+) |
| Attendee & Registration | 15 | Attendee (70+) |
| Geographic & Territory | 11 | - |
| User & Security | 11 | - |
| Budget & Financial | 11 | - |
| Communication | 10 | - |
| Content & Document | 8 | - |
| Speaker Management | 8 | Speaker (100+) |
| Configuration | 7 | - |
| Reporting | 6 | - |
| Compliance | 5 | - |
| Expense | 4 | - |
| Workflow & Status | 4 | - |
| NPI & Target | 3 | - |
| Survey | 2 | - |
| Other/Mapping | 15 | - |
| Total | 138 |
Appendix C: Redux Store Domains (Plannerview)
The plannerview Redux store contains 40+ state slices reflecting the business domains:
route, global, common, meetingTable, meetingDetail, registrations,
registrationsDetail, sitebuilder, siteBuilderConfig, attendeeTypes,
contacts, accommodation, report, accommodationReport, changeReport,
adhocReport, meetingBudget, changeLog, workflow, attachments, transfer,
meetingTask, virtualProgramSetup, user, salesForce, category, pushAlert,
programType, budgetTemplates, brand, team, attendanceFrequency,
registrationWorkflow, templates, preferredSpeakers, forceTargetInvitation,
projectTask, aggSpendReportConfig, uploadLogos, survey, surveyBuilder,
pharmaginUsers, pharmaginRoles, emailInvitationTemplates, compliance,
plids, customReports, calendarAppendix D: Configuration Feature Flags Summary
Agency-Level Flags (agency-{env}.yml)
- projectTaskEnabled, enableScheduledReports, enableApprovalFlow
- enableAutomatedEmail, enablePreferredSpeakersList, enableForceTargetInvitation
- enableHonorariaAmount, enableCloseOutProgram, enableUnsubscribedEmail
- enableDataExceptions, enableAttendeeTrackerDataToSftp
- enableMosaicIntegration, enablePorzioAggSpendReport, enableGoogleGeocodeAPI
Company-Level Flags (company-{env}.yml)
- navigation.disableTopics, navigation.disableTraining
- navigation.disableExpenseReports, navigation.disableNominations
- navigation.disableReports, navigation.disableSpeakerGroup
- navigation.enableAdmin
- enableContractAdvanced, disablePresentationDelete
- disablePresentationOnTraining, disableSurveyAlerts
Product-Level Flags (product-{env}.yml)
- program.editProgram, program.approvalEnabled, program.shareableEnabled
- program.cancelProgramEnabled, program.attachmentsEnabled
- registration.openRegistrationEnabled, registration.registrationSiteEnabled
- registration.closeAttendeeListEnabled, registration.copyAttendeesEnabled
- registration.updateCRMAttendeesEnabled, registration.deleteAttendeeEnabled
- registration.addToSalesforceEnabled, registration.enableEmailInvitation
- documentTemplate.signInSheetEnabled, documentTemplate.paperInvitationEnabled
- documentTemplate.attendeeSurveyResponsesEnabled, documentTemplate.signatureReportEnabled
- documentTemplate.honorariaInvoiceEnabled, documentTemplate.speakerExpenseReimbursementEnabled
- documentTemplate.postProgramCertificationEnabled
- enableNewSurvey, enableCustomReport, enableSpeakerNomination, enablePLID
- fiscalPeriodEnabled, brandBudgetAllocationEnabled
- programSummaryReportRestrictionsEnabled, speakerUtilizationRestrictionsEnabled