Skip to content
Open
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
9 changes: 9 additions & 0 deletions dbschema/migrations/00048-m1fjqfw.edgeql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CREATE MIGRATION m1fjqfwzmxszvkdaqxd3ygmk75xhfd35kmfkr4xmgswlkh7xxoddaq
ONTO m1axeqqxygv6gealfrhk6kvfbjd3eoj3rw3xzb6r6wujjaegng5mpq
{
ALTER TYPE user::User {
CREATE REQUIRED PROPERTY age_verified: std::bool {
SET default := true;
};
};
};
3 changes: 3 additions & 0 deletions dbschema/user.esdl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ module user {
constraint exclusive;
}
required property discord_username -> str;
required property age_verified -> bool {
default := true;
};
link profile := .<user[is Profile];
link amq := .<user[is amq::Account];
link anilist := .<user[is anilist::Account];
Expand Down
2 changes: 2 additions & 0 deletions nanapi/database/calendar/guild_event_delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ class GuildEventDeleteResultProjection(BaseModel):


class GuildEventDeleteResultParticipants(BaseModel):
age_verified: bool
discord_id: str
discord_username: str
id: UUID


class GuildEventDeleteResultOrganizer(BaseModel):
age_verified: bool
discord_id: str
discord_username: str
id: UUID
Expand Down
2 changes: 2 additions & 0 deletions nanapi/database/calendar/guild_event_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,14 @@ class GuildEventMergeResultProjection(BaseModel):


class GuildEventMergeResultParticipants(BaseModel):
age_verified: bool
discord_id: str
discord_username: str
id: UUID


class GuildEventMergeResultOrganizer(BaseModel):
age_verified: bool
discord_id: str
discord_username: str
id: UUID
Expand Down
2 changes: 2 additions & 0 deletions nanapi/database/calendar/guild_event_select.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ class GuildEventSelectResultProjection(BaseModel):


class GuildEventSelectResultParticipants(BaseModel):
age_verified: bool
discord_id: str
discord_username: str
id: UUID


class GuildEventSelectResultOrganizer(BaseModel):
age_verified: bool
discord_id: str
discord_username: str
id: UUID
Expand Down
1 change: 1 addition & 0 deletions nanapi/database/calendar/user_calendar_select.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@


class UserCalendarSelectResultUser(BaseModel):
age_verified: bool
discord_id: str
discord_username: str
id: UUID
Expand Down
1 change: 1 addition & 0 deletions nanapi/database/calendar/user_calendar_select_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@


class UserCalendarSelectAllResultUser(BaseModel):
age_verified: bool
discord_id: str
discord_username: str
id: UUID
Expand Down
1 change: 1 addition & 0 deletions nanapi/database/projection/projo_select.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class ProjectionStatus(StrEnum):


class ProjoSelectResultParticipants(BaseModel):
age_verified: bool
discord_id: str
discord_username: str
id: UUID
Expand Down
1 change: 1 addition & 0 deletions nanapi/database/user/user_select.edgeql
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
select user::User {
discord_id,
discord_username,
age_verified,
}
2 changes: 2 additions & 0 deletions nanapi/database/user/user_select.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
select user::User {
discord_id,
discord_username,
age_verified,
}
"""


class UserSelectResult(BaseModel):
age_verified: bool
discord_id: str
discord_username: str

Expand Down
12 changes: 12 additions & 0 deletions nanapi/database/user/user_upsert.edgeql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
insert user::User {
discord_id := <str>$discord_id,
age_verified := <bool>$age_verified,
discord_username := <str>$discord_username,
}
unless conflict on .discord_id
else (
update user::User set {
age_verified := <bool>$age_verified,
discord_username := <str>$discord_username,
}
)
44 changes: 44 additions & 0 deletions nanapi/database/user/user_upsert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Generated by gel-pydantic-codegen
# pyright: strict
from uuid import UUID

from gel import AsyncIOExecutor
from pydantic import BaseModel, TypeAdapter

EDGEQL_QUERY = r"""
insert user::User {
discord_id := <str>$discord_id,
age_verified := <bool>$age_verified,
discord_username := <str>$discord_username,
}
unless conflict on .discord_id
else (
update user::User set {
age_verified := <bool>$age_verified,
discord_username := <str>$discord_username,
}
)
"""


class UserUpsertResult(BaseModel):
id: UUID


adapter = TypeAdapter[UserUpsertResult](UserUpsertResult)


async def user_upsert(
executor: AsyncIOExecutor,
*,
discord_id: str,
age_verified: bool,
discord_username: str,
) -> UserUpsertResult:
resp = await executor.query_single_json( # pyright: ignore[reportUnknownMemberType]
EDGEQL_QUERY,
discord_id=discord_id,
age_verified=age_verified,
discord_username=discord_username,
)
return adapter.validate_json(resp, strict=False)
1 change: 1 addition & 0 deletions nanapi/database/waicolle/player_get_by_user.edgeql
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ select player {
*,
user: {
discord_id,
age_verified,
},
}
2 changes: 2 additions & 0 deletions nanapi/database/waicolle/player_get_by_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*,
user: {
discord_id,
age_verified,
},
}
"""
Expand All @@ -30,6 +31,7 @@ class WaicolleGameMode(StrEnum):


class PlayerGetByUserResultUser(BaseModel):
age_verified: bool
discord_id: str


Expand Down
6 changes: 6 additions & 0 deletions nanapi/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ class UpsertDiscordAccountBodyItem(BaseModel):
discord_username: str


class UpsertUser(BaseModel):
discord_id: str
discord_username: str
age_verified: bool


class ProfileSearchResult(ProfileGetByDiscordIdResult):
pass

Expand Down
19 changes: 18 additions & 1 deletion nanapi/routers/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
from nanapi.database.user.profile_select_ilike import profile_select_ilike
from nanapi.database.user.user_bulk_merge import UserBulkMergeResult, user_bulk_merge
from nanapi.database.user.user_select import UserSelectResult, user_select
from nanapi.models.user import ProfileSearchResult, UpsertDiscordAccountBodyItem, UpsertProfileBody
from nanapi.database.user.user_upsert import UserUpsertResult, user_upsert
from nanapi.models.user import (
ProfileSearchResult,
UpsertDiscordAccountBodyItem,
UpsertProfileBody,
UpsertUser,
)
from nanapi.utils.clients import get_edgedb
from nanapi.utils.fastapi import HTTPExceptionModel, NanAPIRouter

Expand All @@ -25,6 +31,17 @@ async def upsert_discord_accounts(body: list[UpsertDiscordAccountBodyItem]):
return await user_bulk_merge(get_edgedb(), users=[i.model_dump() for i in body])


@router.oauth2.patch('/account', response_model=UserUpsertResult)
async def upsert_user(body: UpsertUser):
"""upsert an user."""
return await user_upsert(
get_edgedb(),
discord_id=body.discord_id,
discord_username=body.discord_username,
age_verified=body.age_verified,
)


@router.oauth2.get('/profiles/search', response_model=list[ProfileSearchResult])
async def profile_search(discord_ids: str | None = None, pattern: str | None = None):
"""Search user profiles by Discord IDs or pattern."""
Expand Down
8 changes: 8 additions & 0 deletions nanapi/routers/waicolle.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ async def donate_player_coins(
status.HTTP_400_BAD_REQUEST: dict(model=HTTPExceptionModel),
status.HTTP_404_NOT_FOUND: dict(model=HTTPExceptionModel),
status.HTTP_409_CONFLICT: dict(model=HTTPExceptionModel),
status.HTTP_418_IM_A_TEAPOT: dict(model=HTTPExceptionModel),
},
)
async def player_roll(
Expand All @@ -317,9 +318,16 @@ async def player_roll(
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail='Player Not Found'
)

if player.frozen_at is not None:
return Response(status_code=status.HTTP_204_NO_CONTENT)

if player.user.age_verified:
raise HTTPException(
status_code=status.HTTP_418_IM_A_TEAPOT,
detail='Player is underage, no gambling allowed.',
)

# Get Roll
if roll_id is not None:
roll_getter = ROLLS.get(roll_id, None)
Expand Down