Skip to content

Commit 5b5fc21

Browse files
committed
Актуализирована документация модуля Core
1 parent cada2ca commit 5b5fc21

1 file changed

Lines changed: 231 additions & 1 deletion

File tree

docs/modules/core.md

Lines changed: 231 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,233 @@
11
# Core
22

3-
TODO
3+
## Назначение
4+
5+
Модуль `core` содержит общие сущности и инфраструктурные helper'ы, которые
6+
переиспользуются другими доменными модулями Procollab.
7+
8+
В модуле находятся:
9+
10+
- generic-модели лайков, просмотров и ссылок;
11+
- справочники навыков и специализаций;
12+
- generic-связи навыков и специализаций с объектами;
13+
- REST endpoints справочника навыков;
14+
- общие serializers, permissions и pagination;
15+
- helpers для Excel-выгрузок;
16+
- cache-ключи онлайна пользователей;
17+
- WebSocket JWT middleware;
18+
- logging middleware.
19+
20+
## Статус модуля
21+
22+
`core` подключен в публичный API через `/core/`, но публичная API-поверхность
23+
сейчас ограничена endpoints навыков.
24+
25+
Модуль является shared-слоем: изменения в нем могут затронуть `users`,
26+
`projects`, `news`, `feed`, `vacancy`, `partner_programs`, `courses`,
27+
`project_rates`, `metrics` и `chats`.
28+
29+
Собственных тестов у `core` сейчас нет. Часть поведения косвенно покрывается
30+
тестами зависимых модулей.
31+
32+
## Основные возможности
33+
34+
- хранение generic-лайков через `Like`;
35+
- хранение generic-просмотров через `View`;
36+
- хранение generic-ссылок через `Link`;
37+
- справочник навыков `SkillCategory` / `Skill`;
38+
- generic-привязка навыков через `SkillToObject`;
39+
- справочник специализаций `SpecializationCategory` / `Specialization`;
40+
- generic-привязка специализаций через `SpecializationToObject`;
41+
- получение навыков nested-списком по категориям;
42+
- получение навыков плоским paginated-списком с фильтром по названию;
43+
- подготовка XLSX-файлов в памяти;
44+
- безопасная подготовка имени файла и значений Excel-ячеек;
45+
- построение download-response для XLSX;
46+
- формирование ключей online-cache;
47+
- JWT-аутентификация WebSocket через subprotocol;
48+
- перехват стандартного logging в loguru.
49+
50+
## Архитектура
51+
52+
- `core/models.py` - generic-модели, навыки и специализации.
53+
- `core/views.py` - API справочника навыков.
54+
- `core/serializers.py` - serializers навыков и общие request serializers.
55+
- `core/services.py` - лайки, просмотры, ссылки и Base64 image encoder.
56+
- `core/utils.py` - email helper, online-cache keys и Excel helpers.
57+
- `core/permissions.py` - общие permissions.
58+
- `core/pagination.py` - общий limit/offset pagination.
59+
- `core/filters.py` - фильтр навыков.
60+
- `core/fields.py` - кастомное поле списка для comma-separated значений.
61+
- `core/auth/middleware.py` - WebSocket JWT auth middleware.
62+
- `core/log/` - интеграция стандартного logging с loguru.
63+
- `core/admin.py` - Django admin для core-сущностей.
64+
65+
## Ключевые сущности
66+
67+
- `Like` - generic-лайк пользователя к объекту через `ContentType`.
68+
- `View` - generic-просмотр пользователя к объекту через `ContentType`.
69+
- `Link` - generic-ссылка, привязанная к объекту через `ContentType`.
70+
- `SkillCategory` - категория навыка.
71+
- `Skill` - навык внутри категории.
72+
- `SkillToObject` - generic-связь навыка с пользователем, вакансией, проектом
73+
или другим объектом.
74+
- `SpecializationCategory` - категория специализации.
75+
- `Specialization` - специализация внутри категории.
76+
- `SpecializationToObject` - generic-связь специализации с объектом.
77+
78+
## API
79+
80+
- `GET /core/skills/nested/` - категории навыков со вложенным списком навыков.
81+
- `GET /core/skills/inline/` - плоский список навыков с pagination.
82+
83+
Фильтр для `/core/skills/inline/`:
84+
85+
- `name__icontains` - поиск навыка по части названия.
86+
87+
Pagination:
88+
89+
- `limit`, по умолчанию `10`;
90+
- `offset`.
91+
92+
Справочник специализаций физически хранится в `core`, но endpoints находятся в
93+
модуле `users`:
94+
95+
- `GET /auth/users/specializations/nested/`;
96+
- `GET /auth/users/specializations/inline/`.
97+
98+
## Основные сценарии
99+
100+
### 1. Фронт получает справочник навыков
101+
102+
Для отображения навыков по категориям используется:
103+
104+
```text
105+
GET /core/skills/nested/
106+
```
107+
108+
Для поиска и autocomplete используется:
109+
110+
```text
111+
GET /core/skills/inline/?name__icontains=python
112+
```
113+
114+
### 2. Модуль привязывает навыки к объекту
115+
116+
Доменные модули создают `SkillToObject` через `ContentType`.
117+
118+
Например:
119+
120+
- `users` хранит навыки пользователя;
121+
- `vacancy` хранит требуемые навыки вакансии;
122+
- serializers используют `SkillToObjectSerializer` для единого response
123+
формата навыка.
124+
125+
### 3. Модуль фиксирует лайк или просмотр
126+
127+
`core.services` предоставляет функции:
128+
129+
- `set_like(obj, user, is_liked)`;
130+
- `add_like(obj, user)`;
131+
- `remove_like(obj, user)`;
132+
- `is_fan(obj, user)`;
133+
- `get_likes_count(obj)`;
134+
- `set_viewed(obj, user, is_viewed)`;
135+
- `add_view(obj, user)`;
136+
- `remove_view(obj, user)`;
137+
- `is_viewer(obj, user)`;
138+
- `get_views_count(obj)`.
139+
140+
Эти функции используются в `news`, `feed`, `partner_programs`,
141+
`project_rates` и других местах, где нужен generic-счетчик.
142+
143+
Важно: не все лайки в проекте уже переведены на generic-модель `core.Like`.
144+
Например, у проектов и мероприятий еще есть отдельные legacy-модели лайков.
145+
146+
### 4. Модуль формирует XLSX-выгрузку
147+
148+
Для выгрузок используются:
149+
150+
- `XlsxFileToExport`;
151+
- `sanitize_excel_value`;
152+
- `build_xlsx_download_response`.
153+
154+
Эти helpers применяются в `partner_programs`, `project_rates`, `courses`,
155+
`users` и `vacancy`.
156+
157+
### 5. WebSocket подключение проходит JWT-аутентификацию
158+
159+
`TokenAuthMiddleware` подключен в `procollab/asgi.py`.
160+
161+
Он ожидает WebSocket subprotocols в формате:
162+
163+
```text
164+
["Bearer", "<JWT>"]
165+
```
166+
167+
После проверки JWT middleware записывает пользователя в `scope["user"]`.
168+
Этим пользуется `chats.ChatConsumer`.
169+
170+
### 6. Чаты обновляют online-cache
171+
172+
`core.utils` содержит функции:
173+
174+
- `get_user_online_cache_key(user)`;
175+
- `get_users_online_cache_key()`.
176+
177+
`chats` пишет в эти ключи при подключении и отключении пользователя, а
178+
`metrics` читает aggregate-ключ для отображения количества пользователей онлайн.
179+
180+
## Связи с другими модулями
181+
182+
- `users` - навыки, специализации, online-флаги, Excel-выгрузки и permissions.
183+
- `vacancy` - required skills через `SkillToObject`, admin inline и выгрузки.
184+
- `projects` - общие serializers/permissions, счетчики просмотров, online
185+
данные пользователей.
186+
- `news` - generic likes/views.
187+
- `feed` - generic likes/views для записей ленты.
188+
- `partner_programs` - generic likes/views и Excel-выгрузки.
189+
- `project_rates` - счетчики просмотров проектов и выгрузки.
190+
- `courses` - Excel-выгрузка результатов.
191+
- `chats` - WebSocket auth и online-cache keys.
192+
- `metrics` - чтение online-cache.
193+
- `industries` и `events` - переиспользуют общие permissions.
194+
195+
## Ограничения и риски
196+
197+
- У `core` нет собственных тестов; shared-поведение проверяется в основном
198+
косвенно через другие модули.
199+
- `remove_link()` в `core.services` фильтрует `Like`, а не `Link`; это выглядит
200+
как баг.
201+
- `get_views_count()` кеширует значение, но `add_view()` / `remove_view()` не
202+
инвалидируют кеш.
203+
- `get_likes_count()` не использует кеш, хотя `LIKES_CACHING_TIMEOUT` объявлен.
204+
- `Skill`, `SkillCategory`, `Specialization` и `SpecializationCategory` не имеют
205+
уникальности по `name`.
206+
- `SkillToObject` и `SpecializationToObject` не ограничивают дубли на уровне
207+
модели.
208+
- `Base64ImageEncoder.get_encoded_base64_from_url()` использует `urlopen` без
209+
timeout.
210+
- `TokenAuthentication.authenticate()` не обрабатывает отсутствие пользователя
211+
после декодирования JWT.
212+
- `CustomLoguruMiddleware` пишет логи в директорию `log/` внутри `BASE_DIR`;
213+
окружение должно гарантировать доступность этой директории.
214+
- `CustomListField` преобразует список в строку через запятую и обратно; формат
215+
подходит не для всех типов значений.
216+
217+
## Тесты
218+
219+
Собственных тестов у модуля сейчас нет:
220+
221+
```text
222+
DEBUG=True .venv/bin/python manage.py test core
223+
```
224+
225+
Текущий запуск находит `0` тестов.
226+
227+
Поведение `core` частично покрывается тестами зависимых модулей:
228+
229+
- `news` и `feed` проверяют generic likes/views;
230+
- `vacancy` и `users` проверяют работу навыков;
231+
- `metrics` проверяет online-cache keys;
232+
- `partner_programs`, `project_rates`, `courses` проверяют Excel-выгрузки через
233+
общие helpers.

0 commit comments

Comments
 (0)