TKBK Studio
TKBK Studio
Клиенты, проекты, счета и акты в PDF с вашими реквизитами, НДС и напоминания о неоплатах в Telegram
Простая CRM для фрилансера или небольшой студии: клиенты, проекты, счета на оплату и акты об оказании услуг. Всё в одном окне браузера, данные — в файле SQLite на вашем сервере, без подписок на облачные CRM.
Счета нумеруются автоматически (своя нумерация на каждый год), суммы считаются в копейках без ошибок округления, НДС — «без НДС», «в том числе» или «сверху» по ставкам 0–22%. PDF счёта и акта формируются с вашими реквизитами из мастера, таблицей услуг и суммой прописью.
Каждое утро бот присылает в Telegram сводку: какие счета просрочены и у каких срок сегодня или завтра. Кнопка «Письмо клиенту» с помощью нейросети через TKBK API пишет вежливое письмо об отправке счёта, напоминание об оплате или благодарность — с готовой ссылкой на почту.
Интерфейс на htmx без сборки фронтенда, сервер — Fastify. Вход по логину и паролю, защита от подбора и CSRF. Запуск одной командой в Docker.
Для кого: Фрилансеры, самозанятые, ИП и небольшие студии
Ключи и токены не вводятся на сайте — их кладут в файл .env на своём сервере.
CRM_PASSWORDПароль для входа в CRM — Придумайте длинный пароль; логин — CRM_USER (по умолчанию admin)CRM_USERЛогин — По умолчанию adminTZЧасовой пояс — Europe/Moscow по умолчанию — для дат и времени напоминанийTELEGRAM_BOT_TOKENТокен бота для напоминаний — @BotFather → /newbot. Напишите боту /startTELEGRAM_CHAT_IDВаш chat_id в Telegram — Узнать: @userinfobot. Можно ID группыREMINDER_HOURЧас ежедневной сводки — 0–23, по умолчанию 10TKBK_API_KEYКлюч TKBK API — Для кнопки «Письмо клиенту»; без ключа кнопка скрытаTKBK_MODELМодель — claude-haiku-4-5 (по умолчанию) или claude-sonnet-5# {{BRAND}} — мини-CRM
CRM для фрилансера или небольшой студии: клиенты, проекты, счета и акты в PDF с вашими реквизитами, статусы оплат, ежедневная сводка неоплаченных счетов в Telegram и AI-черновики писем клиентам. Данные хранятся в одном файле SQLite на вашем компьютере или сервере.
## Что умеет
- **Клиенты** с реквизитами (ИНН, КПП, адрес) и контактами; карточка клиента со всеми счетами и проектами.
- **Проекты**: статусы «лид / в работе / завершён / архив», бюджет, дедлайн.
- **Счета**: автонумерация `2026-001` (своя на каждый год), позиции с количеством и единицами, НДС «без НДС», «в том числе» или «сверху» (0, 5, 7, 10, 20, 22%).
- **PDF счёта и акта**: банковские реквизиты, таблица услуг, итоги, сумма прописью, строки для подписи.
- **Статусы оплат**: черновик → выставлен → оплачен (с датой), просрочка подсвечивается автоматически.
- **Telegram**: каждое утро сводка просроченных счетов и тех, у которых срок сегодня-завтра; кнопка «Отправить сейчас».
- **AI-письмо клиенту** через TKBK API: отправка счёта, напоминание об оплате, благодарность, отправка акта — с готовой ссылкой «Открыть в почте».
- **Безопасность**: вход по логину и паролю, блокировка подбора пароля, защита от CSRF, CSP-заголовки.
## Быстрый старт с Docker (10 минут)
1. Установите [Docker Desktop](https://www.docker.com/products/docker-desktop/) (или Docker Engine на сервере).
2. Создайте `.env` и придумайте пароль в `CRM_PASSWORD`:
```bash
cp .env.example .env
```
3. Запустите:
```bash
docker compose up -d --build
```
4. Откройте http://localhost:3000. Браузер спросит логин (`admin`) и пароль из `.env`.
5. Добавьте клиента → «Новый счёт» → «Отметить выставленным» → «PDF счёта».
База лежит в Docker-томе `crm-data` и переживает пересборку. Шрифт DejaVu для PDF ставится в образ автоматически.
## Запуск без Docker
Нужен Node.js 22.12+ (рекомендуется 24 LTS).
```bash
npm install
cp .env.example .env
npm start # или npm run dev — с автоперезапуском при правке кода
```
SQLite ставится готовым бинарником — компилятор не нужен. Для PDF нужен шрифт с кириллицей: в Windows и macOS берётся Arial, в Linux — DejaVu Sans (`sudo apt install fonts-dejavu-core`). Свой шрифт: `PDF_FONT_REGULAR=/путь/к/шрифту.ttf` и `PDF_FONT_BOLD=…`.
Без `CRM_PASSWORD` CRM запускается без пароля — только для локальной разработки (`NODE_ENV=production` без пароля не стартует).
## Реквизиты и настройки документов
Реквизиты из мастера TKBK Studio лежат в `src/config.js`: исполнитель, ИНН/КПП, адрес, банк, БИК, счета, подпись, ставка НДС и срок оплаты по умолчанию. Поменяли — перезапустите сервер (`docker compose up -d --build`).
- **НДС.** На УСН и НПД выбирайте «Без НДС». С 2026 года основная ставка — 22%; для УСН с НДС есть ставки 5% и 7%. Ставку можно поменять в каждом счёте.
- **Нумерация.** Каждый год начинается с `001`. Номера не переиспользуются: удалить можно только черновик или отменённый счёт.
- **Акты** формируются из выставленного или оплаченного счёта (один акт на счёт) и нумеруются отдельно.
## Напоминания в Telegram
1. В [@BotFather](https://t.me/BotFather): `/newbot` → токен в `TELEGRAM_BOT_TOKEN`.
2. Напишите своему боту `/start` (иначе он не сможет вам писать).
3. Узнайте свой chat_id у [@userinfobot](https://t.me/userinfobot) → `TELEGRAM_CHAT_ID`. Для группы добавьте бота в группу и укажите её ID (начинается с `-100`).
4. Время сводки — `REMINDER_HOUR` (по умолчанию 10:00 по `TZ`). Сводка приходит раз в день, если есть просроченные счета или счета со сроком сегодня-завтра. На странице «Обзор» есть кнопка «Отправить сводку сейчас».
## AI-письма клиентам (TKBK API)
Добавьте в `.env` ключ `TKBK_API_KEY` (получить — на [tkbk.online](https://tkbk.online)). В карточке счёта появится блок «Письмо клиенту»: выберите цель письма — нейросеть напишет текст по данным счёта (клиент, номер, сумма, срок, услуги) и не станет придумывать лишнего. Модель по умолчанию — `claude-haiku-4-5` (быстрая и недорогая), для более живых текстов поставьте `TKBK_MODEL=claude-sonnet-5`.
## Доступ из интернета (HTTPS)
Пароль передаётся в каждом запросе, поэтому снаружи CRM должна работать только по HTTPS. В `docker-compose.yml` порт открыт лишь для `127.0.0.1`. На сервере поставьте [Caddy](https://caddyserver.com) — он сам получит сертификат:
```
crm.example.ru {
reverse_proxy 127.0.0.1:3000
}
```
и укажите `TRUST_PROXY=true` в `.env`, чтобы блокировка подбора пароля видела настоящий IP.
## Структура проекта
```
src/
server.js запуск: настройки → база → сервер → напоминания
app.js Fastify: авторизация, CSRF, заголовки безопасности, ошибки
config.js реквизиты и настройки документов (из мастера)
env.js db.js auth.js настройки .env, база с миграциями, вход
routes/ клиенты и проекты, счета/акты/PDF/письма, обзор
views/ HTML-фрагменты для htmx
lib/ деньги и сумма прописью, НДС и нумерация, формы, даты, безопасный HTML
pdf/ счёт и акт в PDF, поиск шрифта
services/ Telegram, сводка, TKBK API
public/ index.html, app.js (навигация, строки счёта), app.css
test/ тесты node:test
```
## Тесты
```bash
npm test
```
Проверяются: разбор сумм и сумма прописью, НДС и округления, нумерация по годам, формы, экранирование HTML, сводка в Telegram и запрос к TKBK API (с подменным fetch), вход и CSRF, полный сценарий счёта и PDF.
## FAQ
**Браузер не спрашивает пароль снова / как выйти?** Вход по Basic Auth живёт до закрытия браузера. Чтобы «выйти», закройте все окна браузера или откройте приватное окно.
**PDF не открывается: «Не найден шрифт с кириллицей».** Установите DejaVu (`apt install fonts-dejavu-core`) или укажите путь к TTF-шрифту в `PDF_FONT_REGULAR`.
**Бот не пишет в Telegram.** Напишите боту `/start`, проверьте `TELEGRAM_CHAT_ID` и ошибку в логах (`docker compose logs crm`).
**Как сделать бэкап?** Остановите контейнер и скопируйте том: `docker compose stop crm && docker compose cp crm:/app/data ./backup && docker compose start crm`. Без Docker — файл `data/crm.db`.
**CDN с htmx недоступен.** Скачайте `htmx.min.js` версии 2.0.11 в `public/` и поменяйте адрес скрипта в `public/index.html`.
## Что доработать
- Частичные оплаты и предоплаты.
- Отправка счёта клиенту по email прямо из CRM.
- Договоры по шаблону с реквизитами клиента.
- Импорт банковской выписки и автоматическая отметка оплат.
- Учёт времени по проектам и счёт по часам.
- QR-код для оплаты через СБП в PDF счёта.
Услуги, мастера, свободные окна на 14 дней, напоминания за сутки и за 2 часа, предоплата и отзывы
Оценка 0–10 после заказа: довольных — на Яндекс Карты, 2ГИС и WB, недовольных — сразу к менеджеру
Оплата звёздами или картой, одноразовые ссылки, напоминания о продлении и автоисключение по окончании