def get_permitted_projects_for_user(
    user: "FFAdminUser",
    permission_key: str,
    tag_ids: List[int] = None,  # type: ignore[assignment]
) -> QuerySet[Project]:
    """
    Get all projects that the user has the given permissions for.

    Rules:
        - User has the required permissions directly (UserProjectPermission)
        - User is in a UserPermissionGroup that has required permissions (UserPermissionGroupProjectPermissions)
        - User is an admin for the organisation the project belongs to
        - User has a role attached with the required permissions(if rbac is enabled)
        - User is in a UserPermissionGroup that has a role attached with the required permissions
    NOTE:
        - If `tag_ids` is None, tags filter will not be applied
        - If `tag_ids` is an empty list, only project with no tags will be returned
        - If `tag_ids` is a list of tag IDs, only project with one of those tags will
        be returned
    """
    project_ids_from_base_filter = get_object_id_from_base_permission_filter(
        user,
        Project,  # type: ignore[arg-type]
        permission_key,
        tag_ids=tag_ids,
    )

    organisation_filter = Q(
        organisation__userorganisation__user=user,
        organisation__userorganisation__role=OrganisationRole.ADMIN.name,
    )
    project_ids_from_organisation = Project.objects.filter(
        organisation_filter
    ).values_list("id", flat=True)

    project_ids = project_ids_from_base_filter | set(project_ids_from_organisation)
    return Project.objects.filter(id__in=project_ids)

    Get all projects that the user has the given permissions for.

    Rules:
        - User has the required permissions directly (UserProjectPermission)
        - User is in a UserPermissionGroup that has required permissions (UserPermissionGroupProjectPermissions)
        - User is an admin for the organisation the project belongs to
        - User has a role attached with the required permissions(if rbac is enabled)
        - User is in a UserPermissionGroup that has a role attached with the required permissions
    NOTE:
        - If `tag_ids` is None, tags filter will not be applied
        - If `tag_ids` is an empty list, only project with no tags will be returned
        - If `tag_ids` is a list of tag IDs, only project with one of those tags will
        be returned
    
api/permissions/permission_service.py