diff --git a/b2c_top_services_july_2026.md b/b2c_top_services_july_2026.md
new file mode 100644
index 0000000..49369bc
--- /dev/null
+++ b/b2c_top_services_july_2026.md
@@ -0,0 +1,91 @@
+# Топ-50 услуг по регионам — сегмент B2C
+## Данные за июль 2026 года
+
+
+| № | Регион | Услуга | Кол-во покупок | Сумма (₸) |
+|---|--------|--------|----------------|-----------|
+| 1 | Астана | B2C Абонплата ШПД по FTTx ГТС (New) | 37 372 | 238 463 786,09 |
+| 2 | г.Алматы | B2C Абонплата ШПД по FTTx ГТС (New) | 39 671 | 237 005 698,16 |
+| 3 | г.Алматы | Абонплата ШПД по FTTx для B2C | 35 588 | 152 893 561,28 |
+| 4 | Астана | 2025 B2C Абонплата за Домашний Интернет FTTx ГТС | 35 637 | 136 187 938,99 |
+| 5 | Астана | B2C TV Plus Абонплата Full ГТС | 47 661 | 132 060 372,93 |
+| 6 | Астана | 2021 B2C Абонплата за мобильный номер Kcell GSM закр. | 61 700 | 123 403 164,43 |
+| 7 | г.Алматы | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 57 378 | 110 497 209,55 |
+| 8 | г.Алматы | 2025 B2C Абонплата за Домашний Интернет FTTx ГТС | 29 997 | 106 749 675,59 |
+| 9 | Астана | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 52 504 | 99 235 780,41 |
+| 10 | Астана | 2022 B2C Абонплата за Домашний Интернет FTTx ГТС | 36 946 | 96 430 127,27 |
+| 11 | Астана | Абонплата ШПД по FTTx для B2C | 19 565 | 88 834 659,73 |
+| 12 | Астана | 2024 B2C Абонплата за Домашний Интернет FTTx ГТС | 22 167 | 83 549 325,34 |
+| 13 | г.Алматы | B2C TV Plus Абонплата Full ГТС | 31 221 | 83 511 013,05 |
+| 14 | г.Алматы | 2021 B2C Абонплата за мобильный номер Kcell GSM закр. | 40 838 | 82 748 215,46 |
+| 15 | г.Семей | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 41 486 | 76 400 272,02 |
+| 16 | Астана | TV Plus Абонплата за Премиальный пакет ГТС | 29 210 | 71 278 165,09 |
+| 17 | г.Алматы | 2022 B2C Абонплата за Домашний Интернет FTTx ГТС | 24 001 | 62 521 274,30 |
+| 18 | Астана | 2021 B2C Абонплата за мобильный номер Kcell GSM откр. | 27 864 | 59 635 624,39 |
+| 19 | г.Алматы | 2024 B2C Абонплата за Домашний Интернет FTTx ГТС | 15 678 | 58 970 815,48 |
+| 20 | г.Актобе | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 30 641 | 55 819 936,98 |
+| 21 | г.Алматы | B2C Абонплата за основной телефон ГТС | 52 732 | 49 636 818,50 |
+| 22 | г.Актобе | 2021 B2C Абонплата за мобильный номер Kcell GSM закр. | 25 178 | 48 000 483,43 |
+| 23 | г.Алматы | TV Plus Абонплата за Премиальный пакет ГТС | 19 055 | 45 298 192,89 |
+| 24 | г.Павлодар | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 23 334 | 44 857 518,84 |
+| 25 | г.Алматы | B2C TV Plus Аренда STB оператора новое | 96 183 | 43 252 519,71 |
+| 26 | г.Караганда | Абонплата ШПД по FTTx для B2C | 8 916 | 41 624 727,66 |
+| 27 | Астана | 2026 B2C Абонплата за Домашний Интернет FTTx ГТС | 13 685 | 41 618 770,34 |
+| 28 | г.Алматы | 2018 B2C Абонплата за Домашний Интернет FTTx ГТС | 11 568 | 40 199 964,35 |
+| 29 | г.Тараз | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 21 880 | 39 564 813,34 |
+| 30 | г.Алматы | Абонплата ШПД по ADSL для B2C | 10 710 | 36 238 454,72 |
+| 31 | г.Алматы | 2020 B2C Абонплата за Домашний Интернет FTTx ГТС | 12 148 | 36 010 481,68 |
+| 32 | г.Усть-Каменогорск | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 18 362 | 35 883 527,39 |
+| 33 | г. Шымкент | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 19 180 | 35 338 634,51 |
+| 34 | г. Шымкент | 2021 B2C Абонплата за мобильный номер Kcell GSM закр. | 18 945 | 35 138 664,91 |
+| 35 | Астана | B2C TV Plus Аренда STB оператора новое | 76 655 | 34 746 783,92 |
+| 36 | Астана | 2018 B2C Абонплата за Домашний Интернет FTTx ГТС | 8 705 | 32 905 725,03 |
+| 37 | г.Актобе | B2C Абонплата ШПД по FTTx ГТС (New) | 6 742 | 32 313 021,91 |
+| 38 | г.Усть-Каменогорск | Абонплата ШПД по FTTx для B2C | 7 269 | 31 834 355,15 |
+| 39 | г.Атырау | B2C Абонплата ШПД по FTTx ГТС (New) | 5 495 | 31 688 118,61 |
+| 40 | г.Усть-Каменогорск | B2C Абонплата ШПД по FTTx ГТС (New) | 5 600 | 31 520 413,53 |
+| 41 | Астана | B2C Аренда оборудования ONT оператора - новое | 87 071 | 31 220 264,09 |
+| 42 | г.Павлодар | B2C Абонплата ШПД по FTTx ГТС (New) | 6 104 | 30 831 455,08 |
+| 43 | г.Кокшетау | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 16 818 | 30 654 924,73 |
+| 44 | г.Актобе | 2025 B2C Абонплата за Домашний Интернет FTTx ГТС | 8 613 | 30 562 705,78 |
+| 45 | г.Костанай | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 16 473 | 30 539 180,35 |
+| 46 | Енбекшиказахский район | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 17 347 | 30 429 552,38 |
+| 47 | г.Актобе | 2022 B2C Абонплата за Домашний Интернет FTTx ГТС | 11 709 | 30 303 557,00 |
+| 48 | г.Кызылорда | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 16 539 | 29 772 241,67 |
+| 49 | г.Алматы | 2026 B2C Абонплата за Домашний Интернет FTTx ГТС | 10 206 | 29 200 316,21 |
+| 50 | г.Караганда | 2022 B2C Абонплата за мобильный номер MT-C GSM закр. | 15 714 | 28 837 871,98 |
+
+
+---
+
+
+## Ключевые наблюдения
+
+
+### Лидеры по доходам
+- **Астана** и **г.Алматы** занимают первые места с услугами широкополосного доступа (ШПД) и мобильной связи.
+
+
+### Популярные услуги
+- Абонплата за интернет (FTTx) и мобильные номера (Kcell, MT-C) доминируют в топе.
+
+
+### Массовые услуги
+- **Аренда STB**: 96 183 покупки в Алматы при сумме 43,25 млн ₸
+- **Аренда ONT оборудования**: 87 071 покупка в Астане при сумме 31,22 млн ₸
+
+
+### География
+В топ-50 вошли все крупные города Казахстана:
+- Алматы, Астана, Семей, Актобе, Павлодар, Караганда, Усть-Каменогорск, Шымкент, Тараз, Атырау, Кокшетау, Костанай, Кызылорда, Енбекшиказахский район
+
+
+---
+
+
+**Источник данных:** ClickHouse Хранилище АО «Казахтелеком»
+**Таблица:** sandbox.spec2_main_2spec_detail2_v2_ddt
+**Период:** Июль 2026 (report_period_id = 202607)
+**Сегмент:** B2C
+**Валюта:** Тенге (без НДС)
+**Дата формирования:** 01.09.2026
diff --git a/index.html b/index.html
index 3986c3e..4b8c9c5 100644
--- a/index.html
+++ b/index.html
@@ -3,31 +3,42 @@
-Топ-10 заказов B2C | Казахтелеком
+Топ услуг B2C по регионам | Казахтелеком
@@ -36,55 +47,67 @@
Дашборд B2C
-
+ Июль 2026
- Топ-10 заказов B2C за сегодня
- Самые крупные заказы Казахтелекома по сумме
+ Топ услуг B2C по регионам
+ Сводная статистика покупок услуг по всем регионам Казахстана
-
Всего заказов B2C
-
—
+
Всего покупок
+
—
+
в топ-50
-
Сумма топ-10
-
—
+
Всего регионов
+
—
+
уникальных
-
Средний чек
-
—
+
Услуга-лидер
+
—
+
—
-
Лидер региона
+
Регион-лидер
—
+
—
+
+
+
Топ-10 регионов по покупкам
+
+
+
+
Топ-10 услуг по покупкам
+
+
+
+
+ Полная таблица топ-50
- | # |
- Клиент |
+ # |
Регион |
Услуга |
- Статус |
- Сумма (₸) |
+ Покупок |
+ Сумма (₸) |
-
- | Загрузка данных… |
-
+
- Последнее обновление: —
-
+ Данные за июль 2026 года | Источник: ClickHouse Хранилище АО «Казахтелеком»
@@ -96,92 +119,160 @@
diff --git a/package.json b/package.json
deleted file mode 100644
index 273b549..0000000
--- a/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "crm-dashboard",
- "private": true,
- "type": "commonjs",
- "scripts": { "start": "node server.js" }
-}
diff --git a/server.js b/server.js
deleted file mode 100644
index 4d9e582..0000000
--- a/server.js
+++ /dev/null
@@ -1,110 +0,0 @@
-const http = require("http");
-const fs = require("fs");
-const path = require("path");
-
-const PORT = process.env.PORT || 3000;
-
-function body(req) {
- return new Promise((resolve) => {
- let s = "";
- req.on("data", (c) => (s += c));
- req.on("end", () => { try { resolve(JSON.parse(s || "{}")); } catch (_) { resolve({}); } });
- });
-}
-
-async function fetchAlemOrders() {
- // Интеграция с Alem CRM - данные подтянутся, когда Alem подключится
- if (!process.env.ALEM_BASE_URL || !process.env.ALEM_API_KEY) {
- return null;
- }
-
- try {
- // Создаём сессию
- const sessionResp = await fetch(process.env.ALEM_BASE_URL + "/api/v1/open-api/conversation", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "Authorization": "Bearer " + process.env.ALEM_API_KEY
- },
- body: JSON.stringify({
- template_id: process.env.ALEM_TEMPLATE_ID,
- title: "CRM Dashboard",
- user_id: "crm_b2c_user"
- })
- });
-
- if (!sessionResp.ok) throw new Error("Alem session " + sessionResp.status);
- const sessionBody = await sessionResp.json();
- const sessionId = sessionBody?.data?.session_id;
- if (!sessionId) throw new Error("No session_id from Alem");
-
- // Запрашиваем топ-10 заказов B2C
- const queryResp = await fetch(process.env.ALEM_BASE_URL + "/api/v1/open-api/conversation/" + sessionId + "/send", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "Authorization": "Bearer " + process.env.ALEM_API_KEY
- },
- body: JSON.stringify({
- content: "Покажи топ-10 самых крупных заказов B2C за сегодня в формате JSON с полями: id, client, region, service, status, amount. Только JSON массив.",
- user_id: "crm_b2c_user",
- model_api_key: process.env.ALEM_API_KEY
- })
- });
-
- if (!queryResp.ok) throw new Error("Alem query " + queryResp.status);
-
- // SSE-поток
- const raw = await queryResp.text();
- let answer = null;
- for (const line of raw.split("\n")) {
- const s = line.trim();
- if (!s.startsWith("data:")) continue;
- const payload = s.slice(5).trim();
- if (!payload || payload === "[DONE]") continue;
- try {
- const ev = JSON.parse(payload);
- if (ev && ev.detail && typeof ev.detail.full_content === "string" && ev.detail.full_content) {
- answer = ev.detail.full_content;
- }
- } catch (e) {}
- }
-
- if (!answer) return null;
-
- // Пытаемся извлечь JSON из ответа
- const jsonMatch = answer.match(/\[[\s\S]*\]/);
- if (jsonMatch) {
- return JSON.parse(jsonMatch[0]);
- }
- return null;
- } catch (e) {
- console.error("Alem error:", e.message);
- return null;
- }
-}
-
-http.createServer(async (req, res) => {
- // API: данные для дашборда
- if (req.method === "GET" && req.url.split("?")[0] === "/api/alem-orders") {
- const orders = await fetchAlemOrders();
- res.writeHead(200, {
- "Content-Type": "application/json",
- "Access-Control-Allow-Origin": "*"
- });
- res.end(JSON.stringify({ orders: orders || [] }));
- return;
- }
-
- // Статика: index.html
- let file = req.url === "/" ? "/index.html" : req.url.split("?")[0];
- const full = path.join(__dirname, file);
- if (full.startsWith(__dirname) && fs.existsSync(full) && fs.statSync(full).isFile()) {
- const ext = path.extname(full);
- const type = ext === ".css" ? "text/css" : ext === ".js" ? "application/javascript" : "text/html";
- res.writeHead(200, { "Content-Type": type + "; charset=utf-8" });
- return res.end(fs.readFileSync(full));
- }
-
- res.writeHead(404); res.end("Not found");
-}).listen(PORT, () => console.log("CRM Dashboard на порту " + PORT));