gendesign/backend/app/api/v1/market.py
Light1YT 658d724075
Some checks failed
CI / changes (push) Successful in 8s
CI / frontend-tests (push) Has been skipped
CI / changes (pull_request) Successful in 8s
CI / frontend-tests (pull_request) Has been skipped
CI / backend-tests (push) Successful in 7m37s
CI / backend-tests (pull_request) Successful in 7m42s
Deploy / deploy (push) Blocked by required conditions
Deploy / build-backend (push) Blocked by required conditions
Deploy / build-worker (push) Blocked by required conditions
Deploy / build-frontend (push) Blocked by required conditions
Deploy / changes (push) Has been cancelled
feat(analytics): velocity-anomaly alerts (#17) + ARN ДДУ price indicator (#99)
#17: detect_velocity_anomalies + GET /analytics/velocity-alerts — z-score drop-detection
на domrf_kn_sale_graph (double-gate z≤-2 AND drop≤-30%, starvation-guards). Snapshot=richest
(не MAX — prod новейшие частичные), lookback anchored на latest report_month (scrape лаг ~4мес).
Prod: ЖК Центральный Парк -69%, ~14ms.

#99: mv_ddu_price_indicator (миграция 152) + POST /market/ddu-indicator — ARN-mirror
ценовой индекс per quarter×area_bucket из rosreestr_deals (ДДУ регион 66). MVP: subject-level,
period Q, window 2025-Q2+, methods 1/2 (basis/previous, prev_period_value honesty). Q1-2026
headline 1.0185 vs ARN 1.03 (±5%). Method 3 blocked (нет pre-2025-Q2 данных) — задокументировано.

Closes #17
Closes #99
2026-06-13 22:04:49 +05:00

50 lines
2.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Market indicator endpoints (Issue #99) — ARN-framework for primary market.
POST /api/v1/market/ddu-indicator — per-quarter price indicator of the PRIMARY
market (новостройки/ДДУ) for Свердловская обл., ARN-mirror request/response.
"""
from __future__ import annotations
from typing import Annotated
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.core.db import get_db
from app.schemas.market import DduIndicatorRequest, DduIndicatorResponse
from app.services.analytics import ddu_price_indicator as ddu
router = APIRouter()
@router.post("/ddu-indicator", response_model=DduIndicatorResponse)
def ddu_indicator(
payload: DduIndicatorRequest,
db: Annotated[Session, Depends(get_db)],
) -> DduIndicatorResponse:
"""ARN-style ценовой индикатор первичного рынка (ДДУ) по кварталам × площади.
Принимает то же body, что ARN/НСПД (camelCase). MVP: period_type=Q,
calc methods 1 (базисный) / 2 (предыдущий), субъект 66. Неподдержанные
ARN-опции (M/H/Y, method=3, иные субъекты, cad_quarter) не отвергаются —
отражаются в `notes`. Источник: mv_ddu_price_indicator (migration 152).
Killer-USP: «у нас первичка, у НСПД вторичка» — обе нужны девелоперу.
"""
result = ddu.get_ddu_indicator(
db,
calculation_method=payload.calculation_method,
period_from=payload.period_from,
period_to=payload.period_to,
area_ranges=payload.area_ranges,
federal_subject=payload.federal_subject,
indicators=payload.indicators,
)
# cadastral_quarter is shape-compat only; flag it if the client sent one.
if payload.cadastral_quarter:
result["notes"].append(
"cadastralQuarter не поддержан: первичка (ДДУ) слишком разрежена "
"на уровне кад.квартала — индикатор считается по субъекту (66)."
)
return DduIndicatorResponse(**result)