{"id":31396242,"url":"https://github.com/aasmirnov-webdev/mfti_csharp-developer_final_project","last_synced_at":"2026-05-09T16:04:04.837Z","repository":{"id":315830889,"uuid":"1060956103","full_name":"AASmirnov-Webdev/MFTI_CSharp-Developer_Final_Project","owner":"AASmirnov-Webdev","description":"Выполнение финального проекта в рамках обучения по программе профессиональной переподготовки \"C#-разработчик\" в МФТИ","archived":false,"fork":false,"pushed_at":"2025-09-21T01:15:32.000Z","size":42,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-21T03:11:22.883Z","etag":null,"topics":["api","asp-net-core-web-api","backend","clean-architecture","csharp","ddd","dotnet","solid"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AASmirnov-Webdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-21T00:03:08.000Z","updated_at":"2025-09-21T01:22:14.000Z","dependencies_parsed_at":"2025-09-21T03:11:31.954Z","dependency_job_id":"4fb94a12-a012-4073-b160-cb192c80f330","html_url":"https://github.com/AASmirnov-Webdev/MFTI_CSharp-Developer_Final_Project","commit_stats":null,"previous_names":["aasmirnov-webdev/mfti_csharp-developer_final_project"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/AASmirnov-Webdev/MFTI_CSharp-Developer_Final_Project","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AASmirnov-Webdev%2FMFTI_CSharp-Developer_Final_Project","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AASmirnov-Webdev%2FMFTI_CSharp-Developer_Final_Project/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AASmirnov-Webdev%2FMFTI_CSharp-Developer_Final_Project/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AASmirnov-Webdev%2FMFTI_CSharp-Developer_Final_Project/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AASmirnov-Webdev","download_url":"https://codeload.github.com/AASmirnov-Webdev/MFTI_CSharp-Developer_Final_Project/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AASmirnov-Webdev%2FMFTI_CSharp-Developer_Final_Project/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277503542,"owners_count":25829216,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-29T02:00:09.175Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","asp-net-core-web-api","backend","clean-architecture","csharp","ddd","dotnet","solid"],"created_at":"2025-09-29T11:11:08.267Z","updated_at":"2025-09-29T11:11:09.228Z","avatar_url":"https://github.com/AASmirnov-Webdev.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Финальный проект в рамках обучения по программе профессиональной переподготовки \"C#-разработчик\" в МФТИ\n\n### Веб-приложение для автоматизации бизнес-процессов зоопарка с использованием Domain-Driven Design и Clean Architecture.\n\n# Описание задания\n\n### Вам предстоит разработать веб-приложение для автоматизации следующих бизнес-процессов зоопарка: управление животными; вольерами; расписанием кормлений.\n\nВ ходе общения с заказчиком были выявлены следующие требования к функциональности проектируемого модуля веб-приложения\n\n`Use Cases`:\n- Добавить / удалить животное\n- Добавить / удалить вольер\n- Переместить животное между вольерами\n- Просмотреть расписание кормления\n- Добавить новое кормление в расписание\n- Просмотреть статистику зоопарка (кол-во животных, свободные вольеры и т.д.).\n\nПосле встречи с доменными экспертами. \n\nВы определили три основных класса: `Animal`, `Enclosure` и `FeedingSchedule`. Архитектор проекта предложил вам следующий вариант создания богатой модели предметной области:\n\nЖивотное (`Animal`)\n- Вид, кличка, дата рождения, пол, любимая еда, статус (здоров/болен)\n- Методы: кормить, лечить, переместить в другой вольер\n\nВольер (`Enclosure`)\n- Тип (для хищников, травоядных, птиц, аквариум и т.д.), размер, текущее количество животных, максимальная вместимость\n- Методы: добавить животное, убрать животное, провести уборку\n\nРасписание кормления (`FeedingSchedule`)\n- Животное, время кормления, тип пищи\n- Методы: изменить расписание, отметить выполнение\n\nВыявление `Value Object` оставили на ваше усмотрение.\n\nНа kickoff митинге с командой было приняли решение, в первую очередь, реализовать следующие сервисы:\n- `AnimalTransferService` (для перемещения животных между вольерами)\n- `FeedingOrganizationService` (для организации процесса кормления)\n- `ZooStatisticsService` (для сбора статистики по зоопарку)\n\nОпределить и реализовать следующие доменные события:\n- `AnimalMovedEvent` (при перемещении животного)\n- `FeedingTimeEvent` (при наступлении времени кормления)\n\nОпределили следующую структуру проекта, согласно **Clean Architecture**:\n- `Domain` (ядро, содержит наши модели)\n- `Application` (содержит сервисы, реализующие бизнес-логику приложения)\n- `Infrastructure` (внешние взаимодействия)\n- `Presentation` (контроллеры нашего веб-приложения)\n\nТРЕБУЕТСЯ\n\n1. Разработать классы доменной модели согласно концепции **Domain-Driven Design**\n2. Построить структуру проекта соблюдая принципы **Clean Architecture**.\n3. В слое представления (`Web API` в архитектурном стиле `REST API`) реализовать следующие контроллеры:\n- Контроллер для работы с животными (просмотр информации о животных, добавление новых, удаление);\n- Контроллер для работы с вольерами;\n4. При помощи инструмента проектирования API (например `Swagger`) произвести тестирование нашего приложения:\n- Добавить новые сущности (вольер, животное, расписание кормления);\n- Получить информации о животных, вольерах и расписание кормления;\n- Выполнить операции кормления, перемещения и т.д.\n5. Хранение данных организовать в виде in-memory хранилища (`Infrastructure Layer`)\n6. Написать отчет, в котором отразить:\n- какие пункты из требуемого функционала вы реализовали и в каких классах \\ модулях их можно увидеть. \n- какие концепции **Domain-Driven Design** и принципы **Clean Architecture** вы применили, скажите в каких классах (модулях).\n\nКритерии оценки\n\n1. Реализация основных требований к функциональности\n2. Соблюдение принципов **Clean Architecture**:\n- Слои должны зависеть только внутрь (`Domain` не зависит ни от чего);\n- Все зависимости между слоями через интерфейсы;\n- Бизнес-логика полностью изолирована в `Domain` и `Application` слоях.\n3. Соблюдены концепции **Domain-Driven Design**:\n- Использование `Value Objects` для примитивов;\n- Инкапсуляция бизнес-правил внутри доменных объектов.\n4. Покрыто тестами более 65% кода.\n\n# Реализация проектного решения\n\n## Архитектура\n\n- **Domain Layer**: Бизнес-логика и доменные модели\n- **Application Layer**: Сервисы приложения\n- **Infrastructure Layer**: Репозитории и данные\n- **API Layer**: Web API контроллеры\n\n## Функциональность\n\n- Управление животными (добавление, удаление, перемещение)\n- Управление вольерами\n- Расписание кормлений\n- Статистика зоопарка\n\n## Технологии\n\n- .NET 8.0\n- ASP.NET Core Web API\n- Swagger\n- Clean Architecture\n- Domain-Driven Design\n\n## Установка и запуск через Visual Studio\n\n1. Клонируйте репозиторий\n2. Откройте `ZooManagement.sln`\n3. Установите `API` как Startup Project\n4. Нажмите F5 или Ctrl + F5\n5. Перейдите: `https://localhost:7201/swagger`\n\n\n## xUnit-Тестирование через Visual Studio\n\n1. Откройте Test Explorer (Test → Test Explorer)\n2. Нажмите \"Run All Tests\"\n\n## Тестирование приложения через API Endpoints\n\nИспользуйте Swagger UI для тестирования API endpoints после запуска:\n \n- Swagger UI: `https://localhost:7201/swagger`\n- Animals API: `https://localhost:7201/api/Animals`\n- Enclosures API: `https://localhost:7201/api/Enclosures`\n- Statistics API: `https://localhost:7201/api/Statistics`\n\n## Отчет по проекту!\n\n### 1. Реализованный функционал\n\nUse Cases из задания:\n\na. Добавить / удалить животное:\n- Контроллер: `AnimalsController` (POST /api/Animals, DELETE /api/Animals/{id})\n- Сервис: `InMemoryAnimalRepository` (AddAsync, DeleteAsync)\n- Модель: `Animal` entity\n\nb. Добавить / удалить вольер\n- Контроллер: `EnclosuresController` (POST /api/Enclosures, DELETE /api/Enclosures/{id})\n- Сервис: `InMemoryEnclosureRepository` (AddAsync, DeleteAsync)\n- Модель: `Enclosure` entity\n\nc. Переместить животное между вольерами\n- Контроллер: `AnimalsController` (POST /api/Animals/{id}/transfer/{enclosureId})\n- Сервис: `AnimalTransferService` (TransferAnimal)\n- Событие: `AnimalMovedEvent`\n\nd. Просмотреть расписание кормления\n- Контроллер: `FeedingSchedulesController` (GET /api/FeedingSchedules)\n- Сервис: `InMemoryFeedingScheduleRepository` (GetAllAsync, GetByAnimalIdAsync)\n- Модель: `FeedingSchedule` entity\n\ne. Добавить новое кормление в расписание\n- Контроллер: `FeedingSchedulesController` (POST /api/FeedingSchedules)\n- Сервис: `FeedingOrganizationService` (ScheduleFeedingAsync)\n- Модель: `FeedingSchedule` entity\n\nf. Просмотреть статистику зоопарка\n- Контроллер: `StatisticsController` (GET /api/Statistics/zoo, GET /api/Statistics/feeding)\n- Сервис: `ZooStatisticsService` (GetStatistics)\n- Сервис: `FeedingOrganizationService` (GetFeedingStatisticsAsync)\n\nДополнительный реализованный функционал:\n- Отметка кормления как выполненного: `FeedingSchedulesController` (POST /api/FeedingSchedules/{id}/complete)\n- Уборка вольеров: `EnclosuresController` (POST /api/Enclosures/{id}/clean)\n- Просмотр предстоящих кормлений: `FeedingSchedulesController` (GET /api/FeedingSchedules/upcoming)\n- Получение животных по ID: `AnimalsController` (GET /api/Animals/{id})\n- Получение вольеров по ID: `EnclosuresController` (GET /api/Enclosures/{id})\n\nРазработаны и успешно пройдены 12 Unit-тестов (Tests) примерно 70% покрытия кода\n\nОписание тестов:\n1. `Animal_Feed_Should_Raise_AnimalFedEvent` - проверяет генерацию события кормления\n2. `Animal_Heal_Should_Set_IsHealthy_To_True` - проверяет лечение животного\n3. `Enclosure_AddAnimal_Should_Increase_CurrentCapacity` - проверяет добавление животного в вольер\n4. `Enclosure_AddAnimal_When_Full_Should_Throw_Exception` - проверяет обработку переполнения вольера\n5. `FeedingSchedule_MarkAsCompleted_Should_Set_IsCompleted_To_True` - проверяет отметку кормления\n6. `FeedingSchedule_Reschedule_Should_Change_FeedingTime` - проверяет изменение времени кормления\n7. `AnimalTransferService_TransferAnimal_Should_Move_Animal_Successfully` - тестирует сервис перемещения\n8. `AnimalTransferService_TransferAnimal_When_TargetEnclosure_Full_Should_Throw_Exception` - тестирует ошибки перемещения\n9. `FeedingOrganizationService_ScheduleFeeding_Should_Create_FeedingSchedule` - тестирует создание расписания\n10. `ZooStatisticsService_GetStatistics_Should_Return_Correct_Statistics` - тестирует статистику\n11. `EntityBase_Equals_Should_Work_Correctly` - тестирует сравнение сущностей\n12. `DomainEvent_Should_Have_Correct_Properties` - тестирует свойства событий\n\n### 2. Примененные концепции **Domain-Driven Design** и **Clean Architecture**\n\n### Clean Architecture:\n\n1. Domain Layer (`Domain`)\n- Сущности: `Animal`, `Enclosure`, `FeedingSchedule`, `EntityBase`\n- События: `DomainEvent`, `AnimalMovedEvent`, `FeedingTimeEvent`, `AnimalFedEvent`, `FeedingCompletedEvent`\n- Интерфейсы: `IAnimalRepository`, `IEnclosureRepository`, `IFeedingScheduleRepository`\n- Принцип: Ядро системы не зависит от внешних слоев\n\n2. Application Layer (`Application`)\n- Сервисы: `AnimalTransferService`, `FeedingOrganizationService`, `ZooStatisticsService`\n- DTO: `CreateAnimalRequest`, `CreateEnclosureRequest`, `CreateFeedingScheduleRequest`, `AnimalResponse`, `EnclosureResponse`\n- Принцип: Содержит бизнес-логику приложения, зависит только от `Domain` Layer\n\n3. Infrastructure Layer (`Infrastructure`)\nРеализации репозиториев: `InMemoryAnimalRepository`, `InMemoryEnclosureRepository`, `InMemoryFeedingScheduleRepository`\nПринцип: Реализация внешних зависимостей, зависит от `Domain` и `Application` Layers\n\n4. Presentation Layer (`API`)\n- Контроллеры: `AnimalsController`, `EnclosuresController`, `FeedingSchedulesController`, `StatisticsController`\n- Принцип: Внешний интерфейс системы, зависит от `Application` Layer\n\n### Domain-Driven Design:\n\n1. Rich Domain Model\n- Классы: `Animal`, `Enclosure`, `FeedingSchedule`\n  Поведение в сущностях:\n- `Animal.Feed()`, `Animal.Heal()`, `Animal.MoveToEnclosure()`\n- `Enclosure.AddAnimal()`, `Enclosure.RemoveAnimal()`, `Enclosure.Clean()`\n- `FeedingSchedule.MarkAsCompleted()`, `FeedingSchedule.Reschedule()`\n\n2. Aggregate Roots\n- Сущности: `Animal`, `Enclosure`, `FeedingSchedule` как корни агрегатов\n- Инварианты: `Enclosure.CanAddAnimal()` проверяет вместимость\n\n3. Domain Events\n- События: `AnimalMovedEvent`, `FeedingTimeEvent`, `AnimalFedEvent`, `FeedingCompletedEvent`\n- Генерация: Вызываются через `AddDomainEvent()` в методах доменных сущностей\n\n4. Repositories Pattern\n- Интерфейсы: `IAnimalRepository`, `IEnclosureRepository`, `IFeedingScheduleRepository`\n- Реализации: InMemory репозитории в `Infrastructure` Layer\n- Принцип: Разделение ответственности за доступ к данным\n\n5. Value Objects\n- Реализация: DTO классы в Application Layer (`AnimalResponse`, `EnclosureResponse`)\n- Назначение: Передача данных между слоями без экспозиции доменных сущностей\n\n6. Bounded Contexts\n- Контекст управления животными: `Animal` entity + `AnimalTransferService`\n- Контекст управления вольерами: `Enclosure` entity\n- Контекст кормления: `FeedingSchedule` entity + `FeedingOrganizationService`\n- Контекст статистики: `ZooStatisticsService`\n\n### Принципы SOLID и Clean Code:\n\nSingle Responsibility Principle\n- Каждый сервис и контроллер имеет одну ответственность\n- Репозитории отвечают только за доступ к данным\n\nDependency Inversion Principle\n- Интерфейсы репозиториев в Domain Layer\n- Реализации в Infrastructure Layer\n- Dependency Injection через конструкторы\n\nOpen/Closed Principle\n- Легко добавить новые репозитории (например, для БД)\n- Возможность расширения функционала через новые сервисы\n\nInterface Segregation Principle\n- Каждый репозиторий имеет свой специализированный интерфейс\n\nТестирование:\nUnit Tests (`Tests`)\n- Тесты доменных сущностей: `AnimalTests`, `EnclosureTests`, `FeedingScheduleTests`\n- Тесты сервисов: `AnimalTransferServiceTests`, `FeedingOrganizationServiceTests`, `ZooStatisticsServiceTests`\n\n### 3. Технологический стек\n- `.NET 8.0` - основная платформа\n- `ASP.NET Core Web API` - веб-фреймворк\n- `Swagger` - документация и тестирование API\n- `xUnit` - фреймворк для unit-тестирования\n- `FluentAssertions` - библиотека для assertions\n- `In-Memory Storage` - временное хранилище данных\n\n### 4. Архитектурные решения\n\nIn-Memory репозитории\n- Быстрая реализация для демонстрации\n- Легко заменить на реальную БД\n\nSeparation of Concerns\n- Четкое разделение между слоями\n- Легкая поддержка и тестирование\n\nEvent-Driven Architecture\n- Доменные события для отслеживания изменений\n- Возможность добавления обработчиков событий\n\n---\n## Вывод: Проект успешно реализует все требуемые функции с соблюдением принципов Clean Architecture и Domain-Driven Design.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faasmirnov-webdev%2Fmfti_csharp-developer_final_project","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faasmirnov-webdev%2Fmfti_csharp-developer_final_project","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faasmirnov-webdev%2Fmfti_csharp-developer_final_project/lists"}