Projects отвечают за проектную часть Procollab: создание и редактирование проектов, публичность, участие команды, связь с партнерскими программами, целями, ресурсами, компаниями, вакансиями, подписками и пользовательскими действиями вокруг проекта.
Модуль рабочий, но находится в состоянии технического долга. Основная логика
исторически сосредоточена в крупных файлах projects/views.py,
projects/serializers.py и projects/models.py.
Перед активным рефакторингом модуль требует:
- поддержки regression-тестов при дальнейшем рефакторинге;
- уточнения актуальных и legacy-сценариев;
- разделения бизнес-логики из views/serializers на более явные service/query слои;
- проверки endpoints участников проекта и обновления проекта.
- создание и редактирование проекта;
- просмотр публичных проектов;
- скрытие проекта из общего каталога через
is_public; - работа с черновиками через
draft; - привязка проекта к партнерской программе;
- дублирование проекта в партнерскую программу;
- управление участниками проекта;
- смена лидера проекта;
- подписка и отписка от проекта;
- лайки и просмотры проекта;
- цели проекта;
- ресурсы проекта;
- компании-партнеры проекта;
- вакансии и отклики по проекту;
- отображение проекта в чате, новостях и ленте через связанные модули.
projects/models.py- модели проекта, участников, целей, компаний, ресурсов, ссылок и достижений.projects/views.py- HTTP endpoints и значительная часть orchestration logic.projects/serializers.py- request/response contracts, часть validation и часть бизнес-логики создания/обновления связей.projects/permissions.py- правила видимости проекта и доступа к операциям.projects/helpers.py- вспомогательная бизнес-логика: рекомендации пользователей, обновление ссылок/достижений, привязка к программе.projects/managers.py- queryset helpers для списков, деталей и счетчиков.projects/signals.py- side effects при сохранении проекта.projects/admin.py- настройка Django admin.projects/tests/helpers.py- тестовые builders/factories для проектов, пользователей, программ, компаний и ресурсов.projects/tests/test_*.py- regression-тесты API и ключевых правил модуля.
Project- проект.Collaborator- участник проекта.ProjectLink- ссылка проекта.Achievement- достижение проекта.ProjectGoal- цель проекта.Company- компания.ProjectCompany- связь проекта и компании.Resource- ресурс проекта.- проектные новости - новости внутри проекта; актуальный API реализован через
news.Newsс привязкой кProjectчерезcontent_type/object_id. DefaultProjectCover- дефолтная обложка проекта.DefaultProjectAvatar- дефолтный аватар проекта.
GET /projects/- список публичных проектов.POST /projects/- создание проекта.GET /projects/<id>/- детали проекта.PATCH /projects/<id>/- частичное обновление проекта.PUT /projects/<id>/- полное обновление проекта.DELETE /projects/<id>/- удаление проекта.POST /projects/<id>/like/- лайк проекта.GET /projects/count/- счетчики проектов.GET /projects/<id>/recommended_users- рекомендованные пользователи.GET /projects/<id>/collaborators/- список участников проекта.POST /projects/<id>/collaborators/- добавление участников проекта.DELETE /projects/<id>/collaborators/- удаление участника проекта.DELETE /projects/<id>/collaborators/leave/- выход пользователя из проекта.PATCH /projects/<project_id>/collaborators/<user_id>/switch-leader/- смена лидера проекта.GET /projects/<id>/news/- список новостей внутри проекта.POST /projects/<id>/news/- создание новости проекта.GET /projects/<id>/news/<news_id>/- детальная новость проекта.PATCH /projects/<id>/news/<news_id>/- редактирование новости проекта.DELETE /projects/<id>/news/<news_id>/- удаление новости проекта.POST /projects/<id>/news/<news_id>/set_viewed/- просмотр новости проекта.POST /projects/<id>/news/<news_id>/set_liked/- лайк новости проекта.POST /projects/<id>/subscribe/- подписка на проект.POST /projects/<id>/unsubscribe/- отписка от проекта.GET /projects/<id>/subscribers/- подписчики проекта.GET /projects/<id>/goals/- цели проекта.POST /projects/<id>/goals/- массовое создание целей проекта.GET /projects/<id>/goals/<goal_id>/- детальная цель проекта.PATCH /projects/<id>/goals/<goal_id>/- обновление цели проекта.GET /projects/<id>/resources/- ресурсы проекта.POST /projects/<id>/resources/- создание ресурса проекта.GET /projects/<id>/resources/<resource_id>/- детальный ресурс проекта.PATCH /projects/<id>/resources/<resource_id>/- обновление ресурса.POST /projects/<id>/companies/- создание или привязка компании к проекту.GET /projects/<id>/companies/list/- список компаний проекта.PATCH /projects/<id>/companies/<company_id>/- обновление связи с компанией.DELETE /projects/<id>/companies/<company_id>/- удаление связи с компанией.POST /projects/assign-to-program/- дублирование проекта и привязка к партнерской программе.GET /projects/<id>/responses/- отклики на вакансии проекта.
Пользователь создает проект через POST /projects/. Лидер проекта
подставляется из текущего пользователя.
После создания проекта срабатывают side effects:
- создается
Collaboratorдля лидера проекта; - если проект опубликован, создается
ProjectChat; - при изменении
draftсинхронизируется активность вакансий и новости в ленте.
Если при создании передан partner_program_id, проект дополнительно
привязывается к партнерской программе.
Пользователь открывает список проектов или карточку проекта. В публичном
каталоге отображаются проекты с draft = False и is_public = True.
Детальный просмотр проекта учитывает ProjectVisibilityPermission.
Непубличный проект доступен:
- лидеру;
- администраторам;
- участникам команды;
- пользователям с invite;
- менеджерам и экспертам связанной партнерской программы.
Редактирование проекта выполняется через PUT или PATCH.
При обновлении отдельно обрабатываются:
partner_program_id;achievements, если этот сценарий останется актуальным;links, если этот сценарий останется актуальным.
Сейчас часть этой логики находится во view/helper слое и требует последующего выноса в более явный service layer.
Проект хранит участников через модель Collaborator.
Поддерживаются сценарии:
- просмотр участников;
- добавление участников;
- удаление участника;
- выход пользователя из проекта;
- смена лидера проекта.
Если проект привязан к партнерской программе, Collaborator.clean() проверяет,
что добавляемый пользователь является участником этой программы.
Проект может быть связан с партнерской программой через PartnerProgramProject
и PartnerProgramUserProfile.
Привязка учитывает:
- дедлайн подачи проектов;
- завершенность программы;
- участие пользователя в программе;
- возможность менеджера привязывать проект к программе.
Есть отдельный сценарий дублирования проекта в программу через
POST /projects/assign-to-program/.
Проект может содержать:
- цели (
ProjectGoal); - компании-партнеры (
Company,ProjectCompany); - ресурсы (
Resource).
Resource может быть связан с компанией только если эта компания уже является
партнером проекта.
Новости внутри проекта доступны через /projects/<id>/news/.
Несмотря на проектный URL, актуальная реализация использует общий модуль
news: запись хранится в news.News, а связь с проектом задается через
content_type = Project и object_id = project.id.
- Публичный каталог показывает только
draft = Falseиis_public = True. - Непубличные проекты требуют проверки
ProjectVisibilityPermission. - Лидер проекта автоматически становится участником проекта.
- Лидер не должен удаляться из проекта как обычный участник.
- Проект, связанный с программой, ограничивает редактирование после завершения программы.
- Компания может быть связана с проектом только один раз.
- Ресурс может ссылаться только на компанию, уже привязанную к проекту.
- Проектные новости являются живым frontend-сценарием, но текущие routes
используют общий модуль
news.
Для модуля добавлен первый слой regression-тестов и тестовых helpers.
projects/tests/helpers.py содержит builders/factories для повторяемых
сущностей:
- user;
- project;
- collaborator;
- partner program;
- company;
- project company;
- project goal;
- resource.
Текущие regression-тесты проверяют:
- создание проекта и side effects: лидер становится collaborator, создается чат для опубликованного проекта;
PUT /projects/<id>/по frontend-контракту: полное обновление формы проекта, сохранение текущего лидера, привязка к программе черезpartner_program_idдля участника программы и запрет обновления посторонним пользователем;- visibility rules для публичных и непубличных проектов;
- привязка проекта к партнерской программе;
- запрет привязки к программе без участия пользователя в программе;
- дублирование проекта в партнерскую программу с копированием данных и участников;
- запрет дублирования проекта пользователем, который не является лидером;
- upsert компаний проекта;
- создание ресурсов проекта;
- запрет привязки ресурса к компании, которая не является партнером проекта;
- создание списка целей проекта;
- частичное обновление одной цели проекта;
- запрет создания целей пользователем, который не является лидером проекта;
- подписка, отписка и список подписчиков проекта;
- новости проекта: создание лидером, список внутри проекта, detail для модалки, отметка просмотра, лайк/снятие лайка, редактирование и удаление лидером, запрет создания не-лидером;
- участники проекта: просмотр команды, удаление существующего участника лидером, выход участника из проекта, запрет выхода лидера, смена лидера на существующего участника и отказ при смене лидера на пользователя вне команды;
- фильтры списка проектов:
industry,leader,partner_program,is_company,collaborator__user__in; - signals вокруг
draft: публикация проекта активирует вакансии, создает feed-news для вакансий иProjectChat; возврат в черновик деактивирует вакансии и удаляет их feed-news; повторная публикация не создает дубли.