feat(1c): add read-only companies export layer

This commit is contained in:
igor04091968
2026-05-22 10:46:06 +03:00
parent 31fe43f4bc
commit 02e896b05a
13 changed files with 214 additions and 17 deletions
+20 -2
View File
@@ -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: