From a8b5af617a3bf96db2ffb87a1f9b761e4e7dfc03 Mon Sep 17 00:00:00 2001 From: Yaroslaww-1 Date: Mon, 1 Nov 2021 00:52:04 +0200 Subject: [PATCH 1/5] removed old learn --- services/learn_old/Dockerfile | 7 +++++++ services/{learn => learn_old}/Dockerfile.k8s-build | 0 services/{learn => learn_old}/__init__.py | 0 services/{learn => learn_old}/api/__init__.py | 0 services/{learn => learn_old}/api/asgi.py | 0 services/{learn => learn_old}/api/settings.py | 0 services/{learn => learn_old}/api/wsgi.py | 0 services/{learn => learn_old}/learn/__init__.py | 0 services/{learn => learn_old}/learn/admin.py | 0 services/{learn => learn_old}/learn/api/__init__.py | 0 .../learn/api/auth/authenticated_user_context.py | 0 services/{learn => learn_old}/learn/api/constants.py | 0 .../learn/api/decorators/in_roles_decorator.py | 0 .../{learn => learn_old}/learn/api/enums/roles_enum.py | 0 .../learn/api/exceptions/custom_exception_handler.py | 0 .../learn/api/options/rabbit_mq_options.py | 0 .../learn/api/serializers/dto_serializer.py | 0 services/{learn => learn_old}/learn/api/urls.py | 0 .../{learn => learn_old}/learn/api/views/groups_view.py | 0 .../{learn => learn_old}/learn/api/views/posts_view.py | 0 .../{learn => learn_old}/learn/api/views/students_view.py | 0 .../{learn => learn_old}/learn/api/views/users_view.py | 0 .../{learn => learn_old}/learn/application/__init__.py | 0 .../groups/create_group/create_group_command.py | 0 .../learn/application/groups/dtos/group_dto.py | 0 .../application/groups/get_groups/get_groups_query.py | 0 .../learn/application/groups/group_mapper.py | 0 .../application/posts/create_post/create_post_command.py | 0 .../post_created_domain_event_handler.py | 0 .../learn/application/posts/dtos/post_dto.py | 0 .../learn/application/posts/get_posts/get_posts_query.py | 0 .../learn/application/posts/post_mapper.py | 0 .../learn/application/students/__init__.py | 0 .../learn/application/students/dtos/__init__.py | 0 .../learn/application/students/dtos/student_dto.py | 0 .../students/get_students/get_students_query.py | 0 .../learn/application/students/student_mapper.py | 0 .../application/users/create_user/create_user_command.py | 0 .../users/create_user/upload_user_avatar_command.py | 0 .../learn/application/users/dtos/user_dto.py | 0 .../application/users/get_users/get_user_by_id_query.py | 0 .../learn/application/users/get_users/get_users_query.py | 0 .../user_created/user_created_integration_event.py | 0 .../user_created/user_created_integration_event_handler.py | 0 .../learn/application/users/user_mapper.py | 0 services/{learn => learn_old}/learn/apps.py | 0 services/{learn => learn_old}/learn/domain/__init__.py | 0 .../learn/domain/common/base_typed_id_value_object.py | 0 .../learn/domain/common/domain_events.py | 0 .../{learn => learn_old}/learn/domain/groups/__init__.py | 0 .../learn/domain/groups/entities/__init__.py | 0 .../learn/domain/groups/entities/group.py | 0 .../learn/domain/groups/entities/student_group.py | 0 .../learn/domain/groups/value_objects/__init__.py | 0 .../learn/domain/groups/value_objects/group_id.py | 0 .../learn/domain/groups/value_objects/student_group_id.py | 0 .../learn/domain/groups/value_objects/year.py | 0 .../{learn => learn_old}/learn/domain/posts/__init__.py | 0 .../learn/domain/posts/entities/__init__.py | 0 .../learn/domain/posts/entities/post.py | 0 .../learn/domain/posts/events/post_created_domain_event.py | 0 .../learn/domain/posts/value_objects/__init__.py | 0 .../learn/domain/posts/value_objects/post_id.py | 0 .../{learn => learn_old}/learn/domain/students/__init__.py | 0 .../learn/domain/students/entities/__init__.py | 0 .../learn/domain/students/entities/student.py | 0 .../learn/domain/students/value_objects/__init__.py | 0 .../learn/domain/students/value_objects/student_id.py | 0 .../{learn => learn_old}/learn/domain/users/__init__.py | 0 .../learn/domain/users/entities/__init__.py | 0 .../learn/domain/users/entities/role.py | 0 .../learn/domain/users/entities/user.py | 0 .../learn/domain/users/value_objects/__init__.py | 0 .../learn/domain/users/value_objects/email.py | 0 .../learn/domain/users/value_objects/role_id.py | 0 .../learn/domain/users/value_objects/user_id.py | 0 .../{learn => learn_old}/learn/infrastructure/__init__.py | 0 .../learn/infrastructure/aws/aws_s3_service.py | 0 .../learn/infrastructure/event_bus/__init__.py | 0 .../learn/infrastructure/event_bus/domain/__init__.py | 0 .../infrastructure/event_bus/domain/domain_event_bus.py | 0 .../learn/infrastructure/event_bus/integration/__init__.py | 0 .../event_bus/integration/integration_event.py | 0 .../event_bus/integration/integration_event_bus.py | 0 .../event_bus/integration/integration_event_handler.py | 0 .../event_bus/integration/rabbitmq/__init__.py | 0 .../integration/rabbitmq/rabbit_mq_connection_factory.py | 0 .../integration/rabbitmq/rabbitmq_integration_event_bus.py | 0 .../learn/infrastructure/repositories/group_repository.py | 0 .../learn/infrastructure/repositories/post_repository.py | 0 .../learn/infrastructure/repositories/role_repository.py | 0 .../infrastructure/repositories/student_repository.py | 0 .../learn/infrastructure/repositories/user_repository.py | 0 .../learn/management/commands/runserver.py | 0 .../{learn => learn_old}/learn/management/commands/seed.py | 0 .../{learn => learn_old}/learn/migrations/0001_initial.py | 0 .../{learn => learn_old}/learn/migrations/0002_user.py | 0 .../0003_add_content_and_user_reference_to_post.py | 0 .../learn/migrations/0003_group_and_studentGroup.py | 0 .../learn/migrations/0004_student_group_user_id_unique.py | 0 .../{learn => learn_old}/learn/migrations/0005_meta.py | 0 .../learn/migrations/0006_switched_to_one_to_one.py | 0 .../learn/migrations/0007_rename_post_user.py | 0 .../learn/migrations/0008_auto_20211011_2128.py | 0 .../0008_student_group_switched_to_foreign_key_group.py | 0 .../learn/migrations/0009_merge_0008.py | 0 .../learn/migrations/0010_user_avatar_field.py | 0 .../learn/migrations/0011_add_user_roles.py | 0 services/{learn => learn_old}/learn/migrations/__init__.py | 0 services/{learn => learn_old}/learn/models.py | 0 services/{learn => learn_old}/learn/tests.py | 0 services/{learn => learn_old}/manage.py | 0 services/{learn => learn_old}/requirements.txt | 0 113 files changed, 7 insertions(+) create mode 100644 services/learn_old/Dockerfile rename services/{learn => learn_old}/Dockerfile.k8s-build (100%) rename services/{learn => learn_old}/__init__.py (100%) rename services/{learn => learn_old}/api/__init__.py (100%) rename services/{learn => learn_old}/api/asgi.py (100%) rename services/{learn => learn_old}/api/settings.py (100%) rename services/{learn => learn_old}/api/wsgi.py (100%) rename services/{learn => learn_old}/learn/__init__.py (100%) rename services/{learn => learn_old}/learn/admin.py (100%) rename services/{learn => learn_old}/learn/api/__init__.py (100%) rename services/{learn => learn_old}/learn/api/auth/authenticated_user_context.py (100%) rename services/{learn => learn_old}/learn/api/constants.py (100%) rename services/{learn => learn_old}/learn/api/decorators/in_roles_decorator.py (100%) rename services/{learn => learn_old}/learn/api/enums/roles_enum.py (100%) rename services/{learn => learn_old}/learn/api/exceptions/custom_exception_handler.py (100%) rename services/{learn => learn_old}/learn/api/options/rabbit_mq_options.py (100%) rename services/{learn => learn_old}/learn/api/serializers/dto_serializer.py (100%) rename services/{learn => learn_old}/learn/api/urls.py (100%) rename services/{learn => learn_old}/learn/api/views/groups_view.py (100%) rename services/{learn => learn_old}/learn/api/views/posts_view.py (100%) rename services/{learn => learn_old}/learn/api/views/students_view.py (100%) rename services/{learn => learn_old}/learn/api/views/users_view.py (100%) rename services/{learn => learn_old}/learn/application/__init__.py (100%) rename services/{learn => learn_old}/learn/application/groups/create_group/create_group_command.py (100%) rename services/{learn => learn_old}/learn/application/groups/dtos/group_dto.py (100%) rename services/{learn => learn_old}/learn/application/groups/get_groups/get_groups_query.py (100%) rename services/{learn => learn_old}/learn/application/groups/group_mapper.py (100%) rename services/{learn => learn_old}/learn/application/posts/create_post/create_post_command.py (100%) rename services/{learn => learn_old}/learn/application/posts/domain_event_handlers/post_created_domain_event_handler.py (100%) rename services/{learn => learn_old}/learn/application/posts/dtos/post_dto.py (100%) rename services/{learn => learn_old}/learn/application/posts/get_posts/get_posts_query.py (100%) rename services/{learn => learn_old}/learn/application/posts/post_mapper.py (100%) rename services/{learn => learn_old}/learn/application/students/__init__.py (100%) rename services/{learn => learn_old}/learn/application/students/dtos/__init__.py (100%) rename services/{learn => learn_old}/learn/application/students/dtos/student_dto.py (100%) rename services/{learn => learn_old}/learn/application/students/get_students/get_students_query.py (100%) rename services/{learn => learn_old}/learn/application/students/student_mapper.py (100%) rename services/{learn => learn_old}/learn/application/users/create_user/create_user_command.py (100%) rename services/{learn => learn_old}/learn/application/users/create_user/upload_user_avatar_command.py (100%) rename services/{learn => learn_old}/learn/application/users/dtos/user_dto.py (100%) rename services/{learn => learn_old}/learn/application/users/get_users/get_user_by_id_query.py (100%) rename services/{learn => learn_old}/learn/application/users/get_users/get_users_query.py (100%) rename services/{learn => learn_old}/learn/application/users/integration_events/user_created/user_created_integration_event.py (100%) rename services/{learn => learn_old}/learn/application/users/integration_events/user_created/user_created_integration_event_handler.py (100%) rename services/{learn => learn_old}/learn/application/users/user_mapper.py (100%) rename services/{learn => learn_old}/learn/apps.py (100%) rename services/{learn => learn_old}/learn/domain/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/common/base_typed_id_value_object.py (100%) rename services/{learn => learn_old}/learn/domain/common/domain_events.py (100%) rename services/{learn => learn_old}/learn/domain/groups/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/groups/entities/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/groups/entities/group.py (100%) rename services/{learn => learn_old}/learn/domain/groups/entities/student_group.py (100%) rename services/{learn => learn_old}/learn/domain/groups/value_objects/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/groups/value_objects/group_id.py (100%) rename services/{learn => learn_old}/learn/domain/groups/value_objects/student_group_id.py (100%) rename services/{learn => learn_old}/learn/domain/groups/value_objects/year.py (100%) rename services/{learn => learn_old}/learn/domain/posts/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/posts/entities/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/posts/entities/post.py (100%) rename services/{learn => learn_old}/learn/domain/posts/events/post_created_domain_event.py (100%) rename services/{learn => learn_old}/learn/domain/posts/value_objects/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/posts/value_objects/post_id.py (100%) rename services/{learn => learn_old}/learn/domain/students/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/students/entities/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/students/entities/student.py (100%) rename services/{learn => learn_old}/learn/domain/students/value_objects/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/students/value_objects/student_id.py (100%) rename services/{learn => learn_old}/learn/domain/users/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/users/entities/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/users/entities/role.py (100%) rename services/{learn => learn_old}/learn/domain/users/entities/user.py (100%) rename services/{learn => learn_old}/learn/domain/users/value_objects/__init__.py (100%) rename services/{learn => learn_old}/learn/domain/users/value_objects/email.py (100%) rename services/{learn => learn_old}/learn/domain/users/value_objects/role_id.py (100%) rename services/{learn => learn_old}/learn/domain/users/value_objects/user_id.py (100%) rename services/{learn => learn_old}/learn/infrastructure/__init__.py (100%) rename services/{learn => learn_old}/learn/infrastructure/aws/aws_s3_service.py (100%) rename services/{learn => learn_old}/learn/infrastructure/event_bus/__init__.py (100%) rename services/{learn => learn_old}/learn/infrastructure/event_bus/domain/__init__.py (100%) rename services/{learn => learn_old}/learn/infrastructure/event_bus/domain/domain_event_bus.py (100%) rename services/{learn => learn_old}/learn/infrastructure/event_bus/integration/__init__.py (100%) rename services/{learn => learn_old}/learn/infrastructure/event_bus/integration/integration_event.py (100%) rename services/{learn => learn_old}/learn/infrastructure/event_bus/integration/integration_event_bus.py (100%) rename services/{learn => learn_old}/learn/infrastructure/event_bus/integration/integration_event_handler.py (100%) rename services/{learn => learn_old}/learn/infrastructure/event_bus/integration/rabbitmq/__init__.py (100%) rename services/{learn => learn_old}/learn/infrastructure/event_bus/integration/rabbitmq/rabbit_mq_connection_factory.py (100%) rename services/{learn => learn_old}/learn/infrastructure/event_bus/integration/rabbitmq/rabbitmq_integration_event_bus.py (100%) rename services/{learn => learn_old}/learn/infrastructure/repositories/group_repository.py (100%) rename services/{learn => learn_old}/learn/infrastructure/repositories/post_repository.py (100%) rename services/{learn => learn_old}/learn/infrastructure/repositories/role_repository.py (100%) rename services/{learn => learn_old}/learn/infrastructure/repositories/student_repository.py (100%) rename services/{learn => learn_old}/learn/infrastructure/repositories/user_repository.py (100%) rename services/{learn => learn_old}/learn/management/commands/runserver.py (100%) rename services/{learn => learn_old}/learn/management/commands/seed.py (100%) rename services/{learn => learn_old}/learn/migrations/0001_initial.py (100%) rename services/{learn => learn_old}/learn/migrations/0002_user.py (100%) rename services/{learn => learn_old}/learn/migrations/0003_add_content_and_user_reference_to_post.py (100%) rename services/{learn => learn_old}/learn/migrations/0003_group_and_studentGroup.py (100%) rename services/{learn => learn_old}/learn/migrations/0004_student_group_user_id_unique.py (100%) rename services/{learn => learn_old}/learn/migrations/0005_meta.py (100%) rename services/{learn => learn_old}/learn/migrations/0006_switched_to_one_to_one.py (100%) rename services/{learn => learn_old}/learn/migrations/0007_rename_post_user.py (100%) rename services/{learn => learn_old}/learn/migrations/0008_auto_20211011_2128.py (100%) rename services/{learn => learn_old}/learn/migrations/0008_student_group_switched_to_foreign_key_group.py (100%) rename services/{learn => learn_old}/learn/migrations/0009_merge_0008.py (100%) rename services/{learn => learn_old}/learn/migrations/0010_user_avatar_field.py (100%) rename services/{learn => learn_old}/learn/migrations/0011_add_user_roles.py (100%) rename services/{learn => learn_old}/learn/migrations/__init__.py (100%) rename services/{learn => learn_old}/learn/models.py (100%) rename services/{learn => learn_old}/learn/tests.py (100%) rename services/{learn => learn_old}/manage.py (100%) rename services/{learn => learn_old}/requirements.txt (100%) diff --git a/services/learn_old/Dockerfile b/services/learn_old/Dockerfile new file mode 100644 index 0000000..1e91ed8 --- /dev/null +++ b/services/learn_old/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3 as builder +ENV PYTHONUNBUFFERED=1 +WORKDIR /app +COPY requirements.txt /app/ +RUN pip install -r requirements.txt +COPY . /app/ +CMD ["python", "manage.py", "runserver"] \ No newline at end of file diff --git a/services/learn/Dockerfile.k8s-build b/services/learn_old/Dockerfile.k8s-build similarity index 100% rename from services/learn/Dockerfile.k8s-build rename to services/learn_old/Dockerfile.k8s-build diff --git a/services/learn/__init__.py b/services/learn_old/__init__.py similarity index 100% rename from services/learn/__init__.py rename to services/learn_old/__init__.py diff --git a/services/learn/api/__init__.py b/services/learn_old/api/__init__.py similarity index 100% rename from services/learn/api/__init__.py rename to services/learn_old/api/__init__.py diff --git a/services/learn/api/asgi.py b/services/learn_old/api/asgi.py similarity index 100% rename from services/learn/api/asgi.py rename to services/learn_old/api/asgi.py diff --git a/services/learn/api/settings.py b/services/learn_old/api/settings.py similarity index 100% rename from services/learn/api/settings.py rename to services/learn_old/api/settings.py diff --git a/services/learn/api/wsgi.py b/services/learn_old/api/wsgi.py similarity index 100% rename from services/learn/api/wsgi.py rename to services/learn_old/api/wsgi.py diff --git a/services/learn/learn/__init__.py b/services/learn_old/learn/__init__.py similarity index 100% rename from services/learn/learn/__init__.py rename to services/learn_old/learn/__init__.py diff --git a/services/learn/learn/admin.py b/services/learn_old/learn/admin.py similarity index 100% rename from services/learn/learn/admin.py rename to services/learn_old/learn/admin.py diff --git a/services/learn/learn/api/__init__.py b/services/learn_old/learn/api/__init__.py similarity index 100% rename from services/learn/learn/api/__init__.py rename to services/learn_old/learn/api/__init__.py diff --git a/services/learn/learn/api/auth/authenticated_user_context.py b/services/learn_old/learn/api/auth/authenticated_user_context.py similarity index 100% rename from services/learn/learn/api/auth/authenticated_user_context.py rename to services/learn_old/learn/api/auth/authenticated_user_context.py diff --git a/services/learn/learn/api/constants.py b/services/learn_old/learn/api/constants.py similarity index 100% rename from services/learn/learn/api/constants.py rename to services/learn_old/learn/api/constants.py diff --git a/services/learn/learn/api/decorators/in_roles_decorator.py b/services/learn_old/learn/api/decorators/in_roles_decorator.py similarity index 100% rename from services/learn/learn/api/decorators/in_roles_decorator.py rename to services/learn_old/learn/api/decorators/in_roles_decorator.py diff --git a/services/learn/learn/api/enums/roles_enum.py b/services/learn_old/learn/api/enums/roles_enum.py similarity index 100% rename from services/learn/learn/api/enums/roles_enum.py rename to services/learn_old/learn/api/enums/roles_enum.py diff --git a/services/learn/learn/api/exceptions/custom_exception_handler.py b/services/learn_old/learn/api/exceptions/custom_exception_handler.py similarity index 100% rename from services/learn/learn/api/exceptions/custom_exception_handler.py rename to services/learn_old/learn/api/exceptions/custom_exception_handler.py diff --git a/services/learn/learn/api/options/rabbit_mq_options.py b/services/learn_old/learn/api/options/rabbit_mq_options.py similarity index 100% rename from services/learn/learn/api/options/rabbit_mq_options.py rename to services/learn_old/learn/api/options/rabbit_mq_options.py diff --git a/services/learn/learn/api/serializers/dto_serializer.py b/services/learn_old/learn/api/serializers/dto_serializer.py similarity index 100% rename from services/learn/learn/api/serializers/dto_serializer.py rename to services/learn_old/learn/api/serializers/dto_serializer.py diff --git a/services/learn/learn/api/urls.py b/services/learn_old/learn/api/urls.py similarity index 100% rename from services/learn/learn/api/urls.py rename to services/learn_old/learn/api/urls.py diff --git a/services/learn/learn/api/views/groups_view.py b/services/learn_old/learn/api/views/groups_view.py similarity index 100% rename from services/learn/learn/api/views/groups_view.py rename to services/learn_old/learn/api/views/groups_view.py diff --git a/services/learn/learn/api/views/posts_view.py b/services/learn_old/learn/api/views/posts_view.py similarity index 100% rename from services/learn/learn/api/views/posts_view.py rename to services/learn_old/learn/api/views/posts_view.py diff --git a/services/learn/learn/api/views/students_view.py b/services/learn_old/learn/api/views/students_view.py similarity index 100% rename from services/learn/learn/api/views/students_view.py rename to services/learn_old/learn/api/views/students_view.py diff --git a/services/learn/learn/api/views/users_view.py b/services/learn_old/learn/api/views/users_view.py similarity index 100% rename from services/learn/learn/api/views/users_view.py rename to services/learn_old/learn/api/views/users_view.py diff --git a/services/learn/learn/application/__init__.py b/services/learn_old/learn/application/__init__.py similarity index 100% rename from services/learn/learn/application/__init__.py rename to services/learn_old/learn/application/__init__.py diff --git a/services/learn/learn/application/groups/create_group/create_group_command.py b/services/learn_old/learn/application/groups/create_group/create_group_command.py similarity index 100% rename from services/learn/learn/application/groups/create_group/create_group_command.py rename to services/learn_old/learn/application/groups/create_group/create_group_command.py diff --git a/services/learn/learn/application/groups/dtos/group_dto.py b/services/learn_old/learn/application/groups/dtos/group_dto.py similarity index 100% rename from services/learn/learn/application/groups/dtos/group_dto.py rename to services/learn_old/learn/application/groups/dtos/group_dto.py diff --git a/services/learn/learn/application/groups/get_groups/get_groups_query.py b/services/learn_old/learn/application/groups/get_groups/get_groups_query.py similarity index 100% rename from services/learn/learn/application/groups/get_groups/get_groups_query.py rename to services/learn_old/learn/application/groups/get_groups/get_groups_query.py diff --git a/services/learn/learn/application/groups/group_mapper.py b/services/learn_old/learn/application/groups/group_mapper.py similarity index 100% rename from services/learn/learn/application/groups/group_mapper.py rename to services/learn_old/learn/application/groups/group_mapper.py diff --git a/services/learn/learn/application/posts/create_post/create_post_command.py b/services/learn_old/learn/application/posts/create_post/create_post_command.py similarity index 100% rename from services/learn/learn/application/posts/create_post/create_post_command.py rename to services/learn_old/learn/application/posts/create_post/create_post_command.py diff --git a/services/learn/learn/application/posts/domain_event_handlers/post_created_domain_event_handler.py b/services/learn_old/learn/application/posts/domain_event_handlers/post_created_domain_event_handler.py similarity index 100% rename from services/learn/learn/application/posts/domain_event_handlers/post_created_domain_event_handler.py rename to services/learn_old/learn/application/posts/domain_event_handlers/post_created_domain_event_handler.py diff --git a/services/learn/learn/application/posts/dtos/post_dto.py b/services/learn_old/learn/application/posts/dtos/post_dto.py similarity index 100% rename from services/learn/learn/application/posts/dtos/post_dto.py rename to services/learn_old/learn/application/posts/dtos/post_dto.py diff --git a/services/learn/learn/application/posts/get_posts/get_posts_query.py b/services/learn_old/learn/application/posts/get_posts/get_posts_query.py similarity index 100% rename from services/learn/learn/application/posts/get_posts/get_posts_query.py rename to services/learn_old/learn/application/posts/get_posts/get_posts_query.py diff --git a/services/learn/learn/application/posts/post_mapper.py b/services/learn_old/learn/application/posts/post_mapper.py similarity index 100% rename from services/learn/learn/application/posts/post_mapper.py rename to services/learn_old/learn/application/posts/post_mapper.py diff --git a/services/learn/learn/application/students/__init__.py b/services/learn_old/learn/application/students/__init__.py similarity index 100% rename from services/learn/learn/application/students/__init__.py rename to services/learn_old/learn/application/students/__init__.py diff --git a/services/learn/learn/application/students/dtos/__init__.py b/services/learn_old/learn/application/students/dtos/__init__.py similarity index 100% rename from services/learn/learn/application/students/dtos/__init__.py rename to services/learn_old/learn/application/students/dtos/__init__.py diff --git a/services/learn/learn/application/students/dtos/student_dto.py b/services/learn_old/learn/application/students/dtos/student_dto.py similarity index 100% rename from services/learn/learn/application/students/dtos/student_dto.py rename to services/learn_old/learn/application/students/dtos/student_dto.py diff --git a/services/learn/learn/application/students/get_students/get_students_query.py b/services/learn_old/learn/application/students/get_students/get_students_query.py similarity index 100% rename from services/learn/learn/application/students/get_students/get_students_query.py rename to services/learn_old/learn/application/students/get_students/get_students_query.py diff --git a/services/learn/learn/application/students/student_mapper.py b/services/learn_old/learn/application/students/student_mapper.py similarity index 100% rename from services/learn/learn/application/students/student_mapper.py rename to services/learn_old/learn/application/students/student_mapper.py diff --git a/services/learn/learn/application/users/create_user/create_user_command.py b/services/learn_old/learn/application/users/create_user/create_user_command.py similarity index 100% rename from services/learn/learn/application/users/create_user/create_user_command.py rename to services/learn_old/learn/application/users/create_user/create_user_command.py diff --git a/services/learn/learn/application/users/create_user/upload_user_avatar_command.py b/services/learn_old/learn/application/users/create_user/upload_user_avatar_command.py similarity index 100% rename from services/learn/learn/application/users/create_user/upload_user_avatar_command.py rename to services/learn_old/learn/application/users/create_user/upload_user_avatar_command.py diff --git a/services/learn/learn/application/users/dtos/user_dto.py b/services/learn_old/learn/application/users/dtos/user_dto.py similarity index 100% rename from services/learn/learn/application/users/dtos/user_dto.py rename to services/learn_old/learn/application/users/dtos/user_dto.py diff --git a/services/learn/learn/application/users/get_users/get_user_by_id_query.py b/services/learn_old/learn/application/users/get_users/get_user_by_id_query.py similarity index 100% rename from services/learn/learn/application/users/get_users/get_user_by_id_query.py rename to services/learn_old/learn/application/users/get_users/get_user_by_id_query.py diff --git a/services/learn/learn/application/users/get_users/get_users_query.py b/services/learn_old/learn/application/users/get_users/get_users_query.py similarity index 100% rename from services/learn/learn/application/users/get_users/get_users_query.py rename to services/learn_old/learn/application/users/get_users/get_users_query.py diff --git a/services/learn/learn/application/users/integration_events/user_created/user_created_integration_event.py b/services/learn_old/learn/application/users/integration_events/user_created/user_created_integration_event.py similarity index 100% rename from services/learn/learn/application/users/integration_events/user_created/user_created_integration_event.py rename to services/learn_old/learn/application/users/integration_events/user_created/user_created_integration_event.py diff --git a/services/learn/learn/application/users/integration_events/user_created/user_created_integration_event_handler.py b/services/learn_old/learn/application/users/integration_events/user_created/user_created_integration_event_handler.py similarity index 100% rename from services/learn/learn/application/users/integration_events/user_created/user_created_integration_event_handler.py rename to services/learn_old/learn/application/users/integration_events/user_created/user_created_integration_event_handler.py diff --git a/services/learn/learn/application/users/user_mapper.py b/services/learn_old/learn/application/users/user_mapper.py similarity index 100% rename from services/learn/learn/application/users/user_mapper.py rename to services/learn_old/learn/application/users/user_mapper.py diff --git a/services/learn/learn/apps.py b/services/learn_old/learn/apps.py similarity index 100% rename from services/learn/learn/apps.py rename to services/learn_old/learn/apps.py diff --git a/services/learn/learn/domain/__init__.py b/services/learn_old/learn/domain/__init__.py similarity index 100% rename from services/learn/learn/domain/__init__.py rename to services/learn_old/learn/domain/__init__.py diff --git a/services/learn/learn/domain/common/base_typed_id_value_object.py b/services/learn_old/learn/domain/common/base_typed_id_value_object.py similarity index 100% rename from services/learn/learn/domain/common/base_typed_id_value_object.py rename to services/learn_old/learn/domain/common/base_typed_id_value_object.py diff --git a/services/learn/learn/domain/common/domain_events.py b/services/learn_old/learn/domain/common/domain_events.py similarity index 100% rename from services/learn/learn/domain/common/domain_events.py rename to services/learn_old/learn/domain/common/domain_events.py diff --git a/services/learn/learn/domain/groups/__init__.py b/services/learn_old/learn/domain/groups/__init__.py similarity index 100% rename from services/learn/learn/domain/groups/__init__.py rename to services/learn_old/learn/domain/groups/__init__.py diff --git a/services/learn/learn/domain/groups/entities/__init__.py b/services/learn_old/learn/domain/groups/entities/__init__.py similarity index 100% rename from services/learn/learn/domain/groups/entities/__init__.py rename to services/learn_old/learn/domain/groups/entities/__init__.py diff --git a/services/learn/learn/domain/groups/entities/group.py b/services/learn_old/learn/domain/groups/entities/group.py similarity index 100% rename from services/learn/learn/domain/groups/entities/group.py rename to services/learn_old/learn/domain/groups/entities/group.py diff --git a/services/learn/learn/domain/groups/entities/student_group.py b/services/learn_old/learn/domain/groups/entities/student_group.py similarity index 100% rename from services/learn/learn/domain/groups/entities/student_group.py rename to services/learn_old/learn/domain/groups/entities/student_group.py diff --git a/services/learn/learn/domain/groups/value_objects/__init__.py b/services/learn_old/learn/domain/groups/value_objects/__init__.py similarity index 100% rename from services/learn/learn/domain/groups/value_objects/__init__.py rename to services/learn_old/learn/domain/groups/value_objects/__init__.py diff --git a/services/learn/learn/domain/groups/value_objects/group_id.py b/services/learn_old/learn/domain/groups/value_objects/group_id.py similarity index 100% rename from services/learn/learn/domain/groups/value_objects/group_id.py rename to services/learn_old/learn/domain/groups/value_objects/group_id.py diff --git a/services/learn/learn/domain/groups/value_objects/student_group_id.py b/services/learn_old/learn/domain/groups/value_objects/student_group_id.py similarity index 100% rename from services/learn/learn/domain/groups/value_objects/student_group_id.py rename to services/learn_old/learn/domain/groups/value_objects/student_group_id.py diff --git a/services/learn/learn/domain/groups/value_objects/year.py b/services/learn_old/learn/domain/groups/value_objects/year.py similarity index 100% rename from services/learn/learn/domain/groups/value_objects/year.py rename to services/learn_old/learn/domain/groups/value_objects/year.py diff --git a/services/learn/learn/domain/posts/__init__.py b/services/learn_old/learn/domain/posts/__init__.py similarity index 100% rename from services/learn/learn/domain/posts/__init__.py rename to services/learn_old/learn/domain/posts/__init__.py diff --git a/services/learn/learn/domain/posts/entities/__init__.py b/services/learn_old/learn/domain/posts/entities/__init__.py similarity index 100% rename from services/learn/learn/domain/posts/entities/__init__.py rename to services/learn_old/learn/domain/posts/entities/__init__.py diff --git a/services/learn/learn/domain/posts/entities/post.py b/services/learn_old/learn/domain/posts/entities/post.py similarity index 100% rename from services/learn/learn/domain/posts/entities/post.py rename to services/learn_old/learn/domain/posts/entities/post.py diff --git a/services/learn/learn/domain/posts/events/post_created_domain_event.py b/services/learn_old/learn/domain/posts/events/post_created_domain_event.py similarity index 100% rename from services/learn/learn/domain/posts/events/post_created_domain_event.py rename to services/learn_old/learn/domain/posts/events/post_created_domain_event.py diff --git a/services/learn/learn/domain/posts/value_objects/__init__.py b/services/learn_old/learn/domain/posts/value_objects/__init__.py similarity index 100% rename from services/learn/learn/domain/posts/value_objects/__init__.py rename to services/learn_old/learn/domain/posts/value_objects/__init__.py diff --git a/services/learn/learn/domain/posts/value_objects/post_id.py b/services/learn_old/learn/domain/posts/value_objects/post_id.py similarity index 100% rename from services/learn/learn/domain/posts/value_objects/post_id.py rename to services/learn_old/learn/domain/posts/value_objects/post_id.py diff --git a/services/learn/learn/domain/students/__init__.py b/services/learn_old/learn/domain/students/__init__.py similarity index 100% rename from services/learn/learn/domain/students/__init__.py rename to services/learn_old/learn/domain/students/__init__.py diff --git a/services/learn/learn/domain/students/entities/__init__.py b/services/learn_old/learn/domain/students/entities/__init__.py similarity index 100% rename from services/learn/learn/domain/students/entities/__init__.py rename to services/learn_old/learn/domain/students/entities/__init__.py diff --git a/services/learn/learn/domain/students/entities/student.py b/services/learn_old/learn/domain/students/entities/student.py similarity index 100% rename from services/learn/learn/domain/students/entities/student.py rename to services/learn_old/learn/domain/students/entities/student.py diff --git a/services/learn/learn/domain/students/value_objects/__init__.py b/services/learn_old/learn/domain/students/value_objects/__init__.py similarity index 100% rename from services/learn/learn/domain/students/value_objects/__init__.py rename to services/learn_old/learn/domain/students/value_objects/__init__.py diff --git a/services/learn/learn/domain/students/value_objects/student_id.py b/services/learn_old/learn/domain/students/value_objects/student_id.py similarity index 100% rename from services/learn/learn/domain/students/value_objects/student_id.py rename to services/learn_old/learn/domain/students/value_objects/student_id.py diff --git a/services/learn/learn/domain/users/__init__.py b/services/learn_old/learn/domain/users/__init__.py similarity index 100% rename from services/learn/learn/domain/users/__init__.py rename to services/learn_old/learn/domain/users/__init__.py diff --git a/services/learn/learn/domain/users/entities/__init__.py b/services/learn_old/learn/domain/users/entities/__init__.py similarity index 100% rename from services/learn/learn/domain/users/entities/__init__.py rename to services/learn_old/learn/domain/users/entities/__init__.py diff --git a/services/learn/learn/domain/users/entities/role.py b/services/learn_old/learn/domain/users/entities/role.py similarity index 100% rename from services/learn/learn/domain/users/entities/role.py rename to services/learn_old/learn/domain/users/entities/role.py diff --git a/services/learn/learn/domain/users/entities/user.py b/services/learn_old/learn/domain/users/entities/user.py similarity index 100% rename from services/learn/learn/domain/users/entities/user.py rename to services/learn_old/learn/domain/users/entities/user.py diff --git a/services/learn/learn/domain/users/value_objects/__init__.py b/services/learn_old/learn/domain/users/value_objects/__init__.py similarity index 100% rename from services/learn/learn/domain/users/value_objects/__init__.py rename to services/learn_old/learn/domain/users/value_objects/__init__.py diff --git a/services/learn/learn/domain/users/value_objects/email.py b/services/learn_old/learn/domain/users/value_objects/email.py similarity index 100% rename from services/learn/learn/domain/users/value_objects/email.py rename to services/learn_old/learn/domain/users/value_objects/email.py diff --git a/services/learn/learn/domain/users/value_objects/role_id.py b/services/learn_old/learn/domain/users/value_objects/role_id.py similarity index 100% rename from services/learn/learn/domain/users/value_objects/role_id.py rename to services/learn_old/learn/domain/users/value_objects/role_id.py diff --git a/services/learn/learn/domain/users/value_objects/user_id.py b/services/learn_old/learn/domain/users/value_objects/user_id.py similarity index 100% rename from services/learn/learn/domain/users/value_objects/user_id.py rename to services/learn_old/learn/domain/users/value_objects/user_id.py diff --git a/services/learn/learn/infrastructure/__init__.py b/services/learn_old/learn/infrastructure/__init__.py similarity index 100% rename from services/learn/learn/infrastructure/__init__.py rename to services/learn_old/learn/infrastructure/__init__.py diff --git a/services/learn/learn/infrastructure/aws/aws_s3_service.py b/services/learn_old/learn/infrastructure/aws/aws_s3_service.py similarity index 100% rename from services/learn/learn/infrastructure/aws/aws_s3_service.py rename to services/learn_old/learn/infrastructure/aws/aws_s3_service.py diff --git a/services/learn/learn/infrastructure/event_bus/__init__.py b/services/learn_old/learn/infrastructure/event_bus/__init__.py similarity index 100% rename from services/learn/learn/infrastructure/event_bus/__init__.py rename to services/learn_old/learn/infrastructure/event_bus/__init__.py diff --git a/services/learn/learn/infrastructure/event_bus/domain/__init__.py b/services/learn_old/learn/infrastructure/event_bus/domain/__init__.py similarity index 100% rename from services/learn/learn/infrastructure/event_bus/domain/__init__.py rename to services/learn_old/learn/infrastructure/event_bus/domain/__init__.py diff --git a/services/learn/learn/infrastructure/event_bus/domain/domain_event_bus.py b/services/learn_old/learn/infrastructure/event_bus/domain/domain_event_bus.py similarity index 100% rename from services/learn/learn/infrastructure/event_bus/domain/domain_event_bus.py rename to services/learn_old/learn/infrastructure/event_bus/domain/domain_event_bus.py diff --git a/services/learn/learn/infrastructure/event_bus/integration/__init__.py b/services/learn_old/learn/infrastructure/event_bus/integration/__init__.py similarity index 100% rename from services/learn/learn/infrastructure/event_bus/integration/__init__.py rename to services/learn_old/learn/infrastructure/event_bus/integration/__init__.py diff --git a/services/learn/learn/infrastructure/event_bus/integration/integration_event.py b/services/learn_old/learn/infrastructure/event_bus/integration/integration_event.py similarity index 100% rename from services/learn/learn/infrastructure/event_bus/integration/integration_event.py rename to services/learn_old/learn/infrastructure/event_bus/integration/integration_event.py diff --git a/services/learn/learn/infrastructure/event_bus/integration/integration_event_bus.py b/services/learn_old/learn/infrastructure/event_bus/integration/integration_event_bus.py similarity index 100% rename from services/learn/learn/infrastructure/event_bus/integration/integration_event_bus.py rename to services/learn_old/learn/infrastructure/event_bus/integration/integration_event_bus.py diff --git a/services/learn/learn/infrastructure/event_bus/integration/integration_event_handler.py b/services/learn_old/learn/infrastructure/event_bus/integration/integration_event_handler.py similarity index 100% rename from services/learn/learn/infrastructure/event_bus/integration/integration_event_handler.py rename to services/learn_old/learn/infrastructure/event_bus/integration/integration_event_handler.py diff --git a/services/learn/learn/infrastructure/event_bus/integration/rabbitmq/__init__.py b/services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/__init__.py similarity index 100% rename from services/learn/learn/infrastructure/event_bus/integration/rabbitmq/__init__.py rename to services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/__init__.py diff --git a/services/learn/learn/infrastructure/event_bus/integration/rabbitmq/rabbit_mq_connection_factory.py b/services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/rabbit_mq_connection_factory.py similarity index 100% rename from services/learn/learn/infrastructure/event_bus/integration/rabbitmq/rabbit_mq_connection_factory.py rename to services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/rabbit_mq_connection_factory.py diff --git a/services/learn/learn/infrastructure/event_bus/integration/rabbitmq/rabbitmq_integration_event_bus.py b/services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/rabbitmq_integration_event_bus.py similarity index 100% rename from services/learn/learn/infrastructure/event_bus/integration/rabbitmq/rabbitmq_integration_event_bus.py rename to services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/rabbitmq_integration_event_bus.py diff --git a/services/learn/learn/infrastructure/repositories/group_repository.py b/services/learn_old/learn/infrastructure/repositories/group_repository.py similarity index 100% rename from services/learn/learn/infrastructure/repositories/group_repository.py rename to services/learn_old/learn/infrastructure/repositories/group_repository.py diff --git a/services/learn/learn/infrastructure/repositories/post_repository.py b/services/learn_old/learn/infrastructure/repositories/post_repository.py similarity index 100% rename from services/learn/learn/infrastructure/repositories/post_repository.py rename to services/learn_old/learn/infrastructure/repositories/post_repository.py diff --git a/services/learn/learn/infrastructure/repositories/role_repository.py b/services/learn_old/learn/infrastructure/repositories/role_repository.py similarity index 100% rename from services/learn/learn/infrastructure/repositories/role_repository.py rename to services/learn_old/learn/infrastructure/repositories/role_repository.py diff --git a/services/learn/learn/infrastructure/repositories/student_repository.py b/services/learn_old/learn/infrastructure/repositories/student_repository.py similarity index 100% rename from services/learn/learn/infrastructure/repositories/student_repository.py rename to services/learn_old/learn/infrastructure/repositories/student_repository.py diff --git a/services/learn/learn/infrastructure/repositories/user_repository.py b/services/learn_old/learn/infrastructure/repositories/user_repository.py similarity index 100% rename from services/learn/learn/infrastructure/repositories/user_repository.py rename to services/learn_old/learn/infrastructure/repositories/user_repository.py diff --git a/services/learn/learn/management/commands/runserver.py b/services/learn_old/learn/management/commands/runserver.py similarity index 100% rename from services/learn/learn/management/commands/runserver.py rename to services/learn_old/learn/management/commands/runserver.py diff --git a/services/learn/learn/management/commands/seed.py b/services/learn_old/learn/management/commands/seed.py similarity index 100% rename from services/learn/learn/management/commands/seed.py rename to services/learn_old/learn/management/commands/seed.py diff --git a/services/learn/learn/migrations/0001_initial.py b/services/learn_old/learn/migrations/0001_initial.py similarity index 100% rename from services/learn/learn/migrations/0001_initial.py rename to services/learn_old/learn/migrations/0001_initial.py diff --git a/services/learn/learn/migrations/0002_user.py b/services/learn_old/learn/migrations/0002_user.py similarity index 100% rename from services/learn/learn/migrations/0002_user.py rename to services/learn_old/learn/migrations/0002_user.py diff --git a/services/learn/learn/migrations/0003_add_content_and_user_reference_to_post.py b/services/learn_old/learn/migrations/0003_add_content_and_user_reference_to_post.py similarity index 100% rename from services/learn/learn/migrations/0003_add_content_and_user_reference_to_post.py rename to services/learn_old/learn/migrations/0003_add_content_and_user_reference_to_post.py diff --git a/services/learn/learn/migrations/0003_group_and_studentGroup.py b/services/learn_old/learn/migrations/0003_group_and_studentGroup.py similarity index 100% rename from services/learn/learn/migrations/0003_group_and_studentGroup.py rename to services/learn_old/learn/migrations/0003_group_and_studentGroup.py diff --git a/services/learn/learn/migrations/0004_student_group_user_id_unique.py b/services/learn_old/learn/migrations/0004_student_group_user_id_unique.py similarity index 100% rename from services/learn/learn/migrations/0004_student_group_user_id_unique.py rename to services/learn_old/learn/migrations/0004_student_group_user_id_unique.py diff --git a/services/learn/learn/migrations/0005_meta.py b/services/learn_old/learn/migrations/0005_meta.py similarity index 100% rename from services/learn/learn/migrations/0005_meta.py rename to services/learn_old/learn/migrations/0005_meta.py diff --git a/services/learn/learn/migrations/0006_switched_to_one_to_one.py b/services/learn_old/learn/migrations/0006_switched_to_one_to_one.py similarity index 100% rename from services/learn/learn/migrations/0006_switched_to_one_to_one.py rename to services/learn_old/learn/migrations/0006_switched_to_one_to_one.py diff --git a/services/learn/learn/migrations/0007_rename_post_user.py b/services/learn_old/learn/migrations/0007_rename_post_user.py similarity index 100% rename from services/learn/learn/migrations/0007_rename_post_user.py rename to services/learn_old/learn/migrations/0007_rename_post_user.py diff --git a/services/learn/learn/migrations/0008_auto_20211011_2128.py b/services/learn_old/learn/migrations/0008_auto_20211011_2128.py similarity index 100% rename from services/learn/learn/migrations/0008_auto_20211011_2128.py rename to services/learn_old/learn/migrations/0008_auto_20211011_2128.py diff --git a/services/learn/learn/migrations/0008_student_group_switched_to_foreign_key_group.py b/services/learn_old/learn/migrations/0008_student_group_switched_to_foreign_key_group.py similarity index 100% rename from services/learn/learn/migrations/0008_student_group_switched_to_foreign_key_group.py rename to services/learn_old/learn/migrations/0008_student_group_switched_to_foreign_key_group.py diff --git a/services/learn/learn/migrations/0009_merge_0008.py b/services/learn_old/learn/migrations/0009_merge_0008.py similarity index 100% rename from services/learn/learn/migrations/0009_merge_0008.py rename to services/learn_old/learn/migrations/0009_merge_0008.py diff --git a/services/learn/learn/migrations/0010_user_avatar_field.py b/services/learn_old/learn/migrations/0010_user_avatar_field.py similarity index 100% rename from services/learn/learn/migrations/0010_user_avatar_field.py rename to services/learn_old/learn/migrations/0010_user_avatar_field.py diff --git a/services/learn/learn/migrations/0011_add_user_roles.py b/services/learn_old/learn/migrations/0011_add_user_roles.py similarity index 100% rename from services/learn/learn/migrations/0011_add_user_roles.py rename to services/learn_old/learn/migrations/0011_add_user_roles.py diff --git a/services/learn/learn/migrations/__init__.py b/services/learn_old/learn/migrations/__init__.py similarity index 100% rename from services/learn/learn/migrations/__init__.py rename to services/learn_old/learn/migrations/__init__.py diff --git a/services/learn/learn/models.py b/services/learn_old/learn/models.py similarity index 100% rename from services/learn/learn/models.py rename to services/learn_old/learn/models.py diff --git a/services/learn/learn/tests.py b/services/learn_old/learn/tests.py similarity index 100% rename from services/learn/learn/tests.py rename to services/learn_old/learn/tests.py diff --git a/services/learn/manage.py b/services/learn_old/manage.py similarity index 100% rename from services/learn/manage.py rename to services/learn_old/manage.py diff --git a/services/learn/requirements.txt b/services/learn_old/requirements.txt similarity index 100% rename from services/learn/requirements.txt rename to services/learn_old/requirements.txt From daa7898d1fbfd70ad8955d3530c54eca06213265 Mon Sep 17 00:00:00 2001 From: Yaroslaww-1 Date: Mon, 1 Nov 2021 21:44:48 +0200 Subject: [PATCH 2/5] added example flow --- .gitignore | 1 + services/learn/Dockerfile | 19 ++- .../Controllers/Users/UsersController.cs | 30 +++++ services/learn/Learn.API/Learn.API.csproj | 12 ++ services/learn/Learn.API/Program.cs | 20 +++ services/learn/Learn.API/Startup.cs | 56 +++++++++ .../Learn.API/appsettings.Development.json | 13 ++ services/learn/Learn.API/appsettings.json | 10 ++ .../ApplicationDependencyInjection.cs | 30 +++++ .../Behaviours/UnhandledExceptionBehaviour.cs | 34 +++++ .../Behaviours/ValidationBehaviour.cs | 40 ++++++ .../Learn.Application.csproj | 25 ++++ .../Learn.Application/Users/Dtos/RoleDto.cs | 10 ++ .../Learn.Application/Users/Dtos/UserDto.cs | 12 ++ .../Users/GetUsers/GetUsersQuery.cs | 41 ++++++ .../MappingProfiles/RoleMapperProfile.cs | 14 +++ .../MappingProfiles/UserMapperProfile.cs | 14 +++ .../UserAggregateSpecification.cs | 13 ++ .../ExecutionContextAccessor.cs | 51 ++++++++ .../IExecutionContextAccessor.cs | 9 ++ .../Infrastructure/Options/DatabaseOptions.cs | 9 ++ .../Infrastructure/Options/UrlsOptions.cs | 9 ++ .../Learn.BuildingBlocks.csproj | 11 ++ .../learn/Learn.Domain/Learn.Domain.csproj | 7 ++ services/learn/Learn.Domain/Users/Role.cs | 29 +++++ services/learn/Learn.Domain/Users/User.cs | 35 ++++++ .../RoleEntityConfiguration.cs | 29 +++++ .../UserEntityConfiguration.cs | 48 +++++++ .../EntityFramework/LearnDbContext.cs | 24 ++++ .../20211101194026_Initial.Designer.cs | 119 ++++++++++++++++++ .../Migrations/20211101194026_Initial.cs | 91 ++++++++++++++ .../Migrations/LearnDbContextModelSnapshot.cs | 117 +++++++++++++++++ .../Repositories/Users/IUserRepository.cs | 10 ++ .../Repositories/Users/UserRepository.cs | 12 ++ .../InfrastructureDependencyInjection.cs | 45 +++++++ .../Learn.Infrastructure.csproj | 29 +++++ services/learn/Learn.sln | 49 ++++++++ 37 files changed, 1121 insertions(+), 6 deletions(-) create mode 100644 services/learn/Learn.API/Controllers/Users/UsersController.cs create mode 100644 services/learn/Learn.API/Learn.API.csproj create mode 100644 services/learn/Learn.API/Program.cs create mode 100644 services/learn/Learn.API/Startup.cs create mode 100644 services/learn/Learn.API/appsettings.Development.json create mode 100644 services/learn/Learn.API/appsettings.json create mode 100644 services/learn/Learn.Application/ApplicationDependencyInjection.cs create mode 100644 services/learn/Learn.Application/Configuration/Behaviours/UnhandledExceptionBehaviour.cs create mode 100644 services/learn/Learn.Application/Configuration/Behaviours/ValidationBehaviour.cs create mode 100644 services/learn/Learn.Application/Learn.Application.csproj create mode 100644 services/learn/Learn.Application/Users/Dtos/RoleDto.cs create mode 100644 services/learn/Learn.Application/Users/Dtos/UserDto.cs create mode 100644 services/learn/Learn.Application/Users/GetUsers/GetUsersQuery.cs create mode 100644 services/learn/Learn.Application/Users/MappingProfiles/RoleMapperProfile.cs create mode 100644 services/learn/Learn.Application/Users/MappingProfiles/UserMapperProfile.cs create mode 100644 services/learn/Learn.Application/Users/Specifications/UserAggregateSpecification.cs create mode 100644 services/learn/Learn.BuildingBlocks/Application/ExecutionContext/ExecutionContextAccessor.cs create mode 100644 services/learn/Learn.BuildingBlocks/Application/ExecutionContext/IExecutionContextAccessor.cs create mode 100644 services/learn/Learn.BuildingBlocks/Infrastructure/Options/DatabaseOptions.cs create mode 100644 services/learn/Learn.BuildingBlocks/Infrastructure/Options/UrlsOptions.cs create mode 100644 services/learn/Learn.BuildingBlocks/Learn.BuildingBlocks.csproj create mode 100644 services/learn/Learn.Domain/Learn.Domain.csproj create mode 100644 services/learn/Learn.Domain/Users/Role.cs create mode 100644 services/learn/Learn.Domain/Users/User.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/RoleEntityConfiguration.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/UserEntityConfiguration.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/LearnDbContext.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101194026_Initial.Designer.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101194026_Initial.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Migrations/LearnDbContextModelSnapshot.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/IUserRepository.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/UserRepository.cs create mode 100644 services/learn/Learn.Infrastructure/InfrastructureDependencyInjection.cs create mode 100644 services/learn/Learn.Infrastructure/Learn.Infrastructure.csproj create mode 100644 services/learn/Learn.sln diff --git a/.gitignore b/.gitignore index 0626109..8d665e6 100644 --- a/.gitignore +++ b/.gitignore @@ -163,6 +163,7 @@ bin debug obj launchSettings.json +*.user # IdentityServer tempkey.jwk \ No newline at end of file diff --git a/services/learn/Dockerfile b/services/learn/Dockerfile index 1e91ed8..9779067 100644 --- a/services/learn/Dockerfile +++ b/services/learn/Dockerfile @@ -1,7 +1,14 @@ -FROM python:3 as builder -ENV PYTHONUNBUFFERED=1 +FROM mcr.microsoft.com/dotnet/sdk:5.0 AS builder WORKDIR /app -COPY requirements.txt /app/ -RUN pip install -r requirements.txt -COPY . /app/ -CMD ["python", "manage.py", "runserver"] \ No newline at end of file + +COPY Learn.csproj ./ +RUN dotnet restore Learn.csproj + +COPY . ./source/ +WORKDIR /app/source +RUN dotnet publish -c release -o /release + +FROM mcr.microsoft.com/dotnet/aspnet:5.0 +WORKDIR /release +COPY --from=builder /release ./ +ENTRYPOINT ["dotnet", "Learn.dll"] \ No newline at end of file diff --git a/services/learn/Learn.API/Controllers/Users/UsersController.cs b/services/learn/Learn.API/Controllers/Users/UsersController.cs new file mode 100644 index 0000000..532d660 --- /dev/null +++ b/services/learn/Learn.API/Controllers/Users/UsersController.cs @@ -0,0 +1,30 @@ +using Learn.Application.Users.Dtos; +using Learn.Application.Users.GetUsers; +using MediatR; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Learn.API.Users.Controllers +{ + [ApiController] + [Route("users")] + public class UsersController : ControllerBase + { + private readonly ISender _mediator; + + public UsersController(ISender mediator) + { + _mediator = mediator; + } + + [HttpGet] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task> GetAll() + { + var result = await _mediator.Send(new GetUsersQuery()); + return result; + } + } +} diff --git a/services/learn/Learn.API/Learn.API.csproj b/services/learn/Learn.API/Learn.API.csproj new file mode 100644 index 0000000..4966fbf --- /dev/null +++ b/services/learn/Learn.API/Learn.API.csproj @@ -0,0 +1,12 @@ + + + + net5.0 + + + + + + + + diff --git a/services/learn/Learn.API/Program.cs b/services/learn/Learn.API/Program.cs new file mode 100644 index 0000000..b0f5379 --- /dev/null +++ b/services/learn/Learn.API/Program.cs @@ -0,0 +1,20 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace Users +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/services/learn/Learn.API/Startup.cs b/services/learn/Learn.API/Startup.cs new file mode 100644 index 0000000..5e3faf2 --- /dev/null +++ b/services/learn/Learn.API/Startup.cs @@ -0,0 +1,56 @@ +using Learn.Applciation; +using Learn.Infrastructure; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace Users +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = new ConfigurationBuilder() + .AddJsonFile("appsettings.json") + .AddJsonFile("appsettings.Development.json") + .AddEnvironmentVariables() + .Build(); + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddInfrastructure(Configuration); + + services.AddApplication(); + + services.AddControllers(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UsePathBase(new PathString("/api")); + + app.UseRouting(); + + app.UseAuthentication(); + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + } +} diff --git a/services/learn/Learn.API/appsettings.Development.json b/services/learn/Learn.API/appsettings.Development.json new file mode 100644 index 0000000..442b960 --- /dev/null +++ b/services/learn/Learn.API/appsettings.Development.json @@ -0,0 +1,13 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "UrlsOptions": { + "GatewayApiUrl": "http://localhost:8000" + }, + "Urls": "http://0.0.0.0:8100" +} diff --git a/services/learn/Learn.API/appsettings.json b/services/learn/Learn.API/appsettings.json new file mode 100644 index 0000000..81ff877 --- /dev/null +++ b/services/learn/Learn.API/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/services/learn/Learn.Application/ApplicationDependencyInjection.cs b/services/learn/Learn.Application/ApplicationDependencyInjection.cs new file mode 100644 index 0000000..e1b3eb6 --- /dev/null +++ b/services/learn/Learn.Application/ApplicationDependencyInjection.cs @@ -0,0 +1,30 @@ +using FluentValidation; +using Learn.Application.Configuration.Behaviours; +using MediatR; +using Microsoft.Extensions.DependencyInjection; +using System.Reflection; + +namespace Learn.Applciation +{ + public static class ApplicationDependencyInjection + { + public static IServiceCollection AddApplication(this IServiceCollection services) + { + services.AddAutoMapper(Assembly.GetExecutingAssembly()); + services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly()); + + services.AddMediatR(Assembly.GetExecutingAssembly()); + services.AddPipelineBehaviour(); + + return services; + } + + private static IServiceCollection AddPipelineBehaviour(this IServiceCollection services) + { + services.AddTransient(typeof(IPipelineBehavior<,>), typeof(UnhandledExceptionBehaviour<,>)); + services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviour<,>)); + + return services; + } + } +} \ No newline at end of file diff --git a/services/learn/Learn.Application/Configuration/Behaviours/UnhandledExceptionBehaviour.cs b/services/learn/Learn.Application/Configuration/Behaviours/UnhandledExceptionBehaviour.cs new file mode 100644 index 0000000..c9a25b1 --- /dev/null +++ b/services/learn/Learn.Application/Configuration/Behaviours/UnhandledExceptionBehaviour.cs @@ -0,0 +1,34 @@ +using MediatR; +using Microsoft.Extensions.Logging; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Learn.Application.Configuration.Behaviours +{ + public class UnhandledExceptionBehaviour : IPipelineBehavior + { + private readonly ILogger _logger; + + public UnhandledExceptionBehaviour(ILogger logger) + { + _logger = logger; + } + + public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next) + { + try + { + return await next(); + } + catch (Exception ex) + { + var requestName = typeof(TRequest).Name; + + _logger.LogError(ex, "Unhandled Exception for Request {Name} {@Request}", requestName, request); + + throw; + } + } + } +} diff --git a/services/learn/Learn.Application/Configuration/Behaviours/ValidationBehaviour.cs b/services/learn/Learn.Application/Configuration/Behaviours/ValidationBehaviour.cs new file mode 100644 index 0000000..11e047e --- /dev/null +++ b/services/learn/Learn.Application/Configuration/Behaviours/ValidationBehaviour.cs @@ -0,0 +1,40 @@ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using FluentValidation; +using MediatR; + +namespace Learn.Application.Configuration.Behaviours +{ + public class ValidationBehaviour : IPipelineBehavior + where TRequest : IRequest + { + private readonly IEnumerable> _validators; + + public ValidationBehaviour(IEnumerable> validators) + { + _validators = validators; + } + + public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next) + { + if (_validators.Any()) + { + var context = new ValidationContext(request); + + var validationResults = await Task.WhenAll(_validators.Select(v => v.ValidateAsync(context, cancellationToken))); + var failures = validationResults.SelectMany(r => r.Errors).Where(f => f != null).ToList(); + + if (failures.Count != 0) + { + //TODO: Return all error messages + throw new Exception(failures.First().ErrorMessage); + } + } + return await next(); + } + } +} diff --git a/services/learn/Learn.Application/Learn.Application.csproj b/services/learn/Learn.Application/Learn.Application.csproj new file mode 100644 index 0000000..5cff2fa --- /dev/null +++ b/services/learn/Learn.Application/Learn.Application.csproj @@ -0,0 +1,25 @@ + + + + net5.0 + + + + + + + + + + + + + + + + + + + + + diff --git a/services/learn/Learn.Application/Users/Dtos/RoleDto.cs b/services/learn/Learn.Application/Users/Dtos/RoleDto.cs new file mode 100644 index 0000000..5509013 --- /dev/null +++ b/services/learn/Learn.Application/Users/Dtos/RoleDto.cs @@ -0,0 +1,10 @@ +using System; + +namespace Learn.Application.Users.Dtos +{ + public class RoleDto + { + public Guid Id { get; set; } + public string Name { get; set; } + } +} diff --git a/services/learn/Learn.Application/Users/Dtos/UserDto.cs b/services/learn/Learn.Application/Users/Dtos/UserDto.cs new file mode 100644 index 0000000..85ec823 --- /dev/null +++ b/services/learn/Learn.Application/Users/Dtos/UserDto.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace Learn.Application.Users.Dtos +{ + public class UserDto + { + public Guid Id { get; set; } + public string Name { get; set; } + public List Roles { get; set; } + } +} diff --git a/services/learn/Learn.Application/Users/GetUsers/GetUsersQuery.cs b/services/learn/Learn.Application/Users/GetUsers/GetUsersQuery.cs new file mode 100644 index 0000000..2517697 --- /dev/null +++ b/services/learn/Learn.Application/Users/GetUsers/GetUsersQuery.cs @@ -0,0 +1,41 @@ +using AutoMapper; +using Learn.Application.Users.Dtos; +using Learn.Application.Users.Specifications; +using Learn.Domain.Users; +using Learn.Infrastructure.EntityFramework; +using MediatR; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Ardalis.Specification.EntityFrameworkCore; +using AutoMapper.QueryableExtensions; +using Microsoft.EntityFrameworkCore; + +namespace Learn.Application.Users.GetUsers +{ + public class GetUsersQuery : IRequest> + { + } + + internal class GetJobsQueryHandler : IRequestHandler> + { + private readonly LearnDbContext _dbContext; + private readonly IMapper _mapper; + + public GetJobsQueryHandler(LearnDbContext context, IMapper mapper) + { + _dbContext = context; + _mapper = mapper; + } + + public async Task> Handle(GetUsersQuery request, CancellationToken cancellationToken) + { + var users = await _dbContext.Users + .WithSpecification(new UserAggregateSpecification()) + .AsNoTracking() + .ToListAsync(cancellationToken: cancellationToken); + + return _mapper.Map>(users); + } + } +} diff --git a/services/learn/Learn.Application/Users/MappingProfiles/RoleMapperProfile.cs b/services/learn/Learn.Application/Users/MappingProfiles/RoleMapperProfile.cs new file mode 100644 index 0000000..48d0055 --- /dev/null +++ b/services/learn/Learn.Application/Users/MappingProfiles/RoleMapperProfile.cs @@ -0,0 +1,14 @@ +using AutoMapper; +using Learn.Application.Users.Dtos; +using Learn.Domain.Users; + +namespace Learn.Application.Users.MappingProfiles +{ + public class RoleMapperProfile : Profile + { + public RoleMapperProfile() + { + CreateMap(); + } + } +} diff --git a/services/learn/Learn.Application/Users/MappingProfiles/UserMapperProfile.cs b/services/learn/Learn.Application/Users/MappingProfiles/UserMapperProfile.cs new file mode 100644 index 0000000..9d6b8f9 --- /dev/null +++ b/services/learn/Learn.Application/Users/MappingProfiles/UserMapperProfile.cs @@ -0,0 +1,14 @@ +using AutoMapper; +using Learn.Application.Users.Dtos; +using Learn.Domain.Users; + +namespace Learn.Application.Users.MappingProfiles +{ + public class UserMapperProfile : Profile + { + public UserMapperProfile() + { + CreateMap(); + } + } +} diff --git a/services/learn/Learn.Application/Users/Specifications/UserAggregateSpecification.cs b/services/learn/Learn.Application/Users/Specifications/UserAggregateSpecification.cs new file mode 100644 index 0000000..900c5cc --- /dev/null +++ b/services/learn/Learn.Application/Users/Specifications/UserAggregateSpecification.cs @@ -0,0 +1,13 @@ +using Ardalis.Specification; +using Learn.Domain.Users; + +namespace Learn.Application.Users.Specifications +{ + public class UserAggregateSpecification : Specification + { + public UserAggregateSpecification() + { + base.Query.Include(u => u.Roles); + } + } +} diff --git a/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/ExecutionContextAccessor.cs b/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/ExecutionContextAccessor.cs new file mode 100644 index 0000000..3a42ad4 --- /dev/null +++ b/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/ExecutionContextAccessor.cs @@ -0,0 +1,51 @@ +using Microsoft.AspNetCore.Http; +using System; +using System.Linq; + +namespace Learn.BuildingBlocks.ExecutionContext +{ + public class ExecutionContextAccessor : IExecutionContextAccessor + { + private readonly IHttpContextAccessor _httpContextAccessor; + + public ExecutionContextAccessor(IHttpContextAccessor httpContextAccessor) + { + _httpContextAccessor = httpContextAccessor; + } + + public string Email + { + get + { + //http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier + if (_httpContextAccessor + .HttpContext? + .User? + .Claims? + .SingleOrDefault(x => x.Type.Contains("email"))? + .Value != null) + { + return _httpContextAccessor.HttpContext.User.Claims.Single( + x => x.Type.Contains("email")).Value; + } + + if ((bool)(_httpContextAccessor + .HttpContext? + .Request? + .Headers? + .ContainsKey("email"))) + { + return _httpContextAccessor + .HttpContext? + .Request? + .Headers? + ["email"]; + } + + throw new ApplicationException("User context is not available"); + } + } + + public bool IsAvailable => _httpContextAccessor.HttpContext != null; + } +} diff --git a/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/IExecutionContextAccessor.cs b/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/IExecutionContextAccessor.cs new file mode 100644 index 0000000..2b9afde --- /dev/null +++ b/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/IExecutionContextAccessor.cs @@ -0,0 +1,9 @@ +using System; + +namespace Learn.BuildingBlocks.ExecutionContext +{ + public interface IExecutionContextAccessor + { + string Email { get; } + } +} diff --git a/services/learn/Learn.BuildingBlocks/Infrastructure/Options/DatabaseOptions.cs b/services/learn/Learn.BuildingBlocks/Infrastructure/Options/DatabaseOptions.cs new file mode 100644 index 0000000..e61839e --- /dev/null +++ b/services/learn/Learn.BuildingBlocks/Infrastructure/Options/DatabaseOptions.cs @@ -0,0 +1,9 @@ +namespace Learn.BuildingBlocks.Infrastructure.Options +{ + public class DatabaseOptions + { + public const string Location = "DatabaseOptions"; + + public string ConnectionString { get; set; } + } +} diff --git a/services/learn/Learn.BuildingBlocks/Infrastructure/Options/UrlsOptions.cs b/services/learn/Learn.BuildingBlocks/Infrastructure/Options/UrlsOptions.cs new file mode 100644 index 0000000..33c9a7b --- /dev/null +++ b/services/learn/Learn.BuildingBlocks/Infrastructure/Options/UrlsOptions.cs @@ -0,0 +1,9 @@ +namespace Learn.BuildingBlocks.Infrastructure.Options +{ + public class UrlsOptions + { + public const string Location = "UrlsOptions"; + + public string GatewayApiUrl { get; set; } + } +} diff --git a/services/learn/Learn.BuildingBlocks/Learn.BuildingBlocks.csproj b/services/learn/Learn.BuildingBlocks/Learn.BuildingBlocks.csproj new file mode 100644 index 0000000..8aa17ce --- /dev/null +++ b/services/learn/Learn.BuildingBlocks/Learn.BuildingBlocks.csproj @@ -0,0 +1,11 @@ + + + + net5.0 + + + + + + + diff --git a/services/learn/Learn.Domain/Learn.Domain.csproj b/services/learn/Learn.Domain/Learn.Domain.csproj new file mode 100644 index 0000000..6e9ceba --- /dev/null +++ b/services/learn/Learn.Domain/Learn.Domain.csproj @@ -0,0 +1,7 @@ + + + + net5.0 + + + diff --git a/services/learn/Learn.Domain/Users/Role.cs b/services/learn/Learn.Domain/Users/Role.cs new file mode 100644 index 0000000..8074901 --- /dev/null +++ b/services/learn/Learn.Domain/Users/Role.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +namespace Learn.Domain.Users +{ + public class Role + { + public Guid Id { get; private set; } + public string Name { get; private set; } + public IList Users { get; private set; } + + private Role() + { + // Only for EF + } + + private Role(string name) + { + Id = Guid.NewGuid(); + Name = name; + Users = new List(); + } + + public static Role CreateNew(string name) + { + return new Role(name); + } + } +} diff --git a/services/learn/Learn.Domain/Users/User.cs b/services/learn/Learn.Domain/Users/User.cs new file mode 100644 index 0000000..f0e89f8 --- /dev/null +++ b/services/learn/Learn.Domain/Users/User.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; + +namespace Learn.Domain.Users +{ + public class User + { + public Guid Id { get; private set; } + public string Email { get; private set; } + public string Name { get; private set; } + public string PasswordHash { get; private set; } + public string PasswordHashSalt { get; private set; } + public IList Roles { get; private set; } + + private User() + { + // Only for EF + } + + private User( + string email, + string name, + string passwordHash, + string passwordHashSalt, + List roles) + { + Id = Guid.NewGuid(); + Email = email; + Name = name; + PasswordHash = passwordHash; + PasswordHashSalt = passwordHashSalt; + Roles = roles; + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/RoleEntityConfiguration.cs b/services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/RoleEntityConfiguration.cs new file mode 100644 index 0000000..30afeec --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/RoleEntityConfiguration.cs @@ -0,0 +1,29 @@ +using Learn.Domain.Users; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Learn.Infrastructure.EntityFramework.EntityConfigurations +{ + public class RoleEntityConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder entity) + { + entity.ToTable("role"); + + entity + .Property(u => u.Id) + .HasColumnType("uuid") + .IsRequired(); + + entity.HasKey(u => u.Id); + + entity + .Property(u => u.Name) + .IsRequired(); + + entity + .HasIndex(u => u.Name) + .IsUnique(); + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/UserEntityConfiguration.cs b/services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/UserEntityConfiguration.cs new file mode 100644 index 0000000..08fa437 --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/UserEntityConfiguration.cs @@ -0,0 +1,48 @@ +using Learn.Domain.Users; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using System.Collections.Generic; + +namespace Learn.Infrastructure.EntityFramework.EntityConfigurations +{ + public class UserEntityConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder entity) + { + entity.ToTable("user"); + + entity + .Property(u => u.Id) + .HasColumnType("uuid") + .IsRequired(); + + entity.HasKey(u => u.Id); + + entity + .Property(u => u.Name) + .IsRequired(); + + entity + .Property(u => u.Email) + .IsRequired(); + + entity + .HasIndex(u => u.Email) + .IsUnique(); + + entity + .HasMany(u => u.Roles) + .WithMany(r => r.Users) + .UsingEntity>( + "user_role", + u => u + .HasOne() + .WithMany() + .HasForeignKey("role_id"), + r => r + .HasOne() + .WithMany() + .HasForeignKey("user_id")); + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/LearnDbContext.cs b/services/learn/Learn.Infrastructure/EntityFramework/LearnDbContext.cs new file mode 100644 index 0000000..ace0e99 --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/LearnDbContext.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore; +using Learn.Infrastructure.EntityFramework.EntityConfigurations; +using Learn.Domain.Users; + +namespace Learn.Infrastructure.EntityFramework +{ + public class LearnDbContext : DbContext + { + public DbSet Users { get; set; } + + public DbSet Roles { get; set; } + + public LearnDbContext() : base() { } + + public LearnDbContext(DbContextOptions options) : base(options) { } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ApplyConfigurationsFromAssembly(typeof(RoleEntityConfiguration).Assembly); + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101194026_Initial.Designer.cs b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101194026_Initial.Designer.cs new file mode 100644 index 0000000..78c6cc2 --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101194026_Initial.Designer.cs @@ -0,0 +1,119 @@ +// +using System; +using Learn.Infrastructure.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Learn.Infrastructure.EntityFramework.Migrations +{ + [DbContext(typeof(LearnDbContext))] + [Migration("20211101194026_Initial")] + partial class Initial + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 63) + .HasAnnotation("ProductVersion", "5.0.11") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + modelBuilder.Entity("Learn.Domain.Users.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_role"); + + b.HasIndex("Name") + .IsUnique() + .HasDatabaseName("ix_role_name"); + + b.ToTable("role"); + }); + + modelBuilder.Entity("Learn.Domain.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasColumnName("password_hash"); + + b.Property("PasswordHashSalt") + .HasColumnType("text") + .HasColumnName("password_hash_salt"); + + b.HasKey("Id") + .HasName("pk_user"); + + b.HasIndex("Email") + .IsUnique() + .HasDatabaseName("ix_user_email"); + + b.ToTable("user"); + }); + + modelBuilder.Entity("user_role", b => + { + b.Property("role_id") + .HasColumnType("uuid") + .HasColumnName("role_id"); + + b.Property("user_id") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("role_id", "user_id") + .HasName("pk_user_role"); + + b.HasIndex("user_id") + .HasDatabaseName("ix_user_role_user_id"); + + b.ToTable("user_role"); + }); + + modelBuilder.Entity("user_role", b => + { + b.HasOne("Learn.Domain.Users.Role", null) + .WithMany() + .HasForeignKey("role_id") + .HasConstraintName("fk_user_role_role_role_id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Learn.Domain.Users.User", null) + .WithMany() + .HasForeignKey("user_id") + .HasConstraintName("fk_user_role_user_user_id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101194026_Initial.cs b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101194026_Initial.cs new file mode 100644 index 0000000..a58c9ca --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101194026_Initial.cs @@ -0,0 +1,91 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Learn.Infrastructure.EntityFramework.Migrations +{ + public partial class Initial : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "role", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + name = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_role", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "user", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + email = table.Column(type: "text", nullable: false), + name = table.Column(type: "text", nullable: false), + password_hash = table.Column(type: "text", nullable: true), + password_hash_salt = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("pk_user", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "user_role", + columns: table => new + { + role_id = table.Column(type: "uuid", nullable: false), + user_id = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_user_role", x => new { x.role_id, x.user_id }); + table.ForeignKey( + name: "fk_user_role_role_role_id", + column: x => x.role_id, + principalTable: "role", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_user_role_user_user_id", + column: x => x.user_id, + principalTable: "user", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "ix_role_name", + table: "role", + column: "name", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_user_email", + table: "user", + column: "email", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_user_role_user_id", + table: "user_role", + column: "user_id"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "user_role"); + + migrationBuilder.DropTable( + name: "role"); + + migrationBuilder.DropTable( + name: "user"); + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/LearnDbContextModelSnapshot.cs b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/LearnDbContextModelSnapshot.cs new file mode 100644 index 0000000..7f0b081 --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/LearnDbContextModelSnapshot.cs @@ -0,0 +1,117 @@ +// +using System; +using Learn.Infrastructure.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Learn.Infrastructure.EntityFramework.Migrations +{ + [DbContext(typeof(LearnDbContext))] + partial class LearnDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 63) + .HasAnnotation("ProductVersion", "5.0.11") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + modelBuilder.Entity("Learn.Domain.Users.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_role"); + + b.HasIndex("Name") + .IsUnique() + .HasDatabaseName("ix_role_name"); + + b.ToTable("role"); + }); + + modelBuilder.Entity("Learn.Domain.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasColumnName("password_hash"); + + b.Property("PasswordHashSalt") + .HasColumnType("text") + .HasColumnName("password_hash_salt"); + + b.HasKey("Id") + .HasName("pk_user"); + + b.HasIndex("Email") + .IsUnique() + .HasDatabaseName("ix_user_email"); + + b.ToTable("user"); + }); + + modelBuilder.Entity("user_role", b => + { + b.Property("role_id") + .HasColumnType("uuid") + .HasColumnName("role_id"); + + b.Property("user_id") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("role_id", "user_id") + .HasName("pk_user_role"); + + b.HasIndex("user_id") + .HasDatabaseName("ix_user_role_user_id"); + + b.ToTable("user_role"); + }); + + modelBuilder.Entity("user_role", b => + { + b.HasOne("Learn.Domain.Users.Role", null) + .WithMany() + .HasForeignKey("role_id") + .HasConstraintName("fk_user_role_role_role_id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Learn.Domain.Users.User", null) + .WithMany() + .HasForeignKey("user_id") + .HasConstraintName("fk_user_role_user_user_id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/IUserRepository.cs b/services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/IUserRepository.cs new file mode 100644 index 0000000..cac2c0e --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/IUserRepository.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Learn.Infrastructure.EntityFramework.Repositories.Users +{ + public interface IUserRepository + { + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/UserRepository.cs b/services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/UserRepository.cs new file mode 100644 index 0000000..d16b562 --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/UserRepository.cs @@ -0,0 +1,12 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Learn.Infrastructure.EntityFramework.Repositories.Users +{ + public class UserRepository : IUserRepository + { + + } +} diff --git a/services/learn/Learn.Infrastructure/InfrastructureDependencyInjection.cs b/services/learn/Learn.Infrastructure/InfrastructureDependencyInjection.cs new file mode 100644 index 0000000..1267e2b --- /dev/null +++ b/services/learn/Learn.Infrastructure/InfrastructureDependencyInjection.cs @@ -0,0 +1,45 @@ +using Learn.BuildingBlocks.Infrastructure.Options; +using Learn.Infrastructure.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System; + +namespace Learn.Infrastructure +{ + public static class InfrastructureDependencyInjection + { + public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration) + { + services.AddOptions(configuration); + services.AddDatabaseContext(configuration); + + return services; + } + + private static IServiceCollection AddOptions(this IServiceCollection services, IConfiguration configuration) + { + services.Configure(configuration.GetSection(DatabaseOptions.Location)); + services.Configure(configuration.GetSection(UrlsOptions.Location)); + + return services; + } + + private static IServiceCollection AddDatabaseContext(this IServiceCollection services, IConfiguration configuration) + { + var databaseOptions = configuration.GetSection(DatabaseOptions.Location).Get(); + + var migrationAssembly = typeof(LearnDbContext).Assembly.GetName().Name; + + services.AddDbContext(options => + options + .UseNpgsql( + databaseOptions.ConnectionString, + opt => opt.MigrationsAssembly(migrationAssembly)) + .UseSnakeCaseNamingConvention() + ); + + return services; + } + } +} \ No newline at end of file diff --git a/services/learn/Learn.Infrastructure/Learn.Infrastructure.csproj b/services/learn/Learn.Infrastructure/Learn.Infrastructure.csproj new file mode 100644 index 0000000..1f15b05 --- /dev/null +++ b/services/learn/Learn.Infrastructure/Learn.Infrastructure.csproj @@ -0,0 +1,29 @@ + + + + net5.0 + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + diff --git a/services/learn/Learn.sln b/services/learn/Learn.sln new file mode 100644 index 0000000..91f75fd --- /dev/null +++ b/services/learn/Learn.sln @@ -0,0 +1,49 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31424.327 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Learn.API", "Learn.API\Learn.API.csproj", "{29596B8F-0CD0-4B0D-B8F4-AA50EB574AA1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Learn.Application", "Learn.Application\Learn.Application.csproj", "{A420DBE7-2236-4A38-B173-D6CD2E3F42B8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Learn.Domain", "Learn.Domain\Learn.Domain.csproj", "{E096DEBE-E9CF-42D9-8C63-BC085BBD27BE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Learn.Infrastructure", "Learn.Infrastructure\Learn.Infrastructure.csproj", "{B9EF0C2D-3520-40F9-AC8B-0136348A79FC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Learn.BuildingBlocks", "Learn.BuildingBlocks\Learn.BuildingBlocks.csproj", "{3979895E-55D5-4D9F-BF8F-E928931E44FB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {29596B8F-0CD0-4B0D-B8F4-AA50EB574AA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {29596B8F-0CD0-4B0D-B8F4-AA50EB574AA1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {29596B8F-0CD0-4B0D-B8F4-AA50EB574AA1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {29596B8F-0CD0-4B0D-B8F4-AA50EB574AA1}.Release|Any CPU.Build.0 = Release|Any CPU + {A420DBE7-2236-4A38-B173-D6CD2E3F42B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A420DBE7-2236-4A38-B173-D6CD2E3F42B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A420DBE7-2236-4A38-B173-D6CD2E3F42B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A420DBE7-2236-4A38-B173-D6CD2E3F42B8}.Release|Any CPU.Build.0 = Release|Any CPU + {E096DEBE-E9CF-42D9-8C63-BC085BBD27BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E096DEBE-E9CF-42D9-8C63-BC085BBD27BE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E096DEBE-E9CF-42D9-8C63-BC085BBD27BE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E096DEBE-E9CF-42D9-8C63-BC085BBD27BE}.Release|Any CPU.Build.0 = Release|Any CPU + {B9EF0C2D-3520-40F9-AC8B-0136348A79FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B9EF0C2D-3520-40F9-AC8B-0136348A79FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B9EF0C2D-3520-40F9-AC8B-0136348A79FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B9EF0C2D-3520-40F9-AC8B-0136348A79FC}.Release|Any CPU.Build.0 = Release|Any CPU + {3979895E-55D5-4D9F-BF8F-E928931E44FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3979895E-55D5-4D9F-BF8F-E928931E44FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3979895E-55D5-4D9F-BF8F-E928931E44FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3979895E-55D5-4D9F-BF8F-E928931E44FB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EA606E0E-9C8A-4706-BCA8-240AE261362B} + EndGlobalSection +EndGlobal From f85ad73a6a4f2334189e9b6cb9ee45433d3c33ac Mon Sep 17 00:00:00 2001 From: Yaroslaww-1 Date: Mon, 1 Nov 2021 21:45:15 +0200 Subject: [PATCH 3/5] completely removed old learn --- services/learn_old/Dockerfile | 7 - services/learn_old/Dockerfile.k8s-build | 8 - services/learn_old/__init__.py | 0 services/learn_old/api/__init__.py | 0 services/learn_old/api/asgi.py | 16 -- services/learn_old/api/settings.py | 168 ---------------- services/learn_old/api/wsgi.py | 16 -- services/learn_old/learn/__init__.py | 0 services/learn_old/learn/admin.py | 3 - services/learn_old/learn/api/__init__.py | 0 .../api/auth/authenticated_user_context.py | 18 -- services/learn_old/learn/api/constants.py | 1 - .../api/decorators/in_roles_decorator.py | 21 -- .../learn_old/learn/api/enums/roles_enum.py | 7 - .../exceptions/custom_exception_handler.py | 22 --- .../learn/api/options/rabbit_mq_options.py | 9 - .../learn/api/serializers/dto_serializer.py | 15 -- services/learn_old/learn/api/urls.py | 6 - .../learn_old/learn/api/views/groups_view.py | 24 --- .../learn_old/learn/api/views/posts_view.py | 29 --- .../learn/api/views/students_view.py | 18 -- .../learn_old/learn/api/views/users_view.py | 38 ---- .../learn_old/learn/application/__init__.py | 0 .../create_group/create_group_command.py | 23 --- .../application/groups/dtos/group_dto.py | 7 - .../groups/get_groups/get_groups_query.py | 17 -- .../learn/application/groups/group_mapper.py | 18 -- .../posts/create_post/create_post_command.py | 31 --- .../post_created_domain_event_handler.py | 13 -- .../learn/application/posts/dtos/post_dto.py | 6 - .../posts/get_posts/get_posts_query.py | 17 -- .../learn/application/posts/post_mapper.py | 17 -- .../learn/application/students/__init__.py | 0 .../application/students/dtos/__init__.py | 0 .../application/students/dtos/student_dto.py | 9 - .../get_students/get_students_query.py | 17 -- .../application/students/student_mapper.py | 19 -- .../users/create_user/create_user_command.py | 24 --- .../create_user/upload_user_avatar_command.py | 28 --- .../learn/application/users/dtos/user_dto.py | 7 - .../users/get_users/get_user_by_id_query.py | 15 -- .../users/get_users/get_users_query.py | 17 -- .../user_created_integration_event.py | 20 -- .../user_created_integration_event_handler.py | 34 ---- .../learn/application/users/user_mapper.py | 18 -- services/learn_old/learn/apps.py | 69 ------- services/learn_old/learn/domain/__init__.py | 0 .../common/base_typed_id_value_object.py | 10 - .../learn/domain/common/domain_events.py | 33 ---- .../learn_old/learn/domain/groups/__init__.py | 0 .../learn/domain/groups/entities/__init__.py | 0 .../learn/domain/groups/entities/group.py | 26 --- .../domain/groups/entities/student_group.py | 10 - .../domain/groups/value_objects/__init__.py | 0 .../domain/groups/value_objects/group_id.py | 8 - .../groups/value_objects/student_group_id.py | 8 - .../learn/domain/groups/value_objects/year.py | 9 - .../learn_old/learn/domain/posts/__init__.py | 0 .../learn/domain/posts/entities/__init__.py | 0 .../learn/domain/posts/entities/post.py | 30 --- .../posts/events/post_created_domain_event.py | 9 - .../domain/posts/value_objects/__init__.py | 0 .../domain/posts/value_objects/post_id.py | 8 - .../learn/domain/students/__init__.py | 0 .../domain/students/entities/__init__.py | 0 .../learn/domain/students/entities/student.py | 8 - .../domain/students/value_objects/__init__.py | 0 .../students/value_objects/student_id.py | 8 - .../learn_old/learn/domain/users/__init__.py | 0 .../learn/domain/users/entities/__init__.py | 0 .../learn/domain/users/entities/role.py | 22 --- .../learn/domain/users/entities/user.py | 31 --- .../domain/users/value_objects/__init__.py | 0 .../learn/domain/users/value_objects/email.py | 4 - .../domain/users/value_objects/role_id.py | 8 - .../domain/users/value_objects/user_id.py | 8 - .../learn/infrastructure/__init__.py | 0 .../infrastructure/aws/aws_s3_service.py | 16 -- .../infrastructure/event_bus/__init__.py | 0 .../event_bus/domain/__init__.py | 0 .../event_bus/domain/domain_event_bus.py | 19 -- .../event_bus/integration/__init__.py | 0 .../integration/integration_event.py | 12 -- .../integration/integration_event_bus.py | 12 -- .../integration/integration_event_handler.py | 10 - .../integration/rabbitmq/__init__.py | 0 .../rabbitmq/rabbit_mq_connection_factory.py | 24 --- .../rabbitmq_integration_event_bus.py | 123 ------------ .../repositories/group_repository.py | 36 ---- .../repositories/post_repository.py | 51 ----- .../repositories/role_repository.py | 33 ---- .../repositories/student_repository.py | 21 -- .../repositories/user_repository.py | 56 ------ .../learn/management/commands/runserver.py | 37 ---- .../learn/management/commands/seed.py | 185 ------------------ .../learn/migrations/0001_initial.py | 21 -- .../learn_old/learn/migrations/0002_user.py | 21 -- ..._add_content_and_user_reference_to_post.py | 47 ----- .../migrations/0003_group_and_studentGroup.py | 36 ---- .../0004_student_group_user_id_unique.py | 35 ---- .../learn_old/learn/migrations/0005_meta.py | 37 ---- .../migrations/0006_switched_to_one_to_one.py | 40 ---- .../learn/migrations/0007_rename_post_user.py | 34 ---- .../migrations/0008_auto_20211011_2128.py | 176 ----------------- ...ent_group_switched_to_foreign_key_group.py | 35 ---- .../learn/migrations/0009_merge_0008.py | 14 -- .../migrations/0010_user_avatar_field.py | 39 ---- .../learn/migrations/0011_add_user_roles.py | 43 ---- .../learn_old/learn/migrations/__init__.py | 0 services/learn_old/learn/models.py | 160 --------------- services/learn_old/learn/tests.py | 3 - services/learn_old/manage.py | 27 --- services/learn_old/requirements.txt | 24 --- 113 files changed, 2519 deletions(-) delete mode 100644 services/learn_old/Dockerfile delete mode 100644 services/learn_old/Dockerfile.k8s-build delete mode 100644 services/learn_old/__init__.py delete mode 100644 services/learn_old/api/__init__.py delete mode 100644 services/learn_old/api/asgi.py delete mode 100644 services/learn_old/api/settings.py delete mode 100644 services/learn_old/api/wsgi.py delete mode 100644 services/learn_old/learn/__init__.py delete mode 100644 services/learn_old/learn/admin.py delete mode 100644 services/learn_old/learn/api/__init__.py delete mode 100644 services/learn_old/learn/api/auth/authenticated_user_context.py delete mode 100644 services/learn_old/learn/api/constants.py delete mode 100644 services/learn_old/learn/api/decorators/in_roles_decorator.py delete mode 100644 services/learn_old/learn/api/enums/roles_enum.py delete mode 100644 services/learn_old/learn/api/exceptions/custom_exception_handler.py delete mode 100644 services/learn_old/learn/api/options/rabbit_mq_options.py delete mode 100644 services/learn_old/learn/api/serializers/dto_serializer.py delete mode 100644 services/learn_old/learn/api/urls.py delete mode 100644 services/learn_old/learn/api/views/groups_view.py delete mode 100644 services/learn_old/learn/api/views/posts_view.py delete mode 100644 services/learn_old/learn/api/views/students_view.py delete mode 100644 services/learn_old/learn/api/views/users_view.py delete mode 100644 services/learn_old/learn/application/__init__.py delete mode 100644 services/learn_old/learn/application/groups/create_group/create_group_command.py delete mode 100644 services/learn_old/learn/application/groups/dtos/group_dto.py delete mode 100644 services/learn_old/learn/application/groups/get_groups/get_groups_query.py delete mode 100644 services/learn_old/learn/application/groups/group_mapper.py delete mode 100644 services/learn_old/learn/application/posts/create_post/create_post_command.py delete mode 100644 services/learn_old/learn/application/posts/domain_event_handlers/post_created_domain_event_handler.py delete mode 100644 services/learn_old/learn/application/posts/dtos/post_dto.py delete mode 100644 services/learn_old/learn/application/posts/get_posts/get_posts_query.py delete mode 100644 services/learn_old/learn/application/posts/post_mapper.py delete mode 100644 services/learn_old/learn/application/students/__init__.py delete mode 100644 services/learn_old/learn/application/students/dtos/__init__.py delete mode 100644 services/learn_old/learn/application/students/dtos/student_dto.py delete mode 100644 services/learn_old/learn/application/students/get_students/get_students_query.py delete mode 100644 services/learn_old/learn/application/students/student_mapper.py delete mode 100644 services/learn_old/learn/application/users/create_user/create_user_command.py delete mode 100644 services/learn_old/learn/application/users/create_user/upload_user_avatar_command.py delete mode 100644 services/learn_old/learn/application/users/dtos/user_dto.py delete mode 100644 services/learn_old/learn/application/users/get_users/get_user_by_id_query.py delete mode 100644 services/learn_old/learn/application/users/get_users/get_users_query.py delete mode 100644 services/learn_old/learn/application/users/integration_events/user_created/user_created_integration_event.py delete mode 100644 services/learn_old/learn/application/users/integration_events/user_created/user_created_integration_event_handler.py delete mode 100644 services/learn_old/learn/application/users/user_mapper.py delete mode 100644 services/learn_old/learn/apps.py delete mode 100644 services/learn_old/learn/domain/__init__.py delete mode 100644 services/learn_old/learn/domain/common/base_typed_id_value_object.py delete mode 100644 services/learn_old/learn/domain/common/domain_events.py delete mode 100644 services/learn_old/learn/domain/groups/__init__.py delete mode 100644 services/learn_old/learn/domain/groups/entities/__init__.py delete mode 100644 services/learn_old/learn/domain/groups/entities/group.py delete mode 100644 services/learn_old/learn/domain/groups/entities/student_group.py delete mode 100644 services/learn_old/learn/domain/groups/value_objects/__init__.py delete mode 100644 services/learn_old/learn/domain/groups/value_objects/group_id.py delete mode 100644 services/learn_old/learn/domain/groups/value_objects/student_group_id.py delete mode 100644 services/learn_old/learn/domain/groups/value_objects/year.py delete mode 100644 services/learn_old/learn/domain/posts/__init__.py delete mode 100644 services/learn_old/learn/domain/posts/entities/__init__.py delete mode 100644 services/learn_old/learn/domain/posts/entities/post.py delete mode 100644 services/learn_old/learn/domain/posts/events/post_created_domain_event.py delete mode 100644 services/learn_old/learn/domain/posts/value_objects/__init__.py delete mode 100644 services/learn_old/learn/domain/posts/value_objects/post_id.py delete mode 100644 services/learn_old/learn/domain/students/__init__.py delete mode 100644 services/learn_old/learn/domain/students/entities/__init__.py delete mode 100644 services/learn_old/learn/domain/students/entities/student.py delete mode 100644 services/learn_old/learn/domain/students/value_objects/__init__.py delete mode 100644 services/learn_old/learn/domain/students/value_objects/student_id.py delete mode 100644 services/learn_old/learn/domain/users/__init__.py delete mode 100644 services/learn_old/learn/domain/users/entities/__init__.py delete mode 100644 services/learn_old/learn/domain/users/entities/role.py delete mode 100644 services/learn_old/learn/domain/users/entities/user.py delete mode 100644 services/learn_old/learn/domain/users/value_objects/__init__.py delete mode 100644 services/learn_old/learn/domain/users/value_objects/email.py delete mode 100644 services/learn_old/learn/domain/users/value_objects/role_id.py delete mode 100644 services/learn_old/learn/domain/users/value_objects/user_id.py delete mode 100644 services/learn_old/learn/infrastructure/__init__.py delete mode 100644 services/learn_old/learn/infrastructure/aws/aws_s3_service.py delete mode 100644 services/learn_old/learn/infrastructure/event_bus/__init__.py delete mode 100644 services/learn_old/learn/infrastructure/event_bus/domain/__init__.py delete mode 100644 services/learn_old/learn/infrastructure/event_bus/domain/domain_event_bus.py delete mode 100644 services/learn_old/learn/infrastructure/event_bus/integration/__init__.py delete mode 100644 services/learn_old/learn/infrastructure/event_bus/integration/integration_event.py delete mode 100644 services/learn_old/learn/infrastructure/event_bus/integration/integration_event_bus.py delete mode 100644 services/learn_old/learn/infrastructure/event_bus/integration/integration_event_handler.py delete mode 100644 services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/__init__.py delete mode 100644 services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/rabbit_mq_connection_factory.py delete mode 100644 services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/rabbitmq_integration_event_bus.py delete mode 100644 services/learn_old/learn/infrastructure/repositories/group_repository.py delete mode 100644 services/learn_old/learn/infrastructure/repositories/post_repository.py delete mode 100644 services/learn_old/learn/infrastructure/repositories/role_repository.py delete mode 100644 services/learn_old/learn/infrastructure/repositories/student_repository.py delete mode 100644 services/learn_old/learn/infrastructure/repositories/user_repository.py delete mode 100644 services/learn_old/learn/management/commands/runserver.py delete mode 100644 services/learn_old/learn/management/commands/seed.py delete mode 100644 services/learn_old/learn/migrations/0001_initial.py delete mode 100644 services/learn_old/learn/migrations/0002_user.py delete mode 100644 services/learn_old/learn/migrations/0003_add_content_and_user_reference_to_post.py delete mode 100644 services/learn_old/learn/migrations/0003_group_and_studentGroup.py delete mode 100644 services/learn_old/learn/migrations/0004_student_group_user_id_unique.py delete mode 100644 services/learn_old/learn/migrations/0005_meta.py delete mode 100644 services/learn_old/learn/migrations/0006_switched_to_one_to_one.py delete mode 100644 services/learn_old/learn/migrations/0007_rename_post_user.py delete mode 100644 services/learn_old/learn/migrations/0008_auto_20211011_2128.py delete mode 100644 services/learn_old/learn/migrations/0008_student_group_switched_to_foreign_key_group.py delete mode 100644 services/learn_old/learn/migrations/0009_merge_0008.py delete mode 100644 services/learn_old/learn/migrations/0010_user_avatar_field.py delete mode 100644 services/learn_old/learn/migrations/0011_add_user_roles.py delete mode 100644 services/learn_old/learn/migrations/__init__.py delete mode 100644 services/learn_old/learn/models.py delete mode 100644 services/learn_old/learn/tests.py delete mode 100644 services/learn_old/manage.py delete mode 100644 services/learn_old/requirements.txt diff --git a/services/learn_old/Dockerfile b/services/learn_old/Dockerfile deleted file mode 100644 index 1e91ed8..0000000 --- a/services/learn_old/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM python:3 as builder -ENV PYTHONUNBUFFERED=1 -WORKDIR /app -COPY requirements.txt /app/ -RUN pip install -r requirements.txt -COPY . /app/ -CMD ["python", "manage.py", "runserver"] \ No newline at end of file diff --git a/services/learn_old/Dockerfile.k8s-build b/services/learn_old/Dockerfile.k8s-build deleted file mode 100644 index 3fee00f..0000000 --- a/services/learn_old/Dockerfile.k8s-build +++ /dev/null @@ -1,8 +0,0 @@ -FROM python:3 as builder -ENV PYTHONUNBUFFERED=1 -WORKDIR /app -COPY requirements.txt /app/ -RUN pip install -r requirements.txt -COPY . /app/ -EXPOSE 8000 -CMD ["python", "manage.py", "runserver"] \ No newline at end of file diff --git a/services/learn_old/__init__.py b/services/learn_old/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/api/__init__.py b/services/learn_old/api/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/api/asgi.py b/services/learn_old/api/asgi.py deleted file mode 100644 index 44cf6d6..0000000 --- a/services/learn_old/api/asgi.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -ASGI config for learn project. - -It exposes the ASGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ -""" - -import os - -from django.core.asgi import get_asgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'learn.settings') - -application = get_asgi_application() diff --git a/services/learn_old/api/settings.py b/services/learn_old/api/settings.py deleted file mode 100644 index e06f094..0000000 --- a/services/learn_old/api/settings.py +++ /dev/null @@ -1,168 +0,0 @@ -""" -Django settings for learn project. - -Generated by 'django-admin startproject' using Django 3.2.7. - -For more information on this file, see -https://docs.djangoproject.com/en/3.2/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/3.2/ref/settings/ -""" -import os -from pathlib import Path -from dotenv import load_dotenv - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent -BASEDIR = os.path.abspath(os.path.dirname(__file__)) -load_dotenv(dotenv_path=os.path.join(BASEDIR, '..', '..', '..', '.env', 'learn.env'), verbose=True) - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-7w1^54-vsngif7^!x4y^qvdxl0n600u=a3_-7p6_-_ezq4kgmf' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -# Application definition - -INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'rest_framework', - 'corsheaders', - 'learn', - 'django.contrib.staticfiles', - 'storages', -] - -REST_FRAMEWORK = { - 'EXCEPTION_HANDLER': 'learn.api.exceptions.custom_exception_handler.custom_exception_handler' -} - -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'corsheaders.middleware.CorsMiddleware', - 'django.middleware.common.CommonMiddleware', -] - -ALLOWED_HOSTS_STRING = os.getenv('ALLOWED_HOSTS') - -ALLOWED_HOSTS = ALLOWED_HOSTS_STRING.split(',') - -if ALLOWED_HOSTS.count('*') > 0: - CORS_ALLOW_ALL_ORIGINS = True -else: - CORS_ALLOWED_ORIGINS = ALLOWED_HOSTS - -ROOT_URLCONF = 'learn.api.urls' - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], - }, - }, -] - -WSGI_APPLICATION = 'api.wsgi.application' - - -# Database -# https://docs.djangoproject.com/en/3.2/ref/settings/#databases - -DB_DATABASE_NAME = os.getenv('DB_DATABASE_NAME') -DB_USER = os.getenv('DB_USER') -DB_PASSWORD = os.getenv('DB_PASSWORD') -DB_HOST = os.getenv('DB_HOST') -DB_PORT = os.getenv('DB_PORT') - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': DB_DATABASE_NAME, - 'USER': DB_USER, - 'PASSWORD': DB_PASSWORD, - 'HOST': DB_HOST, - 'PORT': DB_PORT, - } -} - - -# Password validation -# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators - -AUTH_PASSWORD_VALIDATORS = [ - { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', - }, -] - - -# Internationalization -# https://docs.djangoproject.com/en/3.2/topics/i18n/ - -LANGUAGE_CODE = 'en-us' - -TIME_ZONE = 'UTC' - -USE_I18N = True - -USE_L10N = True - -USE_TZ = True - - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/3.2/howto/static-files/ - -STATIC_URL = '/static/' - -# Default primary key field type -# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field - -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' - -AWS_IAM_ACCESS_KEY_ID = os.getenv('AWS_IAM_ACCESS_KEY_ID') -AWS_IAM_SECRET_ACCESS_KEY = os.getenv('AWS_IAM_SECRET_ACCESS_KEY') -AWS_BUCKET_NAME = os.getenv('AWS_BUCKET_NAME') -AWS_REGION_NAME = os.getenv('AWS_REGION_NAME') - -AWS_ACCESS_KEY_ID = AWS_IAM_ACCESS_KEY_ID -AWS_SECRET_ACCESS_KEY = AWS_IAM_SECRET_ACCESS_KEY -AWS_STORAGE_BUCKET_NAME = AWS_BUCKET_NAME -AWS_S3_SIGNATURE_VERSION = 's3v4' -AWS_S3_REGION_NAME = AWS_REGION_NAME -AWS_S3_FILE_OVERWRITE = True -AWS_DEFAULT_ACL = None -AWS_S3_VERIFY = True -DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' diff --git a/services/learn_old/api/wsgi.py b/services/learn_old/api/wsgi.py deleted file mode 100644 index 31b8881..0000000 --- a/services/learn_old/api/wsgi.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -WSGI config for learn project. - -It exposes the WSGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/ -""" - -import os - -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'learn.settings') - -application = get_wsgi_application() diff --git a/services/learn_old/learn/__init__.py b/services/learn_old/learn/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/admin.py b/services/learn_old/learn/admin.py deleted file mode 100644 index ea5d68b..0000000 --- a/services/learn_old/learn/admin.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.contrib import admin - -# Register your models here. diff --git a/services/learn_old/learn/api/__init__.py b/services/learn_old/learn/api/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/api/auth/authenticated_user_context.py b/services/learn_old/learn/api/auth/authenticated_user_context.py deleted file mode 100644 index d7613d3..0000000 --- a/services/learn_old/learn/api/auth/authenticated_user_context.py +++ /dev/null @@ -1,18 +0,0 @@ -import uuid - -from django.core.exceptions import BadRequest -from django.http import HttpRequest - -from learn.domain.users.value_objects.user_id import UserId - - -class AuthenticatedUserContext: - def __init__(self, request: HttpRequest): - self.request = request - - @property - def user_id(self) -> UserId: - user_id = self.request.headers['Userid'] - if not user_id: - raise BadRequest("Request is authenticated but user id is missing.") - return UserId(uuid.UUID(user_id)) diff --git a/services/learn_old/learn/api/constants.py b/services/learn_old/learn/api/constants.py deleted file mode 100644 index 15daf53..0000000 --- a/services/learn_old/learn/api/constants.py +++ /dev/null @@ -1 +0,0 @@ -COMMON_ROUTE_URL = '' diff --git a/services/learn_old/learn/api/decorators/in_roles_decorator.py b/services/learn_old/learn/api/decorators/in_roles_decorator.py deleted file mode 100644 index a9c6891..0000000 --- a/services/learn_old/learn/api/decorators/in_roles_decorator.py +++ /dev/null @@ -1,21 +0,0 @@ -import json -from functools import wraps, partial -from typing import List - -from rest_framework.exceptions import PermissionDenied - -from learn.api.enums.roles_enum import Role - - -def in_roles(roles: List[Role]): - def decorator(function): - @wraps(function) - def wrap(request, *args, **kwargs): - roles_from_request = json.loads(request.headers['Userroles']) - role_from_request = roles_from_request['Name'] - for role in roles: - if role_from_request == str(role.value): - return function(request, *args, **kwargs) - raise PermissionDenied("Permission denied") - return wrap - return decorator diff --git a/services/learn_old/learn/api/enums/roles_enum.py b/services/learn_old/learn/api/enums/roles_enum.py deleted file mode 100644 index a383f7f..0000000 --- a/services/learn_old/learn/api/enums/roles_enum.py +++ /dev/null @@ -1,7 +0,0 @@ -from enum import Enum - - -class Role(Enum): - STUDENT = "Student" - TEACHER = "Teacher" - ADMIN = "Admin" diff --git a/services/learn_old/learn/api/exceptions/custom_exception_handler.py b/services/learn_old/learn/api/exceptions/custom_exception_handler.py deleted file mode 100644 index c35f910..0000000 --- a/services/learn_old/learn/api/exceptions/custom_exception_handler.py +++ /dev/null @@ -1,22 +0,0 @@ -import logging - -from pydantic import ValidationError -from rest_framework.exceptions import PermissionDenied -from rest_framework.response import Response -from rest_framework import status - -from django.core.exceptions import ObjectDoesNotExist - - -def custom_exception_handler(ex, context): - logging.log(logging.ERROR, f'Exception occurred: {repr(ex)}') - if isinstance(ex, ObjectDoesNotExist): - err_data = {'message': 'Object Does Not Exist'} - return Response(err_data, status=status.HTTP_404_NOT_FOUND) - if isinstance(ex, ValidationError): - err_data = {'message': 'Validation Error', 'details': ex.errors()} - return Response(err_data, status=status.HTTP_400_BAD_REQUEST) - if isinstance(ex, PermissionDenied): - err_data = {'message': 'Permission Error'} - return Response(err_data, status=status.HTTP_403_FORBIDDEN) - return Response({'message': 'Unhandled Error', 'details': ex.args}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) diff --git a/services/learn_old/learn/api/options/rabbit_mq_options.py b/services/learn_old/learn/api/options/rabbit_mq_options.py deleted file mode 100644 index be44477..0000000 --- a/services/learn_old/learn/api/options/rabbit_mq_options.py +++ /dev/null @@ -1,9 +0,0 @@ -import os - - -class RabbitMQOptions: - def __init__(self): - self.host_name = os.getenv('RABBITMQ_HOST_NAME') - self.port = os.getenv('RABBITMQ_PORT') - self.queue_name = os.getenv('RABBITMQ_QUEUE_NAME') - self.broker_name = os.getenv('RABBITMQ_BROKER_NAME') diff --git a/services/learn_old/learn/api/serializers/dto_serializer.py b/services/learn_old/learn/api/serializers/dto_serializer.py deleted file mode 100644 index f3c4ee5..0000000 --- a/services/learn_old/learn/api/serializers/dto_serializer.py +++ /dev/null @@ -1,15 +0,0 @@ -from typing import Type - -from pydantic import BaseModel - - -class DtoSerializer: - @staticmethod - def from_json(data, DtoClass: Type[BaseModel]): - return DtoClass(**data) - - @staticmethod - def to_dict(data, many=False): - if many: - return list(map(lambda x: x.dict(), data)) - return data.dict() diff --git a/services/learn_old/learn/api/urls.py b/services/learn_old/learn/api/urls.py deleted file mode 100644 index 3729d08..0000000 --- a/services/learn_old/learn/api/urls.py +++ /dev/null @@ -1,6 +0,0 @@ -from .views.groups_view import groups_urlpatterns -from .views.posts_view import posts_urlpatterns -from .views.students_view import students_group_urlpatterns -from .views.users_view import users_urlpatterns - -urlpatterns = [] + posts_urlpatterns + users_urlpatterns + groups_urlpatterns + students_group_urlpatterns diff --git a/services/learn_old/learn/api/views/groups_view.py b/services/learn_old/learn/api/views/groups_view.py deleted file mode 100644 index 4ecf7f4..0000000 --- a/services/learn_old/learn/api/views/groups_view.py +++ /dev/null @@ -1,24 +0,0 @@ -from django.http import JsonResponse -from django.urls import path -from rest_framework.decorators import api_view, permission_classes - -from learn.api.constants import COMMON_ROUTE_URL -from learn.api.serializers.dto_serializer import DtoSerializer -from learn.application.groups.create_group.create_group_command import CreateGroupCommandDto, CreateGroupCommand -from learn.application.groups.get_groups.get_groups_query import GetGroupsQuery - - -@api_view(["GET", "POST"]) -def process_groups(request): - if request.method == "GET": - groups = GetGroupsQuery().execute() - return JsonResponse(DtoSerializer.to_dict(groups, many=True), safe=False) - elif request.method == "POST": - dto = DtoSerializer.from_json(request.data, CreateGroupCommandDto) - group = CreateGroupCommand().execute(dto) - return JsonResponse(DtoSerializer.to_dict(group), safe=False) - - -groups_urlpatterns = [ - path(f'{COMMON_ROUTE_URL}groups', process_groups), -] diff --git a/services/learn_old/learn/api/views/posts_view.py b/services/learn_old/learn/api/views/posts_view.py deleted file mode 100644 index 53f778b..0000000 --- a/services/learn_old/learn/api/views/posts_view.py +++ /dev/null @@ -1,29 +0,0 @@ -from django.http import JsonResponse, HttpResponse -from django.urls import path -from rest_framework.decorators import api_view, permission_classes - -from learn.api.auth.authenticated_user_context import AuthenticatedUserContext -from learn.api.constants import COMMON_ROUTE_URL -from learn.api.decorators.in_roles_decorator import in_roles -from learn.api.enums.roles_enum import Role -from learn.api.serializers.dto_serializer import DtoSerializer -from learn.application.posts.create_post.create_post_command import CreatePostCommand, CreatePostCommandDto -from learn.application.posts.get_posts.get_posts_query import GetPostsQuery - - -@api_view(['GET', 'POST']) -@in_roles([Role.STUDENT, Role.ADMIN, Role.TEACHER]) -def process_posts(request): - if request.method == "GET": - print('user_id', AuthenticatedUserContext(request).user_id) - posts = GetPostsQuery().execute() - return JsonResponse(DtoSerializer.to_dict(posts, many=True), safe=False) - elif request.method == "POST": - dto = DtoSerializer.from_json(request.data, CreatePostCommandDto) - post = CreatePostCommand().execute(dto) - return JsonResponse(DtoSerializer.to_dict(post), safe=False) - - -posts_urlpatterns = [ - path(f'{COMMON_ROUTE_URL}posts', process_posts), -] diff --git a/services/learn_old/learn/api/views/students_view.py b/services/learn_old/learn/api/views/students_view.py deleted file mode 100644 index 620c5e9..0000000 --- a/services/learn_old/learn/api/views/students_view.py +++ /dev/null @@ -1,18 +0,0 @@ -from django.http import JsonResponse -from django.urls import path -from rest_framework.decorators import api_view - -from learn.api.constants import COMMON_ROUTE_URL -from learn.api.serializers.dto_serializer import DtoSerializer -from learn.application.students.get_students.get_students_query import GetStudentsQuery - - -@api_view(["GET"]) -def get_students(request): - students = GetStudentsQuery().execute() - return JsonResponse(DtoSerializer.to_dict(students, many=True), safe=False) - - -students_group_urlpatterns = [ - path(f'{COMMON_ROUTE_URL}students', get_students), -] diff --git a/services/learn_old/learn/api/views/users_view.py b/services/learn_old/learn/api/views/users_view.py deleted file mode 100644 index 0c8f34a..0000000 --- a/services/learn_old/learn/api/views/users_view.py +++ /dev/null @@ -1,38 +0,0 @@ -from django.http import JsonResponse, QueryDict -from django.urls import path -from rest_framework.decorators import api_view, permission_classes - -from learn.api.constants import COMMON_ROUTE_URL -from learn.api.serializers.dto_serializer import DtoSerializer -from learn.application.users.create_user.create_user_command import CreateUserCommand, CreateUserCommandDto -from learn.application.users.create_user.upload_user_avatar_command import CreateUserAvatarCommandDto, \ - CreateUserAvatarCommand -from learn.application.users.get_users.get_user_by_id_query import GetUserByIdQuery -from learn.application.users.get_users.get_users_query import GetUsersQuery - - -@api_view(["GET", "POST", "PUT"]) -def process_users(request): - if request.method == "GET": - users = GetUsersQuery().execute() - return JsonResponse(DtoSerializer.to_dict(users, many=True), safe=False) - elif request.method == "POST": - dto = DtoSerializer.from_json(request.data, CreateUserCommandDto) - user = CreateUserCommand().execute(dto) - return JsonResponse(DtoSerializer.to_dict(user), safe=False) - elif request.method == "PUT": - dto = DtoSerializer.from_json(request.data.dict(), CreateUserAvatarCommandDto) - CreateUserAvatarCommand().execute(dto) - return JsonResponse({"status": "success"}, status=200, safe=False) - - -@api_view(["GET"]) -def process_user_by_id(request, id): - user = GetUserByIdQuery().execute(id) - return JsonResponse(DtoSerializer.to_dict(user), safe=False) - - -users_urlpatterns = [ - path(f'{COMMON_ROUTE_URL}users', process_users), - path(f'{COMMON_ROUTE_URL}users//', process_user_by_id), -] diff --git a/services/learn_old/learn/application/__init__.py b/services/learn_old/learn/application/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/application/groups/create_group/create_group_command.py b/services/learn_old/learn/application/groups/create_group/create_group_command.py deleted file mode 100644 index dd3524b..0000000 --- a/services/learn_old/learn/application/groups/create_group/create_group_command.py +++ /dev/null @@ -1,23 +0,0 @@ -import inject -from pydantic import BaseModel, StrictStr, StrictInt - -from learn.application.groups.dtos.group_dto import GroupDto -from learn.application.groups.group_mapper import GroupMapper -from learn.domain.groups.entities.group import Group -from learn.infrastructure.repositories.group_repository import GroupRepository - - -class CreateGroupCommandDto(BaseModel): - name: StrictStr - formed_at_year: StrictInt - - -class CreateGroupCommand: - @inject.autoparams() - def __init__(self, group_repository: GroupRepository): - self.group_repository = group_repository - - def execute(self, dto: CreateGroupCommandDto) -> GroupDto: - group = Group.create_new_group(name=dto.name, formed_at_year=dto.formed_at_year) - self.group_repository.save_group(group) - return GroupMapper.to_dto(group) diff --git a/services/learn_old/learn/application/groups/dtos/group_dto.py b/services/learn_old/learn/application/groups/dtos/group_dto.py deleted file mode 100644 index abfd51f..0000000 --- a/services/learn_old/learn/application/groups/dtos/group_dto.py +++ /dev/null @@ -1,7 +0,0 @@ -from pydantic import BaseModel - - -class GroupDto(BaseModel): - id: str - name: str - formed_at_year: int diff --git a/services/learn_old/learn/application/groups/get_groups/get_groups_query.py b/services/learn_old/learn/application/groups/get_groups/get_groups_query.py deleted file mode 100644 index 060815a..0000000 --- a/services/learn_old/learn/application/groups/get_groups/get_groups_query.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import List - -import inject - -from learn.application.groups.dtos.group_dto import GroupDto -from learn.application.groups.group_mapper import GroupMapper -from learn.infrastructure.repositories.group_repository import GroupRepository - - -class GetGroupsQuery: - @inject.autoparams() - def __init__(self, group_repository: GroupRepository): - self.group_repository = group_repository - - def execute(self) -> List[GroupDto]: - groups = self.group_repository.get_groups() - return GroupMapper.to_dtos(groups) diff --git a/services/learn_old/learn/application/groups/group_mapper.py b/services/learn_old/learn/application/groups/group_mapper.py deleted file mode 100644 index b193914..0000000 --- a/services/learn_old/learn/application/groups/group_mapper.py +++ /dev/null @@ -1,18 +0,0 @@ -from typing import List - -from learn.application.groups.dtos.group_dto import GroupDto -from learn.domain.groups.entities.group import Group - - -class GroupMapper: - @staticmethod - def to_dto(entity: Group) -> GroupDto: - return GroupDto( - id=entity.id.value, - name=entity.name, - formed_at_year=entity.formed_at_year.value - ) - - @staticmethod - def to_dtos(entities: List[Group]) -> List[GroupDto]: - return list(map(GroupMapper.to_dto, entities)) diff --git a/services/learn_old/learn/application/posts/create_post/create_post_command.py b/services/learn_old/learn/application/posts/create_post/create_post_command.py deleted file mode 100644 index 5f35c03..0000000 --- a/services/learn_old/learn/application/posts/create_post/create_post_command.py +++ /dev/null @@ -1,31 +0,0 @@ -import inject -from pydantic import BaseModel, StrictStr - -from learn.application.posts.dtos.post_dto import PostDto -from learn.application.posts.post_mapper import PostMapper -from learn.domain.posts.entities.post import Post -from learn.infrastructure.repositories.post_repository import PostRepository -from learn.infrastructure.repositories.user_repository import UserRepository - - -class CreatePostCommandDto(BaseModel): - name: StrictStr - content: StrictStr - - -class CreatePostCommand: - @inject.autoparams() - def __init__(self, post_repository: PostRepository, user_repository: UserRepository): - self.post_repository = post_repository - self.user_repository = user_repository - - def execute(self, dto: CreatePostCommandDto) -> PostDto: - # TODO: replace by authenticated user - created_by = self.user_repository.get_users()[0] - post = Post.create_new_post( - name=dto.name, - content=dto.content, - created_by=created_by - ) - self.post_repository.save_post(post) - return PostMapper.to_dto(post) diff --git a/services/learn_old/learn/application/posts/domain_event_handlers/post_created_domain_event_handler.py b/services/learn_old/learn/application/posts/domain_event_handlers/post_created_domain_event_handler.py deleted file mode 100644 index 9762a9b..0000000 --- a/services/learn_old/learn/application/posts/domain_event_handlers/post_created_domain_event_handler.py +++ /dev/null @@ -1,13 +0,0 @@ -import inject - -from learn.domain.posts.events.post_created_domain_event import PostCreatedDomainEvent -from learn.infrastructure.repositories.student_repository import StudentRepository - - -class PostCreatedDomainEventHandler: - @inject.autoparams() - def __init__(self, repo: StudentRepository): - self.repo = repo - - def handle(self, event: PostCreatedDomainEvent): - print(f"PostCreatedDomainEventHandler {event.id.value} len: {len(self.repo.get_students())}") diff --git a/services/learn_old/learn/application/posts/dtos/post_dto.py b/services/learn_old/learn/application/posts/dtos/post_dto.py deleted file mode 100644 index ee95188..0000000 --- a/services/learn_old/learn/application/posts/dtos/post_dto.py +++ /dev/null @@ -1,6 +0,0 @@ -from pydantic import BaseModel - - -class PostDto(BaseModel): - id: str - name: str diff --git a/services/learn_old/learn/application/posts/get_posts/get_posts_query.py b/services/learn_old/learn/application/posts/get_posts/get_posts_query.py deleted file mode 100644 index 21b4ff7..0000000 --- a/services/learn_old/learn/application/posts/get_posts/get_posts_query.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import List - -import inject - -from learn.application.posts.dtos.post_dto import PostDto -from learn.application.posts.post_mapper import PostMapper -from learn.infrastructure.repositories.post_repository import PostRepository - - -class GetPostsQuery: - @inject.autoparams() - def __init__(self, post_repository: PostRepository): - self.post_repository = post_repository - - def execute(self) -> List[PostDto]: - posts = self.post_repository.get_posts() - return PostMapper.to_dtos(posts) diff --git a/services/learn_old/learn/application/posts/post_mapper.py b/services/learn_old/learn/application/posts/post_mapper.py deleted file mode 100644 index 1c50d18..0000000 --- a/services/learn_old/learn/application/posts/post_mapper.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import List - -from learn.application.posts.dtos.post_dto import PostDto -from learn.domain.posts.entities.post import Post - - -class PostMapper: - @staticmethod - def to_dto(entity: Post) -> PostDto: - return PostDto( - id=entity.id.value, - name=entity.name - ) - - @staticmethod - def to_dtos(entities: List[Post]) -> List[PostDto]: - return list(map(PostMapper.to_dto, entities)) diff --git a/services/learn_old/learn/application/students/__init__.py b/services/learn_old/learn/application/students/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/application/students/dtos/__init__.py b/services/learn_old/learn/application/students/dtos/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/application/students/dtos/student_dto.py b/services/learn_old/learn/application/students/dtos/student_dto.py deleted file mode 100644 index c4c3a1f..0000000 --- a/services/learn_old/learn/application/students/dtos/student_dto.py +++ /dev/null @@ -1,9 +0,0 @@ -from pydantic import BaseModel - -from learn.application.groups.dtos.group_dto import GroupDto -from learn.application.users.dtos.user_dto import UserDto - - -class StudentDto(BaseModel): - user: UserDto - group: GroupDto diff --git a/services/learn_old/learn/application/students/get_students/get_students_query.py b/services/learn_old/learn/application/students/get_students/get_students_query.py deleted file mode 100644 index 2c4eb2d..0000000 --- a/services/learn_old/learn/application/students/get_students/get_students_query.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import List - -import inject - -from learn.application.students.dtos.student_dto import StudentDto -from learn.application.students.student_mapper import StudentMapper -from learn.infrastructure.repositories.student_repository import StudentRepository - - -class GetStudentsQuery: - @inject.autoparams() - def __init__(self, student_repository: StudentRepository): - self.student_repository = student_repository - - def execute(self) -> List[StudentDto]: - students = self.student_repository.get_students() - return StudentMapper.to_dtos(students) diff --git a/services/learn_old/learn/application/students/student_mapper.py b/services/learn_old/learn/application/students/student_mapper.py deleted file mode 100644 index 94c4826..0000000 --- a/services/learn_old/learn/application/students/student_mapper.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import List - -from learn.application.groups.group_mapper import GroupMapper -from learn.application.students.dtos.student_dto import StudentDto -from learn.application.users.user_mapper import UserMapper -from learn.domain.students.entities.student import Student - - -class StudentMapper: - @staticmethod - def to_dto(entity: Student) -> StudentDto: - return StudentDto( - user=UserMapper.to_dto(entity.user), - group=GroupMapper.to_dto(entity.group) - ) - - @staticmethod - def to_dtos(entities: List[Student]) -> List[StudentDto]: - return list(map(StudentMapper.to_dto, entities)) diff --git a/services/learn_old/learn/application/users/create_user/create_user_command.py b/services/learn_old/learn/application/users/create_user/create_user_command.py deleted file mode 100644 index 98362f1..0000000 --- a/services/learn_old/learn/application/users/create_user/create_user_command.py +++ /dev/null @@ -1,24 +0,0 @@ -import inject -from pydantic import BaseModel, StrictStr, EmailStr - - -from learn.application.users.dtos.user_dto import UserDto -from learn.application.users.user_mapper import UserMapper -from learn.domain.users.entities.user import User -from learn.infrastructure.repositories.user_repository import UserRepository - - -class CreateUserCommandDto(BaseModel): - name: StrictStr - email: EmailStr - - -class CreateUserCommand: - @inject.autoparams() - def __init__(self, user_repository: UserRepository): - self.user_repository = user_repository - - def execute(self, dto: CreateUserCommandDto) -> UserDto: - user = User.create_new_user(name=dto.name, email=dto.email) - self.user_repository.save_user(user) - return UserMapper.to_dto(user) diff --git a/services/learn_old/learn/application/users/create_user/upload_user_avatar_command.py b/services/learn_old/learn/application/users/create_user/upload_user_avatar_command.py deleted file mode 100644 index 7a45dc9..0000000 --- a/services/learn_old/learn/application/users/create_user/upload_user_avatar_command.py +++ /dev/null @@ -1,28 +0,0 @@ -import inject -from django.core.files.uploadedfile import InMemoryUploadedFile - -from pydantic import BaseModel - -from learn.infrastructure.aws.aws_s3_service import AwsS3Service -from learn.infrastructure.repositories.user_repository import UserRepository - - -class CreateUserAvatarCommandDto(BaseModel): - id: str - avatar: InMemoryUploadedFile - - class Config: - arbitrary_types_allowed = True - - -class CreateUserAvatarCommand: - @inject.autoparams() - def __init__(self, user_repository: UserRepository): - self.user_repository = user_repository - - def execute(self, dto: CreateUserAvatarCommandDto) -> None: - user = self.user_repository.get_user_by_id(dto.id) - url = AwsS3Service.upload_replace_file(dto.id, user.avatar, dto.avatar) - user.set_avatar(url) - # TODO: use update_user in future(when roles will be done) - self.user_repository.update_user_avatar(user) diff --git a/services/learn_old/learn/application/users/dtos/user_dto.py b/services/learn_old/learn/application/users/dtos/user_dto.py deleted file mode 100644 index a75b07f..0000000 --- a/services/learn_old/learn/application/users/dtos/user_dto.py +++ /dev/null @@ -1,7 +0,0 @@ -from pydantic import BaseModel - - -class UserDto(BaseModel): - id: str - name: str - email: str diff --git a/services/learn_old/learn/application/users/get_users/get_user_by_id_query.py b/services/learn_old/learn/application/users/get_users/get_user_by_id_query.py deleted file mode 100644 index 98512a3..0000000 --- a/services/learn_old/learn/application/users/get_users/get_user_by_id_query.py +++ /dev/null @@ -1,15 +0,0 @@ -import inject - -from learn.application.users.dtos.user_dto import UserDto -from learn.application.users.user_mapper import UserMapper -from learn.infrastructure.repositories.user_repository import UserRepository - - -class GetUserByIdQuery: - @inject.autoparams() - def __init__(self, user_repository: UserRepository): - self.user_repository = user_repository - - def execute(self, id) -> UserDto: - user = self.user_repository.get_user_by_id(id) - return UserMapper.to_dto(user) diff --git a/services/learn_old/learn/application/users/get_users/get_users_query.py b/services/learn_old/learn/application/users/get_users/get_users_query.py deleted file mode 100644 index 5ca812c..0000000 --- a/services/learn_old/learn/application/users/get_users/get_users_query.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import List - -import inject - -from learn.application.users.dtos.user_dto import UserDto -from learn.application.users.user_mapper import UserMapper -from learn.infrastructure.repositories.user_repository import UserRepository - - -class GetUsersQuery: - @inject.autoparams() - def __init__(self, user_repository: UserRepository): - self.user_repository = user_repository - - def execute(self) -> List[UserDto]: - users = self.user_repository.get_users() - return UserMapper.to_dtos(users) diff --git a/services/learn_old/learn/application/users/integration_events/user_created/user_created_integration_event.py b/services/learn_old/learn/application/users/integration_events/user_created/user_created_integration_event.py deleted file mode 100644 index fbf4cf9..0000000 --- a/services/learn_old/learn/application/users/integration_events/user_created/user_created_integration_event.py +++ /dev/null @@ -1,20 +0,0 @@ -import datetime -import uuid -from typing import Any, List - -from pydantic import BaseModel - -from learn.infrastructure.event_bus.integration.integration_event import IntegrationEvent - - -class UserCreatedIntegrationEvent(BaseModel, IntegrationEvent): - id: uuid.UUID - occurred_on: datetime.datetime - user_id: uuid.UUID - name: str - email: str - roles: List[str] - - @staticmethod - def type(): - return "UserCreatedIntegrationEvent" diff --git a/services/learn_old/learn/application/users/integration_events/user_created/user_created_integration_event_handler.py b/services/learn_old/learn/application/users/integration_events/user_created/user_created_integration_event_handler.py deleted file mode 100644 index aaa46d8..0000000 --- a/services/learn_old/learn/application/users/integration_events/user_created/user_created_integration_event_handler.py +++ /dev/null @@ -1,34 +0,0 @@ -from typing import Dict - -import inject - -from learn.application.users.integration_events.user_created.user_created_integration_event import \ - UserCreatedIntegrationEvent -from learn.domain.users.entities.user import User -from learn.domain.users.value_objects.user_id import UserId -from learn.infrastructure.event_bus.integration.integration_event_handler import IntegrationEventHandler -from learn.infrastructure.repositories.role_repository import RoleRepository -from learn.infrastructure.repositories.user_repository import UserRepository - - -class UserCreatedIntegrationEventHandler(IntegrationEventHandler): - @inject.autoparams() - def __init__(self, user_repository: UserRepository, role_repository: RoleRepository): - self._user_repository = user_repository - self._role_repository = role_repository - - def handle(self, event: Dict): - print("process") - event = UserCreatedIntegrationEvent(**event) - - roles = self._role_repository.get_roles() - user_roles = [role for role in roles if role.name in event.roles] - - user = User.initialize( - id=UserId(event.user_id), - name=event.name, - email=event.email, - roles=user_roles - ) - - self._user_repository.create(user) diff --git a/services/learn_old/learn/application/users/user_mapper.py b/services/learn_old/learn/application/users/user_mapper.py deleted file mode 100644 index f10de27..0000000 --- a/services/learn_old/learn/application/users/user_mapper.py +++ /dev/null @@ -1,18 +0,0 @@ -from typing import List - -from learn.application.users.dtos.user_dto import UserDto -from learn.domain.users.entities.user import User - - -class UserMapper: - @staticmethod - def to_dto(entity: User) -> UserDto: - return UserDto( - id=entity.id.value, - name=entity.name, - email=entity.email.value - ) - - @staticmethod - def to_dtos(entities: List[User]) -> List[UserDto]: - return list(map(UserMapper.to_dto, entities)) diff --git a/services/learn_old/learn/apps.py b/services/learn_old/learn/apps.py deleted file mode 100644 index 54cce12..0000000 --- a/services/learn_old/learn/apps.py +++ /dev/null @@ -1,69 +0,0 @@ -import inject -from django.apps import AppConfig - - -class LearnConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'learn' - - def ready(self): - inject.configure_once(self.configure) - self._subscribe_to_domain_events() - - def configure(self, binder): - self._configure_infrastructure(binder) - self._configure_application(binder) - - def _configure_infrastructure(self, binder): - # Options - from learn.api.options.rabbit_mq_options import RabbitMQOptions - binder.bind_to_constructor(RabbitMQOptions, RabbitMQOptions) - - # Event Bus - from learn.infrastructure.event_bus.integration.integration_event_bus import IntegrationEventBus - from learn.infrastructure.event_bus.domain.domain_event_bus import DomainEventBus - from learn.infrastructure.event_bus.integration.rabbitmq.rabbitmq_integration_event_bus import \ - RabbitMQIntegrationEventBus - from learn.infrastructure.event_bus.integration.rabbitmq.rabbit_mq_connection_factory import RabbitMQConnectionFactory - binder.bind_to_constructor(RabbitMQConnectionFactory, RabbitMQConnectionFactory) - rabbit_mq_connection_factory = RabbitMQConnectionFactory(RabbitMQOptions()) - rabbit_mq_integration_event_bus = RabbitMQIntegrationEventBus(rabbit_mq_connection_factory) - binder.bind_to_constructor(IntegrationEventBus, rabbit_mq_integration_event_bus) - binder.bind_to_constructor(DomainEventBus, DomainEventBus) - - # Repositories - from learn.infrastructure.repositories.group_repository import GroupRepository - from learn.infrastructure.repositories.post_repository import PostRepository - from learn.infrastructure.repositories.student_repository import StudentRepository - from learn.infrastructure.repositories.user_repository import UserRepository - from learn.infrastructure.repositories.role_repository import RoleRepository - binder.bind_to_constructor(PostRepository, PostRepository) - binder.bind_to_constructor(UserRepository, UserRepository) - binder.bind_to_constructor(StudentRepository, StudentRepository) - binder.bind_to_constructor(GroupRepository, GroupRepository) - binder.bind_to_constructor(RoleRepository, RoleRepository) - - def _configure_application(self, binder): - # Domain Events - from learn.domain.common.domain_events import DomainEventHandler - from learn.domain.posts.events.post_created_domain_event import PostCreatedDomainEvent - from learn.application.posts.domain_event_handlers.post_created_domain_event_handler import \ - PostCreatedDomainEventHandler - binder.bind_to_constructor(DomainEventHandler[PostCreatedDomainEvent], PostCreatedDomainEventHandler) - - # Integration Events - from learn.infrastructure.event_bus.integration.integration_event_handler import IntegrationEventHandler - from learn.application.users.integration_events.user_created.user_created_integration_event import \ - UserCreatedIntegrationEvent - from learn.application.users.integration_events.user_created.user_created_integration_event_handler import \ - UserCreatedIntegrationEventHandler - binder.bind_to_constructor(IntegrationEventHandler["UserCreatedIntegrationEvent"], UserCreatedIntegrationEventHandler) - - def _subscribe_to_domain_events(self): - from learn.application.users.integration_events.user_created.user_created_integration_event import \ - UserCreatedIntegrationEvent - from learn.infrastructure.event_bus.integration.rabbitmq.rabbitmq_integration_event_bus import \ - RabbitMQIntegrationEventBus - integration_event_bus = inject.get_injector().get_instance(RabbitMQIntegrationEventBus) - integration_event_bus.start_consuming() - integration_event_bus.subscribe(UserCreatedIntegrationEvent.type()) diff --git a/services/learn_old/learn/domain/__init__.py b/services/learn_old/learn/domain/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/common/base_typed_id_value_object.py b/services/learn_old/learn/domain/common/base_typed_id_value_object.py deleted file mode 100644 index 50c5f1d..0000000 --- a/services/learn_old/learn/domain/common/base_typed_id_value_object.py +++ /dev/null @@ -1,10 +0,0 @@ -import uuid - - -class BaseTypedIdValueObject: - def __init__(self, value: uuid.UUID): - self._value = value - - @property - def value(self) -> str: - return self._value.hex diff --git a/services/learn_old/learn/domain/common/domain_events.py b/services/learn_old/learn/domain/common/domain_events.py deleted file mode 100644 index 77a8d5c..0000000 --- a/services/learn_old/learn/domain/common/domain_events.py +++ /dev/null @@ -1,33 +0,0 @@ -import uuid -from abc import ABC, abstractmethod -from typing import List, TypeVar, Generic, Type, Callable - - -T = TypeVar("T") -E = TypeVar('E') - - -class DomainEvent: - def __init__(self): - self.id = uuid.uuid4() - - -class DomainEventHandler(ABC, Generic[E]): - @abstractmethod - def handle(self, event: E): - raise NotImplementedError() - - -class WithDomainEventsMixin: - def __init__(self) -> None: - self._pending_domain_events: List[DomainEvent] = [] - - def add_domain_event(self, event: DomainEvent) -> None: - self._pending_domain_events.append(event) - - @property - def domain_events(self) -> List[DomainEvent]: - return self._pending_domain_events[:] - - def clear_domain_events(self) -> None: - self._pending_domain_events.clear() diff --git a/services/learn_old/learn/domain/groups/__init__.py b/services/learn_old/learn/domain/groups/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/groups/entities/__init__.py b/services/learn_old/learn/domain/groups/entities/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/groups/entities/group.py b/services/learn_old/learn/domain/groups/entities/group.py deleted file mode 100644 index fb42572..0000000 --- a/services/learn_old/learn/domain/groups/entities/group.py +++ /dev/null @@ -1,26 +0,0 @@ -import uuid - -from learn.domain.groups.entities.student_group import StudentGroup -from learn.domain.groups.value_objects.group_id import GroupId -from learn.domain.groups.value_objects.student_group_id import StudentGroupId -from learn.domain.groups.value_objects.year import Year -from learn.domain.users.value_objects.user_id import UserId - - -class Group: - def __init__(self, id: GroupId, name: str, formed_at_year: Year): - self.id = id - self.name = name - self.formed_at_year = formed_at_year - - @classmethod - def create_new_group(cls, name: str, formed_at_year: int) -> "Group": - id = GroupId(value=uuid.uuid4()) - formed_at_year = Year(value=formed_at_year) - group = Group(id, name, formed_at_year) - return group - - def add_student(self, student_user_id: UserId) -> "StudentGroup": - id = StudentGroupId(value=uuid.uuid4()) - student_group = StudentGroup(id, student_user_id, self.id) - return student_group \ No newline at end of file diff --git a/services/learn_old/learn/domain/groups/entities/student_group.py b/services/learn_old/learn/domain/groups/entities/student_group.py deleted file mode 100644 index 7e1ed84..0000000 --- a/services/learn_old/learn/domain/groups/entities/student_group.py +++ /dev/null @@ -1,10 +0,0 @@ -from learn.domain.groups.value_objects.group_id import GroupId -from learn.domain.groups.value_objects.student_group_id import StudentGroupId -from learn.domain.users.value_objects.user_id import UserId - - -class StudentGroup: - def __init__(self, id: StudentGroupId, user_id: UserId, group_id: GroupId): - self.id = id - self.user_id = user_id - self.group_id = group_id diff --git a/services/learn_old/learn/domain/groups/value_objects/__init__.py b/services/learn_old/learn/domain/groups/value_objects/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/groups/value_objects/group_id.py b/services/learn_old/learn/domain/groups/value_objects/group_id.py deleted file mode 100644 index 53580cd..0000000 --- a/services/learn_old/learn/domain/groups/value_objects/group_id.py +++ /dev/null @@ -1,8 +0,0 @@ -import uuid - -from learn.domain.common.base_typed_id_value_object import BaseTypedIdValueObject - - -class GroupId(BaseTypedIdValueObject): - def __init__(self, value: uuid.UUID): - super().__init__(value) diff --git a/services/learn_old/learn/domain/groups/value_objects/student_group_id.py b/services/learn_old/learn/domain/groups/value_objects/student_group_id.py deleted file mode 100644 index 376f5fd..0000000 --- a/services/learn_old/learn/domain/groups/value_objects/student_group_id.py +++ /dev/null @@ -1,8 +0,0 @@ -import uuid - -from learn.domain.common.base_typed_id_value_object import BaseTypedIdValueObject - - -class StudentGroupId(BaseTypedIdValueObject): - def __init__(self, value: uuid.UUID): - super().__init__(value) diff --git a/services/learn_old/learn/domain/groups/value_objects/year.py b/services/learn_old/learn/domain/groups/value_objects/year.py deleted file mode 100644 index c4764b8..0000000 --- a/services/learn_old/learn/domain/groups/value_objects/year.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.core.exceptions import ValidationError - - -class Year: - def __init__(self, value: int): - if 2010 < value < 2100: - self.value = value - else: - raise ValidationError("Invalid year") diff --git a/services/learn_old/learn/domain/posts/__init__.py b/services/learn_old/learn/domain/posts/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/posts/entities/__init__.py b/services/learn_old/learn/domain/posts/entities/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/posts/entities/post.py b/services/learn_old/learn/domain/posts/entities/post.py deleted file mode 100644 index 7db1898..0000000 --- a/services/learn_old/learn/domain/posts/entities/post.py +++ /dev/null @@ -1,30 +0,0 @@ -from datetime import datetime -import uuid - -from learn.domain.common.domain_events import WithDomainEventsMixin -from learn.domain.posts.events.post_created_domain_event import PostCreatedDomainEvent -from learn.domain.posts.value_objects.post_id import PostId -from learn.domain.users.entities.user import User - - -class Post(WithDomainEventsMixin): - def __init__(self, id: PostId, name: str, content: str, created_at: datetime.timestamp, created_by: User): - super().__init__() - self.id = id - self.name = name - self.content = content - self.created_by = created_by - self.created_at = created_at - - # Just an example. TODO: remove - def get_public_url(self, base_posts_url: str) -> str: - return f'{base_posts_url}/{self.id}' - - @classmethod - def create_new_post(cls, name: str, content: str, created_by: User) -> "Post": - id = PostId(value=uuid.uuid4()) - post = Post(id, name, content, datetime.now(), created_by) - post.add_domain_event(PostCreatedDomainEvent( - id - )) - return post diff --git a/services/learn_old/learn/domain/posts/events/post_created_domain_event.py b/services/learn_old/learn/domain/posts/events/post_created_domain_event.py deleted file mode 100644 index 7a76617..0000000 --- a/services/learn_old/learn/domain/posts/events/post_created_domain_event.py +++ /dev/null @@ -1,9 +0,0 @@ -from dataclasses import dataclass - -from learn.domain.common.domain_events import DomainEvent -from learn.domain.posts.value_objects.post_id import PostId - - -@dataclass(frozen=True) -class PostCreatedDomainEvent(DomainEvent): - id: PostId diff --git a/services/learn_old/learn/domain/posts/value_objects/__init__.py b/services/learn_old/learn/domain/posts/value_objects/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/posts/value_objects/post_id.py b/services/learn_old/learn/domain/posts/value_objects/post_id.py deleted file mode 100644 index c5fd531..0000000 --- a/services/learn_old/learn/domain/posts/value_objects/post_id.py +++ /dev/null @@ -1,8 +0,0 @@ -import uuid - -from learn.domain.common.base_typed_id_value_object import BaseTypedIdValueObject - - -class PostId(BaseTypedIdValueObject): - def __init__(self, value: uuid.UUID): - super().__init__(value) diff --git a/services/learn_old/learn/domain/students/__init__.py b/services/learn_old/learn/domain/students/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/students/entities/__init__.py b/services/learn_old/learn/domain/students/entities/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/students/entities/student.py b/services/learn_old/learn/domain/students/entities/student.py deleted file mode 100644 index a75a582..0000000 --- a/services/learn_old/learn/domain/students/entities/student.py +++ /dev/null @@ -1,8 +0,0 @@ -from learn.domain.groups.entities.group import Group -from learn.domain.users.entities.user import User - - -class Student: - def __init__(self, user: User, group: Group): - self.user = user - self.group = group diff --git a/services/learn_old/learn/domain/students/value_objects/__init__.py b/services/learn_old/learn/domain/students/value_objects/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/students/value_objects/student_id.py b/services/learn_old/learn/domain/students/value_objects/student_id.py deleted file mode 100644 index daa1dab..0000000 --- a/services/learn_old/learn/domain/students/value_objects/student_id.py +++ /dev/null @@ -1,8 +0,0 @@ -import uuid - -from learn.domain.common.base_typed_id_value_object import BaseTypedIdValueObject - - -class StudentId(BaseTypedIdValueObject): - def __init__(self, value: uuid.UUID): - super().__init__(value) diff --git a/services/learn_old/learn/domain/users/__init__.py b/services/learn_old/learn/domain/users/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/users/entities/__init__.py b/services/learn_old/learn/domain/users/entities/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/users/entities/role.py b/services/learn_old/learn/domain/users/entities/role.py deleted file mode 100644 index 274872c..0000000 --- a/services/learn_old/learn/domain/users/entities/role.py +++ /dev/null @@ -1,22 +0,0 @@ -import uuid - - -from learn.domain.users.value_objects.role_id import RoleId - - -# IMPORTANT: this class is temporary. It should be replaced with enum value object -class Role: - def __init__(self, id: RoleId, name: str): - self.id = id - self.name = name - - @classmethod - def create_new_role(cls, name: str) -> "Role": - id = RoleId(value=uuid.uuid4()) - role = Role(id, name) - return role - - @classmethod - def initialize(cls, id: RoleId, name: str) -> "Role": - role = Role(id, name) - return role diff --git a/services/learn_old/learn/domain/users/entities/user.py b/services/learn_old/learn/domain/users/entities/user.py deleted file mode 100644 index 98b67e0..0000000 --- a/services/learn_old/learn/domain/users/entities/user.py +++ /dev/null @@ -1,31 +0,0 @@ -import uuid -from typing import List - -from learn.domain.users.entities.role import Role -from learn.domain.users.value_objects.email import Email -from learn.domain.users.value_objects.user_id import UserId - - -class User: - def __init__(self, id: UserId, name: str, email: Email, roles: List[Role], avatar: str = None): - self.id = id - self.name = name - self.email = email - self.roles = roles - self.avatar = avatar - - @classmethod - def create_new_user(cls, name: str, email: str, roles: List[Role]) -> "User": - id = UserId(value=uuid.uuid4()) - email = Email(value=email) - user = User(id, name, email, roles) - return user - - @classmethod - def initialize(cls, id: UserId, name: str, email: str, roles: List[Role]) -> "User": - email = Email(value=email) - user = User(id, name, email, roles) - return user - - def set_avatar(self, avatar: str) -> None: - self.avatar = avatar diff --git a/services/learn_old/learn/domain/users/value_objects/__init__.py b/services/learn_old/learn/domain/users/value_objects/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/domain/users/value_objects/email.py b/services/learn_old/learn/domain/users/value_objects/email.py deleted file mode 100644 index db07c4e..0000000 --- a/services/learn_old/learn/domain/users/value_objects/email.py +++ /dev/null @@ -1,4 +0,0 @@ -class Email: - def __init__(self, value: str): - self.value = value - # TODO: add validation diff --git a/services/learn_old/learn/domain/users/value_objects/role_id.py b/services/learn_old/learn/domain/users/value_objects/role_id.py deleted file mode 100644 index d825cf2..0000000 --- a/services/learn_old/learn/domain/users/value_objects/role_id.py +++ /dev/null @@ -1,8 +0,0 @@ -import uuid - -from learn.domain.common.base_typed_id_value_object import BaseTypedIdValueObject - - -class RoleId(BaseTypedIdValueObject): - def __init__(self, value: uuid.UUID): - super().__init__(value) diff --git a/services/learn_old/learn/domain/users/value_objects/user_id.py b/services/learn_old/learn/domain/users/value_objects/user_id.py deleted file mode 100644 index 8766582..0000000 --- a/services/learn_old/learn/domain/users/value_objects/user_id.py +++ /dev/null @@ -1,8 +0,0 @@ -import uuid - -from learn.domain.common.base_typed_id_value_object import BaseTypedIdValueObject - - -class UserId(BaseTypedIdValueObject): - def __init__(self, value: uuid.UUID): - super().__init__(value) diff --git a/services/learn_old/learn/infrastructure/__init__.py b/services/learn_old/learn/infrastructure/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/infrastructure/aws/aws_s3_service.py b/services/learn_old/learn/infrastructure/aws/aws_s3_service.py deleted file mode 100644 index ddfa5ed..0000000 --- a/services/learn_old/learn/infrastructure/aws/aws_s3_service.py +++ /dev/null @@ -1,16 +0,0 @@ -import os - -from django.core.files.storage import default_storage - - -class AwsS3Service: - @staticmethod - def upload_replace_file(id, prevUrl, file): - AWS_BUCKET_NAME = os.getenv('AWS_BUCKET_NAME') - AWS_REGION_NAME = os.getenv('AWS_REGION_NAME') - if prevUrl is not None: - path = prevUrl.replace(f"https://s3-{AWS_REGION_NAME}.amazonaws.com/{AWS_BUCKET_NAME}/", "") - default_storage.delete(path) - filepath = default_storage.save("media/" + id + "/" + file.name, file) - fileUrl = f"https://s3-{AWS_REGION_NAME}.amazonaws.com/{AWS_BUCKET_NAME}/{filepath}" - return fileUrl diff --git a/services/learn_old/learn/infrastructure/event_bus/__init__.py b/services/learn_old/learn/infrastructure/event_bus/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/infrastructure/event_bus/domain/__init__.py b/services/learn_old/learn/infrastructure/event_bus/domain/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/infrastructure/event_bus/domain/domain_event_bus.py b/services/learn_old/learn/infrastructure/event_bus/domain/domain_event_bus.py deleted file mode 100644 index 6be21cf..0000000 --- a/services/learn_old/learn/infrastructure/event_bus/domain/domain_event_bus.py +++ /dev/null @@ -1,19 +0,0 @@ -import logging -from typing import List - -import inject - -from learn.domain.common.domain_events import DomainEvent, DomainEventHandler - - -class DomainEventBus: - def process_domain_event(self, event: DomainEvent) -> None: - logging.info(f"start processing domain event, {event}") - injector = inject.get_injector() - handler = injector.get_instance(DomainEventHandler[type(event)]) - handler.handle(event) - logging.info(f"end processing domain event, {event}") - - def process_domain_events(self, events: List[DomainEvent]) -> None: - for event in events: - self.process_domain_event(event) diff --git a/services/learn_old/learn/infrastructure/event_bus/integration/__init__.py b/services/learn_old/learn/infrastructure/event_bus/integration/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/infrastructure/event_bus/integration/integration_event.py b/services/learn_old/learn/infrastructure/event_bus/integration/integration_event.py deleted file mode 100644 index f14be7a..0000000 --- a/services/learn_old/learn/infrastructure/event_bus/integration/integration_event.py +++ /dev/null @@ -1,12 +0,0 @@ -import datetime -import uuid - - -class IntegrationEvent: - def __init__(self): - self.id = uuid.uuid4() - self.occurred_on = datetime.datetime.now() - - @staticmethod - def type(): - raise NotImplementedError() diff --git a/services/learn_old/learn/infrastructure/event_bus/integration/integration_event_bus.py b/services/learn_old/learn/infrastructure/event_bus/integration/integration_event_bus.py deleted file mode 100644 index dd890ca..0000000 --- a/services/learn_old/learn/infrastructure/event_bus/integration/integration_event_bus.py +++ /dev/null @@ -1,12 +0,0 @@ -from abc import ABC, abstractmethod -from typing import TypeVar - -from learn.infrastructure.event_bus.integration.integration_event_handler import IntegrationEventHandler - -E = TypeVar('E') - - -class IntegrationEventBus(ABC): - @abstractmethod - def subscribe(self, event: E): - raise NotImplementedError() diff --git a/services/learn_old/learn/infrastructure/event_bus/integration/integration_event_handler.py b/services/learn_old/learn/infrastructure/event_bus/integration/integration_event_handler.py deleted file mode 100644 index 94db41b..0000000 --- a/services/learn_old/learn/infrastructure/event_bus/integration/integration_event_handler.py +++ /dev/null @@ -1,10 +0,0 @@ -from abc import ABC, abstractmethod -from typing import TypeVar, Generic, Dict - -E = TypeVar('E') - - -class IntegrationEventHandler(ABC, Generic[E]): - @abstractmethod - def handle(self, event: Dict): - raise NotImplementedError() \ No newline at end of file diff --git a/services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/__init__.py b/services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/rabbit_mq_connection_factory.py b/services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/rabbit_mq_connection_factory.py deleted file mode 100644 index dd12330..0000000 --- a/services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/rabbit_mq_connection_factory.py +++ /dev/null @@ -1,24 +0,0 @@ -import inject -import pika -from pika.adapters.blocking_connection import BlockingChannel - -from learn.api.options.rabbit_mq_options import RabbitMQOptions - - -class RabbitMQConnectionFactory: - @inject.autoparams() - def __init__(self, options: RabbitMQOptions): - self._options = options - self._connection = pika.BlockingConnection(pika.ConnectionParameters(host=options.host_name, port=options.port)) - - @property - def connection(self): - return self._connection - - @property - def broker_name(self): - return self._options.broker_name - - @property - def queue_name(self): - return self._options.queue_name diff --git a/services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/rabbitmq_integration_event_bus.py b/services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/rabbitmq_integration_event_bus.py deleted file mode 100644 index bb6f58f..0000000 --- a/services/learn_old/learn/infrastructure/event_bus/integration/rabbitmq/rabbitmq_integration_event_bus.py +++ /dev/null @@ -1,123 +0,0 @@ -import asyncio -import json -import logging -from typing import TypeVar -import humps -import threading -import inject -from pika import spec -from pika.adapters.blocking_connection import BlockingChannel -from apscheduler.schedulers.background import BackgroundScheduler - - -from learn.infrastructure.event_bus.integration.integration_event_bus import IntegrationEventBus -from learn.infrastructure.event_bus.integration.integration_event_handler import IntegrationEventHandler -from learn.infrastructure.event_bus.integration.rabbitmq.rabbit_mq_connection_factory import RabbitMQConnectionFactory - - -E = TypeVar('E') - - -class RabbitMQIntegrationEventBus(IntegrationEventBus): - @inject.autoparams() - def __init__(self, connection_factory: RabbitMQConnectionFactory): - self._connection_factory = connection_factory - self._consumer_channel = self._create_consumer_channel() - - def _create_consumer_channel(self) -> BlockingChannel: - channel = self._connection_factory.connection.channel() - - channel.exchange_declare( - exchange=self._connection_factory.broker_name, - exchange_type='direct' - ) - - channel.queue_declare( - queue=self._connection_factory.queue_name, - durable=True, - exclusive=False, - auto_delete=False - ) - - channel.basic_qos(prefetch_count=1) - - return channel - - def subscribe(self, event_type: str): - self._consumer_channel.queue_bind( - queue=self._connection_factory.queue_name, - exchange=self._connection_factory.broker_name, - routing_key=event_type - ) - - def _start_consuming(self): - self._consumer_channel.basic_consume( - queue=self._connection_factory.queue_name, - auto_ack=False, - on_message_callback=self._process_integration_event - ) - - self._consumer_channel.start_consuming() - # a = self._consumer_channel.consume( - # queue=self._connection_factory.queue_name, - # ) - - def _process_integration_events(self): - print("processing integration events") - self._connection_factory.connection.process_data_events() - - def start_consuming(self): - # consumer_thread = threading.Thread(target=self._start_consuming) - # consumer_thread.start() - self._consumer_channel.basic_consume( - queue=self._connection_factory.queue_name, - auto_ack=False, - on_message_callback=self._process_integration_event - ) - - queue_polling_job = BackgroundScheduler() - queue_polling_job.add_job(self._process_integration_events, 'interval', seconds=10) - queue_polling_job.start() - - # self._consumer_channel.start_consuming() - - # def start_consuming(self): - # self._consumer_channel.basic_consume( - # queue=self._connection_factory.queue_name, - # auto_ack=False, - # on_message_callback=self._process_integration_event - # ) - # - # queue_polling_job = threading.Timer(10.0, self._fetch_and_process_integration_events) - # queue_polling_job.start() - # self._consumer_channel.start_consuming() - - def _process_integration_event(self, ch, method: spec.Basic.Deliver, properties: spec.BasicProperties, body: bytes): - try: - event_type = method.routing_key - event = humps.depascalize(json.loads(body.decode("utf-8", "ignore"))) - print(f"start processing integration event, {event}") - injector = inject.get_injector() - handler = injector.get_instance(IntegrationEventHandler[event_type]) - handler.handle(event) - self._consumer_channel.basic_ack(delivery_tag=method.delivery_tag, multiple=False) - print(f"end processing integration event, {event}") - except Exception as e: - print(f"exception during integration event processing {e}") - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, traceback): - self._connection_factory.connection.close() - - -# class RabbitMQIntegrationEventBusStarter: -# def __init__(self, event_bus: RabbitMQIntegrationEventBus): -# self._event_bus = event_bus -# -# def start(self): -# consumer_thread = threading.Thread(target=self._event_bus._start_consuming) -# consumer_thread.start() - - diff --git a/services/learn_old/learn/infrastructure/repositories/group_repository.py b/services/learn_old/learn/infrastructure/repositories/group_repository.py deleted file mode 100644 index 44c088f..0000000 --- a/services/learn_old/learn/infrastructure/repositories/group_repository.py +++ /dev/null @@ -1,36 +0,0 @@ -from typing import List - -from learn.domain.groups.entities.group import Group -from learn.domain.groups.value_objects.group_id import GroupId -from learn.domain.groups.value_objects.year import Year -from learn.models import Group as GroupModel - - -class GroupRepository: - def __init__(self): - pass - - @staticmethod - def model_to_entity(group_model: GroupModel) -> Group: - id = GroupId(group_model.id) - formed_at_year = Year(group_model.formed_at_year) - return Group( - id=id, - name=group_model.name, - formed_at_year=formed_at_year - ) - - def get_groups(self) -> List[Group]: - groups = GroupModel.objects.all() - return list(map(self.model_to_entity, groups)) - - def save_group(self, group: Group) -> None: - GroupModel.objects.update_or_create( - id=group.id.value, - name=group.name, - formed_at_year=group.formed_at_year.value - ) - - # TODO: implement. Left as an example - def add_student(self) -> None: - raise NotImplementedError() diff --git a/services/learn_old/learn/infrastructure/repositories/post_repository.py b/services/learn_old/learn/infrastructure/repositories/post_repository.py deleted file mode 100644 index f59fd05..0000000 --- a/services/learn_old/learn/infrastructure/repositories/post_repository.py +++ /dev/null @@ -1,51 +0,0 @@ -from typing import List - -import inject - -from learn.domain.posts.entities.post import Post -from learn.domain.posts.value_objects.post_id import PostId -from learn.infrastructure.event_bus.domain.domain_event_bus import DomainEventBus -from learn.infrastructure.repositories.user_repository import UserRepository -from learn.models import Post as PostModel - - -class PostRepository: - @inject.autoparams() - def __init__(self, event_bus: DomainEventBus): - self.event_bus = event_bus - - @staticmethod - def model_to_entity(model: PostModel) -> Post: - return Post( - id=PostId(model.id), - name=model.name, - content=model.content, - created_at=model.created_at, - created_by=UserRepository.model_to_entity(model.created_by) - ) - - @staticmethod - def entity_to_model(entity: PostModel) -> PostModel: - return PostModel( - id=entity.id.value, - name=entity.name, - content=entity.content, - created_at=entity.created_at, - created_by=UserRepository.entity_to_model(entity.created_by) - ) - - def get_posts(self) -> List[Post]: - posts = PostModel.objects.all() - return list(map(self.model_to_entity, posts)) - - def save_post(self, post: Post) -> None: - self.event_bus.process_domain_events(post.domain_events) - post.clear_domain_events() - post_to_save = self.entity_to_model(post) - PostModel.objects.update_or_create( - id=post_to_save.id, - name=post_to_save.name, - content=post_to_save.content, - created_at=post_to_save.created_at, - created_by=post_to_save.created_by - ) diff --git a/services/learn_old/learn/infrastructure/repositories/role_repository.py b/services/learn_old/learn/infrastructure/repositories/role_repository.py deleted file mode 100644 index 968459b..0000000 --- a/services/learn_old/learn/infrastructure/repositories/role_repository.py +++ /dev/null @@ -1,33 +0,0 @@ -from typing import List - -from learn.domain.users.entities.role import Role -from learn.domain.users.value_objects.role_id import RoleId -from learn.models import Role as RoleModel - - -class RoleRepository: - @staticmethod - def model_to_entity(model: RoleModel) -> Role: - return Role( - id=RoleId(model.id), - name=model.name, - ) - - @staticmethod - def model_to_entities(models: List[RoleModel]) -> List[Role]: - return list(map(lambda r: RoleRepository.model_to_entity(r), models)) - - @staticmethod - def entity_to_model(entity: Role) -> RoleModel: - return RoleModel( - id=entity.id.value, - name=entity.name, - ) - - @staticmethod - def entity_to_models(entities: List[Role]) -> List[RoleModel]: - return list(map(lambda r: RoleRepository.entity_to_model(r), entities)) - - def get_roles(self) -> List[Role]: - roles = RoleModel.objects.all() - return list(map(self.model_to_entity, roles)) diff --git a/services/learn_old/learn/infrastructure/repositories/student_repository.py b/services/learn_old/learn/infrastructure/repositories/student_repository.py deleted file mode 100644 index b684ad5..0000000 --- a/services/learn_old/learn/infrastructure/repositories/student_repository.py +++ /dev/null @@ -1,21 +0,0 @@ -from typing import List, Callable - -from learn.domain.students.entities.student import Student -from learn.infrastructure.repositories.group_repository import GroupRepository -from learn.infrastructure.repositories.user_repository import UserRepository -from learn.models import User as UserModel, Group as GroupModel, Student as StudentModel - - -class StudentRepository: - @staticmethod - def model_to_entity(user_model: UserModel, group_model: GroupModel) -> Student: - return Student( - user=UserRepository.model_to_entity(user_model), - group=GroupRepository.model_to_entity(group_model) - ) - - def get_students(self) -> List[Student]: - # TODO: filter by role - students = StudentModel.objects.all() - map_lambda: Callable[[StudentModel], Student] = lambda sd: self.model_to_entity(s.user, s.group) - return list(map(map_lambda, students)) diff --git a/services/learn_old/learn/infrastructure/repositories/user_repository.py b/services/learn_old/learn/infrastructure/repositories/user_repository.py deleted file mode 100644 index 4c72770..0000000 --- a/services/learn_old/learn/infrastructure/repositories/user_repository.py +++ /dev/null @@ -1,56 +0,0 @@ -from typing import List - -from django.forms import model_to_dict - -from learn.domain.users.entities.user import User -from learn.domain.users.value_objects.user_id import UserId -from learn.domain.users.value_objects.email import Email -from learn.infrastructure.repositories.role_repository import RoleRepository -from learn.models import User as UserModel, Role as RoleModel - - -class UserRepository: - @staticmethod - def model_to_entity(model: UserModel, roles: List[RoleModel]) -> User: - return User( - id=UserId(model.id), - name=model.name, - email=Email(model.email), - avatar=model.avatar, - roles=RoleRepository.model_to_entities(roles) - ) - - @staticmethod - def entity_to_model(entity: User) -> UserModel: - return UserModel( - id=entity.id.value, - name=entity.name, - email=entity.email.value, - avatar=entity.avatar, - ) - - def get_users(self) -> List[User]: - users = UserModel.objects.all() - # TODO: create model_to_entities - return list(map(self.model_to_entity, users)) - - def get_user_by_id(self, id) -> User: - user = UserModel.objects.get(id=id) - # TODO: fetch roles - return self.model_to_entity(user, []) - - def create(self, user: User) -> None: - user_model = self.entity_to_model(user) - user_model.save() - roles1 = RoleModel.objects.filter(name__in=list(map(lambda r: r.name, user.roles))) - for role in roles1: - user_model.roles.add(role) - # UserRoleModel.objects.create(list(map(lambda r: UserRoleModel())) RoleRepository.entity_to_models(user.roles)) - - def update_user(self, user: User) -> None: - # TODO: update roles - UserModel.objects.update_or_create(model_to_dict(self.entity_to_model(user)), id=user.id.value) - - # Temp function - def update_user_avatar(self, user: User) -> None: - UserModel.objects.filter(id=user.id.value).update(avatar=user.avatar) diff --git a/services/learn_old/learn/management/commands/runserver.py b/services/learn_old/learn/management/commands/runserver.py deleted file mode 100644 index 24a8457..0000000 --- a/services/learn_old/learn/management/commands/runserver.py +++ /dev/null @@ -1,37 +0,0 @@ -import _thread -import os -import signal -import sys -import logging - - -from django.core.management.commands.runserver import Command as RunServer - - -def quit(*args): - print('Quit app') - sys.exit(1) - - -signal.signal(signal.SIGINT, quit) -signal.signal(signal.SIGTERM, quit) - - -class Command(RunServer): - # def run(self, *args, **options): - # if os.environ.get('RUN_MAIN') != 'true': - # self.stdout.write('About to start running') - # try: - # super(Command, self).run(**options) - # except Exception as e: - # _thread.interrupt_main() - # logging.exception("An exception was thrown!") - # raise - - def inner_run(self, *args, **options): - try: - super().inner_run(*args, **options) - except Exception as e: - _thread.interrupt_main() - logging.exception("An exception was thrown!") - raise diff --git a/services/learn_old/learn/management/commands/seed.py b/services/learn_old/learn/management/commands/seed.py deleted file mode 100644 index 76a7548..0000000 --- a/services/learn_old/learn/management/commands/seed.py +++ /dev/null @@ -1,185 +0,0 @@ -from django.utils import timezone -import uuid - -from django.core.management.base import BaseCommand -import random -import logging - -from learn.models import Post, User, Group, Student, Role - -logger = logging.getLogger(__name__) - - -# python manage.py seed - - -class Command(BaseCommand): - help = "seed database for testing and development." - - def handle(self, *args, **options): - self.stdout.write('seeding data...') - run_seed(self) - self.stdout.write('done.') - - -def clear_data(): - logger.info("Delete Posts") - Post.objects.all().delete() - - logger.info("Delete Students") - Student.objects.all().delete() - - logger.info("Delete Users") - User.objects.all().delete() - - logger.info("Delete Roles") - Role.objects.all().delete() - - logger.info("Delete Groups") - Group.objects.all().delete() - - -def create_roles(): - logger.info("Creating roles") - - role = Role( - id=uuid.uuid4(), - name="Admin", - ) - role.save() - - role = Role( - id=uuid.uuid4(), - name="Student", - ) - role.save() - - role = Role( - id=uuid.uuid4(), - name="Teacher", - ) - role.save() - - logger.info("Roles created") - - -def create_users(): - logger.info("Creating users") - - role = Role.objects.get(name="Admin") - user = User( - id="11111111-1111-1111-1111-111111111111", - name="Admin", - email="admin@gmail.com", - avatar=None - ) - user.save() - user.roles.set([role]) - - role = Role.objects.get(name="Teacher") - user = User( - id="22222222-2222-2222-2222-222222222222", - name="Teacher", - email="teacher@gmail.com", - avatar=None - ) - user.save() - user.roles.set([role]) - - role = Role.objects.get(name="Student") - user = User( - id="33333333-3333-3333-3333-333333333333", - name="Student", - email="student@gmail.com", - avatar=None - ) - user.save() - user.roles.set([role]) - - logger.info("Users created") - - -def create_posts(): - logger.info("Creating posts") - - created_by = User.objects.get(id="22222222-2222-2222-2222-222222222222") - post = Post( - id=uuid.uuid4(), - name="1st lab", - content="First lab will be available at the end of today", - created_at=timezone.now(), - created_by=created_by - ) - post.save() - - created_by = User.objects.get(id="22222222-2222-2222-2222-222222222222") - post = Post( - id=uuid.uuid4(), - name="Pair link", - content="Pair link is here", - created_at=timezone.now(), - created_by=created_by - ) - post.save() - - created_by = User.objects.get(id="22222222-2222-2222-2222-222222222222") - post = Post( - id=uuid.uuid4(), - name="Dopka(", - content="Vseh na dopku =(", - created_at=timezone.now(), - created_by=created_by - ) - post.save() - - logger.info("Posts created") - - -def create_groups(): - logger.info("Creating groups") - group = Group( - id=uuid.uuid4(), - name="IP-96", - formed_at_year=2019 - ) - group.save() - - group = Group( - id=uuid.uuid4(), - name="IP-92", - formed_at_year=2019 - ) - group.save() - - group = Group( - id=uuid.uuid4(), - name="IP-91", - formed_at_year=2019 - ) - group.save() - - logger.info("Groups created") - - -def create_students(): - logger.info("Creating students") - - user = User.objects.get(id="33333333-3333-3333-3333-333333333333") - group = Group.objects.get(name="IP-96") - student = Student( - id=uuid.uuid4(), - user=user, - group=group - ) - student.save() - - logger.info("Students created") - - -def run_seed(self): - clear_data() - create_roles() - create_users() - create_groups() - create_students() - create_posts() diff --git a/services/learn_old/learn/migrations/0001_initial.py b/services/learn_old/learn/migrations/0001_initial.py deleted file mode 100644 index 416afa0..0000000 --- a/services/learn_old/learn/migrations/0001_initial.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.2.4 on 2021-09-16 20:01 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='Post', - fields=[ - ('id', models.UUIDField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=100)), - ], - ), - ] diff --git a/services/learn_old/learn/migrations/0002_user.py b/services/learn_old/learn/migrations/0002_user.py deleted file mode 100644 index eec9d92..0000000 --- a/services/learn_old/learn/migrations/0002_user.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.2.4 on 2021-09-21 17:42 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('learn', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='User', - fields=[ - ('id', models.UUIDField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=100)), - ('email', models.CharField(max_length=100)), - ], - ), - ] diff --git a/services/learn_old/learn/migrations/0003_add_content_and_user_reference_to_post.py b/services/learn_old/learn/migrations/0003_add_content_and_user_reference_to_post.py deleted file mode 100644 index dd1e58b..0000000 --- a/services/learn_old/learn/migrations/0003_add_content_and_user_reference_to_post.py +++ /dev/null @@ -1,47 +0,0 @@ -# Generated by Django 3.2.4 on 2021-09-29 17:51 - -from django.db import migrations, models -import django.db.models.deletion -import django.utils.timezone -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('learn', '0002_user'), - ] - - operations = [ - migrations.AddField( - model_name='post', - name='content', - field=models.TextField(default=''), - preserve_default=False, - ), - migrations.AddField( - model_name='post', - name='created_at', - field=models.DateTimeField(default=django.utils.timezone.now), - preserve_default=False, - ), - migrations.AddField( - model_name='post', - name='user', - field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='learn.user'), - preserve_default=False, - ), - migrations.AlterField( - model_name='user', - name='id', - field=models.UUIDField(default=uuid.UUID('40e3b8fb-319d-4f86-96d6-fd05e444df8b'), primary_key=True, serialize=False), - ), - migrations.AlterModelTable( - name='post', - table='post', - ), - migrations.AlterModelTable( - name='user', - table='user', - ), - ] diff --git a/services/learn_old/learn/migrations/0003_group_and_studentGroup.py b/services/learn_old/learn/migrations/0003_group_and_studentGroup.py deleted file mode 100644 index fa1197d..0000000 --- a/services/learn_old/learn/migrations/0003_group_and_studentGroup.py +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by Django 3.2.4 on 2021-10-01 11:17 - -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('learn', '0003_add_content_and_user_reference_to_post'), - ] - - operations = [ - migrations.CreateModel( - name='Group', - fields=[ - ('id', models.UUIDField(default=uuid.UUID('1e25c2d7-097c-4d4e-aad2-966d5fceab9f'), primary_key=True, serialize=False)), - ('name', models.CharField(max_length=100)), - ('formed_at_year', models.IntegerField()), - ], - ), - migrations.AlterField( - model_name='user', - name='id', - field=models.UUIDField(default=uuid.UUID('151c0946-e986-4308-936b-9651f3b1fadf'), primary_key=True, serialize=False), - ), - migrations.CreateModel( - name='StudentGroup', - fields=[ - ('id', models.UUIDField(default=uuid.UUID('d47495a9-d97d-4570-b921-26d811eebda1'), primary_key=True, serialize=False)), - ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.group')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.user')), - ], - ), - ] diff --git a/services/learn_old/learn/migrations/0004_student_group_user_id_unique.py b/services/learn_old/learn/migrations/0004_student_group_user_id_unique.py deleted file mode 100644 index 9e604f4..0000000 --- a/services/learn_old/learn/migrations/0004_student_group_user_id_unique.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 3.2.4 on 2021-10-02 16:03 - -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('learn', '0003_group_and_studentGroup'), - ] - - operations = [ - migrations.AlterField( - model_name='group', - name='id', - field=models.UUIDField(default=uuid.UUID('498539ca-23e0-428f-b1a0-72dcb918d22c'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='studentgroup', - name='id', - field=models.UUIDField(default=uuid.UUID('1723f841-af74-4a8f-8842-307d42bb8ef0'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='studentgroup', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.user', unique=True), - ), - migrations.AlterField( - model_name='user', - name='id', - field=models.UUIDField(default=uuid.UUID('9bc85eca-d97a-4713-bf33-74a5a60b9f5e'), primary_key=True, serialize=False), - ), - ] diff --git a/services/learn_old/learn/migrations/0005_meta.py b/services/learn_old/learn/migrations/0005_meta.py deleted file mode 100644 index 663577c..0000000 --- a/services/learn_old/learn/migrations/0005_meta.py +++ /dev/null @@ -1,37 +0,0 @@ -# Generated by Django 3.2.4 on 2021-10-03 10:16 - -from django.db import migrations, models -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('learn', '0004_student_group_user_id_unique'), - ] - - operations = [ - migrations.AlterField( - model_name='group', - name='id', - field=models.UUIDField(default=uuid.UUID('0039ab4b-271a-401c-901f-371e9ff73ce5'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='studentgroup', - name='id', - field=models.UUIDField(default=uuid.UUID('ffac9fd6-4070-4ee0-8e9e-75f0bb7990f8'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='user', - name='id', - field=models.UUIDField(default=uuid.UUID('d55a08c8-e4fc-40da-80bf-ed1108eee24e'), primary_key=True, serialize=False), - ), - migrations.AlterModelTable( - name='group', - table='group', - ), - migrations.AlterModelTable( - name='studentgroup', - table='student_group', - ), - ] diff --git a/services/learn_old/learn/migrations/0006_switched_to_one_to_one.py b/services/learn_old/learn/migrations/0006_switched_to_one_to_one.py deleted file mode 100644 index 74ab3c3..0000000 --- a/services/learn_old/learn/migrations/0006_switched_to_one_to_one.py +++ /dev/null @@ -1,40 +0,0 @@ -# Generated by Django 3.2.4 on 2021-10-04 17:13 - -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('learn', '0005_meta'), - ] - - operations = [ - migrations.AlterField( - model_name='group', - name='id', - field=models.UUIDField(default=uuid.UUID('00448f59-673f-402b-8014-f264e302be16'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='studentgroup', - name='group', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='learn.group'), - ), - migrations.AlterField( - model_name='studentgroup', - name='id', - field=models.UUIDField(default=uuid.UUID('688786a5-a7cb-4b7e-8727-c07511de2fbc'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='studentgroup', - name='user', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='learn.user'), - ), - migrations.AlterField( - model_name='user', - name='id', - field=models.UUIDField(default=uuid.UUID('8e93029b-c1fa-48d4-95fb-a9f18b68e939'), primary_key=True, serialize=False), - ), - ] diff --git a/services/learn_old/learn/migrations/0007_rename_post_user.py b/services/learn_old/learn/migrations/0007_rename_post_user.py deleted file mode 100644 index 4fd10a7..0000000 --- a/services/learn_old/learn/migrations/0007_rename_post_user.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 3.2.4 on 2021-10-04 19:32 - -from django.db import migrations, models -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('learn', '0006_switched_to_one_to_one'), - ] - - operations = [ - migrations.RenameField( - model_name='post', - old_name='user', - new_name='created_by', - ), - migrations.AlterField( - model_name='group', - name='id', - field=models.UUIDField(default=uuid.UUID('06d8ee6c-15d3-4275-abc3-e2b1474a251c'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='studentgroup', - name='id', - field=models.UUIDField(default=uuid.UUID('c407344b-2071-4ec0-904d-1053462a3b2c'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='user', - name='id', - field=models.UUIDField(default=uuid.UUID('9ef3d516-4251-413e-a13d-d204fe698b6d'), primary_key=True, serialize=False), - ), - ] diff --git a/services/learn_old/learn/migrations/0008_auto_20211011_2128.py b/services/learn_old/learn/migrations/0008_auto_20211011_2128.py deleted file mode 100644 index 60300c2..0000000 --- a/services/learn_old/learn/migrations/0008_auto_20211011_2128.py +++ /dev/null @@ -1,176 +0,0 @@ -# Generated by Django 3.2.4 on 2021-10-11 18:28 - -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('learn', '0007_rename_post_user'), - ] - - operations = [ - migrations.CreateModel( - name='Chat', - fields=[ - ('id', models.UUIDField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=100)), - ('created_at', models.DateTimeField()), - ], - options={ - 'db_table': 'chat', - }, - ), - migrations.CreateModel( - name='Course', - fields=[ - ('id', models.UUIDField(primary_key=True, serialize=False)), - ('name', models.CharField(max_length=100)), - ('created_at', models.DateTimeField()), - ], - options={ - 'db_table': 'course', - }, - ), - migrations.CreateModel( - name='CourseAssignment', - fields=[ - ('id', models.UUIDField(primary_key=True, serialize=False)), - ('deadline_at', models.DateTimeField()), - ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.course')), - ], - options={ - 'db_table': 'course_assignment', - }, - ), - migrations.CreateModel( - name='CourseAssignmentSubmission', - fields=[ - ('id', models.UUIDField(primary_key=True, serialize=False)), - ('submitted_at', models.DateTimeField()), - ('content', models.TextField()), - ('assignment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.courseassignment')), - ], - options={ - 'db_table': 'course_assignment_submission', - }, - ), - migrations.CreateModel( - name='CourseAssignmentSubmissionReview', - fields=[ - ('id', models.UUIDField(primary_key=True, serialize=False)), - ('reviewed_at', models.DateTimeField()), - ('mark', models.IntegerField()), - ], - options={ - 'db_table': 'course_assignment_submission_review', - }, - ), - migrations.CreateModel( - name='Message', - fields=[ - ('id', models.UUIDField(primary_key=True, serialize=False)), - ('content', models.TextField()), - ('created_at', models.DateTimeField()), - ('chat', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.chat')), - ], - options={ - 'db_table': 'message', - }, - ), - migrations.CreateModel( - name='Role', - fields=[ - ('id', models.UUIDField(default=uuid.UUID('68962706-0e28-4bdf-bce4-13c3e384dfc0'), primary_key=True, serialize=False)), - ('name', models.CharField(max_length=100)), - ], - options={ - 'db_table': 'role', - }, - ), - migrations.CreateModel( - name='Student', - fields=[ - ('id', models.UUIDField(default=uuid.UUID('4a4d0ee8-d669-42a7-b0e6-e15b50b9e957'), primary_key=True, serialize=False)), - ], - options={ - 'db_table': 'student', - }, - ), - migrations.CreateModel( - name='UserChat', - fields=[ - ('id', models.UUIDField(primary_key=True, serialize=False)), - ('chat', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.chat')), - ], - options={ - 'db_table': 'user_chat', - }, - ), - migrations.AlterField( - model_name='group', - name='id', - field=models.UUIDField(default=uuid.UUID('bf9f5680-3f3d-404a-a306-266d58041847'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='user', - name='id', - field=models.UUIDField(default=uuid.UUID('08b048b6-3e6d-4f6f-909f-86c66e071e91'), primary_key=True, serialize=False), - ), - migrations.DeleteModel( - name='StudentGroup', - ), - migrations.AddField( - model_name='userchat', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.user'), - ), - migrations.AddField( - model_name='student', - name='group', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.group'), - ), - migrations.AddField( - model_name='student', - name='user', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='learn.user'), - ), - migrations.AddField( - model_name='message', - name='created_by', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.user'), - ), - migrations.AddField( - model_name='courseassignmentsubmissionreview', - name='reviewed_by', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.student'), - ), - migrations.AddField( - model_name='courseassignmentsubmissionreview', - name='submission', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.courseassignmentsubmission'), - ), - migrations.AddField( - model_name='courseassignmentsubmission', - name='submitted_by', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.student'), - ), - migrations.AddField( - model_name='course', - name='teacher', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.user'), - ), - migrations.AddField( - model_name='chat', - name='created_by', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.user'), - ), - migrations.AddField( - model_name='user', - name='role', - field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='learn.role'), - preserve_default=False, - ), - ] diff --git a/services/learn_old/learn/migrations/0008_student_group_switched_to_foreign_key_group.py b/services/learn_old/learn/migrations/0008_student_group_switched_to_foreign_key_group.py deleted file mode 100644 index 61683ee..0000000 --- a/services/learn_old/learn/migrations/0008_student_group_switched_to_foreign_key_group.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 3.2.4 on 2021-10-10 11:27 - -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('learn', '0007_rename_post_user'), - ] - - operations = [ - migrations.AlterField( - model_name='group', - name='id', - field=models.UUIDField(default=uuid.UUID('d23508f6-bdc3-47c7-bbed-8d610051162e'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='studentgroup', - name='group', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='learn.group'), - ), - migrations.AlterField( - model_name='studentgroup', - name='id', - field=models.UUIDField(default=uuid.UUID('23e98e2e-c402-4d8c-8eb6-8f26c957b089'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='user', - name='id', - field=models.UUIDField(default=uuid.UUID('8636d3bd-6fc6-47dc-8e06-4bc926d66080'), primary_key=True, serialize=False), - ), - ] diff --git a/services/learn_old/learn/migrations/0009_merge_0008.py b/services/learn_old/learn/migrations/0009_merge_0008.py deleted file mode 100644 index c0dd6b2..0000000 --- a/services/learn_old/learn/migrations/0009_merge_0008.py +++ /dev/null @@ -1,14 +0,0 @@ -# Generated by Django 3.2.4 on 2021-10-20 09:14 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('learn', '0008_auto_20211011_2128'), - ('learn', '0008_student_group_switched_to_foreign_key_group'), - ] - - operations = [ - ] diff --git a/services/learn_old/learn/migrations/0010_user_avatar_field.py b/services/learn_old/learn/migrations/0010_user_avatar_field.py deleted file mode 100644 index b1251ac..0000000 --- a/services/learn_old/learn/migrations/0010_user_avatar_field.py +++ /dev/null @@ -1,39 +0,0 @@ -# Generated by Django 3.2.4 on 2021-10-21 20:59 - -from django.db import migrations, models -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('learn', '0009_merge_0008'), - ] - - operations = [ - migrations.AddField( - model_name='user', - name='avatar', - field=models.CharField(max_length=200, null=True), - ), - migrations.AlterField( - model_name='group', - name='id', - field=models.UUIDField(default=uuid.UUID('a64ae565-dc56-4ffa-b57c-258c37c5a5fe'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='role', - name='id', - field=models.UUIDField(default=uuid.UUID('6d4cef31-62af-404f-aaa9-4ac1a2476bb7'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='student', - name='id', - field=models.UUIDField(default=uuid.UUID('4d9c5a99-b975-4374-9374-c966ca169482'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='user', - name='id', - field=models.UUIDField(default=uuid.UUID('4b476107-7bbe-4324-a6cd-2740673d7f28'), primary_key=True, serialize=False), - ), - ] diff --git a/services/learn_old/learn/migrations/0011_add_user_roles.py b/services/learn_old/learn/migrations/0011_add_user_roles.py deleted file mode 100644 index a4a5a2b..0000000 --- a/services/learn_old/learn/migrations/0011_add_user_roles.py +++ /dev/null @@ -1,43 +0,0 @@ -# Generated by Django 3.2.4 on 2021-10-30 18:12 - -from django.db import migrations, models -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('learn', '0010_user_avatar_field'), - ] - - operations = [ - migrations.RemoveField( - model_name='user', - name='role', - ), - migrations.AddField( - model_name='user', - name='roles', - field=models.ManyToManyField(db_table='user_role', to='learn.Role'), - ), - migrations.AlterField( - model_name='group', - name='id', - field=models.UUIDField(default=uuid.UUID('3e32e07d-ac22-4193-b51f-be441a1a0387'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='role', - name='id', - field=models.UUIDField(default=uuid.UUID('b3a84fde-e42b-4f77-98b7-a3ba6452e466'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='student', - name='id', - field=models.UUIDField(default=uuid.UUID('8a39bb99-d567-4dfa-908f-684ac14f7953'), primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='user', - name='id', - field=models.UUIDField(default=uuid.UUID('3a2b868a-6c98-4b73-ab64-4e7005b4d653'), primary_key=True, serialize=False), - ), - ] diff --git a/services/learn_old/learn/migrations/__init__.py b/services/learn_old/learn/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/services/learn_old/learn/models.py b/services/learn_old/learn/models.py deleted file mode 100644 index 8d9896c..0000000 --- a/services/learn_old/learn/models.py +++ /dev/null @@ -1,160 +0,0 @@ -import uuid - -from django.db import models - - -# https://docs.djangoproject.com/en/3.2/ref/models/fields/ - - -class Role(models.Model): - id = models.UUIDField(primary_key=True, default=uuid.uuid4()) - name = models.CharField(max_length=100) - - class Meta: - db_table = "role" - - objects = models.Manager() - - -class User(models.Model): - id = models.UUIDField(primary_key=True, default=uuid.uuid4()) - name = models.CharField(max_length=100) - email = models.CharField(max_length=100) - avatar = models.CharField(max_length=200, null=True) - - roles = models.ManyToManyField(Role, db_table="user_role") - - class Meta: - db_table = "user" - - objects = models.Manager() - - -class Group(models.Model): - id = models.UUIDField(primary_key=True, default=uuid.uuid4()) - name = models.CharField(max_length=100) - formed_at_year = models.IntegerField() - - class Meta: - db_table = "group" - - objects = models.Manager() - - -class Student(models.Model): - id = models.UUIDField(primary_key=True, default=uuid.uuid4()) - - user = models.OneToOneField(User, on_delete=models.CASCADE) - group = models.ForeignKey(Group, on_delete=models.CASCADE) - - class Meta: - db_table = "student" - - objects = models.Manager() - - -class Post(models.Model): - id = models.UUIDField(primary_key=True) - name = models.CharField(max_length=100) - content = models.TextField(null=False) - created_at = models.DateTimeField(null=False) - - created_by = models.ForeignKey(User, on_delete=models.CASCADE) - - class Meta: - db_table = "post" - - objects = models.Manager() - - -class Chat(models.Model): - id = models.UUIDField(primary_key=True) - name = models.CharField(max_length=100) - created_at = models.DateTimeField(null=False) - - created_by = models.ForeignKey(User, on_delete=models.CASCADE) - - class Meta: - db_table = "chat" - - objects = models.Manager() - - -class UserChat(models.Model): - id = models.UUIDField(primary_key=True) - - chat = models.ForeignKey(Chat, on_delete=models.CASCADE) - user = models.ForeignKey(User, on_delete=models.CASCADE) - - class Meta: - db_table = "user_chat" - - objects = models.Manager() - - -class Message(models.Model): - id = models.UUIDField(primary_key=True) - content = models.TextField(null=False) - created_at = models.DateTimeField(null=False) - - chat = models.ForeignKey(Chat, on_delete=models.CASCADE) - created_by = models.ForeignKey(User, on_delete=models.CASCADE) - - class Meta: - db_table = "message" - - objects = models.Manager() - - -class Course(models.Model): - id = models.UUIDField(primary_key=True) - name = models.CharField(max_length=100) - created_at = models.DateTimeField(null=False) - - teacher = models.ForeignKey(User, on_delete=models.CASCADE) - - class Meta: - db_table = "course" - - objects = models.Manager() - - -class CourseAssignment(models.Model): - id = models.UUIDField(primary_key=True) - deadline_at = models.DateTimeField(null=False) - - course = models.ForeignKey(Course, on_delete=models.CASCADE) - - class Meta: - db_table = "course_assignment" - - objects = models.Manager() - - -class CourseAssignmentSubmission(models.Model): - id = models.UUIDField(primary_key=True) - submitted_at = models.DateTimeField(null=False) - content = models.TextField() - - assignment = models.ForeignKey(CourseAssignment, on_delete=models.CASCADE) - submitted_by = models.ForeignKey(Student, on_delete=models.CASCADE) - - class Meta: - db_table = "course_assignment_submission" - - objects = models.Manager() - - -class CourseAssignmentSubmissionReview(models.Model): - id = models.UUIDField(primary_key=True) - reviewed_at = models.DateTimeField(null=False) - mark = models.IntegerField() - - submission = models.ForeignKey(CourseAssignmentSubmission, on_delete=models.CASCADE) - reviewed_by = models.ForeignKey(Student, on_delete=models.CASCADE) - - class Meta: - db_table = "course_assignment_submission_review" - - -objects = models.Manager() diff --git a/services/learn_old/learn/tests.py b/services/learn_old/learn/tests.py deleted file mode 100644 index de8bdc0..0000000 --- a/services/learn_old/learn/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/services/learn_old/manage.py b/services/learn_old/manage.py deleted file mode 100644 index 975451f..0000000 --- a/services/learn_old/manage.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python -"""Django's command-line utility for administrative tasks.""" -import os -import sys -from django.core.management.commands.runserver import Command as RunServer - - -def main(): - """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'api.settings') - HOST = os.getenv('HOST') - PORT = os.getenv('PORT') - RunServer.default_port = PORT - RunServer.default_addr = HOST - try: - from django.core.management import execute_from_command_line - except ImportError as exc: - raise ImportError( - "Couldn't import Django. Are you sure it's installed and " - "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" - ) from exc - execute_from_command_line(sys.argv) - - -if __name__ == '__main__': - main() diff --git a/services/learn_old/requirements.txt b/services/learn_old/requirements.txt deleted file mode 100644 index 5509335..0000000 --- a/services/learn_old/requirements.txt +++ /dev/null @@ -1,24 +0,0 @@ -asgiref==3.4.1 -boto3==1.18.65 -botocore==1.21.65 -Django==3.2.4 -django-cors-headers==3.7.0 -django-storages==1.11.1 -djangorestframework==3.12.4 -dnspython==2.1.0 -email-validator==1.1.3 -idna==3.2 -Inject==4.3.1 -jmespath==0.10.0 -psycopg2-binary==2.9.1 -pydantic==1.8.2 -python-dateutil==2.8.2 -python-dotenv==0.19.0 -pytz==2021.1 -s3transfer==0.5.0 -six==1.16.0 -sqlparse==0.4.2 -typing-extensions==3.10.0.2 -urllib3==1.26.7 - -pika~=1.2.0 From 2c27ad9ee25c958a35b3e3e825811a23e239bc1a Mon Sep 17 00:00:00 2001 From: Yaroslaww-1 Date: Tue, 2 Nov 2021 01:12:02 +0200 Subject: [PATCH 4/5] added db seeding and migrations autorun && added id value objects --- services/learn/Learn.API/Startup.cs | 2 + .../Learn.Application/Users/Dtos/UserDto.cs | 1 + .../Domain/TypedIdValueBase.cs | 59 ++++++++++ .../StronglyTypedIdValueConverterSelector.cs | 61 ++++++++++ .../Infrastructure/TypedIdValueConverter.cs | 17 +++ .../Learn.BuildingBlocks.csproj | 1 + .../learn/Learn.Domain/Learn.Domain.csproj | 4 + services/learn/Learn.Domain/Users/Role.cs | 6 +- services/learn/Learn.Domain/Users/RoleId.cs | 13 +++ services/learn/Learn.Domain/Users/User.cs | 35 ++++-- services/learn/Learn.Domain/Users/UserId.cs | 13 +++ ...900_RemovePasswordInfoFromUser.Designer.cs | 109 ++++++++++++++++++ ...211101230900_RemovePasswordInfoFromUser.cs | 33 ++++++ .../Migrations/LearnDbContextModelSnapshot.cs | 10 -- .../EntityFramework/Seeding/DatabaseSeeder.cs | 83 +++++++++++++ .../InfrastructureDependencyInjection.cs | 53 +++++++-- 16 files changed, 470 insertions(+), 30 deletions(-) create mode 100644 services/learn/Learn.BuildingBlocks/Domain/TypedIdValueBase.cs create mode 100644 services/learn/Learn.BuildingBlocks/Infrastructure/StronglyTypedIdValueConverterSelector.cs create mode 100644 services/learn/Learn.BuildingBlocks/Infrastructure/TypedIdValueConverter.cs create mode 100644 services/learn/Learn.Domain/Users/RoleId.cs create mode 100644 services/learn/Learn.Domain/Users/UserId.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101230900_RemovePasswordInfoFromUser.Designer.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101230900_RemovePasswordInfoFromUser.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Seeding/DatabaseSeeder.cs diff --git a/services/learn/Learn.API/Startup.cs b/services/learn/Learn.API/Startup.cs index 5e3faf2..4e4f76f 100644 --- a/services/learn/Learn.API/Startup.cs +++ b/services/learn/Learn.API/Startup.cs @@ -51,6 +51,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { endpoints.MapControllers(); }); + + app.ConfigureInfrastructure(); } } } diff --git a/services/learn/Learn.Application/Users/Dtos/UserDto.cs b/services/learn/Learn.Application/Users/Dtos/UserDto.cs index 85ec823..2d18a44 100644 --- a/services/learn/Learn.Application/Users/Dtos/UserDto.cs +++ b/services/learn/Learn.Application/Users/Dtos/UserDto.cs @@ -7,6 +7,7 @@ public class UserDto { public Guid Id { get; set; } public string Name { get; set; } + public string Email { get; set; } public List Roles { get; set; } } } diff --git a/services/learn/Learn.BuildingBlocks/Domain/TypedIdValueBase.cs b/services/learn/Learn.BuildingBlocks/Domain/TypedIdValueBase.cs new file mode 100644 index 0000000..9639476 --- /dev/null +++ b/services/learn/Learn.BuildingBlocks/Domain/TypedIdValueBase.cs @@ -0,0 +1,59 @@ +using System; + +namespace Learn.BuildingBlocks.Domain +{ + public abstract class TypedIdValueBase : IEquatable + { + public Guid Value { get; } + + protected TypedIdValueBase(Guid value) + { + if (value == Guid.Empty) + { + throw new InvalidOperationException("Id value cannot be empty!"); + } + + Value = value; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + return obj is TypedIdValueBase other && Equals(other); + } + + public override int GetHashCode() + { + return Value.GetHashCode(); + } + + public bool Equals(TypedIdValueBase other) + { + return this.Value == other?.Value; + } + + public static bool operator ==(TypedIdValueBase obj1, TypedIdValueBase obj2) + { + if (object.Equals(obj1, null)) + { + if (object.Equals(obj2, null)) + { + return true; + } + + return false; + } + + return obj1.Equals(obj2); + } + + public static bool operator !=(TypedIdValueBase x, TypedIdValueBase y) + { + return !(x == y); + } + } +} diff --git a/services/learn/Learn.BuildingBlocks/Infrastructure/StronglyTypedIdValueConverterSelector.cs b/services/learn/Learn.BuildingBlocks/Infrastructure/StronglyTypedIdValueConverterSelector.cs new file mode 100644 index 0000000..061c769 --- /dev/null +++ b/services/learn/Learn.BuildingBlocks/Infrastructure/StronglyTypedIdValueConverterSelector.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using Learn.BuildingBlocks.Domain; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Learn.BuildingBlocks.Infrastructure +{ + /// + /// Based on https://andrewlock.net/strongly-typed-ids-in-ef-core-using-strongly-typed-entity-ids-to-avoid-primitive-obsession-part-4/ + /// + public class StronglyTypedIdValueConverterSelector : ValueConverterSelector + { + private readonly ConcurrentDictionary<(Type ModelClrType, Type ProviderClrType), ValueConverterInfo> _converters + = new ConcurrentDictionary<(Type ModelClrType, Type ProviderClrType), ValueConverterInfo>(); + + public StronglyTypedIdValueConverterSelector(ValueConverterSelectorDependencies dependencies) + : base(dependencies) + { + } + + public override IEnumerable Select(Type modelClrType, Type providerClrType = null) + { + var baseConverters = base.Select(modelClrType, providerClrType); + foreach (var converter in baseConverters) + { + yield return converter; + } + + var underlyingModelType = UnwrapNullableType(modelClrType); + var underlyingProviderType = UnwrapNullableType(providerClrType); + + if (underlyingProviderType is null || underlyingProviderType == typeof(Guid)) + { + var isTypedIdValue = typeof(TypedIdValueBase).IsAssignableFrom(underlyingModelType); + if (isTypedIdValue) + { + var converterType = typeof(TypedIdValueConverter<>).MakeGenericType(underlyingModelType); + + yield return _converters.GetOrAdd((underlyingModelType, typeof(Guid)), _ => + { + return new ValueConverterInfo( + modelClrType: modelClrType, + providerClrType: typeof(Guid), + factory: valueConverterInfo => (ValueConverter)Activator.CreateInstance(converterType, valueConverterInfo.MappingHints)); + }); + } + } + } + + private static Type UnwrapNullableType(Type type) + { + if (type is null) + { + return null; + } + + return Nullable.GetUnderlyingType(type) ?? type; + } + } +} diff --git a/services/learn/Learn.BuildingBlocks/Infrastructure/TypedIdValueConverter.cs b/services/learn/Learn.BuildingBlocks/Infrastructure/TypedIdValueConverter.cs new file mode 100644 index 0000000..2266055 --- /dev/null +++ b/services/learn/Learn.BuildingBlocks/Infrastructure/TypedIdValueConverter.cs @@ -0,0 +1,17 @@ +using System; +using Learn.BuildingBlocks.Domain; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Learn.BuildingBlocks.Infrastructure +{ + public class TypedIdValueConverter : ValueConverter + where TTypedIdValue : TypedIdValueBase + { + public TypedIdValueConverter(ConverterMappingHints mappingHints = null) + : base(id => id.Value, value => Create(value), mappingHints) + { + } + + private static TTypedIdValue Create(Guid id) => Activator.CreateInstance(typeof(TTypedIdValue), id) as TTypedIdValue; + } +} \ No newline at end of file diff --git a/services/learn/Learn.BuildingBlocks/Learn.BuildingBlocks.csproj b/services/learn/Learn.BuildingBlocks/Learn.BuildingBlocks.csproj index 8aa17ce..f2db09c 100644 --- a/services/learn/Learn.BuildingBlocks/Learn.BuildingBlocks.csproj +++ b/services/learn/Learn.BuildingBlocks/Learn.BuildingBlocks.csproj @@ -6,6 +6,7 @@ + diff --git a/services/learn/Learn.Domain/Learn.Domain.csproj b/services/learn/Learn.Domain/Learn.Domain.csproj index 6e9ceba..ad235fc 100644 --- a/services/learn/Learn.Domain/Learn.Domain.csproj +++ b/services/learn/Learn.Domain/Learn.Domain.csproj @@ -4,4 +4,8 @@ net5.0 + + + + diff --git a/services/learn/Learn.Domain/Users/Role.cs b/services/learn/Learn.Domain/Users/Role.cs index 8074901..459d6a3 100644 --- a/services/learn/Learn.Domain/Users/Role.cs +++ b/services/learn/Learn.Domain/Users/Role.cs @@ -5,9 +5,9 @@ namespace Learn.Domain.Users { public class Role { - public Guid Id { get; private set; } + public RoleId Id { get; private set; } public string Name { get; private set; } - public IList Users { get; private set; } + public List Users { get; private set; } private Role() { @@ -16,7 +16,7 @@ private Role() private Role(string name) { - Id = Guid.NewGuid(); + Id = new RoleId(Guid.NewGuid()); Name = name; Users = new List(); } diff --git a/services/learn/Learn.Domain/Users/RoleId.cs b/services/learn/Learn.Domain/Users/RoleId.cs new file mode 100644 index 0000000..683fbff --- /dev/null +++ b/services/learn/Learn.Domain/Users/RoleId.cs @@ -0,0 +1,13 @@ +using Learn.BuildingBlocks.Domain; +using System; + +namespace Learn.Domain.Users +{ + public class RoleId : TypedIdValueBase + { + public RoleId(Guid value) + : base(value) + { + } + } +} diff --git a/services/learn/Learn.Domain/Users/User.cs b/services/learn/Learn.Domain/Users/User.cs index f0e89f8..88fee6c 100644 --- a/services/learn/Learn.Domain/Users/User.cs +++ b/services/learn/Learn.Domain/Users/User.cs @@ -5,12 +5,10 @@ namespace Learn.Domain.Users { public class User { - public Guid Id { get; private set; } + public UserId Id { get; private set; } public string Email { get; private set; } public string Name { get; private set; } - public string PasswordHash { get; private set; } - public string PasswordHashSalt { get; private set; } - public IList Roles { get; private set; } + public List Roles { get; private set; } private User() { @@ -18,18 +16,37 @@ private User() } private User( + UserId id, string email, string name, - string passwordHash, - string passwordHashSalt, List roles) { - Id = Guid.NewGuid(); + Id = id; Email = email; Name = name; - PasswordHash = passwordHash; - PasswordHashSalt = passwordHashSalt; Roles = roles; } + + private User(string email, string name, List roles) + { + Id = new UserId(Guid.NewGuid()); + Email = email; + Name = name; + Roles = roles; + } + + public static User CreateNew(string email, string name, List roles) + { + return new User(email, name, roles); + } + + public static User Initialize( + UserId id, + string email, + string name, + List roles) + { + return new User(id, email, name, roles); + } } } diff --git a/services/learn/Learn.Domain/Users/UserId.cs b/services/learn/Learn.Domain/Users/UserId.cs new file mode 100644 index 0000000..05181ac --- /dev/null +++ b/services/learn/Learn.Domain/Users/UserId.cs @@ -0,0 +1,13 @@ +using Learn.BuildingBlocks.Domain; +using System; + +namespace Learn.Domain.Users +{ + public class UserId : TypedIdValueBase + { + public UserId(Guid value) + : base(value) + { + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101230900_RemovePasswordInfoFromUser.Designer.cs b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101230900_RemovePasswordInfoFromUser.Designer.cs new file mode 100644 index 0000000..93c9055 --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101230900_RemovePasswordInfoFromUser.Designer.cs @@ -0,0 +1,109 @@ +// +using System; +using Learn.Infrastructure.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Learn.Infrastructure.EntityFramework.Migrations +{ + [DbContext(typeof(LearnDbContext))] + [Migration("20211101230900_RemovePasswordInfoFromUser")] + partial class RemovePasswordInfoFromUser + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 63) + .HasAnnotation("ProductVersion", "5.0.11") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + modelBuilder.Entity("Learn.Domain.Users.Role", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_role"); + + b.HasIndex("Name") + .IsUnique() + .HasDatabaseName("ix_role_name"); + + b.ToTable("role"); + }); + + modelBuilder.Entity("Learn.Domain.Users.User", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_user"); + + b.HasIndex("Email") + .IsUnique() + .HasDatabaseName("ix_user_email"); + + b.ToTable("user"); + }); + + modelBuilder.Entity("user_role", b => + { + b.Property("role_id") + .HasColumnType("uuid") + .HasColumnName("role_id"); + + b.Property("user_id") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("role_id", "user_id") + .HasName("pk_user_role"); + + b.HasIndex("user_id") + .HasDatabaseName("ix_user_role_user_id"); + + b.ToTable("user_role"); + }); + + modelBuilder.Entity("user_role", b => + { + b.HasOne("Learn.Domain.Users.Role", null) + .WithMany() + .HasForeignKey("role_id") + .HasConstraintName("fk_user_role_role_role_id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Learn.Domain.Users.User", null) + .WithMany() + .HasForeignKey("user_id") + .HasConstraintName("fk_user_role_user_user_id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101230900_RemovePasswordInfoFromUser.cs b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101230900_RemovePasswordInfoFromUser.cs new file mode 100644 index 0000000..b768ed4 --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211101230900_RemovePasswordInfoFromUser.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Learn.Infrastructure.EntityFramework.Migrations +{ + public partial class RemovePasswordInfoFromUser : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "password_hash", + table: "user"); + + migrationBuilder.DropColumn( + name: "password_hash_salt", + table: "user"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "password_hash", + table: "user", + type: "text", + nullable: true); + + migrationBuilder.AddColumn( + name: "password_hash_salt", + table: "user", + type: "text", + nullable: true); + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/LearnDbContextModelSnapshot.cs b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/LearnDbContextModelSnapshot.cs index 7f0b081..1327869 100644 --- a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/LearnDbContextModelSnapshot.cs +++ b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/LearnDbContextModelSnapshot.cs @@ -22,7 +22,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Learn.Domain.Users.Role", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasColumnType("uuid") .HasColumnName("id"); @@ -44,7 +43,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Learn.Domain.Users.User", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasColumnType("uuid") .HasColumnName("id"); @@ -58,14 +56,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("text") .HasColumnName("name"); - b.Property("PasswordHash") - .HasColumnType("text") - .HasColumnName("password_hash"); - - b.Property("PasswordHashSalt") - .HasColumnType("text") - .HasColumnName("password_hash_salt"); - b.HasKey("Id") .HasName("pk_user"); diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Seeding/DatabaseSeeder.cs b/services/learn/Learn.Infrastructure/EntityFramework/Seeding/DatabaseSeeder.cs new file mode 100644 index 0000000..b5bddb8 --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Seeding/DatabaseSeeder.cs @@ -0,0 +1,83 @@ +using Learn.Domain.Users; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Learn.Infrastructure.EntityFramework.Seeding +{ + public class DatabaseSeeder + { + private readonly IApplicationBuilder _app; + + public DatabaseSeeder(IApplicationBuilder app) + { + _app = app; + } + + public void SeedDatabase() + { + SeedRoles(); + SeedUsers(); + } + + private void SeedRoles() + { + using (var scope = _app.ApplicationServices.GetService().CreateScope()) + { + using var context = scope.ServiceProvider.GetRequiredService(); + + var existingRoles = context.Roles.ToList(); + + if (!existingRoles.Any()) + { + context.Roles.Add(Role.CreateNew("Student")); + + context.Roles.Add(Role.CreateNew("Teacher")); + + context.Roles.Add(Role.CreateNew("Admin")); + + context.SaveChanges(); + } + }; + } + + private void SeedUsers() + { + using (var scope = _app.ApplicationServices.GetService().CreateScope()) + { + using var context = scope.ServiceProvider.GetRequiredService(); + + var existingUsers = context.Users.ToList(); + + var existingRoles = context.Roles.ToList(); + + if (!existingUsers.Any()) + { + context.Users.Add(User.Initialize( + new UserId(new Guid("33333333-3333-3333-3333-333333333333")), + "student@gmail.com", + "Student", + existingRoles.Where(r => r.Name == "Student").ToList())); + + context.Users.Add(User.Initialize( + new UserId(new Guid("22222222-2222-2222-2222-222222222222")), + "teacher@gmail.com", + "Teacher", + existingRoles.Where(r => r.Name == "Teacher").ToList())); + + context.Users.Add(User.Initialize( + new UserId(new Guid("11111111-1111-1111-1111-111111111111")), + "admin@gmail.com", + "Admin", + existingRoles.Where(r => r.Name == "Admin").ToList())); + + context.SaveChanges(); + } + }; + } + } +} diff --git a/services/learn/Learn.Infrastructure/InfrastructureDependencyInjection.cs b/services/learn/Learn.Infrastructure/InfrastructureDependencyInjection.cs index 1267e2b..e174e0d 100644 --- a/services/learn/Learn.Infrastructure/InfrastructureDependencyInjection.cs +++ b/services/learn/Learn.Infrastructure/InfrastructureDependencyInjection.cs @@ -1,6 +1,10 @@ +using Learn.BuildingBlocks.Infrastructure; using Learn.BuildingBlocks.Infrastructure.Options; using Learn.Infrastructure.EntityFramework; +using Learn.Infrastructure.EntityFramework.Seeding; +using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; @@ -17,6 +21,21 @@ public static IServiceCollection AddInfrastructure(this IServiceCollection servi return services; } + public static IApplicationBuilder ConfigureInfrastructure(this IApplicationBuilder app, bool migrate = true, bool seed = true) + { + if (migrate) + { + MigrateDatabase(app); + } + + if (seed) + { + SeedDatabase(app); + } + + return app; + } + private static IServiceCollection AddOptions(this IServiceCollection services, IConfiguration configuration) { services.Configure(configuration.GetSection(DatabaseOptions.Location)); @@ -31,15 +50,33 @@ private static IServiceCollection AddDatabaseContext(this IServiceCollection ser var migrationAssembly = typeof(LearnDbContext).Assembly.GetName().Name; - services.AddDbContext(options => - options - .UseNpgsql( - databaseOptions.ConnectionString, - opt => opt.MigrationsAssembly(migrationAssembly)) - .UseSnakeCaseNamingConvention() - ); + services.AddDbContext(options => + { + options + .UseNpgsql( + databaseOptions.ConnectionString, + opt => opt.MigrationsAssembly(migrationAssembly)) + .UseSnakeCaseNamingConvention(); + + options.ReplaceService(); + }); return services; } - } + + public static void MigrateDatabase(IApplicationBuilder app) + { + using (var scope = app.ApplicationServices.GetService().CreateScope()) + { + using var context = scope.ServiceProvider.GetRequiredService(); + context.Database.Migrate(); + }; + } + + public static void SeedDatabase(IApplicationBuilder app) + { + var databaseSeeder = new DatabaseSeeder(app); + databaseSeeder.SeedDatabase(); + } + } } \ No newline at end of file From 356a573164a0a6f4477337212fb94a589740fee1 Mon Sep 17 00:00:00 2001 From: Yaroslaww-1 Date: Tue, 2 Nov 2021 22:06:58 +0200 Subject: [PATCH 5/5] added chats --- .../Controllers/Chats/ChatsController.cs | 40 ++++ .../Controllers/Chats/CreateChatRequest.cs | 7 + .../Chats/CreateChat/CreateChatCommand.cs | 60 ++++++ .../Learn.Application/Chats/Dtos/ChatDto.cs | 12 ++ .../Chats/Dtos/ChatMemberDto.cs | 9 + .../GetAuthenticatedUserChatsQuery.cs | 52 +++++ .../MappingProfiles/ChatMappingProfile.cs | 17 ++ .../ChatAggregateSpecification.cs | 15 ++ .../ChatByCreatorIdSpecification.cs | 14 ++ .../Users/GetUsers/GetUsersQuery.cs | 2 +- .../MappingProfiles/RoleMapperProfile.cs | 3 +- .../MappingProfiles/UserMapperProfile.cs | 3 +- .../UserByEmailSpecification.cs | 13 ++ .../ExecutionContextAccessor.cs | 16 +- .../ExecutionContext/IUserContext.cs | 7 + services/learn/Learn.Domain/Chats/Chat.cs | 36 ++++ services/learn/Learn.Domain/Chats/ChatId.cs | 13 ++ .../learn/Learn.Domain/Chats/ChatMember.cs | 31 +++ .../learn/Learn.Domain/Chats/ChatmemberId.cs | 13 ++ .../Learn.Domain/Chats/IChatRepository.cs | 9 + .../Configuration/UserContext/UserContext.cs | 16 ++ .../ChatEntityConfiguration.cs | 35 ++++ .../ChatMemberEntityConfiguration.cs | 25 +++ .../EntityFramework/LearnDbContext.cs | 5 + .../20211102192744_AddChats.Designer.cs | 172 ++++++++++++++++ .../Migrations/20211102192744_AddChats.cs | 67 +++++++ ...0211102200505_AddChatCreatedBy.Designer.cs | 189 ++++++++++++++++++ .../20211102200505_AddChatCreatedBy.cs | 45 +++++ .../Migrations/LearnDbContextModelSnapshot.cs | 80 ++++++++ .../Repositories/ChatRepository.cs | 21 ++ .../Repositories/Users/IUserRepository.cs | 10 - .../Repositories/Users/UserRepository.cs | 12 -- .../InfrastructureDependencyInjection.cs | 25 ++- .../Learn.Infrastructure.csproj | 1 + 34 files changed, 1035 insertions(+), 40 deletions(-) create mode 100644 services/learn/Learn.API/Controllers/Chats/ChatsController.cs create mode 100644 services/learn/Learn.API/Controllers/Chats/CreateChatRequest.cs create mode 100644 services/learn/Learn.Application/Chats/CreateChat/CreateChatCommand.cs create mode 100644 services/learn/Learn.Application/Chats/Dtos/ChatDto.cs create mode 100644 services/learn/Learn.Application/Chats/Dtos/ChatMemberDto.cs create mode 100644 services/learn/Learn.Application/Chats/GetAuthenticatedUserChats/GetAuthenticatedUserChatsQuery.cs create mode 100644 services/learn/Learn.Application/Chats/MappingProfiles/ChatMappingProfile.cs create mode 100644 services/learn/Learn.Application/Chats/Specifications/ChatAggregateSpecification.cs create mode 100644 services/learn/Learn.Application/Chats/Specifications/ChatByCreatorIdSpecification.cs create mode 100644 services/learn/Learn.Application/Users/Specifications/UserByEmailSpecification.cs create mode 100644 services/learn/Learn.BuildingBlocks/Application/ExecutionContext/IUserContext.cs create mode 100644 services/learn/Learn.Domain/Chats/Chat.cs create mode 100644 services/learn/Learn.Domain/Chats/ChatId.cs create mode 100644 services/learn/Learn.Domain/Chats/ChatMember.cs create mode 100644 services/learn/Learn.Domain/Chats/ChatmemberId.cs create mode 100644 services/learn/Learn.Domain/Chats/IChatRepository.cs create mode 100644 services/learn/Learn.Infrastructure/Configuration/UserContext/UserContext.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/ChatEntityConfiguration.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/ChatMemberEntityConfiguration.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102192744_AddChats.Designer.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102192744_AddChats.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102200505_AddChatCreatedBy.Designer.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102200505_AddChatCreatedBy.cs create mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Repositories/ChatRepository.cs delete mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/IUserRepository.cs delete mode 100644 services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/UserRepository.cs diff --git a/services/learn/Learn.API/Controllers/Chats/ChatsController.cs b/services/learn/Learn.API/Controllers/Chats/ChatsController.cs new file mode 100644 index 0000000..4429f86 --- /dev/null +++ b/services/learn/Learn.API/Controllers/Chats/ChatsController.cs @@ -0,0 +1,40 @@ +using Learn.Application.Chats.CreateChat; +using Learn.Application.Chats.Dtos; +using Learn.Application.Chats.GetChats; +using MediatR; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Collections; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Learn.API.Controllers.Chats +{ + [ApiController] + [Route("chats")] + public class ChatsController : ControllerBase + { + private readonly ISender _mediator; + + public ChatsController(ISender mediator) + { + _mediator = mediator; + } + + [HttpGet("my")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task> Create() + { + var result = await _mediator.Send(new GetAuthenticatedUserChatsQuery()); + return result; + } + + [HttpPost] + [ProducesResponseType(typeof(ChatDto), StatusCodes.Status200OK)] + public async Task Create([FromBody] CreateChatRequest request) + { + var result = await _mediator.Send(new CreateChatCommand(request.Name)); + return result; + } + } +} diff --git a/services/learn/Learn.API/Controllers/Chats/CreateChatRequest.cs b/services/learn/Learn.API/Controllers/Chats/CreateChatRequest.cs new file mode 100644 index 0000000..52e09c5 --- /dev/null +++ b/services/learn/Learn.API/Controllers/Chats/CreateChatRequest.cs @@ -0,0 +1,7 @@ +namespace Learn.API.Controllers.Chats +{ + public class CreateChatRequest + { + public string Name { get; set; } + } +} diff --git a/services/learn/Learn.Application/Chats/CreateChat/CreateChatCommand.cs b/services/learn/Learn.Application/Chats/CreateChat/CreateChatCommand.cs new file mode 100644 index 0000000..eec7e29 --- /dev/null +++ b/services/learn/Learn.Application/Chats/CreateChat/CreateChatCommand.cs @@ -0,0 +1,60 @@ +using Ardalis.Specification.EntityFrameworkCore; +using AutoMapper; +using Learn.Application.Chats.Dtos; +using Learn.Application.Users.Dtos; +using Learn.Application.Users.Specifications; +using Learn.BuildingBlocks.Application.ExecutionContext; +using Learn.Domain.Chats; +using Learn.Domain.Users; +using Learn.Infrastructure.EntityFramework; +using MediatR; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Learn.Application.Chats.CreateChat +{ + public class CreateChatCommand : IRequest + { + public string Name { get; set; } + + public CreateChatCommand(string name) + { + Name = name; + } + } + + internal class CreateChatCommandHandler : IRequestHandler + { + private readonly LearnDbContext _dbContext; + private readonly IChatRepository _chatRepository; + private readonly IMapper _mapper; + private readonly IUserContext _userContext; + + public CreateChatCommandHandler(LearnDbContext dbContext, IChatRepository chatRepository, IMapper mapper, IUserContext userContext) + { + _dbContext = dbContext; + _chatRepository = chatRepository; + _mapper = mapper; + _userContext = userContext; + } + + public async Task Handle(CreateChatCommand request, CancellationToken cancellationToken) + { + var createdBy = await _dbContext.Users + .WithSpecification(new UserAggregateSpecification()) + .WithSpecification(new UserByEmailSpecification(_userContext.Email)) + .FirstAsync(); + + var chat = Chat.CreateNew(request.Name, createdBy); + + await _chatRepository.AddAsync(chat); + + return _mapper.Map(chat); + } + } +} diff --git a/services/learn/Learn.Application/Chats/Dtos/ChatDto.cs b/services/learn/Learn.Application/Chats/Dtos/ChatDto.cs new file mode 100644 index 0000000..60fa5d8 --- /dev/null +++ b/services/learn/Learn.Application/Chats/Dtos/ChatDto.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace Learn.Application.Chats.Dtos +{ + public class ChatDto + { + public Guid Id { get; set; } + public string Name { get; set; } + public List Members { get; set; } + } +} diff --git a/services/learn/Learn.Application/Chats/Dtos/ChatMemberDto.cs b/services/learn/Learn.Application/Chats/Dtos/ChatMemberDto.cs new file mode 100644 index 0000000..c147136 --- /dev/null +++ b/services/learn/Learn.Application/Chats/Dtos/ChatMemberDto.cs @@ -0,0 +1,9 @@ +using System; + +namespace Learn.Application.Chats.Dtos +{ + public class ChatMemberDto + { + public string Name { get; set; } + } +} diff --git a/services/learn/Learn.Application/Chats/GetAuthenticatedUserChats/GetAuthenticatedUserChatsQuery.cs b/services/learn/Learn.Application/Chats/GetAuthenticatedUserChats/GetAuthenticatedUserChatsQuery.cs new file mode 100644 index 0000000..dd0f1d3 --- /dev/null +++ b/services/learn/Learn.Application/Chats/GetAuthenticatedUserChats/GetAuthenticatedUserChatsQuery.cs @@ -0,0 +1,52 @@ +using Ardalis.Specification.EntityFrameworkCore; +using AutoMapper; +using Learn.Application.Chats.Dtos; +using Learn.Application.Chats.Specifications; +using Learn.Application.Users.Specifications; +using Learn.BuildingBlocks.Application.ExecutionContext; +using Learn.Infrastructure.EntityFramework; +using MediatR; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Learn.Application.Chats.GetChats +{ + public class GetAuthenticatedUserChatsQuery : IRequest> + { + } + + internal class GetAuthenticatedUserChatsQueryHandler : IRequestHandler> + { + private readonly LearnDbContext _dbContext; + private readonly IMapper _mapper; + private readonly IUserContext _userContext; + + public GetAuthenticatedUserChatsQueryHandler(LearnDbContext context, IMapper mapper, IUserContext userContext) + { + _dbContext = context; + _mapper = mapper; + _userContext = userContext; + } + + public async Task> Handle(GetAuthenticatedUserChatsQuery request, CancellationToken cancellationToken) + { + var createdBy = await _dbContext.Users + .WithSpecification(new UserByEmailSpecification(_userContext.Email)) + .AsNoTracking() + .FirstAsync(); + + var chats = await _dbContext.Chats + .WithSpecification(new ChatAggregateSpecification()) + .WithSpecification(new ChatByCreatorIdSpecification(createdBy.Id)) + .AsNoTracking() + .ToListAsync(); + + return _mapper.Map>(chats); + } + } +} diff --git a/services/learn/Learn.Application/Chats/MappingProfiles/ChatMappingProfile.cs b/services/learn/Learn.Application/Chats/MappingProfiles/ChatMappingProfile.cs new file mode 100644 index 0000000..2fd156a --- /dev/null +++ b/services/learn/Learn.Application/Chats/MappingProfiles/ChatMappingProfile.cs @@ -0,0 +1,17 @@ +using AutoMapper; +using Learn.Application.Chats.Dtos; +using Learn.Domain.Chats; +using Learn.Domain.Users; + +namespace Learn.Application.Chats.MappingProfiles +{ + public class ChatMappingProfile : Profile + { + public ChatMappingProfile() + { + CreateMap(); + CreateMap() + .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id.Value)); + } + } +} diff --git a/services/learn/Learn.Application/Chats/Specifications/ChatAggregateSpecification.cs b/services/learn/Learn.Application/Chats/Specifications/ChatAggregateSpecification.cs new file mode 100644 index 0000000..0b4515c --- /dev/null +++ b/services/learn/Learn.Application/Chats/Specifications/ChatAggregateSpecification.cs @@ -0,0 +1,15 @@ +using Ardalis.Specification; +using Learn.Domain.Chats; + +namespace Learn.Application.Chats.Specifications +{ + public class ChatAggregateSpecification : Specification + { + public ChatAggregateSpecification() + { + base.Query + .Include(c => c.Members) + .ThenInclude(m => m.User); + } + } +} diff --git a/services/learn/Learn.Application/Chats/Specifications/ChatByCreatorIdSpecification.cs b/services/learn/Learn.Application/Chats/Specifications/ChatByCreatorIdSpecification.cs new file mode 100644 index 0000000..71c8286 --- /dev/null +++ b/services/learn/Learn.Application/Chats/Specifications/ChatByCreatorIdSpecification.cs @@ -0,0 +1,14 @@ +using Ardalis.Specification; +using Learn.Domain.Chats; +using Learn.Domain.Users; + +namespace Learn.Application.Chats.Specifications +{ + public class ChatByCreatorIdSpecification : Specification + { + public ChatByCreatorIdSpecification(UserId userId) + { + base.Query.Where(u => u.CreatedBy.Id == userId); + } + } +} diff --git a/services/learn/Learn.Application/Users/GetUsers/GetUsersQuery.cs b/services/learn/Learn.Application/Users/GetUsers/GetUsersQuery.cs index 2517697..14ff1d0 100644 --- a/services/learn/Learn.Application/Users/GetUsers/GetUsersQuery.cs +++ b/services/learn/Learn.Application/Users/GetUsers/GetUsersQuery.cs @@ -33,7 +33,7 @@ public async Task> Handle(GetUsersQuery request, Cancellati var users = await _dbContext.Users .WithSpecification(new UserAggregateSpecification()) .AsNoTracking() - .ToListAsync(cancellationToken: cancellationToken); + .ToListAsync(); return _mapper.Map>(users); } diff --git a/services/learn/Learn.Application/Users/MappingProfiles/RoleMapperProfile.cs b/services/learn/Learn.Application/Users/MappingProfiles/RoleMapperProfile.cs index 48d0055..905f1b7 100644 --- a/services/learn/Learn.Application/Users/MappingProfiles/RoleMapperProfile.cs +++ b/services/learn/Learn.Application/Users/MappingProfiles/RoleMapperProfile.cs @@ -8,7 +8,8 @@ public class RoleMapperProfile : Profile { public RoleMapperProfile() { - CreateMap(); + CreateMap() + .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id.Value)); } } } diff --git a/services/learn/Learn.Application/Users/MappingProfiles/UserMapperProfile.cs b/services/learn/Learn.Application/Users/MappingProfiles/UserMapperProfile.cs index 9d6b8f9..b098843 100644 --- a/services/learn/Learn.Application/Users/MappingProfiles/UserMapperProfile.cs +++ b/services/learn/Learn.Application/Users/MappingProfiles/UserMapperProfile.cs @@ -8,7 +8,8 @@ public class UserMapperProfile : Profile { public UserMapperProfile() { - CreateMap(); + CreateMap() + .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id.Value)); } } } diff --git a/services/learn/Learn.Application/Users/Specifications/UserByEmailSpecification.cs b/services/learn/Learn.Application/Users/Specifications/UserByEmailSpecification.cs new file mode 100644 index 0000000..a56851b --- /dev/null +++ b/services/learn/Learn.Application/Users/Specifications/UserByEmailSpecification.cs @@ -0,0 +1,13 @@ +using Ardalis.Specification; +using Learn.Domain.Users; + +namespace Learn.Application.Users.Specifications +{ + public class UserByEmailSpecification : Specification, ISingleResultSpecification + { + public UserByEmailSpecification(string email) + { + base.Query.Where(u => u.Email == email); + } + } +} diff --git a/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/ExecutionContextAccessor.cs b/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/ExecutionContextAccessor.cs index 3a42ad4..ac99f8c 100644 --- a/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/ExecutionContextAccessor.cs +++ b/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/ExecutionContextAccessor.cs @@ -17,29 +17,17 @@ public string Email { get { - //http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier - if (_httpContextAccessor - .HttpContext? - .User? - .Claims? - .SingleOrDefault(x => x.Type.Contains("email"))? - .Value != null) - { - return _httpContextAccessor.HttpContext.User.Claims.Single( - x => x.Type.Contains("email")).Value; - } - if ((bool)(_httpContextAccessor .HttpContext? .Request? .Headers? - .ContainsKey("email"))) + .ContainsKey("UserEmail"))) { return _httpContextAccessor .HttpContext? .Request? .Headers? - ["email"]; + ["UserEmail"]; } throw new ApplicationException("User context is not available"); diff --git a/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/IUserContext.cs b/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/IUserContext.cs new file mode 100644 index 0000000..8213a1b --- /dev/null +++ b/services/learn/Learn.BuildingBlocks/Application/ExecutionContext/IUserContext.cs @@ -0,0 +1,7 @@ +namespace Learn.BuildingBlocks.Application.ExecutionContext +{ + public interface IUserContext + { + public string Email { get; } + } +} diff --git a/services/learn/Learn.Domain/Chats/Chat.cs b/services/learn/Learn.Domain/Chats/Chat.cs new file mode 100644 index 0000000..2f1f1e9 --- /dev/null +++ b/services/learn/Learn.Domain/Chats/Chat.cs @@ -0,0 +1,36 @@ +using Learn.Domain.Users; +using System; +using System.Collections.Generic; + +namespace Learn.Domain.Chats +{ + public class Chat + { + public ChatId Id { get; private set; } + public string Name { get; private set; } + public User CreatedBy { get; private set; } + public List Members { get; private set; } + + private Chat() + { + // Only for EF + } + + private Chat(ChatId chatId, string name, User createdBy, List members) + { + Id = chatId; + Name = name; + CreatedBy = createdBy; + Members = members; + } + + public static Chat CreateNew(string name, User createdBy) + { + var chatId = new ChatId(Guid.NewGuid()); + + var firstChatMember = ChatMember.CreateNew(createdBy, chatId); + + return new Chat(chatId, name, createdBy, new List() { firstChatMember }); + } + } +} diff --git a/services/learn/Learn.Domain/Chats/ChatId.cs b/services/learn/Learn.Domain/Chats/ChatId.cs new file mode 100644 index 0000000..866fcb0 --- /dev/null +++ b/services/learn/Learn.Domain/Chats/ChatId.cs @@ -0,0 +1,13 @@ +using Learn.BuildingBlocks.Domain; +using System; + +namespace Learn.Domain.Chats +{ + public class ChatId : TypedIdValueBase + { + public ChatId(Guid value) + : base(value) + { + } + } +} diff --git a/services/learn/Learn.Domain/Chats/ChatMember.cs b/services/learn/Learn.Domain/Chats/ChatMember.cs new file mode 100644 index 0000000..57c8850 --- /dev/null +++ b/services/learn/Learn.Domain/Chats/ChatMember.cs @@ -0,0 +1,31 @@ +using Learn.Domain.Users; +using System; +using System.Collections.Generic; + +namespace Learn.Domain.Chats +{ + public class ChatMember + { + public ChatMemberId Id { get; private set; } + public ChatId ChatId { get; private set; } + public User User { get; private set; } + public string Name { get => User.Name; } + + private ChatMember() + { + // Only for EF + } + + private ChatMember(User user, ChatId chatId) + { + Id = new ChatMemberId(Guid.NewGuid()); + User = user; + ChatId = chatId; + } + + public static ChatMember CreateNew(User user, ChatId chatId) + { + return new ChatMember(user, chatId); + } + } +} diff --git a/services/learn/Learn.Domain/Chats/ChatmemberId.cs b/services/learn/Learn.Domain/Chats/ChatmemberId.cs new file mode 100644 index 0000000..b063236 --- /dev/null +++ b/services/learn/Learn.Domain/Chats/ChatmemberId.cs @@ -0,0 +1,13 @@ +using Learn.BuildingBlocks.Domain; +using System; + +namespace Learn.Domain.Chats +{ + public class ChatMemberId : TypedIdValueBase + { + public ChatMemberId(Guid value) + : base(value) + { + } + } +} diff --git a/services/learn/Learn.Domain/Chats/IChatRepository.cs b/services/learn/Learn.Domain/Chats/IChatRepository.cs new file mode 100644 index 0000000..40e31ab --- /dev/null +++ b/services/learn/Learn.Domain/Chats/IChatRepository.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Learn.Domain.Chats +{ + public interface IChatRepository + { + public Task AddAsync(Chat chat); + } +} diff --git a/services/learn/Learn.Infrastructure/Configuration/UserContext/UserContext.cs b/services/learn/Learn.Infrastructure/Configuration/UserContext/UserContext.cs new file mode 100644 index 0000000..b78b60f --- /dev/null +++ b/services/learn/Learn.Infrastructure/Configuration/UserContext/UserContext.cs @@ -0,0 +1,16 @@ +using Learn.BuildingBlocks.ExecutionContext; + +namespace Learn.BuildingBlocks.Application.ExecutionContext +{ + public class UserContext : IUserContext + { + private readonly IExecutionContextAccessor _executionContextAccessor; + + public UserContext(IExecutionContextAccessor executionContextAccessor) + { + _executionContextAccessor = executionContextAccessor; + } + + public string Email => new(_executionContextAccessor.Email); + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/ChatEntityConfiguration.cs b/services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/ChatEntityConfiguration.cs new file mode 100644 index 0000000..63e8c2c --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/ChatEntityConfiguration.cs @@ -0,0 +1,35 @@ +using Learn.Domain.Chats; +using Learn.Domain.Users; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using System.Collections.Generic; + +namespace Learn.Infrastructure.EntityFramework.EntityConfigurations +{ + public class ChatEntityConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder entity) + { + entity.ToTable("chat"); + + entity + .Property(c => c.Id) + .HasColumnType("uuid") + .IsRequired(); + + entity.HasKey(c => c.Id); + + entity + .Property(c => c.Name) + .IsRequired(); + + entity + .HasOne(c => c.CreatedBy); + + entity + .HasMany(c => c.Members) + .WithOne() + .HasForeignKey("ChatId"); + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/ChatMemberEntityConfiguration.cs b/services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/ChatMemberEntityConfiguration.cs new file mode 100644 index 0000000..51f5553 --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/EntityConfigurations/ChatMemberEntityConfiguration.cs @@ -0,0 +1,25 @@ +using Learn.Domain.Chats; +using Learn.Domain.Users; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Learn.Infrastructure.EntityFramework.EntityConfigurations +{ + public class ChatMemberEntityConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder entity) + { + entity.ToTable("chat_member"); + + entity + .Property(cm => cm.Id) + .HasColumnType("uuid") + .IsRequired(); + + entity.HasKey(cm => cm.Id); + + entity + .HasOne(cm => cm.User); + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/LearnDbContext.cs b/services/learn/Learn.Infrastructure/EntityFramework/LearnDbContext.cs index ace0e99..13acbd3 100644 --- a/services/learn/Learn.Infrastructure/EntityFramework/LearnDbContext.cs +++ b/services/learn/Learn.Infrastructure/EntityFramework/LearnDbContext.cs @@ -1,6 +1,7 @@ using Microsoft.EntityFrameworkCore; using Learn.Infrastructure.EntityFramework.EntityConfigurations; using Learn.Domain.Users; +using Learn.Domain.Chats; namespace Learn.Infrastructure.EntityFramework { @@ -10,6 +11,10 @@ public class LearnDbContext : DbContext public DbSet Roles { get; set; } + public DbSet Chats { get; set; } + + public DbSet ChatMembers { get; set; } + public LearnDbContext() : base() { } public LearnDbContext(DbContextOptions options) : base(options) { } diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102192744_AddChats.Designer.cs b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102192744_AddChats.Designer.cs new file mode 100644 index 0000000..9cfb7ce --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102192744_AddChats.Designer.cs @@ -0,0 +1,172 @@ +// +using System; +using Learn.Infrastructure.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Learn.Infrastructure.EntityFramework.Migrations +{ + [DbContext(typeof(LearnDbContext))] + [Migration("20211102192744_AddChats")] + partial class AddChats + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 63) + .HasAnnotation("ProductVersion", "5.0.11") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + modelBuilder.Entity("Learn.Domain.Chats.Chat", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_chat"); + + b.ToTable("chat"); + }); + + modelBuilder.Entity("Learn.Domain.Chats.ChatMember", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ChatId") + .HasColumnType("uuid") + .HasColumnName("chat_id"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_chat_member"); + + b.HasIndex("ChatId") + .HasDatabaseName("ix_chat_member_chat_id"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_chat_member_user_id"); + + b.ToTable("chat_member"); + }); + + modelBuilder.Entity("Learn.Domain.Users.Role", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_role"); + + b.HasIndex("Name") + .IsUnique() + .HasDatabaseName("ix_role_name"); + + b.ToTable("role"); + }); + + modelBuilder.Entity("Learn.Domain.Users.User", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_user"); + + b.HasIndex("Email") + .IsUnique() + .HasDatabaseName("ix_user_email"); + + b.ToTable("user"); + }); + + modelBuilder.Entity("user_role", b => + { + b.Property("role_id") + .HasColumnType("uuid") + .HasColumnName("role_id"); + + b.Property("user_id") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("role_id", "user_id") + .HasName("pk_user_role"); + + b.HasIndex("user_id") + .HasDatabaseName("ix_user_role_user_id"); + + b.ToTable("user_role"); + }); + + modelBuilder.Entity("Learn.Domain.Chats.ChatMember", b => + { + b.HasOne("Learn.Domain.Chats.Chat", null) + .WithMany("Members") + .HasForeignKey("ChatId") + .HasConstraintName("fk_chat_member_chat_chat_id"); + + b.HasOne("Learn.Domain.Users.User", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_chat_member_users_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("user_role", b => + { + b.HasOne("Learn.Domain.Users.Role", null) + .WithMany() + .HasForeignKey("role_id") + .HasConstraintName("fk_user_role_role_role_id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Learn.Domain.Users.User", null) + .WithMany() + .HasForeignKey("user_id") + .HasConstraintName("fk_user_role_user_user_id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Learn.Domain.Chats.Chat", b => + { + b.Navigation("Members"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102192744_AddChats.cs b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102192744_AddChats.cs new file mode 100644 index 0000000..5c3f2ff --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102192744_AddChats.cs @@ -0,0 +1,67 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Learn.Infrastructure.EntityFramework.Migrations +{ + public partial class AddChats : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "chat", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + name = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_chat", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "chat_member", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + chat_id = table.Column(type: "uuid", nullable: true), + user_id = table.Column(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("pk_chat_member", x => x.id); + table.ForeignKey( + name: "fk_chat_member_chat_chat_id", + column: x => x.chat_id, + principalTable: "chat", + principalColumn: "id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_chat_member_users_user_id", + column: x => x.user_id, + principalTable: "user", + principalColumn: "id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "ix_chat_member_chat_id", + table: "chat_member", + column: "chat_id"); + + migrationBuilder.CreateIndex( + name: "ix_chat_member_user_id", + table: "chat_member", + column: "user_id"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "chat_member"); + + migrationBuilder.DropTable( + name: "chat"); + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102200505_AddChatCreatedBy.Designer.cs b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102200505_AddChatCreatedBy.Designer.cs new file mode 100644 index 0000000..65dd9c8 --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102200505_AddChatCreatedBy.Designer.cs @@ -0,0 +1,189 @@ +// +using System; +using Learn.Infrastructure.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Learn.Infrastructure.EntityFramework.Migrations +{ + [DbContext(typeof(LearnDbContext))] + [Migration("20211102200505_AddChatCreatedBy")] + partial class AddChatCreatedBy + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 63) + .HasAnnotation("ProductVersion", "5.0.11") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + modelBuilder.Entity("Learn.Domain.Chats.Chat", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("CreatedById") + .HasColumnType("uuid") + .HasColumnName("created_by_id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_chat"); + + b.HasIndex("CreatedById") + .HasDatabaseName("ix_chat_created_by_id"); + + b.ToTable("chat"); + }); + + modelBuilder.Entity("Learn.Domain.Chats.ChatMember", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ChatId") + .HasColumnType("uuid") + .HasColumnName("chat_id"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_chat_member"); + + b.HasIndex("ChatId") + .HasDatabaseName("ix_chat_member_chat_id"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_chat_member_user_id"); + + b.ToTable("chat_member"); + }); + + modelBuilder.Entity("Learn.Domain.Users.Role", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_role"); + + b.HasIndex("Name") + .IsUnique() + .HasDatabaseName("ix_role_name"); + + b.ToTable("role"); + }); + + modelBuilder.Entity("Learn.Domain.Users.User", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_user"); + + b.HasIndex("Email") + .IsUnique() + .HasDatabaseName("ix_user_email"); + + b.ToTable("user"); + }); + + modelBuilder.Entity("user_role", b => + { + b.Property("role_id") + .HasColumnType("uuid") + .HasColumnName("role_id"); + + b.Property("user_id") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("role_id", "user_id") + .HasName("pk_user_role"); + + b.HasIndex("user_id") + .HasDatabaseName("ix_user_role_user_id"); + + b.ToTable("user_role"); + }); + + modelBuilder.Entity("Learn.Domain.Chats.Chat", b => + { + b.HasOne("Learn.Domain.Users.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .HasConstraintName("fk_chat_users_created_by_id"); + + b.Navigation("CreatedBy"); + }); + + modelBuilder.Entity("Learn.Domain.Chats.ChatMember", b => + { + b.HasOne("Learn.Domain.Chats.Chat", null) + .WithMany("Members") + .HasForeignKey("ChatId") + .HasConstraintName("fk_chat_member_chat_chat_id"); + + b.HasOne("Learn.Domain.Users.User", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_chat_member_users_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("user_role", b => + { + b.HasOne("Learn.Domain.Users.Role", null) + .WithMany() + .HasForeignKey("role_id") + .HasConstraintName("fk_user_role_role_role_id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Learn.Domain.Users.User", null) + .WithMany() + .HasForeignKey("user_id") + .HasConstraintName("fk_user_role_user_user_id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Learn.Domain.Chats.Chat", b => + { + b.Navigation("Members"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102200505_AddChatCreatedBy.cs b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102200505_AddChatCreatedBy.cs new file mode 100644 index 0000000..530588e --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/20211102200505_AddChatCreatedBy.cs @@ -0,0 +1,45 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Learn.Infrastructure.EntityFramework.Migrations +{ + public partial class AddChatCreatedBy : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "created_by_id", + table: "chat", + type: "uuid", + nullable: true); + + migrationBuilder.CreateIndex( + name: "ix_chat_created_by_id", + table: "chat", + column: "created_by_id"); + + migrationBuilder.AddForeignKey( + name: "fk_chat_users_created_by_id", + table: "chat", + column: "created_by_id", + principalTable: "user", + principalColumn: "id", + onDelete: ReferentialAction.Restrict); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "fk_chat_users_created_by_id", + table: "chat"); + + migrationBuilder.DropIndex( + name: "ix_chat_created_by_id", + table: "chat"); + + migrationBuilder.DropColumn( + name: "created_by_id", + table: "chat"); + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/LearnDbContextModelSnapshot.cs b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/LearnDbContextModelSnapshot.cs index 1327869..e0f5ed0 100644 --- a/services/learn/Learn.Infrastructure/EntityFramework/Migrations/LearnDbContextModelSnapshot.cs +++ b/services/learn/Learn.Infrastructure/EntityFramework/Migrations/LearnDbContextModelSnapshot.cs @@ -19,6 +19,56 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasAnnotation("ProductVersion", "5.0.11") .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + modelBuilder.Entity("Learn.Domain.Chats.Chat", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("CreatedById") + .HasColumnType("uuid") + .HasColumnName("created_by_id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_chat"); + + b.HasIndex("CreatedById") + .HasDatabaseName("ix_chat_created_by_id"); + + b.ToTable("chat"); + }); + + modelBuilder.Entity("Learn.Domain.Chats.ChatMember", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ChatId") + .HasColumnType("uuid") + .HasColumnName("chat_id"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_chat_member"); + + b.HasIndex("ChatId") + .HasDatabaseName("ix_chat_member_chat_id"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_chat_member_user_id"); + + b.ToTable("chat_member"); + }); + modelBuilder.Entity("Learn.Domain.Users.Role", b => { b.Property("Id") @@ -85,6 +135,31 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("user_role"); }); + modelBuilder.Entity("Learn.Domain.Chats.Chat", b => + { + b.HasOne("Learn.Domain.Users.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .HasConstraintName("fk_chat_users_created_by_id"); + + b.Navigation("CreatedBy"); + }); + + modelBuilder.Entity("Learn.Domain.Chats.ChatMember", b => + { + b.HasOne("Learn.Domain.Chats.Chat", null) + .WithMany("Members") + .HasForeignKey("ChatId") + .HasConstraintName("fk_chat_member_chat_chat_id"); + + b.HasOne("Learn.Domain.Users.User", "User") + .WithMany() + .HasForeignKey("UserId") + .HasConstraintName("fk_chat_member_users_user_id"); + + b.Navigation("User"); + }); + modelBuilder.Entity("user_role", b => { b.HasOne("Learn.Domain.Users.Role", null) @@ -101,6 +176,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); + + modelBuilder.Entity("Learn.Domain.Chats.Chat", b => + { + b.Navigation("Members"); + }); #pragma warning restore 612, 618 } } diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Repositories/ChatRepository.cs b/services/learn/Learn.Infrastructure/EntityFramework/Repositories/ChatRepository.cs new file mode 100644 index 0000000..f623321 --- /dev/null +++ b/services/learn/Learn.Infrastructure/EntityFramework/Repositories/ChatRepository.cs @@ -0,0 +1,21 @@ +using Learn.Domain.Chats; +using System.Threading.Tasks; + +namespace Learn.Infrastructure.EntityFramework.Repositories.Users +{ + public class ChatRepository : IChatRepository + { + private readonly LearnDbContext _dbContext; + + public ChatRepository(LearnDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task AddAsync(Chat chat) + { + await _dbContext.Chats.AddAsync(chat); + await _dbContext.SaveChangesAsync(); + } + } +} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/IUserRepository.cs b/services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/IUserRepository.cs deleted file mode 100644 index cac2c0e..0000000 --- a/services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/IUserRepository.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Learn.Infrastructure.EntityFramework.Repositories.Users -{ - public interface IUserRepository - { - } -} diff --git a/services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/UserRepository.cs b/services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/UserRepository.cs deleted file mode 100644 index d16b562..0000000 --- a/services/learn/Learn.Infrastructure/EntityFramework/Repositories/Users/UserRepository.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Learn.Infrastructure.EntityFramework.Repositories.Users -{ - public class UserRepository : IUserRepository - { - - } -} diff --git a/services/learn/Learn.Infrastructure/InfrastructureDependencyInjection.cs b/services/learn/Learn.Infrastructure/InfrastructureDependencyInjection.cs index e174e0d..48e32c0 100644 --- a/services/learn/Learn.Infrastructure/InfrastructureDependencyInjection.cs +++ b/services/learn/Learn.Infrastructure/InfrastructureDependencyInjection.cs @@ -1,13 +1,17 @@ +using Learn.BuildingBlocks.Application.ExecutionContext; +using Learn.BuildingBlocks.ExecutionContext; using Learn.BuildingBlocks.Infrastructure; using Learn.BuildingBlocks.Infrastructure.Options; +using Learn.Domain.Chats; using Learn.Infrastructure.EntityFramework; +using Learn.Infrastructure.EntityFramework.Repositories.Users; using Learn.Infrastructure.EntityFramework.Seeding; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using System; namespace Learn.Infrastructure { @@ -18,6 +22,9 @@ public static IServiceCollection AddInfrastructure(this IServiceCollection servi services.AddOptions(configuration); services.AddDatabaseContext(configuration); + services.AddRepositories(); + services.AddUserContext(); + return services; } @@ -44,6 +51,22 @@ private static IServiceCollection AddOptions(this IServiceCollection services, I return services; } + private static IServiceCollection AddRepositories(this IServiceCollection services) + { + services.AddTransient(); + + return services; + } + + private static IServiceCollection AddUserContext(this IServiceCollection services) + { + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + + return services; + } + private static IServiceCollection AddDatabaseContext(this IServiceCollection services, IConfiguration configuration) { var databaseOptions = configuration.GetSection(DatabaseOptions.Location).Get(); diff --git a/services/learn/Learn.Infrastructure/Learn.Infrastructure.csproj b/services/learn/Learn.Infrastructure/Learn.Infrastructure.csproj index 1f15b05..21e0c45 100644 --- a/services/learn/Learn.Infrastructure/Learn.Infrastructure.csproj +++ b/services/learn/Learn.Infrastructure/Learn.Infrastructure.csproj @@ -6,6 +6,7 @@ +