@ai.all/ds7 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,51 @@
1
+ # 03-Performance · Hydration Strategy & TBT Minimization
2
+
3
+ > Как избавиться от зависаний интерфейса (Total Blocking Time < 50ms) при первом входе на страницу.
4
+
5
+ ---
6
+
7
+ ## 1. В чём опасность полной гидратации
8
+
9
+ Nuxt генерирует чистый статический HTML. Браузер быстро его отображает, но затем запускается процесс **гидратации (Hydration)**:
10
+ * Vue начинает «оживлять» каждый компонент на странице, вешать слушатели событий и инициализировать реактивные объекты;
11
+ * Если на странице 15 секций (калькулятор, карта проектов, чат, модалки, слайдеры), этот процесс может занять **250–500 мс** на среднем мобильном процессоре;
12
+ * В это время страница «висит» — пользователь тыкает по меню или кнопке, а клик не срабатывает.
13
+
14
+ ---
15
+
16
+ ## 2. Стратегия отложенной гидратации в DS7
17
+
18
+ ### 1. Отложенные второстепенные виджеты (`requestIdleCallback`)
19
+ Виджеты, которые не нужны в первую секунду (чат WhatsApp, куки-баннер, модалка звонка, звуковые эффекты), гидрируются только тогда, когда процессор свободен:
20
+
21
+ ```vue
22
+ <script setup lang="ts">
23
+ const shouldHydrateIdle = ref(false)
24
+
25
+ onMounted(() => {
26
+ if ('requestIdleCallback' in window) {
27
+ window.requestIdleCallback(() => { shouldHydrateIdle.value = true })
28
+ } else {
29
+ setTimeout(() => { shouldHydrateIdle.value = true }, 1500)
30
+ }
31
+ })
32
+ </script>
33
+
34
+ <template>
35
+ <ClientOnly>
36
+ <SiteChat v-if="shouldHydrateIdle" />
37
+ <SiteCookieBanner v-if="shouldHydrateIdle" />
38
+ </ClientOnly>
39
+ </template>
40
+ ```
41
+
42
+ ### 2. Ленивая гидратация по скроллу (`when-visible`)
43
+ Тяжелые интерактивные секции ниже первого экрана (интерактивная карта проектов `HomeProjectMap`, модель дня и ночи `HomeDayNight`) гидрируются только тогда, когда пользователь приближается к ним при прокрутке.
44
+
45
+ ### 3. Пассивные слушатели событий (`passive: true`)
46
+ В компоненте `UiCardSlider` и любых событиях скролла/тача:
47
+ ```ts
48
+ window.addEventListener('scroll', onScroll, { passive: true })
49
+ track.addEventListener('touchstart', onTouchStart, { passive: true })
50
+ ```
51
+ Браузер заранее знает, что скрипт не отменит стандартную прокрутку страницы (`preventDefault`), и скроллит страницу с максимальной частотой 120 FPS без микро-фризов.
@@ -0,0 +1,70 @@
1
+ # 04-SEO · AEO & GEO: Optimization for AI Search Engines
2
+
3
+ > Answer Engine Optimization (AEO) и Generative Engine Optimization (GEO): как сделать сайт источником цитирования для Perplexity, SearchGPT, Claude и Google Gemini Overviews.
4
+
5
+ ---
6
+
7
+ ## 1. Смена парадигмы: от «Ключевых слов» к «Фактической плотности»
8
+
9
+ Классические поисковики считали вхождения слов в текст.
10
+ Современные нейросети (SearchGPT, Gemini, Perplexity) считывают **семантические утверждения и факты**. Они ищут лаконичные, точные, проверяемые ответы на вопросы пользователя.
11
+
12
+ ---
13
+
14
+ ## 2. Структура Direct Answer Block (Блок прямого ответа)
15
+
16
+ Каждый раздел сайта, отвечающий на информационный вопрос, должен начинаться с **блока прямого ответа**:
17
+
18
+ ```html
19
+ <!-- 1. Заголовок — конкретный вопрос пользователя -->
20
+ <h2 id="faq-cost">¿Cuánto cuesta instalar placas solares en una casa en Sevilla?</h2>
21
+
22
+ <!-- 2. Блок прямого ответа: 40–50 слов, точные цифры, без вводных фраз -->
23
+ <p class="direct-answer">
24
+ Una instalación estándar de 4 kW (8 paneles solares de alta eficiencia) en Sevilla tiene
25
+ un coste medio de <strong>4.200 € a 5.600 €</strong> sin ayudas. Con la bonificación del 50%
26
+ del IBI en Sevilla y la deducción de hasta el 40% en el IRPF, el coste neto final se sitúa
27
+ entre <strong>2.600 € y 3.300 €</strong>, con un retorno de inversión en 3,8 años.
28
+ </p>
29
+ ```
30
+
31
+ ### Почему это работает:
32
+ Нейросеть вырезает этот абзац целиком и вставляет в карточку быстрого ответа (AI Summary), прикрепляя ссылку на наш сайт как на **авторитетный первоисточник**.
33
+
34
+ ---
35
+
36
+ ## 3. Таблицы характеристик и списки (AI-Ready Data)
37
+
38
+ ИИ парсит таблицы данных в десятки раз быстрее, чем сплошной текст:
39
+
40
+ ```html
41
+ <table class="ai-data-table">
42
+ <thead>
43
+ <tr>
44
+ <th>Modelo</th>
45
+ <th>Potencia</th>
46
+ <th>Eficiencia</th>
47
+ <th>Garantía</th>
48
+ <th>Precio estimado</th>
49
+ </tr>
50
+ </thead>
51
+ <tbody>
52
+ <tr>
53
+ <td>Panel Monocristalino N-Type</td>
54
+ <td>450 W</td>
55
+ <td>22,5 %</td>
56
+ <td>25 años</td>
57
+ <td>139 €</td>
58
+ </tr>
59
+ </tbody>
60
+ </table>
61
+ ```
62
+
63
+ ---
64
+
65
+ ## 4. Ссылки на законы и государственные бюллетени Испании
66
+
67
+ Для закрепления статуса доверия в контенте всегда указываются ссылки на первоисточники:
68
+ * **RD 244/2019** — закон Испании о компенсации излишков и коллективном потреблении;
69
+ * **BOE (Boletín Oficial del Estado)** — регламент налоговых вычетов IRPF;
70
+ * **Plan MOVES III** — государственная субсидия на зарядные станции для электрокаров.
@@ -0,0 +1,41 @@
1
+ # 04-SEO · Google Local Pack, E-E-A-T & Behavioral Signals
2
+
3
+ > Главные драйверы бесплатного органического трафика без закупки рекламных ссылок.
4
+
5
+ ---
6
+
7
+ ## 1. Google Local Pack (Карты как генератор 50% заявок в Испании)
8
+
9
+ В сфере монтажа и инжиниринга в Испании половина клиентов выбирает компанию на **Google Maps**:
10
+
11
+ ### Факторы ранжирования в Local 3-Pack:
12
+ 1. **Синхронизация NAP (Name, Address, Phone):**
13
+ Название, физический адрес в Севилье/Камасе и номер телефона на сайте в `Schema.org/LocalBusiness` должны совпадать **символ-в-символ** с профилем компании в **Google Business Profile**.
14
+ 2. **Живые отзывы:**
15
+ Регулярное пополнение отзывов от реальных клиентов с прикрепленными фотографиями установленных панелей на крышах.
16
+ 3. **Гео-привязка сервисных зон:**
17
+ В коде страницы и в микроразметке четко указываются города обслуживания: `Sevilla`, `Málaga`, `Marbella`, `Cádiz`, `Estepona`.
18
+
19
+ ---
20
+
21
+ ## 2. Стандарты E-E-A-T (Опыт, Экспертность, Авторитет, Доверие)
22
+
23
+ Поскольку покупка солнечной электростанции стоит 4 000 – 15 000 €, Google применяет жесткие алгоритмы оценки надежности (YMYL):
24
+
25
+ * **Юридические реквизиты:** Размещение CIF компании (`HELIONIX ENERGY SLU`), номера в торговом реестре Испании, юридического и фактического адреса.
26
+ * **Сертификации монтажников:** Упоминание допусков электромонтажников категории especialista в Андалусии.
27
+ * **Официальные партнерства:** Логотипы и упоминание статуса установщика брендов: V2C, Livoltek, Huawei, GoodWe, Canadian Solar.
28
+
29
+ ---
30
+
31
+ ## 3. Поведенческие сигналы (Dwell Time и закрытие интента)
32
+
33
+ Алгоритм Google RankBrain оценивает реакцию пользователей:
34
+
35
+ 1. **Мгновенный отклик (FCP < 0.4s):**
36
+ Человек кликает по ссылке и сразу видит контент. Нет белого экрана — отказ минимальный.
37
+ 2. **Вовлечение через интерактив (High Dwell Time):**
38
+ Интерактивный калькулятор заставляет пользователя провести на странице **3–5 минут** (двигает ползунок, выбирает аккумулятор, смотрит график окупаемости).
39
+ 3. **Отсутствие возврата в поиск (Zero Pogo-Sticking):**
40
+ Клиент нажимает кнопку перехода в WhatsApp или скачивает PDF-смету. Его потребность полностью закрыта. Он **не возвращается в поиск Google** продолжать поиски.
41
+ Для поисковика это доказательство высшего качества страницы: сайт автоматически поднимается на первые позиции.
@@ -0,0 +1,90 @@
1
+ # 04-SEO · Structured Data & Schema.org Graph
2
+
3
+ > Машиночитаемая микроразметка JSON-LD: как превратить сайт в структурированную базу данных для поисковых систем.
4
+
5
+ ---
6
+
7
+ ## 1. Единый граф сущностей (`@graph`)
8
+
9
+ Вместо разрозненных кусочков разметки на странице генерируется единый связанный граф через `@graph`:
10
+
11
+ ```json
12
+ {
13
+ "@context": "https://schema.org",
14
+ "@graph": [
15
+ {
16
+ "@type": "Organization",
17
+ "@id": "https://miluzsolar.es/#organization",
18
+ "name": "Mi Luz Solar",
19
+ "legalName": "HELIONIX ENERGY SLU",
20
+ "url": "https://miluzsolar.es",
21
+ "logo": "https://miluzsolar.es/brand/mi-luz-solar.svg",
22
+ "email": "info@miluzsolar.es",
23
+ "address": {
24
+ "@type": "PostalAddress",
25
+ "addressLocality": "Camas",
26
+ "addressRegion": "Sevilla",
27
+ "addressCountry": "ES"
28
+ },
29
+ "areaServed": ["Sevilla", "Málaga", "Cádiz", "Andalucía"]
30
+ },
31
+ {
32
+ "@type": "WebSite",
33
+ "@id": "https://miluzsolar.es/#website",
34
+ "url": "https://miluzsolar.es",
35
+ "name": "Mi Luz Solar",
36
+ "publisher": { "@id": "https://miluzsolar.es/#organization" },
37
+ "inLanguage": ["es", "en", "uk"]
38
+ }
39
+ ]
40
+ ]
41
+ ```
42
+
43
+ ---
44
+
45
+ ## 2. Разметка товаров для каталога (`Product` + `Offer`)
46
+
47
+ Позволяет Google выводить цены, плашку «В наличии» и рейтинг прямо в поисковой выдаче:
48
+
49
+ ```json
50
+ {
51
+ "@type": "Product",
52
+ "name": "V2C Trydan e-Charger 7.4 kW",
53
+ "image": "https://miluzsolar.es/images/p/v2c-trydan.webp",
54
+ "description": "Cargador inteligente para coche eléctrico con integración fotovoltaica y carga por excedentes solares.",
55
+ "brand": {
56
+ "@type": "Brand",
57
+ "name": "V2C"
58
+ },
59
+ "offers": {
60
+ "@type": "Offer",
61
+ "price": "782.40",
62
+ "priceCurrency": "EUR",
63
+ "priceValidUntil": "2026-12-31",
64
+ "availability": "https://schema.org/InStock",
65
+ "seller": { "@id": "https://miluzsolar.es/#organization" }
66
+ }
67
+ }
68
+ ```
69
+
70
+ ---
71
+
72
+ ## 3. Разметка FAQ (`FAQPage`)
73
+
74
+ Гарантирует появление выпадающих вопросов и ответов прямо в результатах поиска Google:
75
+
76
+ ```json
77
+ {
78
+ "@type": "FAQPage",
79
+ "mainEntity": [
80
+ {
81
+ "@type": "Question",
82
+ "name": "¿Cuánto se tarda en instalar las placas solares?",
83
+ "acceptedAnswer": {
84
+ "@type": "Answer",
85
+ "text": "La instalación física en una vivienda unifamiliar se realiza habitualmente en 24 a 48 horas. La legalización completa y gestión de excedentes toma entre 2 y 4 semanas."
86
+ }
87
+ }
88
+ ]
89
+ }
90
+ ```
@@ -0,0 +1,57 @@
1
+ # 05-Internationalization · Single Hub & Instant Language Scaling
2
+
3
+ > Единая архитектура локализации: как добавлять новые языки (es, en, uk, de, fr, it) за 2 минуты без раскидывания переводов по проекту.
4
+
5
+ ---
6
+
7
+ ## 1. Архитектурный принцип: Single Hub (Единый хаб)
8
+
9
+ ❌ **Как делать НЕЛЬЗЯ:**
10
+ Хранить тексты в разных местах: часть в `i18n/`, часть в объектах `L(es, en, uk)` внутри компонентов, часть жестко зашитой в шаблонах.
11
+
12
+ ✅ **Как устроено в DS7:**
13
+ Все системные строки интерфейса хранятся **строго в одном месте**:
14
+ ```
15
+ i18n/
16
+ └── locales/
17
+ ├── es.ts # Испанский (базовый)
18
+ ├── en.ts # Английский
19
+ ├── uk.ts # Украинский
20
+ ├── de.ts # Немецкий (новый)
21
+ └── fr.ts # Французский (новый)
22
+ ```
23
+
24
+ ---
25
+
26
+ ## 2. Как добавить новый язык за 2 минуты:
27
+
28
+ ### Шаг 1: Добавить файл перевода
29
+ Скопируйте `es.ts` в `de.ts` и переведите значения ключей.
30
+
31
+ ### Шаг 2: Зарегистрировать язык в `nuxt.config.ts`:
32
+ ```ts
33
+ // nuxt.config.ts
34
+ i18n: {
35
+ strategy: 'prefix_except_default',
36
+ defaultLocale: 'es',
37
+ locales: [
38
+ { code: 'es', language: 'es-ES', name: 'Español', file: 'es.ts' },
39
+ { code: 'en', language: 'en-GB', name: 'English', file: 'en.ts' },
40
+ { code: 'uk', language: 'uk-UA', name: 'Українська', file: 'uk.ts' },
41
+ { code: 'de', language: 'de-DE', name: 'Deutsch', file: 'de.ts' } // <-- Добавлена одна строчка!
42
+ ],
43
+ langDir: '../i18n/locales'
44
+ }
45
+ ```
46
+
47
+ Все маршруты (`/de`, `/de/hogares`, `/de/tienda`), переключатели в шапке, hreflang теги и sitemap для нового языка сгенерируются автоматически!
48
+
49
+ ---
50
+
51
+ ## 3. Четкое разделение: UI-строки vs Бизнес-данные
52
+
53
+ * **`i18n/locales/*.ts`** — отвечает **только за интерфейсные строки**:
54
+ Названия кнопок («Contactar», «Calcular mi ahorro»), подписи форм, элементы навигации, системные сообщения об ошибках.
55
+ * **`app/data/*.ts`** — отвечает **за бизнес-данные и каталог**:
56
+ Список товаров, технические характеристики, список городов, база статей блога.
57
+ * **Типизация:** Данные из `app/data/` проверяются TypeScript-интерфейсами. Если пропущен перевод на один из языков, компилятор не пропустит билд в продакшн.
@@ -0,0 +1,32 @@
1
+ {
2
+ "nav": {
3
+ "home": "Inicio",
4
+ "residential": "Hogares",
5
+ "business": "Empresas",
6
+ "mobility": "Movilidad",
7
+ "equipment": "Equipamiento",
8
+ "service": "Mantenimiento",
9
+ "contact": "Contactar"
10
+ },
11
+ "common": {
12
+ "viewProduct": "Ver producto",
13
+ "requestQuote": "Pedir presupuesto",
14
+ "calculate": "Calcular ahorro",
15
+ "fromPrice": "desde",
16
+ "close": "Cerrar",
17
+ "send": "Enviar",
18
+ "success": "Solicitud enviada correctamente"
19
+ },
20
+ "calc": {
21
+ "title": "Calcula tu ahorro solar",
22
+ "billLabel": "¿Cuánto pagas de luz al mes?",
23
+ "yearlySavings": "Ahorro anual estimado",
24
+ "recommendedPower": "Potencia recomendada",
25
+ "paybackTime": "Amortización estimada"
26
+ },
27
+ "badges": {
28
+ "top": "TOP Ventas",
29
+ "new": "Novedad",
30
+ "sale": "Oferta"
31
+ }
32
+ }
@@ -0,0 +1,36 @@
1
+ # 06-Business · B2C, B2B & B2A Business Models
2
+
3
+ > Современные финансовые и коммерческие модели в солнечной энергетике Испании (2025–2026).
4
+
5
+ ---
6
+
7
+ ## 1. B2C (Hogares / Частные дома)
8
+
9
+ ### «Batería Virtual» (Виртуальный аккумулятор) и Factura 0,00 €
10
+ * В солнечные месяцы (май–сентябрь) в Андалусии панели производят больше, чем потребляет дом.
11
+ * Излишки отправляются в сеть, а энергокомпания (Octopus, Repsol, Próxima) начисляет евро на виртуальный счет;
12
+ * Зимой эти накопленные евро списываются в счет оплаты ночного электричества.
13
+ * **Результат для клиента:** Круглогодичный счет **0,00 € в фактуре**.
14
+
15
+ ### Comunidades Energéticas (RD 244/2019)
16
+ * По закону Испании панели на одной крыше могут распределять электричество между соседними домами в радиусе до 2 км;
17
+ * Предложение для урбанизаций и таунхаусов (adosados): совместная установка одной мощной станции со скидкой до 35% для каждого соседа.
18
+
19
+ ---
20
+
21
+ ## 2. B2B (Empresas / Предприятия и фабрики)
22
+
23
+ ### Модель PPA (Power Purchase Agreement / 0€ Inversión)
24
+ * Главная проблема директоров компаний: нежелание тратить 50 000 – 100 000 € оборотных средств;
25
+ * **Решение PPA:** Инвестор или Mi Luz Solar устанавливает электростанцию на крыше предприятия **за 0 € капиталовложений**.
26
+ * Предприятие просто покупает чистую энергию со своей же крыши по фиксированной низкой ставке (например, 0.08 €/кВт·ч вместо 0.19 €/кВт·ч из сети), экономя сотни тысяч евро.
27
+
28
+ ### Solar Carports (Солнечные навесы для парковок)
29
+ * Навесы из панелей над открытыми парковками отелей, складов, гипермаркетов и спорткомплексов;
30
+ * Тень для автомобилей клиентов от андалузского солнца + встроенные зарядные станции V2C для сотрудников и автопарка.
31
+
32
+ ---
33
+
34
+ ## 3. B2A (Comunidades de Propietarios и Госсектор)
35
+
36
+ * Программы энергоэффективности Next Generation EU субсидируют до **60%** затрат на установку солнечных панелей на крышах многоквартирных домов для питания лифтов, гаражей и освещения подъездов.
@@ -0,0 +1,50 @@
1
+ # 06-Business · Contextual Leads, WhatsApp Deep-Link & PDF Proposals
2
+
3
+ > Как конвертировать посетителей в квалифицированные заявки с максимальным закрытием в продажу.
4
+
5
+ ---
6
+
7
+ ## 1. Персонализированный WhatsApp Deep-Link
8
+
9
+ Обычная ссылка `wa.me/34613050156` заставляет пользователя самостоятельно придумывать текст. В 40% случаев он закрывает вкладку.
10
+
11
+ ### Стандарт DS7:
12
+ При клике на любую кнопку связи («Consultar en WhatsApp», «Pedir estudio») скрипт формирует динамическую ссылку с **полным контекстом расчета**:
13
+
14
+ ```ts
15
+ const generateWhatsAppLink = (context: {
16
+ page: string
17
+ monthlyBill?: number
18
+ powerKw?: number
19
+ productId?: string
20
+ }) => {
21
+ const phone = '34613050156'
22
+ let text = '¡Hola Mi Luz Solar! '
23
+ if (context.monthlyBill) {
24
+ text += `He calculado una instalación para mi factura de ${context.monthlyBill} €/mes (aprox. ${context.powerKw} kW). `
25
+ }
26
+ if (context.productId) {
27
+ text += `Me interesa el equipo: ${context.productId}. `
28
+ }
29
+ text += '¿Podríais confirmarme la disponibilidad y subvenciones aplicables?'
30
+
31
+ return `https://wa.me/${phone}?text=${encodeURIComponent(text)}`
32
+ }
33
+ ```
34
+
35
+ Клиент открывает WhatsApp — сообщение уже написано за него. Ему остается нажать кнопку «Отправить». Менеджер сразу видит параметры и моментально закрывает сделку.
36
+
37
+ ---
38
+
39
+ ## 2. Мгновенная генерация PDF-сметы в браузере
40
+
41
+ * После работы с калькулятором пользователю предлагается: **«Descargar propuesta técnica preliminar (PDF)»**;
42
+ * Прямо в браузере за 1 секунду формируется брендированный PDF с графиком окупаемости, перечнем оборудования и контактами;
43
+ * Условие получения — ввод телефона или email;
44
+ * Конверсия возрастает в 2–3 раза по сравнению с обычной формой обратного звонка.
45
+
46
+ ---
47
+
48
+ ## 3. Оффлайн-очередь заявок (Offline Lead Queue)
49
+
50
+ При кратковременном обрыве мобильного интернета форма не выдает красную ошибку. Данные сохраняются в `IndexedDB / localStorage` и автоматически отправляются на сервер сразу при восстановлении сетевого соединения. Ни один лид не теряется.
@@ -0,0 +1,38 @@
1
+ # 06-Business · EV & Solar Ecosystem (V2C, V2H, Plan MOVES III)
2
+
3
+ > Современная связка солнечной энергетики и электромобильности. Как продавать умные зарядные станции и станции самопотребления.
4
+
5
+ ---
6
+
7
+ ## 1. Зарядка от излишков солнца (100% Solar Surplus)
8
+
9
+ Станции испанского производителя **V2C Trydan** — якорный продукт для направления `Movilidad`:
10
+ * **Принцип:** Станция связывается по Wi-Fi с инвертором (Huawei, Livoltek, GoodWe). Если дом потребляет 1 кВт, а панели генерируют 5 кВт, оставшиеся 4 кВт излишка автоматически направляются в батарею автомобиля.
11
+ * **Выгода:** Машина заряжается **чистой бесплатной энергией солнца (0 € расходов)**, не покупая ни одного кВт·ч из сети.
12
+
13
+ ---
14
+
15
+ ## 2. Метрика «Солнечный километр»
16
+
17
+ Клиентам тяжело воспринимать абстрактные технические показатели (кВт, амперы, вольты).
18
+ В интерфейсе все формулы переводятся в **километры бесплатной езды**:
19
+ * *«6 солнечных панелей на крыше = 45 км бесплатного ежедневного пробега»*.
20
+ * *«Экономия на заправке автомобиля: более 180 € в месяц по сравнению с бензином»*.
21
+
22
+ ---
23
+
24
+ ## 3. V2H (Vehicle-to-Home) — Электромобиль как аккумулятор дома
25
+
26
+ * Обычная домашняя батарея (например, 5 кВт·ч) стоит около 3 000 €.
27
+ * Батарея современного электромобиля — **60–80 кВт·ч** (в 12–15 раз больше!).
28
+ * Технология V2H позволяет использовать емкость электромобиля для питания дома в вечерние часы пиковых тарифов или при аварийных отключениях электросети.
29
+
30
+ ---
31
+
32
+ ## 4. Субсидии Plan MOVES III (Возврат до 70–80%)
33
+
34
+ Государственная программа Испании компенсирует большую часть стоимости зарядной станции и ее монтажа:
35
+ * В карточках товаров V2C всегда выводятся две цены:
36
+ * Базовая цена оборудования;
37
+ * **Финальная цена после субсидии Plan MOVES III** (`782 € → 234 €`).
38
+ * Это снимает ценовые возражения и стимулирует покупку комплекта «Панели + Зарядка».
@@ -0,0 +1,133 @@
1
+ # DS7 · 07 — Targeted Testing Strategy
2
+
3
+ > **Принцип:** Запускай минимально достаточный тест — не весь suite.
4
+ > Полный прогон — только перед PR/деплоем. Ежедневная разработка — точечные проверки.
5
+
6
+ ---
7
+
8
+ ## Иерархия тестов (от быстрого к медленному)
9
+
10
+ ```
11
+ 1. Unit (domain logic) ~10ms/test → запускать всегда при изменении логики
12
+ 2. Composable (Vue reactive) ~50ms/test → при изменении composable
13
+ 3. Component (Vue TU) ~200ms/test → при изменении компонента
14
+ 4. E2E / Playwright ~5s/flow → только критичные пути, перед релизом
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Инструменты
20
+
21
+ | Инструмент | Назначение |
22
+ |---|---|
23
+ | **Vitest** | Unit + composable + component тесты |
24
+ | **@vue/test-utils** | Маунт Vue-компонентов без браузера |
25
+ | **Playwright** | E2E (checkout, calculator flow, 404) |
26
+
27
+ ---
28
+
29
+ ## Команды — точечные запуски
30
+
31
+ ```bash
32
+ # Один файл
33
+ npx vitest run app/domain/calculators/residential.test.ts
34
+
35
+ # Одна папка
36
+ npx vitest run app/domain/calculators/
37
+
38
+ # По имени теста
39
+ npx vitest run -t "savings calculator"
40
+
41
+ # Минимальный вывод (экономит токены в AI-диалоге)
42
+ npx vitest run --reporter=dot
43
+
44
+ # Полный suite — только перед коммитом
45
+ npx vitest run
46
+
47
+ # Watch (только при локальной разработке)
48
+ npx vitest --reporter=dot
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Правила именования тестов
54
+
55
+ ```typescript
56
+ // ✅ Описательное: что тестируем + ожидаемый результат
57
+ it('calculates savings with 30% self-consumption correctly', () => { ... })
58
+
59
+ // ❌ Слабое: непонятно что ломается
60
+ it('works', () => { ... })
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Структура тест-файла
66
+
67
+ ```typescript
68
+ // app/domain/calculators/residential.test.ts
69
+
70
+ import { describe, it, expect } from 'vitest'
71
+ import { calcSavings } from './residential'
72
+
73
+ // Self-contained: тест запускается изолированно без глобального setup
74
+ describe('calcSavings', () => {
75
+ it('returns zero savings for zero consumption', () => {
76
+ expect(calcSavings({ kwhMonth: 0, panelKw: 5, tariff: 0.18 })).toBe(0)
77
+ })
78
+
79
+ it('caps savings at 100% of bill', () => {
80
+ const r = calcSavings({ kwhMonth: 100, panelKw: 20, tariff: 0.18 })
81
+ expect(r.savingsPct).toBeLessThanOrEqual(100)
82
+ })
83
+ })
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Правила тестового покрытия
89
+
90
+ | Слой | Покрытие | Инструмент |
91
+ |---|---|---|
92
+ | `domain/calculators/` | **≥ 90%** | Vitest unit |
93
+ | `composables/` | **≥ 70%** | Vitest + @vue/test-utils |
94
+ | `components/ui/` | **критичные пути** | @vue/test-utils |
95
+ | `pages/` | **smoke только** | Playwright |
96
+
97
+ > **Не тестировать:** статичные данные (`app/data/`), CSS, переводы (i18n) — их не нужно юнит-тестировать.
98
+
99
+ ---
100
+
101
+ ## Стратегия для AI-агентов (экономия токенов)
102
+
103
+ 1. **Перед правкой** — запусти только тест изменяемого файла
104
+ 2. **После правки** — снова только этот тест (`--reporter=dot`)
105
+ 3. **Расширяй scope** только если изменение затронуло shared logic
106
+ 4. **Полный suite** — один раз в конце задачи, не в каждой итерации
107
+
108
+ ```bash
109
+ # Шаблон для AI-итерации (минимум токенов):
110
+ npx vitest run path/to/changed.test.ts --reporter=dot
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Vitest Config (рекомендуемый минимум)
116
+
117
+ ```typescript
118
+ // vitest.config.ts
119
+ import { defineConfig } from 'vitest/config'
120
+
121
+ export default defineConfig({
122
+ test: {
123
+ environment: 'jsdom',
124
+ include: ['**/*.test.ts'],
125
+ exclude: ['node_modules', 'ds7', 'dist'],
126
+ reporter: process.env.CI ? 'verbose' : 'dot', // dot = меньше вывода
127
+ coverage: {
128
+ include: ['app/domain/**', 'app/composables/**'],
129
+ reporter: ['text-summary'], // краткий отчёт, не таблицы
130
+ },
131
+ },
132
+ })
133
+ ```