Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#3316: automatically add domain managers as portfolio members - [MS] #3421

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

Matt-Spence
Copy link
Contributor

@Matt-Spence Matt-Spence commented Jan 29, 2025

Ticket

Resolves #3316

Changes

  • Adds new logic to the create_federal_portfolio script that loops through all domains in a given portfolio and adds their domain managers (including invited managers) to the portfolio org.
  • Tests

Context for reviewers

Setup

Identify or create several domains that are part of the same organization and have a few managers, at least one of which should be you (for checking emails). Run the script for that organization with the --add-managers flag set to True, and ensure that:

  • The portfolio is created successfully
  • All the managers are added as members to the portfolio
  • all invited managers are added
  • No new emails are sent.

Code Review Verification Steps

As the original developer, I have

Satisfied acceptance criteria and met development standards

  • Met the acceptance criteria, or will meet them in a subsequent PR
  • Created/modified automated tests
  • Update documentation in READMEs and/or onboarding guide

Ensured code standards are met (Original Developer)

  • If any updated dependencies on Pipfile, also update dependencies in requirements.txt.
  • Interactions with external systems are wrapped in try/except
  • Error handling exists for unusual or missing values

Validated user-facing changes (if applicable)

  • Tag @dotgov-designers in this PR's Reviewers for design review. If code is not user-facing, delete design reviewer checklist
  • Verify new pages have been added to .pa11yci file so that they will be tested with our automated accessibility testing
  • Checked keyboard navigability
  • Tested general usability, landmarks, page header structure, and links with a screen reader (such as Voiceover or ANDI)

As a code reviewer, I have

Reviewed, tested, and left feedback about the changes

  • Pulled this branch locally and tested it
  • Verified code meets all checks above. Address any checks that are not satisfied
  • Reviewed this code and left comments. Indicate if comments must be addressed before code is merged
  • Checked that all code is adequately covered by tests
  • Verify migrations are valid and do not conflict with existing migrations

Validated user-facing changes as a developer

Note: Multiple code reviewers can share the checklists above, a second reviewer should not make a duplicate checklist. All checks should be checked before approving, even those labeled N/A.

  • New pages have been added to .pa11yci file so that they will be tested with our automated accessibility testing
  • Checked keyboard navigability
  • Meets all designs and user flows provided by design/product
  • Tested general usability, landmarks, page header structure, and links with a screen reader (such as Voiceover or ANDI)
  • (Rarely needed) Tested as both an analyst and applicant user

As a designer reviewer, I have

Verified that the changes match the design intention

  • Checked that the design translated visually
  • Checked behavior. Comment any found issues or broken flows.
  • Checked different states (empty, one, some, error)
  • Checked for landmarks, page heading structure, and links

Validated user-facing changes as a designer

  • Checked keyboard navigability
  • Tested general usability, landmarks, page header structure, and links with a screen reader (such as Voiceover or ANDI)
  • Tested with multiple browsers (check off which ones were used)
    • Chrome
    • Microsoft Edge
    • FireFox
    • Safari
  • (Rarely needed) Tested as both an analyst and applicant user

References

Screenshots

Copy link

github-actions bot commented Feb 3, 2025

🥳 Successfully deployed to developer sandbox ms.

@Matt-Spence Matt-Spence changed the title (DRAFT) #3316: automatically add domain managers as portfolio members - [MS] #3316: automatically add domain managers as portfolio members - [MS] Feb 3, 2025
Copy link

github-actions bot commented Feb 3, 2025

🥳 Successfully deployed to developer sandbox ms.

@zandercymatics zandercymatics self-assigned this Feb 6, 2025
Copy link
Contributor

@zandercymatics zandercymatics left a comment

Choose a reason for hiding this comment

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

Would you be able to pull stagings DB into getgov-ms so I can test this script there?

As for the code:
Great unit tests. You are just missing a documentation update in data_migration.md, but looks good. Runs well locally on about 25 records.

Since this script will be dealing with ~200 or so records (and maybe more if we loop through more portfolios), I've included some optional optimization things. Its obviously not as important for scripts to be super performant, but it would be a nice-to-have as speaking from experience with a lot of records it can cut down runtime from 20-30 minutes down to a few seconds with large enough datasets (like our transition domains).

I did not note it, but you could also use bulk_create for all three of your steps - though you may lose some logging detail under try/except. If that is something you want to do, what I've personally done in that case is to make the query more specific such that it never enters a error state and instead just lumps it under skipped instead

for email in invited_managers:
self.create_portfolio_invitation(portfolio, email)

def create_portfolio_invitation(self, portfolio: Portfolio, email: str):
Copy link
Contributor

Choose a reason for hiding this comment

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

(Q) Do we auto-send emails now when they are created now? We added some logic to these recently, I just don't entirely recall the rules to it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think we automatically send them when a portfolio invitation object is created, I think we send emails at the same time but as it's own separate command. That said I also don't entirely understand these rules. I didn't receive any emails when I tested it but it's always possible that there was an email whitelist issue or something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm pretty sure that I would need to be calling the send_portfolio_invitation_email function to send an email.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for checking in on this! I think this is definitely a non-issue

agency_name = options.get("agency_name")
branch = options.get("branch")
parse_requests = options.get("parse_requests")
parse_domains = options.get("parse_domains")
both = options.get("both")
add_managers = options.get("add_managers")
Copy link
Contributor

Choose a reason for hiding this comment

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

On line 105, can you change that line to be if parse_requests or parse_domains or add_managers and change the CommandError? This would add capability to script such that you can just run it with just create_federal_portfolio --add_managers, which would be useful in situations where we don't also want to add new domain requests or domains

(sorry for the image, doesn't let me select it directly)
image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good idea, will do.

skip_existing_portfolios = options.get("skip_existing_portfolios")

if not both:
if not parse_requests and not parse_domains:
raise CommandError("You must specify at least one of --parse_requests or --parse_domains.")
if not (parse_requests or parse_domains or add_managers):
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice refactor here, thanks


# Fetch all domains associated with the portfolio
domains = Domain.objects.filter(domain_info__portfolio=portfolio)
domain_managers: set[int] = set()
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
domain_managers: set[int] = set()
domain_managers: set[UserDomainRole] = set()

Comment on lines 217 to 233
for id in domain_managers:
try:
# manager is a user id
user = User.objects.get(id=id)
_, created = UserPortfolioPermission.objects.get_or_create(
portfolio=portfolio,
user=user,
defaults={"roles": [UserPortfolioRoleChoices.ORGANIZATION_MEMBER]},
)
self.added_managers.add(user)
if created:
logger.info(f"Added manager '{user}' to portfolio '{portfolio}'")
else:
logger.info(f"Manager '{user}' already exists in portfolio '{portfolio}'")
except User.DoesNotExist:
self.failed_managers.add(user)
logger.debug(f"User '{user}' does not exist")
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you mean to change this as well, given the changes to domain_managers?

Copy link

github-actions bot commented Feb 6, 2025

🥳 Successfully deployed to developer sandbox ms.

2 similar comments
Copy link

github-actions bot commented Feb 6, 2025

🥳 Successfully deployed to developer sandbox ms.

Copy link

github-actions bot commented Feb 6, 2025

🥳 Successfully deployed to developer sandbox ms.

Copy link

github-actions bot commented Feb 6, 2025

🥳 Successfully deployed to developer sandbox ms.

Copy link

github-actions bot commented Feb 6, 2025

🥳 Successfully deployed to developer sandbox ms.

1 similar comment
Copy link

github-actions bot commented Feb 6, 2025

🥳 Successfully deployed to developer sandbox ms.

Copy link
Contributor

@zandercymatics zandercymatics left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link

github-actions bot commented Feb 6, 2025

🥳 Successfully deployed to developer sandbox ms.

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.

Automatically add domain managers as members to a portfolio (script)
2 participants