Skip to content

feat: Invite admin and trigger braze functionality has been updated #2542

Merged
iloveagent57 merged 1 commit intoopenedx:masterfrom
rgopalrao-sonata-png:rgopalrao/ENT-11238-invite-admin-endpoint
Mar 16, 2026
Merged

feat: Invite admin and trigger braze functionality has been updated #2542
iloveagent57 merged 1 commit intoopenedx:masterfrom
rgopalrao-sonata-png:rgopalrao/ENT-11238-invite-admin-endpoint

Conversation

@rgopalrao-sonata-png
Copy link
Contributor

@rgopalrao-sonata-png rgopalrao-sonata-png commented Mar 4, 2026

ENT-11238: Enterprise Admin Invite Flow with Braze Email Integration

Summary

This PR implements the admin invitation and management system for the People Management feature, consolidating multiple related JIRA tickets into a single cohesive solution.

Primary Features:

  1. Bulk Admin Invitation - Send invites to multiple new users or learners with either admin or existing learner based email routing
  2. Braze Email Integration - Email campaigns for new admin and learner-to-admin invitations
  3. Role-Based Deletion - Deletion logic that preserves admin accounts for auditability(Soft delete of admin)

🎫 Related JIRA Tickets

This PR consolidates the following dependent tickets:

Ticket Description Status
ENT-11238 Main: Email invite triggering when admin invites new admin (Part of Epic ENT-10680) ✅ Completed
ENT-11519 Braze email campaign for new admin invites (list of emails) ✅ Completed
ENT-11555 Braze email campaign for existing learners being promoted to admin ✅ Completed
ENT-11264 Role-based deletion logic for admin accounts (preserves auditability) and hard deletion of pending customer admins ✅ Completed

Epic: ENT-10680 - People Management Admin Invite Flow


⚙️ What Changed

Problem Statement

As part of of Invite Admin functionality from people management

  • Email notification to be sent to the new user to be admin
  • Email notification to be sent to the new admin who is already existing learner
  • Soft deletion of the admin
  • Hard deletion of the pending admin

Solution Overview

🔹 Workflow 1: Invite Admins (ENT-11238, ENT-11519, ENT-11555)

Admin Portal → invite_admins API → Email Routing → Email Delivery
                                      ├─ New Users → Braze Campaign (ENT-11519)
                                      ├─ Existing Learners → Braze Campaign (ENT-11555)
                                      ├─ Already Admins → Skip (return status)
                                  

🔹 Workflow 2: Delete Admins (ENT-11264)

Admin Portal → delete_admin API → Role Type Detection
                                   ├─ role=pending → Hard Delete (remove PendingEnterpriseCustomerAdminUser)
                                   └─ role=admin → Soft Delete (remove role, deactivate ECU if no other roles)

API Changes

New Endpoints

1. Invite Admins

POST /enterprise/api/v1/enterprise-customer-admin/{enterprise_customer_uuid}/admin-invites

Request Body:

{
  "emails": ["admin1@example.com", "admin2@example.com"]
}

Response (200 OK):

[
  {"email": "admin1@example.com", "status": "invite sent"},
  {"email": "admin2@example.com", "status": "already admin"}
]

Status Values:

  • "invite sent" - New invitation created
  • "already sent" - Pending invitation exists
  • "already admin" - User is already an active admin

2. Delete Admin

DELETE /enterprise/api/v1/enterprise-customer-admin/{customer_id}/delete/?role={role_type}

Query Parameters:

  • role (required): Either "pending" or "admin"

For role=pending:

  • Hard deletes PendingEnterpriseCustomerAdminUser record

For role=admin:

  • Removes admin role assignment from SystemWideEnterpriseUserRoleAssignment
  • Deactivates EnterpriseCustomerUser if no other roles exist
  • Deactivates Django User account if no roles exist across ALL enterprises

Response (200 OK):

{
  "message": "Admin admin@example.com deleted successfully and user account deactivated",
  "user_deactivated": true
}

Modified Endpoints

Deprecated (URL Changed):

- DELETE /api/v1/enterprise-customer/{enterprise_customer_uuid}/admins/{admin_pk}/
+DELETE /enterprise/api/v1/enterprise-customer-admin/{enterprise_customer_uuid}/admins/{id}/?role=<role>

Breaking Change: The old endpoint has been removed. Clients must migrate to the new URL pattern.


📁 Key Files Changed

Modified Files

  • enterprise/api/v1/views/enterprise_customer_admin.py - Invite and delete endpoints
  • enterprise/api/utils.py - Utility functions for admin management
  • enterprise/api/v1/serializers.py - AdminInviteSerializer for email validation
  • enterprise/tasks.py - send_enterprise_admin_invite_email Celery task
  • enterprise/constants.py - New constants for admin status and Braze endpoints
  • tests/test_enterprise/api/test_enterprise_customer_admin.py - Comprehensive test suite

Testing Coverage

Unit Tests Added

Invite Admins Endpoint :

  • Valid email batch processing
  • Duplicate email detection (case-insensitive)
  • Email normalization (whitespace, casing)
  • Existing admin detection
  • Pending invitation detection
  • Race condition handling
  • Large batch support (100+ emails)
  • Database error handling
  • Permission validation

Delete Admin Endpoint:

  • Hard deletion of pending admins
  • Soft deletion of active admins
  • Role assignment removal
  • ECU deactivation logic
  • User account deactivation logic
  • Multi-enterprise role preservation
  • Database error handling
  • Permission validation

Braze API Client :

  • Recipient building with validation
  • Campaign message sending
  • HTTP error handling (4xx, 5xx)
  • Timeout and connection errors
  • Retry logic validation
  • Large batch warnings

Utility Functions :

  • Admin email retrieval (active, inactive, pending)
  • Braze campaign routing (new vs. existing users)
  • Transaction atomicity
  • Race condition handling

Integration Tests

✅ Devstack validation with screenshots (see below)
✅ End-to-end email delivery verification
✅ Multi-admin deletion scenarios


📸 Test Results & Visual Proof

All test scenarios have been validated in devstack. Screenshots demonstrate the functionality:

1. Invitation Already Sent (ENT-11238)

When inviting admins who already have pending invitations, the system correctly identifies them:
Invitation already sent
Invitation_mails

✅ Result: Returns "pending_admin_emails" list instead of creating duplicates

2. Email Triggered via Braze (ENT-11519)

New admin invitations successfully trigger Braze email campaigns:
Triggered email

✅ Result: Returns "inactive_admin_emails" list preventing spam to removed users

4. Existing Learner Promotion (ENT-11555)

When inviting existing learners to become admins, they're routed through the learner-to-admin flow:
Learner emails

✅ Result: Existing users get promoted to admin role without re-registration

5. Admin Deletion with ECU Deactivation (ENT-11264)

Role-based deletion correctly deactivates user accounts when no other roles exist:
User deactivated admin

✅ Result: Returns "user_deactivated": true flag confirming soft delete


Deployment Notes

Required Settings

Requires to add the following to your Django settings(edx-internal):

# Braze Campaign IDs for admin invites
BRAZE_ADMIN_INVITE_CAMPAIGN_ID = '<campaign-id-for-new-admins>'
BRAZE_LEARNER_INVITE_CAMPAIGN_ID = '<campaign-id-for-existing-learners>'

# Existing Braze settings (should already be configured)
ENTERPRISE_BRAZE_API_KEY = '<your-braze-api-key>'
EDX_BRAZE_API_SERVER = 'https://rest.iad-01.braze.com'

Database Migrations

No database migrations required - uses existing models.

Backward Compatibility

Breaking Change: The old delete admin endpoint URL has changed:

- DELETE /api/v1/enterprise-customer/{uuid}/admins/{pk}/
+DELETE /enterprise/api/v1/enterprise-customer-admin/{enterprise_customer_uuid}/admins/{id}/?role=<role>

Additional Context

  • Email campaigns must be configured in Braze before deployment

@openedx-webhooks
Copy link

Thanks for the pull request, @rgopalrao-sonata-png!

This repository is currently maintained by @openedx/2u-enterprise.

Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review.

🔘 Get product approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.
🔘 Provide context

To help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads
🔘 Submit a signed contributor agreement (CLA)

⚠️ We ask all contributors to the Open edX project to submit a signed contributor agreement or indicate their institutional affiliation.
Please see the CONTRIBUTING file for more information.

If you've signed an agreement in the past, you may need to re-sign.
See The New Home of the Open edX Codebase for details.

Once you've signed the CLA, please allow 1 business day for it to be processed.
After this time, you can re-run the CLA check by adding a comment below that you have signed it.
If the CLA check continues to fail, you can tag the @openedx/cla-problems team in a comment for further assistance.

🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.

Details
Where can I find more information?

If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:

When can I expect my changes to be merged?

Our goal is to get community contributions seen and reviewed as efficiently as possible.

However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Mar 4, 2026
@github-project-automation github-project-automation bot moved this to Needs Triage in Contributions Mar 4, 2026
@rgopalrao-sonata-png rgopalrao-sonata-png force-pushed the rgopalrao/ENT-11238-invite-admin-endpoint branch 11 times, most recently from 6ed4ddc to b95d747 Compare March 5, 2026 17:22
@e0d e0d changed the title feat: Invite admin and trigger braze functionality has been updated feat: Invite admin and trigger braze functionality has been updated Mar 5, 2026
@rgopalrao-sonata-png rgopalrao-sonata-png force-pushed the rgopalrao/ENT-11238-invite-admin-endpoint branch 14 times, most recently from a8c2bf2 to cecd539 Compare March 6, 2026 08:14
@rgopalrao-sonata-png rgopalrao-sonata-png force-pushed the rgopalrao/ENT-11238-invite-admin-endpoint branch 12 times, most recently from 4d31117 to c771029 Compare March 11, 2026 11:56
@mphilbrick211 mphilbrick211 added the needs test run Author's first PR to this repository, awaiting test authorization from Axim label Mar 11, 2026
@mphilbrick211 mphilbrick211 moved this from Needs Triage to Needs Tests Run or CLA Signed in Contributions Mar 11, 2026
@rgopalrao-sonata-png rgopalrao-sonata-png force-pushed the rgopalrao/ENT-11238-invite-admin-endpoint branch 2 times, most recently from 6989af9 to 4ac677a Compare March 12, 2026 04:32
Copy link

@vshaikismail-sonata vshaikismail-sonata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM...!!!

@rgopalrao-sonata-png rgopalrao-sonata-png force-pushed the rgopalrao/ENT-11238-invite-admin-endpoint branch 7 times, most recently from 1d8b105 to 0d4bb8c Compare March 12, 2026 06:57
@e0d
Copy link

e0d commented Mar 13, 2026

@rgopalrao-sonata-png I've added you to the openedx-triage team as you are covered under an entity CLA. This will mean that tests will run automatically when you submit a pull request in the future. Please look for an invitation in your email and accept it.

@e0d
Copy link

e0d commented Mar 13, 2026

@rgopalrao-sonata-png Looks like there one failed check and some conflicts that need to be resolved.

@rgopalrao-sonata-png
Copy link
Contributor Author

Thanks for the review — I’ve incorporated the feedback, fixed. Could you please re-review the latest diff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

open-source-contribution PR author is not from Axim or 2U

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants