Skip to content

Conversation

@sjasti-sonata-svg
Copy link

Merge checklist:

  • Any new requirements are in the right place (do not manually modify the requirements/*.txt files)
    • base.in if needed in production but edx-platform doesn't install it
    • test-master.in if edx-platform pins it, with a matching version
    • make upgrade && make requirements have been run to regenerate requirements
  • make static has been run to update webpack bundling if any static content was updated
  • ./manage.py makemigrations has been run
    • Checkout the Database Migration Confluence page for helpful tips on creating migrations.
    • Note: This must be run if you modified any models.
      • It may or may not make a migration depending on exactly what you modified, but it should still be run.
    • This should be run from either a venv with all the lms/edx-enterprise requirements installed or if you checked out edx-enterprise into the src directory used by lms, you can run this command through an lms shell.
      • It would be ./manage.py lms makemigrations in the shell.
  • Version bumped
  • Changelog record added
  • Translations updated (see docs/internationalization.rst but also this isn't blocking for merge atm)

Post merge:

  • Tag pushed and a new version released
    • Note: Assets will be added automatically. You just need to provide a tag (should match your version number) and title and description.
  • After versioned build finishes in GitHub Actions, verify version has been pushed to PyPI
    • Each step in the release build has a condition flag that checks if the rest of the steps are done and if so will deploy to PyPi.
      (so basically once your build finishes, after maybe a minute you should see the new version in PyPi automatically (on refresh))
  • PR created in edx-platform to upgrade dependencies (including edx-enterprise)
    • Trigger the 'Upgrade one Python dependency' action against master in edx-platform with new version number to generate version bump PR
    • This must be done after the version is visible in PyPi as make upgrade in edx-platform will look for the latest version in PyPi.
    • Note: the edx-enterprise constraint in edx-platform must also be bumped to the latest version in PyPi.

@sjasti-sonata-svg
Copy link
Author

This is the ticket :
ENT-11235
Description:
We need to support new metadata for admins, including tracking when an admin was invited and when they joined. Review the existing admin table and ensure new fields do not break existing APIs.

Copy link
Contributor

@kiram15 kiram15 left a comment

Choose a reason for hiding this comment

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

I'm confused as to why we are changing fields in the EnterpriseCustomerUser table. When you are going to pull all the admins for the new admin DataTable, we should not be going through a list of the EnterpriseCustomerUsers, but rather another table of all the admins. As I said in the comment, I think the best approach would be adding the invited_date and joined_date fields to EnterpriseCustomerAdmin table, and then plan to pull in the (relevant, non-onboarding tour) information for the DataTable y'all will be creating.

I also think that whenever we're adding new fields, its good to include in the PR how they will be getting populated. Here is how EnterpriseCustomerAdmins are currently created (in a post_save django signal where an "enterprise_admin" system-wide role is assigned to the user). I'm assuming the plan is to have the invited_date be when the PendingEnterpriseCustomerAdminUser record is created, and then a joined_date be populated if/when the EnterpriseCustomerAdmin record is created, but in order for me to review these fields, I need to know more information about these dates.

@kiram15 kiram15 self-requested a review December 24, 2025 00:42
@kiram15 kiram15 dismissed their stale review December 24, 2025 00:42

Don't want to block this PR before I go on vacation

@pwnage101
Copy link
Contributor

Before merging, please squash your commits to only one commit and use a more descriptive title, such as "feat: add date fields to track enterprise user invitation lifecycle". Please also change the title of this PR to match that more descriptive title.

@sjasti-sonata-svg sjasti-sonata-svg force-pushed the feat/admin-invite-metadata-ENT-11235 branch 2 times, most recently from 0cda236 to dc95ac2 Compare January 7, 2026 17:47
self._assert_pending_ecus_exist(should_exist=False)

@mark.django_db
class TestEnterpriseCustomerAdminSignals(unittest.TestCase):
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you please verify that invited_date and joined_date fields are set to the correct values, you can extend your test cases to compare against expected timestamps

Copy link
Author

Choose a reason for hiding this comment

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

Hi @msaha-sonata ,
Added the test cases.

Copy link
Contributor

@msaha-sonata msaha-sonata left a comment

Choose a reason for hiding this comment

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

Looks good to me

Copy link
Contributor

@kiram15 kiram15 left a comment

Choose a reason for hiding this comment

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

Make sure you update the changelog and init file, and rename the title and commits like Troy mentioned. Once it's in a good state, I can merge it in tomorrow!

CHANGELOG.rst Outdated
---------------------
* feat: added atlas translations flow in enterprise app

[6.5.8] - 2025-12-16
Copy link
Contributor

Choose a reason for hiding this comment

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

The changelog needs to be updated because of updates that happened since, and also the init file needs to be updated too.

Copy link
Author

Choose a reason for hiding this comment

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

Hi @kiram15
Done the changes. I have updated the files. could you please do the further process.

@sjasti-sonata-svg sjasti-sonata-svg force-pushed the feat/admin-invite-metadata-ENT-11235 branch from 339bbdb to 63a0c5f Compare January 22, 2026 03:07
@sjasti-sonata-svg sjasti-sonata-svg changed the title ENT-11235: update schema ENT-11235: Updating schema to add invited_date and joined_date fields to customer admin. Jan 22, 2026
Copy link
Contributor

@pwnage101 pwnage101 left a comment

Choose a reason for hiding this comment

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

In additional to my requested changes, please also make sure your commits do not include a "Merge" commit. In your case, the number of commits should be just 1.

Image

Comment on lines 3973 to 3978
"""Track the date and time when a pending enterprise admin invite was created."""
invited_date = models.DateTimeField(
null=True,
blank=True,
help_text="Timestamp when the admin invite was created."
)
Copy link
Contributor

Choose a reason for hiding this comment

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

This field seems redundant; there's already a created field inherited from TimeStampedModel. Furthermore, this PR lacks code changes for populating this field.

Copy link
Author

Choose a reason for hiding this comment

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

Hi @pwnage101
I am removing invited_date and joined_date, populated invited_date directly at creation time in init.py.
Is that fine?

default=False,
help_text=_("Whether the admin has completed the onboarding tour.")
)
"""Track when the admin was invited."""
Copy link
Contributor

Choose a reason for hiding this comment

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

This is the incorrect syntax for code comments. Use # prefix:

Suggested change
"""Track when the admin was invited."""
# Track when the admin was invited.

Copy link
Author

Choose a reason for hiding this comment

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

Hi @pwnage101
Done

help_text="Timestamp when the admin was invited."
)
"""Track when the admin accepted the invite and joined."""
joined_date = models.DateTimeField(
Copy link
Contributor

Choose a reason for hiding this comment

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

This model also inherits TimeStampedModel, so joined_date is redundant with created.

Copy link
Author

Choose a reason for hiding this comment

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

Done

instance.display_name = f'SSO-config-{instance.identity_provider}-{num_records_for_customer + 1}'

@receiver(post_save, sender=EnterpriseCustomerAdmin)
def populate_admin_onboarding_metadata(sender, instance, created, **kwargs):
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this entire signal is not necessary. We have direct access to the code that creates the EnterpriseCustomerAdmins:

EnterpriseCustomerAdmin.objects.get_or_create(
enterprise_customer_user=enterprise_customer_user,
)

You only need to update that call to look like this:

        EnterpriseCustomerAdmin.objects.get_or_create(
            enterprise_customer_user=enterprise_customer_user,
            defaults={'invited_date': pending_admin_user.created},
        )

We typically reserve signals in cases where direct code manipulation is not possible, or breaks modularity.

Copy link
Author

Choose a reason for hiding this comment

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

Hi @pwnage101
I have worked on this .
could you please review the same and let me any changes required.

Copy link
Author

Choose a reason for hiding this comment

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

Done

@sjasti-sonata-svg sjasti-sonata-svg force-pushed the feat/admin-invite-metadata-ENT-11235 branch from e64e451 to dce1bd4 Compare February 2, 2026 17:34
enterprise_customer_user=eu,
last_login=timezone.now()
last_login=timezone.now(),
joined_date=timezone.now()
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: leave a trailing comma.

Copy link
Author

Choose a reason for hiding this comment

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

Done

@@ -0,0 +1,49 @@
# Generated by Django 5.2.8 on 2025-12-29 17:47
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like you forgot to delete this file.

Copy link
Author

Choose a reason for hiding this comment

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

Hi @pwnage101
Deleted the file.

default=False,
help_text=_("Whether the admin has completed the onboarding tour.")
)
"""Track when the admin accepted the invite and joined."""
Copy link
Contributor

Choose a reason for hiding this comment

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

This is the incorrect syntax for code comments. Use # prefix:

Suggested change
"""Track when the admin accepted the invite and joined."""
# Track when the admin accepted the invite and joined.

Copy link
Author

Choose a reason for hiding this comment

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

Done

).count()
instance.display_name = f'SSO-config-{instance.identity_provider}-{num_records_for_customer + 1}'


Copy link
Contributor

Choose a reason for hiding this comment

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

re-add empty line to simplify diff.

Copy link
Author

Choose a reason for hiding this comment

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

Added empty line.

Comment on lines 11 to 20
from django.utils.timezone import now

from enterprise import models, roles_api
from enterprise.api import activate_admin_permissions
from enterprise.api_client.enterprise_catalog import EnterpriseCatalogApiClient
from enterprise.decorators import disable_for_loaddata
from enterprise.models import (
EnterpriseCustomerAdmin,
PendingEnterpriseCustomerAdminUser,
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove added imports which are no longer used.

Copy link
Author

Choose a reason for hiding this comment

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

Done.

Comment on lines 24 to 34
[6.6.2] - 2026-01-15
---------------------
* feat: add a waffle flag for invite admins

[6.6.1] - 2026-01-09
---------------------
* fix: issue regarding the gettext package in atlas translations flow

[6.6.0] - 2026-01-08
---------------------
* feat: added atlas translations flow in enterprise app
Copy link
Contributor

Choose a reason for hiding this comment

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

Your commit should never include changelog entries from other commits. You still need to rebase your commit onto the upstream origin.

Copy link
Author

Choose a reason for hiding this comment

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

Done

Your project description goes here.
"""

__version__ = "6.6.2"
Copy link
Contributor

Choose a reason for hiding this comment

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

If the version jump is this large, you need to rebase your commit on the origin (openedx/edx-enterprise master branch).

Copy link
Author

Choose a reason for hiding this comment

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

Done.

self._assert_pending_ecus_exist(should_exist=False)

@mark.django_db
class TestEnterpriseCustomerAdminSignals(unittest.TestCase):
Copy link
Contributor

Choose a reason for hiding this comment

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

This feature no longer uses signals, so it should not be considered a signals test. You should relocate these test cases. Probably tests/test_models.py

Copy link
Author

Choose a reason for hiding this comment

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

DONE.

@sjasti-sonata-svg sjasti-sonata-svg force-pushed the feat/admin-invite-metadata-ENT-11235 branch from be1db8e to bf159c2 Compare February 4, 2026 11:39
…and add invitation lifecycle fields

removed signal and set invited_date via defaults

updating changelog.rst

Removed  unintended migration file

fixed comments
@sjasti-sonata-svg sjasti-sonata-svg force-pushed the feat/admin-invite-metadata-ENT-11235 branch from bf159c2 to bd4b650 Compare February 4, 2026 11:57
@sjasti-sonata-svg
Copy link
Author

Hi @pwnage101 ,
I have done the changes. please review the same and let me know any changes needed.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants