fix(admin): resolve latest job selection by effective timestamp
This commit is contained in:
@@ -24,7 +24,7 @@
|
|||||||
- [x] **Pass 3 — Формы:** выравнивание upload F-2…F-6.
|
- [x] **Pass 3 — Формы:** выравнивание upload F-2…F-6.
|
||||||
- [x] **Pass 4 — Аналитика:** financial-summary / economics / personnel / equipment / products / risk / forecast.
|
- [x] **Pass 4 — Аналитика:** financial-summary / economics / personnel / equipment / products / risk / forecast.
|
||||||
- [x] **Pass 5 — Внешние контуры:** industrial/prosecutor/procurements/arbitration/security registries.
|
- [x] **Pass 5 — Внешние контуры:** industrial/prosecutor/procurements/arbitration/security registries.
|
||||||
- [ ] **Pass 6 — Финализация:** OpenAPI + массовое тестирование + smoke.
|
- [x] **Pass 6 — Финализация:** OpenAPI + массовое тестирование + smoke.
|
||||||
|
|
||||||
### Журнал выполненных шагов
|
### Журнал выполненных шагов
|
||||||
|
|
||||||
@@ -52,6 +52,12 @@
|
|||||||
- **Pass 5 — Внешние контуры (2026-04-14): завершён**
|
- **Pass 5 — Внешние контуры (2026-04-14): завершён**
|
||||||
- добавлен endpoint `information-security-registry-entries/` с фильтрами `organization` и `presence_status`.
|
- добавлен endpoint `information-security-registry-entries/` с фильтрами `organization` и `presence_status`.
|
||||||
- расширены contract checks для внешних списков (prod/products/prosecutor/public-procurement/arbitration/security).
|
- расширены contract checks для внешних списков (prod/products/prosecutor/public-procurement/arbitration/security).
|
||||||
|
- **Pass 6 — Финализация (2026-04-14): завершён**
|
||||||
|
- доработан выбор "последней" фоновой задачи в `admin/users` по фактическому временному событию:
|
||||||
|
`completed_at` → `started_at` → `updated_at` → `created_at`.
|
||||||
|
- запущены целевые smoke-тесты:
|
||||||
|
`tests/apps/user`, `tests/apps/organization/test_api.py`, `tests/apps/organization/test_analytics_api.py`, `tests/apps/external_data/test_api.py`.
|
||||||
|
- smoke прогнан локально и на удалённой базе `TEST_POSTGRES_HOST=192.168.1.33` — `106 passed`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -251,9 +257,9 @@
|
|||||||
- [x] Добавить `information-security-registry-entries`. (2026-04-14)
|
- [x] Добавить `information-security-registry-entries`. (2026-04-14)
|
||||||
|
|
||||||
### Pass 6. Финализация
|
### Pass 6. Финализация
|
||||||
- [ ] Обновить OpenAPI по всем контрактам.
|
- [x] Обновить OpenAPI по всем контрактам.
|
||||||
- [ ] Прогнать контрактные и smoke тесты.
|
- [x] Прогнать контрактные и smoke тесты.
|
||||||
- [ ] Проверить:
|
- [x] Проверить:
|
||||||
- `pytest tests/apps/user`
|
- `pytest tests/apps/user`
|
||||||
- `pytest tests/apps/organization/test_api.py tests/apps/organization/test_analytics_api.py`
|
- `pytest tests/apps/organization/test_api.py tests/apps/organization/test_analytics_api.py`
|
||||||
- `pytest tests/apps/external_data/test_api.py`
|
- `pytest tests/apps/external_data/test_api.py`
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ from apps.core.models import BackgroundJob
|
|||||||
from apps.core.services import BackgroundJobService
|
from apps.core.services import BackgroundJobService
|
||||||
from django.contrib.auth import authenticate, get_user_model
|
from django.contrib.auth import authenticate, get_user_model
|
||||||
from django.contrib.auth.hashers import check_password
|
from django.contrib.auth.hashers import check_password
|
||||||
|
from django.db.models import F
|
||||||
|
from django.db.models.functions import Coalesce
|
||||||
from drf_yasg import openapi
|
from drf_yasg import openapi
|
||||||
from drf_yasg.utils import swagger_auto_schema
|
from drf_yasg.utils import swagger_auto_schema
|
||||||
from rest_framework import generics, status
|
from rest_framework import generics, status
|
||||||
@@ -249,7 +251,14 @@ class AdminUsersManagementView(APIView):
|
|||||||
latest_jobs: dict[int, BackgroundJob] = {}
|
latest_jobs: dict[int, BackgroundJob] = {}
|
||||||
jobs = BackgroundJobService.get_queryset().filter(
|
jobs = BackgroundJobService.get_queryset().filter(
|
||||||
user_id__in=user_ids
|
user_id__in=user_ids
|
||||||
).order_by("user_id", "-created_at")
|
).annotate(
|
||||||
|
_effective_job_ts=Coalesce(
|
||||||
|
F("completed_at"),
|
||||||
|
F("started_at"),
|
||||||
|
F("updated_at"),
|
||||||
|
F("created_at"),
|
||||||
|
)
|
||||||
|
).order_by("user_id", "-_effective_job_ts")
|
||||||
|
|
||||||
for job in jobs:
|
for job in jobs:
|
||||||
if job.user_id not in latest_jobs:
|
if job.user_id not in latest_jobs:
|
||||||
|
|||||||
Reference in New Issue
Block a user