fix(source-cards): scope counters to OPK organizations
Some checks failed
CI/CD Pipeline / Quality Gate (push) Failing after 1m8s
CI/CD Pipeline / Build and Push Images (push) Has been skipped
CI/CD Pipeline / Deploy Dev via Compose (push) Has been skipped
CI/CD Pipeline / Internal Notify (push) Successful in 1s

This commit is contained in:
2026-08-18 10:59:40 +02:00
parent cdc4698864
commit 4e72abbe9a
3 changed files with 48 additions and 4 deletions

View File

@@ -34,6 +34,7 @@ ACTIVE_JOB_STATUSES = [JobStatus.PENDING, JobStatus.STARTED, JobStatus.RETRY]
STALE_ACTIVE_MAX_AGE_MINUTES = 4 * 60
STALE_PENDING_MAX_AGE_MINUTES = 24 * 60
SOURCE_CARD_STATS_CACHE_TIMEOUT_SECONDS = 7 * 24 * 60 * 60
SOURCE_CARD_STATS_CACHE_SCHEMA_VERSION = 2
@dataclass(frozen=True)
@@ -665,7 +666,10 @@ class SourceCardService:
version = get_source_data_cache_version()
slugs = ",".join(definition.slug for definition in definitions)
slugs_digest = blake2s(slugs.encode(), digest_size=8).hexdigest()
return f"parsers:source_cards:aggregate_stats:{version}:{slugs_digest}"
return (
"parsers:source_cards:aggregate_stats:"
f"v{SOURCE_CARD_STATS_CACHE_SCHEMA_VERSION}:{version}:{slugs_digest}"
)
@classmethod
def _build_item_stats_by_code(
@@ -688,7 +692,10 @@ class SourceCardService:
return {}
rows = (
OrganizationSourceRecord.objects.filter(source__in=unique_sources)
OrganizationSourceRecord.objects.filter(
source__in=unique_sources,
extension__organization__opk_registry_membership=True,
)
.order_by()
.values("source")
.annotate(
@@ -762,6 +769,7 @@ class SourceCardService:
rows = (
OrganizationSourceExtension.objects.filter(
organization__opk_registry_membership=True,
source_group__in=source_groups,
records_count__gt=0,
)

View File

@@ -39,6 +39,7 @@ def _save_source_record(
organization_name: str = "",
title: str = "",
payload: dict | None = None,
opk_registry_membership: bool = True,
) -> None:
payload = dict(payload or {})
if inn:
@@ -46,6 +47,7 @@ def _save_source_record(
create_directory_organization(
name=organization_name or title or external_id,
inn=inn,
opk_registry_membership=opk_registry_membership,
)
else:
rn_key = organization_name or title or external_id
@@ -53,7 +55,10 @@ def _save_source_record(
payload.setdefault("rn", rn)
get_or_create_directory_organization(
rn=rn,
defaults={"name": organization_name or title or external_id},
defaults={
"name": organization_name or title or external_id,
"opk_registry_membership": opk_registry_membership,
},
)
OrganizationSourceIngestionService.save_records(
source=source,
@@ -441,6 +446,33 @@ class SourceCardServiceDatabaseTest(TestCase):
def setUp(self):
SourceCardService.clear_cache()
def test_source_card_counters_include_only_opk_organizations(self):
_save_source_record(
source=ParserLoadLog.Source.PROCUREMENTS_44FZ,
external_id="opk-notice",
inn="7701234567",
organization_name="Организация ОПК",
title="Закупка организации ОПК",
)
_save_source_record(
source=ParserLoadLog.Source.PROCUREMENTS_44FZ,
external_id="non-opk-notice",
inn="7701234568",
organization_name="Организация вне ОПК",
title="Закупка организации вне ОПК",
opk_registry_membership=False,
)
card = SourceCardService.get_card("public-procurements")
source_item = next(
item for item in card["source_items"] if item["code"] == "procurements_44fz"
)
self.assertEqual(source_item["records_count"], 1)
self.assertEqual(source_item["organizations_count"], 1)
self.assertEqual(card["records_count"], 1)
self.assertEqual(card["organizations_count"], 1)
def test_enqueue_vacancy_refresh_reuses_fresh_active_job(self):
existing = BackgroundJob.objects.create(
task_id="active-vacancies",

View File

@@ -53,6 +53,7 @@ def _save_source_record(
name=organization_name or title or external_id,
inn=inn,
ogrn=ogrn,
opk_registry_membership=True,
)
else:
rn_key = organization_name or title or external_id
@@ -60,7 +61,10 @@ def _save_source_record(
payload["rn"] = rn
get_or_create_directory_organization(
rn=rn,
defaults={"name": organization_name or title or external_id},
defaults={
"name": organization_name or title or external_id,
"opk_registry_membership": True,
},
)
OrganizationSourceIngestionService.save_records(
source=source,