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

branch: dev (WIP) #6

Draft
wants to merge 58 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
f287bcd
rename: `repository.py` -> `abc.py`
Colk-tech Jan 24, 2024
23b7976
add: add `./src/domain` directory
Colk-tech Jan 24, 2024
ec273e1
add: add `./src/domain/base` directory
Colk-tech Jan 24, 2024
b33cb9d
add: add `Field` and `FrozenField` class
Colk-tech Jan 24, 2024
773b3df
rename: rename `field.py` -> `value.py`
Colk-tech Jan 24, 2024
412138d
rename: rename `Field` -> `ValueObject`, `FrozenField` -> `FrozenValu…
Colk-tech Jan 24, 2024
4e20c56
feat: add `Entity` class
Colk-tech Jan 24, 2024
c44a1bb
add: add `./src/domain/user` directory
Colk-tech Jan 25, 2024
2efa783
rename: rename `model.py` -> `entity.py`
Colk-tech Jan 25, 2024
c44a0c5
feat: add `UserID` and `UserNickname`
Colk-tech Jan 25, 2024
26bd211
rename: rename `UserNickname` -> `UserGlobalNickname`
Colk-tech Jan 25, 2024
333adea
feat: add `UserNickname` class
Colk-tech Jan 25, 2024
a6f010b
remove: remove `UserNickname` class
Colk-tech Jan 25, 2024
4871cf7
rename: rename `UserGlobalNickname` -> `UserNickname`
Colk-tech Jan 25, 2024
25b5a07
feat: add `description` in `.../user/field.py`
Colk-tech Jan 25, 2024
17cf92b
feat: add `User` entity model
Colk-tech Jan 25, 2024
6edcf78
rename: rename `UserID` -> `UserIdentifier`
Colk-tech Jan 25, 2024
90fee0e
rename: rename `UserID` -> `UserIdentifier` in `.../user/entity.py`
Colk-tech Jan 25, 2024
129fb24
add: add a new directory: `./src/domain/common`
Colk-tech Jan 25, 2024
a55e5dc
feat: add new common validator `value_must_have_tzinfo()`
Colk-tech Jan 25, 2024
20f6911
remove: remove UTC validators
Colk-tech Jan 25, 2024
93be9e7
reformat: reformat Exception messages
Colk-tech Jan 25, 2024
d451d09
feat: add common value objects related to `datetime.datetime`
Colk-tech Jan 25, 2024
de895b9
feat: add `NullableCreatedAt` and `NullableUpdatedAt`
Colk-tech Jan 25, 2024
0413728
feat: add `created_at` and `updated_at` in `User`
Colk-tech Jan 25, 2024
692ab50
add: add a new directory `./src/domain/member`
Colk-tech Jan 25, 2024
0be385e
feat: add `MemberLocalNickname`
Colk-tech Jan 25, 2024
78a59c0
add: add a new directory `./src/domain/server`
Colk-tech Jan 25, 2024
703c966
feat: add a value object `ServerIdentifier`
Colk-tech Jan 25, 2024
5e0a334
feat: add `Member` entity
Colk-tech Jan 25, 2024
4635f73
feat: add a `ValueObject`: `ServerName`
Colk-tech Jan 25, 2024
8231b3b
feat: add `Server` entity
Colk-tech Jan 25, 2024
162c585
rename: `./src/domain/member/field.py` -> `.../value.py`
Colk-tech Jan 25, 2024
9695545
feat: install `discord.py`
Colk-tech Jan 25, 2024
04877fd
feat: add a new directory `./src/infrastructure/message`
Colk-tech Jan 25, 2024
d52249b
rename: `./src/domain/user/field.py` -> `.../value.py`
Colk-tech Jan 29, 2024
6c3866f
feat: add `UserRepository` abstract class
Colk-tech Jan 29, 2024
c339d83
feat: add `ServerRepository` abstract class
Colk-tech Jan 29, 2024
d075bc9
feat: add `MemberRepository` abstract class
Colk-tech Jan 29, 2024
e64eb4e
add: add a new directory under `./src/infrastructure/database/sqlalch…
Colk-tech Jan 29, 2024
ab6742c
add: add a new directory under `./src/infrastructure/database/sqlalch…
Colk-tech Jan 29, 2024
16c6288
add: add a new directory under `./src/infrastructure/database/sqlalch…
Colk-tech Jan 29, 2024
744eee3
modify: change `...Repository` methods
Colk-tech Jan 29, 2024
9d6344b
feat: add `SATableNames` class
Colk-tech Jan 29, 2024
8fe8be7
remove: remove `table_name.py`
Colk-tech Jan 29, 2024
aaf418f
add: add a comment in `SATableNames`
Colk-tech Jan 29, 2024
c19a742
feat: add common value object classes, `UID` and `NullableUID`
Colk-tech Jan 29, 2024
30471a4
feat: add `cls.generate()` function in `UID` and `NullableUID`
Colk-tech Jan 29, 2024
29d012a
fix: fix class inheritance structure of `./src/domain`
Colk-tech Jan 29, 2024
74648a2
fix: fix class inheritance structure of `./src/domain` (2)
Colk-tech Jan 29, 2024
f1da0d7
rename: rename names of fields of SQLAlchemy mixins
Colk-tech Jan 29, 2024
55d8134
feat: add `SAServer` class
Colk-tech Jan 29, 2024
a245f47
feat: add `SAServerTranslator` class
Colk-tech Jan 29, 2024
437f253
feat: add `SAServerTranslator` class
Colk-tech Jan 29, 2024
a91885f
feat: add `UNIQUE` and `INDEX` in `UIDMixin.record_uid`
Colk-tech Jan 29, 2024
f964a40
feat: add `SAUser` class
Colk-tech Jan 29, 2024
3936ab3
feat: add `SAUserTranslator` class
Colk-tech Jan 29, 2024
fe6e655
misc: save current status
Colk-tech Jan 30, 2024
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
2 changes: 2 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class GenkaiEraConfig(BaseSettings):
IS_CI: int = 0
IS_TEST: int = 0

DISCORD_TOKEN: str

POSTGRES_HOST: str
POSTGRES_PORT: str
POSTGRES_DB_NAME: str = "genkaiera"
Expand Down
14 changes: 14 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import asyncio

from src.di.container import container
from src.infrastructure.message.client import MessageClientInterface


async def main() -> None:
client: MessageClientInterface = container.get(MessageClientInterface)

await client.start()


if __name__ == "__main__":
asyncio.run(main())
447 changes: 446 additions & 1 deletion poetry.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ sqlalchemy = "^2.0.25"
asyncpg = "^0.29.0"
alembic = "^1.13.1"
python-dotenv = "^1.0.0"
discord = "^2.3.2"

[tool.poetry.group.dev.dependencies]
mypy = "^1.8.0"
Expand Down
6 changes: 3 additions & 3 deletions script/load_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def parse_0_or_1_envvar(name: str) -> bool:

except (ValueError, TypeError):
raise RuntimeError(
"RuntimeError: the value of the CI environment variable must be an integer with value 0 or 1."
"the value of the CI environment variable must be an integer with value 0 or 1."
)

else:
Expand All @@ -35,8 +35,8 @@ def load_dotenv() -> None:

except ImportError:
raise RuntimeError(
"RuntimeError: failed to import 'dotenv'.\n"
"Please install python-dotenv to use this command."
"failed to import 'dotenv'.\n"
"please install python-dotenv to use this command."
)

envfiles_to_load: list[str]
Expand Down
2 changes: 1 addition & 1 deletion script/run_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def execute_command(command_list: list[str]) -> None:

if (proc.returncode is None) or (proc.returncode != 0):
raise CommandError(
f"Error in command execution with return code: {proc.returncode}"
f"error in command execution with return code: {proc.returncode}"
)


Expand Down
File renamed without changes.
34 changes: 34 additions & 0 deletions src/adapter/repository/member.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from abc import abstractmethod
from typing import Generic

from src.adapter.repository.abc import Repository
from src.adapter.type import RawSessionType
from src.domain.member.entity import Member
from src.domain.server.value import ServerIdentifier
from src.domain.user.value import UserIdentifier


class MemberRepository(Repository, Generic[RawSessionType]):
@abstractmethod
async def save(
self,
member: Member,
) -> Member:
raise NotImplementedError()

@abstractmethod
async def get_latest_by_server_id_and_user_id(
self,
server_id: ServerIdentifier,
user_id: UserIdentifier,
) -> Member:
raise NotImplementedError()

@abstractmethod
async def get_history_by_server_id_and_user_id(
self,
server_id: ServerIdentifier,
user_id: UserIdentifier,
limit: int,
) -> list[Member]:
raise NotImplementedError()
31 changes: 31 additions & 0 deletions src/adapter/repository/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from abc import abstractmethod
from typing import Generic

from src.adapter.repository.abc import Repository
from src.adapter.type import RawSessionType
from src.domain.server.entity import Server
from src.domain.server.value import ServerIdentifier


class ServerRepository(Repository, Generic[RawSessionType]):
@abstractmethod
async def save(
self,
server: Server,
) -> Server:
raise NotImplementedError()

@abstractmethod
async def get_latest_by_id(
self,
server_id: ServerIdentifier,
) -> Server:
raise NotImplementedError()

@abstractmethod
async def get_history_by_id(
self,
server_id: ServerIdentifier,
limit: int,
) -> list[Server]:
raise NotImplementedError()
31 changes: 31 additions & 0 deletions src/adapter/repository/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from abc import abstractmethod
from typing import Generic

from src.adapter.repository.abc import Repository
from src.adapter.type import RawSessionType
from src.domain.user.entity import User
from src.domain.user.value import UserIdentifier


class UserRepository(Repository, Generic[RawSessionType]):
@abstractmethod
async def save(
self,
user: User,
) -> User:
raise NotImplementedError()

@abstractmethod
async def get_latest_by_id(
self,
user_id: UserIdentifier,
) -> User:
raise NotImplementedError()

@abstractmethod
async def get_history_by_id(
self,
user_id: UserIdentifier,
limit: int,
) -> list[User]:
raise NotImplementedError()
10 changes: 10 additions & 0 deletions src/common/library/pydantic/validator/tzinfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import datetime


def value_must_have_tzinfo(
v: datetime.datetime,
) -> datetime.datetime:
if v.tzinfo is None:
raise ValueError("the value must have tzinfo.")

return v
15 changes: 0 additions & 15 deletions src/common/library/pydantic/validator/utc.py

This file was deleted.

6 changes: 2 additions & 4 deletions src/common/library/sqlalchemy/field/sauuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ def process_bind_param(
if isinstance(value, UUID):
return str(value)

raise ValueError(
f"ValueError: value '{value}' is not a valid instance of 'uuid.UUID'."
)
raise ValueError(f"value '{value}' is not a valid instance of 'uuid.UUID'.")

def process_result_value(
self, value: Optional[str], dialect: Optional[Dialect] = None
Expand All @@ -39,7 +37,7 @@ def process_result_value(
return UUID(value)

raise ValueError(
f"ValueError: value '{value}' is not 'None' or a valid instance of 'uuid.UUID'."
f"value '{value}' is not 'None' or a valid instance of 'uuid.UUID'."
)

# noinspection PyMethodMayBeStatic
Expand Down
8 changes: 4 additions & 4 deletions src/common/library/sqlalchemy/mixin/timestamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


class CreatedAtMixin(object):
created_at: Mapped[datetime.datetime] = mapped_column(
record_created_at: Mapped[datetime.datetime] = mapped_column(
name=DEFAULT_CREATED_AT_COLUMN_NAME,
type_=DateTime(timezone=True),
server_default=func.now(),
Expand All @@ -19,7 +19,7 @@ class CreatedAtMixin(object):


class UpdatedAtMixin(object):
updated_at: Mapped[datetime.datetime] = mapped_column(
record_updated_at: Mapped[datetime.datetime] = mapped_column(
name=DEFAULT_UPDATED_AT_COLUMN_NAME,
type_=DateTime(timezone=True),
onupdate=func.now(),
Expand All @@ -29,14 +29,14 @@ class UpdatedAtMixin(object):

# We get an error when we do 'class TimestampMixin(CreatedAtMixin, UpdatedAtMixin)'
class TimestampMixin(object):
created_at: Mapped[datetime.datetime] = mapped_column(
record_created_at: Mapped[datetime.datetime] = mapped_column(
name=DEFAULT_CREATED_AT_COLUMN_NAME,
type_=DateTime(timezone=True),
server_default=func.now(),
nullable=False,
)

updated_at: Mapped[datetime.datetime] = mapped_column(
record_updated_at: Mapped[datetime.datetime] = mapped_column(
name=DEFAULT_UPDATED_AT_COLUMN_NAME,
type_=DateTime(timezone=True),
onupdate=func.now(),
Expand Down
4 changes: 3 additions & 1 deletion src/common/library/sqlalchemy/mixin/uid.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@


class UIDMixin(object):
uid: Mapped[uuid.UUID] = mapped_column(
record_uid: Mapped[uuid.UUID] = mapped_column(
name=DEFAULT_UID_COLUMN_NAME,
type_=SAUUID,
primary_key=True,
default=uuid.uuid4,
nullable=False,
unique=True,
index=True,
)
2 changes: 2 additions & 0 deletions src/di/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

from src.di.module.config import GenkaiEraConfigModule
from src.di.module.database import GenkaiEraSADatabaseModule
from src.di.module.message import GenkaiEraMessageModule

container = Injector(
[
GenkaiEraConfigModule,
GenkaiEraSADatabaseModule,
GenkaiEraMessageModule,
]
)
20 changes: 20 additions & 0 deletions src/di/module/message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from injector import Module, Binder, ClassProvider

from src.message.discord.client import DiscordClient
from src.infrastructure.message.client import MessageClientInterface


class GenkaiEraMessageModule(Module):
def __init__(
self,
) -> None:
pass

def configure(
self,
binder: Binder,
) -> None:
binder.bind(
MessageClientInterface,
ClassProvider(DiscordClient),
)
Empty file added src/domain/__init__.py
Empty file.
Empty file added src/domain/base/__init__.py
Empty file.
7 changes: 7 additions & 0 deletions src/domain/base/entity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from pydantic import BaseModel

from src.common.library.pydantic.config import FrozenConfig


class Entity(BaseModel):
model_config = FrozenConfig
11 changes: 11 additions & 0 deletions src/domain/base/value.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from pydantic import BaseModel

from src.common.library.pydantic.config import BaseConfig


class ValueObject(BaseModel):
model_config = BaseConfig


class FrozenValueObject(BaseModel):
model_config = BaseConfig
Empty file added src/domain/common/__init__.py
Empty file.
Loading
Loading