Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions apps/community_dashboard/graphql/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import strawberry
from asgiref.sync import sync_to_async
from django.db import models
from django.shortcuts import aget_object_or_404
from django.utils import timezone

from apps.community_dashboard.models import AggregatedUserGroupStatData, AggregatedUserStatData
from apps.contributor.models import ContributorUser
from apps.contributor.models import ContributorUser, ContributorUserGroup
from utils.graphql.inputs import FirebaseOrInternalIdInputType

from .types import (
AggregateHelper,
Expand Down Expand Up @@ -117,17 +117,19 @@ async def community_filtered_stats(
) -> CommunityFilteredStats:
return CommunityFilteredStats(date_range=date_range)

# By Internal ID
@strawberry.field
async def community_user_stats(
self,
firebase_id: strawberry.ID,
user_id: FirebaseOrInternalIdInputType,
) -> ContributorUserStats:
user = await aget_object_or_404(ContributorUser, firebase_id=firebase_id)
user = await FirebaseOrInternalIdInputType.aget_object_or_404(ContributorUser, object_id=user_id)
return ContributorUserStats(user=user)

@strawberry.field
async def community_user_group_stats(
self,
user_group_id: strawberry.ID,
user_group_id: FirebaseOrInternalIdInputType,
) -> ContributorUserGroupStats:
return ContributorUserGroupStats(user_group_id=int(user_group_id))
user_group = await FirebaseOrInternalIdInputType.aget_object_or_404(ContributorUserGroup, object_id=user_group_id)
return ContributorUserGroupStats(user_group=user_group)
14 changes: 9 additions & 5 deletions apps/community_dashboard/graphql/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from django_cte import With # type: ignore[reportMissingTypeStubs]

from apps.community_dashboard.models import AggregatedUserGroupStatData, AggregatedUserStatData
from apps.contributor.models import ContributorUser
from apps.contributor.models import ContributorUser, ContributorUserGroup
from apps.project.models import Project, ProjectTypeEnum
from utils.graphql.inputs import DateRangeInput
from utils.graphql.types import AreaSqKm, GenericJSON
Expand Down Expand Up @@ -349,6 +349,10 @@ def __post_init__(self, user: ContributorUser):
async def id(self) -> strawberry.ID:
return typing.cast("strawberry.ID", self._user.pk)

@strawberry.field
async def firebase_id(self) -> strawberry.ID:
return typing.cast("strawberry.ID", self._user.firebase_id)

@strawberry.field
async def stats(self) -> ContributorUserStatType:
# TODO: Cache this
Expand Down Expand Up @@ -423,15 +427,15 @@ def __post_init__(self, date_range: DateRangeInput | None, user_group_id: int):

@strawberry.type
class ContributorUserGroupStats:
user_group_id: InitVar[int]
user_group: InitVar[ContributorUserGroup]

_user_group_id: strawberry.Private[int] = dataclass_field(init=False)
_ug_qs: strawberry.Private[models.QuerySet[AggregatedUserGroupStatData]] = dataclass_field(init=False)

def __post_init__(self, user_group_id: int):
self._user_group_id = user_group_id
def __post_init__(self, user_group: ContributorUserGroup):
self._user_group_id = user_group.pk
self._ug_qs = AggregatedUserGroupStatData.objects.filter(
user_group_id=user_group_id,
user_group_id=user_group.pk,
)

@strawberry.field
Expand Down
10 changes: 5 additions & 5 deletions apps/community_dashboard/tests/query_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def test_filtered_community_stats(self):
def test_user_group_aggregated_calc(self):
query = """
query MyQuery($userGroupId: ID!) {
communityUserGroupStats(userGroupId: $userGroupId) {
communityUserGroupStats(userGroupId: {id: $userGroupId}) {
stats {
totalAreaSwiped
totalContributors
Expand Down Expand Up @@ -306,7 +306,7 @@ def test_user_group_aggregated_calc(self):
def test_user_group_query(self):
query = """
query MyQuery($userGroupId: ID!, $pagination: OffsetPaginationInput!) {
contributorUserGroup(id: $userGroupId) {
contributorUserGroup(userGroupId: {id: $userGroupId}) {
id
name
createdAt
Expand Down Expand Up @@ -502,13 +502,13 @@ def test_user_query(self):
$toDate: Date!,
) {

contributorUserByFirebaseId(firebaseId: $firebaseId) {
contributorUser(userId: {firebaseId: $firebaseId}) {
id
firebaseId
username
}

communityUserStats(firebaseId: $firebaseId) {
communityUserStats(userId: {firebaseId: $firebaseId}) {
id
stats {
totalSwipes
Expand Down Expand Up @@ -644,7 +644,7 @@ def test_user_query(self):
)

assert {
"contributorUserByFirebaseId": {
"contributorUser": {
"id": self.gID(contributor_user.pk),
"firebaseId": contributor_user.firebase_id,
"username": contributor_user.username,
Expand Down
21 changes: 14 additions & 7 deletions apps/contributor/graphql/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import strawberry
import strawberry_django
from django.db.models import QuerySet
from django.shortcuts import aget_object_or_404
from strawberry_django.pagination import OffsetPaginated
from strawberry_django.permissions import IsAuthenticated

from apps.contributor.models import ContributorTeam, ContributorUser, ContributorUserGroup, ContributorUserGroupMembership
from utils.graphql.inputs import FirebaseOrInternalIdInputType

from .filters import (
ContributorTeamFilter,
Expand All @@ -31,18 +31,25 @@ class Query:
filters=ContributorUserFilter,
)

contributor_user: ContributorUserType = strawberry_django.field()

contributor_user_group: ContributorUserGroupType = strawberry_django.field()

# Team
contributor_team: ContributorTeamType = strawberry_django.field()

@strawberry.field
async def contributor_user_by_firebase_id(self, firebase_id: strawberry.ID) -> ContributorUserType:
obj = await aget_object_or_404(ContributorUser, firebase_id=firebase_id)
async def contributor_user(
self,
user_id: FirebaseOrInternalIdInputType,
) -> ContributorUserType:
obj = await FirebaseOrInternalIdInputType.aget_object_or_404(ContributorUser, object_id=user_id)
return typing.cast("ContributorUserType", obj)

@strawberry.field
async def contributor_user_group(
self,
user_group_id: FirebaseOrInternalIdInputType,
) -> ContributorUserGroupType:
obj = await FirebaseOrInternalIdInputType.aget_object_or_404(ContributorUserGroup, object_id=user_group_id)
return typing.cast("ContributorUserGroupType", obj)

# --- Paginated
# --- ContributorUserGroup
@strawberry_django.offset_paginated(
Expand Down
3 changes: 2 additions & 1 deletion apps/project/graphql/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,9 @@ def public_projects(
) -> QuerySet[Project]:
return Project.objects.filter(
status__in=[
Project.Status.FINISHED,
Project.Status.PUBLISHED,
Project.Status.PAUSED,
Project.Status.FINISHED,
],
).all()

Expand Down
15 changes: 10 additions & 5 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,7 @@ type ContributorUserStatType {

type ContributorUserStats {
filteredStats(dateRange: DateRangeInput = null): ContributorUserFilteredStats!
firebaseId: ID!
id: ID!
stats: ContributorUserStatType!

Expand Down Expand Up @@ -804,6 +805,11 @@ type FindTutorialTaskPropertyType {
tileZ: Int!
}

input FirebaseOrInternalIdInputType @oneOf {
firebaseId: ID
id: ID
}

interface FirebasePushResourceTypeMixin {
firebaseId: String!
firebaseLastPushed: DateTime
Expand Down Expand Up @@ -2009,13 +2015,12 @@ type Query {

"""Stats from last 30 days."""
communityStatsLatest: CommunityStatsType!
communityUserGroupStats(userGroupId: ID!): ContributorUserGroupStats!
communityUserStats(firebaseId: ID!): ContributorUserStats!
communityUserGroupStats(userGroupId: FirebaseOrInternalIdInputType!): ContributorUserGroupStats!
communityUserStats(userId: FirebaseOrInternalIdInputType!): ContributorUserStats!
contributorTeam(id: ID!): ContributorTeamType!
contributorTeams(includeAll: Boolean! = false, filters: ContributorTeamFilter, order: ContributorTeamOrder, pagination: OffsetPaginationInput): ContributorTeamTypeOffsetPaginated! @isAuthenticated
contributorUser(id: ID!): ContributorUserType!
contributorUserByFirebaseId(firebaseId: ID!): ContributorUserType!
contributorUserGroup(id: ID!): ContributorUserGroupType!
contributorUser(userId: FirebaseOrInternalIdInputType!): ContributorUserType!
contributorUserGroup(userGroupId: FirebaseOrInternalIdInputType!): ContributorUserGroupType!
contributorUserGroupMembers(includeAll: Boolean! = false, filters: ContributorUserGroupMembershipFilter, order: ContributorUserGroupMembershipOrder, pagination: OffsetPaginationInput): ContributorUserGroupMembershipTypeOffsetPaginated!
contributorUserGroups(includeAll: Boolean! = false, filters: ContributorUserGroupFilter, order: ContributorUserGroupOrder, pagination: OffsetPaginationInput): ContributorUserGroupTypeOffsetPaginated!
contributorUsers(pagination: OffsetPaginationInput, filters: ContributorUserFilter, order: ContributorUserOrder): ContributorUserTypeOffsetPaginated!
Expand Down
19 changes: 19 additions & 0 deletions utils/graphql/inputs.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
import datetime

import strawberry
from django.db import models
from django.shortcuts import aget_object_or_404


@strawberry.input
class DateRangeInput:
from_date: datetime.date
to_date: datetime.date


@strawberry.input(one_of=True)
class FirebaseOrInternalIdInputType:
id: strawberry.Maybe[strawberry.ID]
firebase_id: strawberry.Maybe[strawberry.ID]

@staticmethod
async def aget_object_or_404[M: models.Model](
model: type[M],
object_id: "FirebaseOrInternalIdInputType",
) -> M:
if object_id.id is not None:
return await aget_object_or_404(model, id=object_id.id.value)
if object_id.firebase_id is not None:
return await aget_object_or_404(model, firebase_id=object_id.firebase_id.value)
raise Exception("This should never be called")
Loading