{
  "person": {
    "name": "Валентин Савиных",
    "jobTitle": "Full-cycle разработчик",
    "areaServed": "Кировская область и удалённо по России",
    "url": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/",
    "contacts": {
      "phone": "+79229005910",
      "email": "valstan@valstan.ru",
      "telegram": "https://t.me/VAL_STAN",
      "github": "https://github.com/Valstan"
    }
  },
  "site": {
    "url": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai",
    "host": "валентин.вмалмыже.рф"
  },
  "tools": [
    {
      "id": "tehzadanie",
      "title": "Черновик техзадания",
      "url": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/tehzadanie/",
      "output": "черновик техзадания текстом: что нужно, что есть, границы, вопросы до старта",
      "computedInBrowser": true,
      "sendsDataToServer": false,
      "questions": 8,
      "asOf": "2026-09-04"
    }
  ],
  "tasks": [
    {
      "slug": "sayt-uchrezhdeniyu",
      "question": "Нужен сайт учреждению или организации",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/zadachi/sayt-uchrezhdeniyu/",
      "timeline": "Каркас на своём домене — недели, а не месяцы: стек и решения переиспользуются с соседних сайтов.",
      "proof": [
        "Портал культуры Малмыжского района",
        "Гоньба",
        "вМалмыже"
      ]
    },
    {
      "slug": "perenos-starogo-sayta",
      "question": "Перенести старый сайт без потери позиций в поиске",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/zadachi/perenos-starogo-sayta/",
      "timeline": "Сайт на 100–150 страниц реально перенести за день-два — это мой замер на такой работе; она на витрине не показывается по решению заказчика, поэтому проверить утверждение снаружи нельзя.",
      "proof": [
        "Сабантуй Малмыж",
        "Портал культуры Малмыжского района"
      ]
    },
    {
      "slug": "uchetnaya-sistema",
      "question": "Нужна учётная система на предприятие",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/zadachi/uchetnaya-sistema/",
      "timeline": "Такие системы не делаются «под ключ за месяц»: сначала один участок учёта в работе, дальше по очереди.",
      "proof": [
        "Матрица РМЗ"
      ]
    },
    {
      "slug": "sayt-sobytiya",
      "question": "Сайт события или фестиваля к конкретной дате",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/zadachi/sayt-sobytiya/",
      "timeline": "Под дату — да: сайт Ярмарки собран переиспользованием готовых решений соседнего проекта.",
      "proof": [
        "Сабантуй Малмыж",
        "Ярмарка Казанская"
      ]
    },
    {
      "slug": "avtomatizaciya-publikacij",
      "question": "Автоматизировать сбор и публикацию контента",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/zadachi/avtomatizaciya-publikacij/",
      "timeline": "Первый работающий конвейер — недели; дальше добавляются источники и каналы.",
      "proof": [
        "Сарафан"
      ]
    },
    {
      "slug": "prilozhenie-bez-magazinov",
      "question": "Приложение на телефон без App Store и Google Play",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/zadachi/prilozhenie-bez-magazinov/",
      "timeline": "Первый рабочий релиз — месяцы, потому что роли и данные людей делаются аккуратно.",
      "proof": [
        "Тренер"
      ]
    }
  ],
  "services": [
    {
      "id": "sites",
      "title": "Сайты и порталы под ключ",
      "need": "Нужен сайт учреждению, событию или компании — и чтобы им можно было управлять без программиста",
      "body": "Сайт с админкой, в которой контент правит сам заказчик, поиск по материалам, разметка под поисковики и ИИ-ассистентов.",
      "areaServed": "Кировская область и удалённо по России"
    },
    {
      "id": "erp",
      "title": "Настольные учётные системы",
      "need": "Нужен учёт на производстве или складе, а интернет на местах нестабильный",
      "body": "Программа на компьютерах предприятия работает офлайн с локальной базой и сама синхронизируется с сервером, когда связь есть. Печать документов с подписями, обновление у всех пользователей разом, отказоустойчивый сервер.",
      "areaServed": "Кировская область и удалённо по России"
    },
    {
      "id": "automation",
      "title": "Сервисы автоматизации",
      "need": "Рутина съедает время: собрать, отобрать и опубликовать контент вручную",
      "body": "Сервис мониторит источники, отбирает нужное (в том числе с помощью ИИ) и публикует по расписанию сразу в несколько каналов. Фоновые очереди, устойчивость к сбоям внешних сервисов.",
      "areaServed": "Кировская область и удалённо по России"
    },
    {
      "id": "pwa",
      "title": "Мобильные приложения без магазинов приложений",
      "need": "Нужно приложение у людей в телефоне, но не хочется проходить публикацию в сторах",
      "body": "Устанавливаемое веб-приложение (PWA) с офлайн-режимом и пуш-уведомлениями — работает и на iPhone, и на Android. Обновление выкатывается сразу всем, без ожидания модерации.",
      "areaServed": "Кировская область и удалённо по России"
    },
    {
      "id": "auth",
      "title": "Вход, роли и 152-ФЗ",
      "need": "В системе персональные данные — нужно сделать правильно с первого дня",
      "body": "Единый вход для нескольких сервисов, роли и права с первого дня, соответствие закону о персональных данных, включая детские: согласие, локализация в РФ, минимизация, план действий при инциденте.",
      "areaServed": "Кировская область и удалённо по России"
    },
    {
      "id": "infra",
      "title": "Вывод в прод и эксплуатация",
      "need": "Код есть, а до работающего сайта на своём домене руки не доходят",
      "body": "Сборка в CI, деплой по SSH, HTTPS с автопродлением, кириллические домены, экономная эксплуатация на недорогих серверах с жёсткими лимитами памяти, проверка после каждого деплоя.",
      "areaServed": "Кировская область и удалённо по России"
    }
  ],
  "works": [
    {
      "slug": "matrica-rmz",
      "title": "Матрица РМЗ",
      "tagline": "Настольная ERP-система для завода по ремонту двигателей",
      "status": "в проде",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/matrica-rmz/",
      "prodUrlUnicode": null,
      "prodUrl": null,
      "stack": "TypeScript; Electron + React 18 (клиент), Node 22 + Express (сервер); PostgreSQL 16 / SQLite, Drizzle ORM; pnpm-монорепо",
      "facts": [
        {
          "claim": "Самый активный проект: 523 коммита за 30 дней.",
          "asOf": "2026-07-31",
          "verify": "measured"
        },
        {
          "claim": "Работает офлайн: данные пишутся локально и догоняют сервер при появлении связи.",
          "asOf": "2026-07-31",
          "verify": "measured"
        },
        {
          "claim": "Многоэтапный аудит безопасности — критичные находки закрыты на проде.",
          "asOf": "2026-07-31",
          "verify": "measured"
        }
      ]
    },
    {
      "slug": "gonba",
      "title": "Гоньба",
      "tagline": "Сайт-CMS населённого пункта: новости и материалы под управлением редактора",
      "status": "в проде",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/gonba/",
      "prodUrlUnicode": "гоньба.рф",
      "prodUrl": "https://xn--80abf4be9f.xn--p1ai/",
      "stack": "Next.js 15 + Payload CMS, TypeScript, PostgreSQL, pnpm 10; CI/CD на GitHub Actions",
      "facts": [
        {
          "claim": "Сайт открыт и работает — можно зайти и проверить самому.",
          "asOf": "2026-08-01",
          "verify": "external"
        },
        {
          "claim": "47 коммитов за последние 30 дней; серия из 8 зелёных деплоев подряд.",
          "asOf": "2026-09-04",
          "verify": "measured"
        },
        {
          "claim": "Редактор правит сайт сам — программист для наполнения не нужен.",
          "asOf": "2026-08-01",
          "verify": "measured"
        }
      ]
    },
    {
      "slug": "sabantuy-malmyzh",
      "title": "Сабантуй Малмыж",
      "tagline": "Сайт национального фестиваля с живой программой дня и народной фотолентой",
      "status": "в проде",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/sabantuy-malmyzh/",
      "prodUrlUnicode": "сабантуй.вмалмыже.рф",
      "prodUrl": "https://xn--80aac7atuli.xn--80adkdyec4j.xn--p1ai/",
      "stack": "Next.js 15 + Payload CMS 3.75 + PostgreSQL, TypeScript, pnpm 10",
      "facts": [
        {
          "claim": "Сайт открыт и работает — можно зайти и проверить самому.",
          "asOf": "2026-08-01",
          "verify": "external"
        },
        {
          "claim": "В день фестиваля пик 4,6 запроса в секунду, ноль сбоев, запас мощности около четырёхкратного.",
          "asOf": "2026-07-04",
          "verify": "measured"
        },
        {
          "claim": "Контрольный нагрузочный замер показал потолок около 84 запросов в секунду на том же сервере.",
          "asOf": "2026-07-25",
          "verify": "measured"
        }
      ]
    },
    {
      "slug": "trener",
      "title": "Тренер",
      "tagline": "Платформа спортивной школы: сеть филиалов, расписание, объявления, подтверждения от родителей",
      "status": "в проде",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/trener/",
      "prodUrlUnicode": "интер.вмалмыже.рф",
      "prodUrl": "https://xn--e1afpni.xn--80adkdyec4j.xn--p1ai/",
      "stack": "Next.js 15 + Payload CMS 3.75 + React 19 + PostgreSQL; клиент — PWA; web-push (APNs / FCM + VAPID); хостинг в РФ",
      "facts": [
        {
          "claim": "Сайт открыт и работает — можно зайти и проверить самому.",
          "asOf": "2026-08-01",
          "verify": "external"
        },
        {
          "claim": "В проде с 26 июня 2026 — больше двух месяцев обслуживает живых пользователей.",
          "asOf": "2026-09-04",
          "verify": "measured"
        },
        {
          "claim": "Из приложения одной школы выросло в платформу сети филиалов с ролями владельца, администратора, тренера и родителя.",
          "asOf": "2026-07-31",
          "verify": "measured"
        },
        {
          "claim": "Требования 152-ФЗ по детским данным заложены в архитектуру, а не добавлены потом.",
          "asOf": "2026-07-31",
          "verify": "measured"
        }
      ]
    },
    {
      "slug": "pozvoni",
      "title": "ПОЗВОНИ",
      "tagline": "Справочник услуг города: одно приложение, много дверей — первым открылось такси",
      "status": "в проде",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/pozvoni/",
      "prodUrlUnicode": "позвони.вмалмыже.рф",
      "prodUrl": "https://xn--b1ajetccd.xn--80adkdyec4j.xn--p1ai/",
      "stack": "Next.js + Payload CMS + PostgreSQL, TypeScript, pnpm; клиент — PWA; MapLibre + собственные тайлы OSM (PMTiles) + локальный геокодер; OIDC-вход",
      "facts": [
        {
          "claim": "Справочник открыт и работает — можно зайти и проверить самому.",
          "asOf": "2026-09-11",
          "verify": "external"
        },
        {
          "claim": "Первый выход в прод — 29 августа 2026; вторая дверь, весь справочник целиком, открыта 30 августа.",
          "asOf": "2026-09-04",
          "verify": "measured"
        },
        {
          "claim": "Карта и поиск адреса работают без единого обращения к сторонним сервисам — видно в панели сети браузера.",
          "asOf": "2026-08-29",
          "verify": "external"
        },
        {
          "claim": "В адресной базе города 103 улицы и 2094 адреса, карта укладывается в 1,23 МиБ.",
          "asOf": "2026-08-29",
          "verify": "measured"
        },
        {
          "claim": "Вход через единый вход экосистемы проверен живым входом, без ручной регистрации.",
          "asOf": "2026-09-03",
          "verify": "measured"
        }
      ]
    },
    {
      "slug": "sarafan-reklama",
      "title": "Рекламная площадка «Сарафан»",
      "tagline": "Сеть районных новостных сообществ и продажа рекламы в ней",
      "status": "в проде",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/sarafan-reklama/",
      "prodUrlUnicode": "сарафан.вмалмыже.рф",
      "prodUrl": "https://xn--80aaa6cmey.xn--80adkdyec4j.xn--p1ai/regions/links",
      "stack": "Python 3.12, FastAPI, Celery + Redis, PostgreSQL, интеграция с VK API; витрина — серверный рендер",
      "facts": [
        {
          "claim": "Сеть из 26 сообществ, 29 173 подписчика суммарно — числа на странице живые, обновляются каждую ночь.",
          "asOf": "2026-08-02",
          "verify": "external"
        },
        {
          "claim": "Охват — 23 района Кировской области и 3 сообщества в Татарстане: экспансия за пределы области уже началась.",
          "asOf": "2026-08-02",
          "verify": "external"
        },
        {
          "claim": "Новости в сообществах выходят без участия человека, круглосуточно — сеть растёт без роста ручного труда.",
          "asOf": "2026-08-02",
          "verify": "measured"
        }
      ]
    },
    {
      "slug": "sarafan",
      "title": "Сарафан",
      "tagline": "Автоматизированная редакция: сбор новостей, ИИ-отбор и публикация по расписанию",
      "status": "внутренний сервис",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/sarafan/",
      "prodUrlUnicode": null,
      "prodUrl": null,
      "stack": "Python 3.12, FastAPI, Celery + Redis, PostgreSQL, интеграция с VK API; деплой по SSH + systemd",
      "facts": [
        {
          "claim": "Единый вход «ЕСА вМалмыже.рф» работает от начала до конца; выдача клиентов и ключей — самообслуживанием.",
          "asOf": "2026-07-29",
          "verify": "measured"
        },
        {
          "claim": "Около 1400 автотестов.",
          "asOf": "2026-07-29",
          "verify": "measured"
        }
      ]
    },
    {
      "slug": "yarmarka-kazanskaya",
      "title": "Ярмарка Казанская",
      "tagline": "Сайт городского праздника с летописью по годам и живым режимом дня события",
      "status": "в проде",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/yarmarka-kazanskaya/",
      "prodUrlUnicode": "казанская.вмалмыже.рф",
      "prodUrl": "https://xn--80aaa0andu6a3j.xn--80adkdyec4j.xn--p1ai/",
      "stack": "Next.js 15 + Payload CMS 3.75 + PostgreSQL, pnpm 10",
      "facts": [
        {
          "claim": "Сайт открыт и работает — можно зайти и проверить самому.",
          "asOf": "2026-08-01",
          "verify": "external"
        },
        {
          "claim": "Запуск за счёт переиспользования стека соседнего проекта — недели вместо месяцев.",
          "asOf": "2026-07-31",
          "verify": "measured"
        },
        {
          "claim": "Отмену праздника 2026 года сайт отработал сменой режима, а не переделкой.",
          "asOf": "2026-07-24",
          "verify": "external"
        }
      ]
    },
    {
      "slug": "karman",
      "title": "Карман",
      "tagline": "Личный менеджер кредитов с напоминаниями в Telegram",
      "status": "в проде",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/karman/",
      "prodUrlUnicode": null,
      "prodUrl": null,
      "stack": "Next.js 16 (App Router) + React 19 + TypeScript, Drizzle ORM + PostgreSQL, Tailwind CSS v4",
      "facts": [
        {
          "claim": "Три разных стека (Django, Vite, Express) сведены в один без сброса паролей пользователей.",
          "asOf": "2026-07-31",
          "verify": "measured"
        },
        {
          "claim": "Воркер напоминаний не тянет ни одной внешней зависимости.",
          "asOf": "2026-07-31",
          "verify": "measured"
        }
      ]
    },
    {
      "slug": "vmalmyzhe",
      "title": "вМалмыже",
      "tagline": "Городской информационный портал района",
      "status": "в проде",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/vmalmyzhe/",
      "prodUrlUnicode": "вмалмыже.рф",
      "prodUrl": "https://xn--80adkdyec4j.xn--p1ai/",
      "stack": "Next.js 15 + Payload CMS 3.75 + PostgreSQL, TypeScript, pnpm; CI/CD + systemd",
      "facts": [
        {
          "claim": "Портал открыт и работает — можно зайти и проверить самому.",
          "asOf": "2026-08-01",
          "verify": "external"
        },
        {
          "claim": "Первые рабочие этапы портала выведены в прод в день запуска работ.",
          "asOf": "2026-07-26",
          "verify": "measured"
        }
      ]
    },
    {
      "slug": "dom-kultury",
      "title": "Портал культуры Малмыжского района",
      "tagline": "Портал-матрёшка: учреждения культуры района под одной крышей, каждое со своим лицом",
      "status": "в проде",
      "page": "https://xn--80adkmnnb2b.xn--80adkdyec4j.xn--p1ai/raboty/dom-kultury/",
      "prodUrlUnicode": "культура.вмалмыже.рф",
      "prodUrl": "https://xn--80atdujec4e.xn--80adkdyec4j.xn--p1ai/",
      "stack": "Next.js 15 + Payload CMS 3.75 + PostgreSQL, TypeScript, pnpm; CI/CD + systemd",
      "facts": [
        {
          "claim": "Портал открыт и работает — можно зайти и проверить самому.",
          "asOf": "2026-09-04",
          "verify": "external"
        },
        {
          "claim": "Основной адрес — культура.вмалмыже.рф; прежний домкультуры.вмалмыже.рф отвечает перенаправлением, старые ссылки не теряются.",
          "asOf": "2026-09-04",
          "verify": "external"
        },
        {
          "claim": "Первый сбор материалов прошёл по всем 33 сообществам учреждений района: 632 записи и 2457 медиафайлов легли в портал черновиками, до решения редактора о публикации.",
          "asOf": "2026-09-04",
          "verify": "measured"
        },
        {
          "claim": "Собственное фирменное оформление с эмблемой портала, разделами праздников и страницами домов культуры района — вместо типового каркаса.",
          "asOf": "2026-09-05",
          "verify": "external"
        }
      ]
    }
  ]
}