feat(generative): POST /concepts/recompute — live финрасчёт по massing-program (#1965 Stage 2a) #2024
1 changed files with 147 additions and 0 deletions
|
|
@ -34,6 +34,44 @@ export interface paths {
|
|||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/v1/concepts/recompute": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/**
|
||||
* Recompute Massing
|
||||
* @description Stage 2a (#1965, эпик #1953) — LIVE-пересчёт экономики из 3D-массинга.
|
||||
*
|
||||
* Hot, debounced-эндпоинт для интерактивных слайдеров Stage 2b: фронтовый
|
||||
* ``computeModel`` отдаёт агрегированную программу (суммарное пятно × этажность),
|
||||
* мы синтезируем :class:`TEAP` (``synthesize_teap_from_program`` — те же нормативные
|
||||
* константы, что и обычная генерация) и прогоняем готовый чистый ``compute_financial``
|
||||
* → пересчитанный ТЭП + финмодель.
|
||||
*
|
||||
* Цена продажи жилья:
|
||||
* * ``market_price_per_sqm`` в теле → используется как есть (FAST path, БЕЗ БД) —
|
||||
* фронт резолвит цену один раз и шлёт её в каждом keystroke-запросе. Источник
|
||||
* берём из ``payload.price_source`` (ПОДЛИННЫЙ source, который фронт получил из
|
||||
* financial_estimate — objective_geo_radius / objective_district_median /
|
||||
* district_reference / class_norm); если фронт его не прислал — дефолтный лейбл.
|
||||
* НЕ хардкодим source — иначе honest-флаг в UI/PDF врёт о происхождении цены.
|
||||
* * иначе, если передан ``parcel_centroid_wkt`` → ``_lookup_market_price`` по центроиду
|
||||
* через ``run_in_threadpool`` (тот же приём, что и в ``create_concept``; sync SQLAlchemy
|
||||
* не должен блокировать event loop). Падение lookup'а → норматив класса, не 500.
|
||||
* * иначе (нет ни цены, ни центроида) → норматив класса (``price_source="class_norm"``).
|
||||
*/
|
||||
post: operations["recompute_massing_api_v1_concepts_recompute_post"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/v1/chat/ask": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
|
@ -4065,6 +4103,82 @@ export interface components {
|
|||
*/
|
||||
updated_at: string;
|
||||
};
|
||||
/**
|
||||
* MassingProgram
|
||||
* @description Stage 2a (#1965) — агрегированная массинг-программа для LIVE-пересчёта экономики.
|
||||
*
|
||||
* Контракт POST ``/api/v1/concepts/recompute``: вход — уже СВЁРНУТАЯ программа из
|
||||
* фронтового ``computeModel`` интерактивного 3D-массинга (суммарное пятно × этажность),
|
||||
* без покомпонентной геометрии секций. Эндпоинт синтезирует из неё :class:`TEAP` и
|
||||
* прогоняет готовый ``compute_financial`` → пересчитанная экономика для дебаунс-слайдеров
|
||||
* Stage 2b.
|
||||
*
|
||||
* Класс жилья / тип застройки — те же Literal-множества, что у :class:`ConceptInput`
|
||||
* и ``compute_financial`` (single source of truth по допустимым значениям).
|
||||
*/
|
||||
MassingProgram: {
|
||||
/**
|
||||
* Total Footprint Sqm
|
||||
* @description Суммарное пятно застройки всех секций, кв.м (скаляр)
|
||||
*/
|
||||
total_footprint_sqm: number;
|
||||
/**
|
||||
* Floors
|
||||
* @description Этажность программы
|
||||
*/
|
||||
floors: number;
|
||||
/**
|
||||
* Sections
|
||||
* @description Число секций (метаданные программы)
|
||||
* @default 1
|
||||
*/
|
||||
sections: number;
|
||||
/**
|
||||
* Site Area Sqm
|
||||
* @description Площадь участка для плотности (FAR)
|
||||
*/
|
||||
site_area_sqm: number;
|
||||
/**
|
||||
* Housing Class
|
||||
* @default comfort
|
||||
* @enum {string}
|
||||
*/
|
||||
housing_class: "econom" | "comfort" | "business";
|
||||
/**
|
||||
* Development Type
|
||||
* @default mid_rise
|
||||
* @enum {string}
|
||||
*/
|
||||
development_type: "spot" | "mid_rise" | "high_rise";
|
||||
/**
|
||||
* Land Cost Rub
|
||||
* @description Стоимость участка для финмодели (опционально)
|
||||
*/
|
||||
land_cost_rub?: number | null;
|
||||
/**
|
||||
* Market Price Per Sqm
|
||||
* @description Предрезолвленная рыночная цена жилья, руб/кв.м (skip DB lookup)
|
||||
*/
|
||||
market_price_per_sqm?: number | null;
|
||||
/**
|
||||
* Price Source
|
||||
* @description Подлинный источник предрезолвленной цены (forward из financial_estimate)
|
||||
*/
|
||||
price_source?: string | null;
|
||||
/**
|
||||
* Parcel Centroid Wkt
|
||||
* @description WKT-точка центроида участка (WGS84) для DB-резолва цены при fallback
|
||||
*/
|
||||
parcel_centroid_wkt?: string | null;
|
||||
};
|
||||
/**
|
||||
* MassingRecomputeOutput
|
||||
* @description Stage 2a (#1965) — результат LIVE-пересчёта: синтезированный ТЭП + финмодель.
|
||||
*/
|
||||
MassingRecomputeOutput: {
|
||||
teap: components["schemas"]["TEAP"];
|
||||
financial: components["schemas"]["FinancialModel"];
|
||||
};
|
||||
/**
|
||||
* ObjectiveConfigUpdateRequest
|
||||
* @description PATCH-style — обновляет только переданные поля.
|
||||
|
|
@ -4911,6 +5025,39 @@ export interface operations {
|
|||
};
|
||||
};
|
||||
};
|
||||
recompute_massing_api_v1_concepts_recompute_post: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["MassingProgram"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["MassingRecomputeOutput"];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
ask_api_v1_chat_ask_post: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue