feat(1c): add read-only companies export layer
This commit is contained in:
@@ -59,6 +59,7 @@ def health() -> dict[str, Any]:
|
||||
"""
|
||||
SELECT
|
||||
countIf(counterparty != '') AS documents_with_counterparty,
|
||||
(SELECT count() FROM analytics_1c.companies) AS companies_total,
|
||||
(SELECT count() FROM analytics_1c.company_forecasts) AS forecasts_total,
|
||||
(SELECT count() FROM analytics_1c.company_health_signals) AS health_signals_total
|
||||
FROM analytics_1c.documents
|
||||
@@ -83,6 +84,14 @@ def companies_overview(
|
||||
infobase,
|
||||
organization,
|
||||
counterparty,
|
||||
company_name,
|
||||
owner_user,
|
||||
base_path,
|
||||
current_status,
|
||||
db_size_bytes,
|
||||
reglog_size_bytes,
|
||||
active_locks,
|
||||
current_activity_score,
|
||||
last_seen_at,
|
||||
days_since_last_activity,
|
||||
docs_7d,
|
||||
@@ -135,6 +144,16 @@ def company_summary(counterparty: str, infobase: str | None = None) -> dict[str,
|
||||
ORDER BY score DESC, generated_at DESC
|
||||
"""
|
||||
timeline_sql = f"""
|
||||
SELECT ts, infobase, company_name, owner_user, current_status, db_size_bytes, reglog_size_bytes, active_locks, current_activity_score
|
||||
FROM analytics_1c.v_company_portfolio_overview
|
||||
WHERE counterparty = {q(counterparty)}
|
||||
{"AND infobase = " + q(infobase) if infobase else ""}
|
||||
LIMIT 1
|
||||
"""
|
||||
forecasts = rows_to_dict(client.query(forecast_sql))
|
||||
signals = rows_to_dict(client.query(signals_sql))
|
||||
company_state = rows_to_dict(client.query(timeline_sql))
|
||||
timeline_sql = f"""
|
||||
SELECT ts, infobase, doc_type, operation_type, amount, status, author
|
||||
FROM analytics_1c.documents
|
||||
WHERE counterparty = {q(counterparty)}
|
||||
@@ -142,8 +161,6 @@ def company_summary(counterparty: str, infobase: str | None = None) -> dict[str,
|
||||
ORDER BY ts DESC
|
||||
LIMIT 20
|
||||
"""
|
||||
forecasts = rows_to_dict(client.query(forecast_sql))
|
||||
signals = rows_to_dict(client.query(signals_sql))
|
||||
timeline = rows_to_dict(client.query(timeline_sql))
|
||||
essence = (
|
||||
f"Компания {counterparty}: за 30 дней событий {card['docs_30d']}, суммарная активность {card['amount_30d']}, "
|
||||
@@ -152,6 +169,7 @@ def company_summary(counterparty: str, infobase: str | None = None) -> dict[str,
|
||||
return {
|
||||
"essence": essence,
|
||||
"card": card,
|
||||
"company_state": company_state[0] if company_state else None,
|
||||
"forecasts": forecasts,
|
||||
"signals": signals,
|
||||
"recent_documents": timeline,
|
||||
|
||||
@@ -164,6 +164,22 @@ def main() -> int:
|
||||
""",
|
||||
)
|
||||
}
|
||||
company_state_map = {
|
||||
row["infobase"]: row
|
||||
for row in query_rows(
|
||||
client,
|
||||
"""
|
||||
SELECT
|
||||
infobase,
|
||||
current_status,
|
||||
active_locks,
|
||||
temp_db_present,
|
||||
scheduler_touched,
|
||||
current_activity_score
|
||||
FROM analytics_1c.v_companies_current
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
forecast_rows: list[list[Any]] = []
|
||||
signal_rows: list[list[Any]] = []
|
||||
@@ -186,6 +202,12 @@ def main() -> int:
|
||||
days_since_last_activity = (date.today() - latest_day).days
|
||||
open_cases_total = cases_map.get((infobase, counterparty), 0)
|
||||
detections_total = detections_map.get((infobase, counterparty), 0)
|
||||
company_state = company_state_map.get(infobase, {})
|
||||
current_status = str(company_state.get("current_status") or "")
|
||||
active_locks = int(company_state.get("active_locks") or 0)
|
||||
temp_db_present = int(company_state.get("temp_db_present") or 0)
|
||||
scheduler_touched = int(company_state.get("scheduler_touched") or 0)
|
||||
current_activity_score = float(company_state.get("current_activity_score") or 0)
|
||||
|
||||
for metric, values in (("docs_total", docs_series), ("amount_total", amount_series)):
|
||||
for horizon in horizons:
|
||||
@@ -221,6 +243,11 @@ def main() -> int:
|
||||
signals.append(("amount_drop", 70, "high", f"Активность по компании {counterparty} упала более чем на 50% неделя к неделе."))
|
||||
if docs_prev_7d > 0 and docs_7d == 0:
|
||||
signals.append(("docs_stopped", 55, "medium", f"По компании {counterparty} прекратился поток документов за последние 7 дней."))
|
||||
if current_status == "busy" or active_locks > 0 or temp_db_present > 0:
|
||||
score = min(85, 45 + active_locks * 5 + temp_db_present * 10)
|
||||
signals.append(("base_busy", score, severity_score_to_label(score), f"Файловая база компании {counterparty} занята: status={current_status}, locks={active_locks}, tempDb={temp_db_present}."))
|
||||
if scheduler_touched > 0 and current_activity_score >= 15:
|
||||
signals.append(("scheduler_activity", 35, "medium", f"По компании {counterparty} есть активность scheduler и повышенный activity score {current_activity_score}."))
|
||||
if open_cases_total > 0:
|
||||
signals.append(("open_cases", min(95, 40 + open_cases_total * 10), severity_score_to_label(min(95, 40 + open_cases_total * 10)), f"По компании {counterparty} есть открытые кейсы: {open_cases_total}."))
|
||||
if detections_total > 0:
|
||||
|
||||
Reference in New Issue
Block a user