Продвинутый

Система задач 3 & Done: управление делами без хлопот

Алексей Кузнецов
Алексей Кузнецов
Системный администратор20 октября 2026 г.11 мин чтения

Алексей Кузнецов разбирает систему задач 3 & Done — голосовой ввод, приватность и хранение. Как она устраняет рутину и помогает сосредоточиться на важном.

Система задач 3 & Done: управление делами без хлопот

Алексей Кузнецов разбирает систему задач 3 & Done — голосовой ввод, приватность и хранение. Как она устраняет рутину и помогает сосредоточиться на важном.

Зачем нужна система задач 3 & Done

Проблема перегрузки задачами

Ситуация знакома каждому, кто хоть раз пытался управлять делами через обычный список. Вчера вечером вы добавляете в таск-трекер десять пунктов: «проверить логи на Пятачке», «сделать бэкап конфигов», «написать отчёт». Утром — ещё пять. К концу дня список вырос до сорока, а вы всё ещё смотрите на него, не понимая, с чего начать.

Рутина размывает внимание. Каждая новая задача — это переключение контекста, а переключения стоят. По данным исследований, восстановление концентрации после переключения занимает в среднем 23 минуты. В вашем случае, если вы админ, это может быть дольше: пока вы разбираетесь, где упал сервис на «Сове», забываете про бэкап на «Кролике».

Самая больная часть — это не объём, а хаос. Обычные to-do приложения хранят всё в одной куче. Нет понятности, что срочно, а что можно отложить. Нет связи между задачами: «обновить Docker» и «перезапустить контейнеры» — это одна операция, но в списке они две.

В моей практике хватало и [DeepSQL](/guides/razvertyvanie-deepsql-размещение на домашних серверах-dba-agent-dlya-postgresql-i-mysql-uf6iti) для мониторинга БД, и временных шкал для анализа событий, но управление задачами оставалось руками. Пока не наткнулся на 3 & Done.

Цель — сократить рутину до минимума

Система 3 & Done строится на простом принципе: три источника задач, один способ их обрабатывать. Никаких пяти колонок в Kanban, никаких приоритетов «очень срочно». Три канала, один выход.

Первый канал — голос. Утром вы говорите: «Нужно проверить диски на Пятачке», и задача попадает в систему. Никаких раскладок, никаких «потом добавлю». Голосовой ввод работает даже в машине или на кухне, где руки заняты.

Второй канал — автоматический. События из инфраструктуры: алерт от Prometheus, ошибка в journald, падение контейнера. Вместо того чтобы смотреть в Grafana и вручную создавать тикет, система делает это за вас.

Третий канал — ручной. Когда вы сами решаете, что нужно сделать: «настроить бэкапы на Сове». Но даже здесь минимум действий — пара кликов или одна команда в терминале.

Все три канала сходятся в PostgreSQL. Зачем именно ей, если есть десятки облачных сервисов? Потому что [локальный стек](/articles/размещение на домашних серверах-ai-workflow-db-ollama-sql) даёт предсказуемость. Вы знаете, где лежат ваши данные, кто к ним доступен, и как их вытащить, если сервис умрёт.

Конфиг базы в моём случае прост:

sql
CREATE TABLE tasks (
    id SERIAL PRIMARY KEY,
    source TEXT NOT NULL, -- 'voice', 'alert', 'manual'
    content TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT NOW(),
    completed BOOLEAN DEFAULT FALSE
);

CREATE INDEX idx_tasks_source ON tasks(source);
CREATE INDEX idx_tasks_completed ON tasks(completed);

Рутину сокращают не только за счёт трёх каналов. Голосовой ввод убирает необходимость печатать. Автоматический импорт алертов — это как [агент DeepSQL](/guides/razvertyvanie-deepsql-размещение на домашних серверах-dba-agent-dlya-postgresql-i-mysql-uf6iti), только для задач: система сама следит за состоянием и создаёт тикеты, когда что-то ломается.

Результат: вместо часа, который вы тратите на то, чтобы разобрать список из сорока пунктов, вы тратите пять минут на то, чтобы обработать три. Остальное — на самом деле работает.

Как устроена 3 & Done: архитектура и принцип работы

Голосовой и текстовый ввод

Самая большая радость 3 & Done — в том, что я могу не трогать клавиатуру вообще. Говоришь в микрофон, система записывает, распознаёт речь и создаёт задачу. Для быстрых заметок на ходу это спасение.

Распознавание речи работает через Whisper — локальная модель, никуда не отправляет аудио. Настраивается в docker-compose.yml:

yaml
  stt-service:
    image: ghcr.io/3anddone/stt:latest
    volumes:
      - ./models/whisper:/models
    environment:
      - MODEL_SIZE=base
      - LANGUAGE=ru

Модель base — компромисс между скоростью и точностью. На моём R730 с GPU RTX 3060 разбор фразы длится около трёх секунд. Хватает, чтобы не стоять и не ждать.

Текстовый ввод — это обычный HTTP API. Любой клиент, даже curl, может создать задачу:

bash
curl -X POST http://localhost:8080/api/tasks \
  -H "Content-Type: application/json" \
  -d '{"title": "Проверить логи на Пятачке", "project": "infra"}'

Или через Telegram-бота, если удобнее писать с телефона. Бот тоже локальный — ставится в контейнере, токен берётся из BotFather, а дальше всё работает через webhook или long-polling.

Главное — нет привязки к одному интерфейсу. Голос, веб-форма, CLI, Telegram — всё сходится в одну очередь задач.

Хранение данных и приватность

Все задачи, проекты, метки и логи живут в PostgreSQL. Никаких JSON-файлов в /tmp — только настоящая база, с бэкапами и репликацией.

sql
CREATE TABLE tasks (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    title TEXT NOT NULL,
    project TEXT,
    completed BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT NOW(),
    completed_at TIMESTAMP
);

Бэкапы делаются стандартным pg_dump + cron:

bash
0 2 * * * pg_dump -U postgres 3anddone | gzip > /backup/3anddone-$(date +%F).sql.gz

Приватность — один из столпов системы. Никаких облаков, никаких синхронизаций с чужими серверами. Всё, что вы набираете или говорите — остаётся на вашем оборудовании. Даже аудио с распознаванием речи не сохраняется: модель обрабатывает поток и сразу отбрасывает.

Если нужен доступ снаружи — ставьте Caddy с TLS от Let's Encrypt. Настраивается в два шага:

caddy
3anddone.example.com {
    reverse_proxy localhost:8080
    encode gzip
}

А для полной уверенности можно завести отдельный TrueNAS с ZFS-снимками на случай, если что-то пойдёт не так. У меня так и есть — хранилище на 48 ТБ, и ни разу не подвело.

Связанное чтение: [размещение на домашних серверах AI: локальный стек DB, Ollama и SQL](/articles/размещение на домашних серверах-ai-workflow-db-ollama-sql) — как построить локальный AI-стек рядом с 3 & Done.

Технологии, лежащие в основе

PostgreSQL как хранилище задач

Задачи в 3 & Done хранятся в обычной таблице. Никаких JSON-полей, никаких вложенных структур — только столбцы с чёткими типами. Это даёт предсказуемость схемы и позволяет пользоваться привычными запросами.

sql
CREATE TABLE tasks (
    id          SERIAL PRIMARY KEY,
    title       TEXT NOT NULL,
    description TEXT,
    status      TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'done', 'archived')),
    priority    SMALLINT NOT NULL DEFAULT 3 CHECK (priority BETWEEN 1 AND 5),
    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    completed_at TIMESTAMPTZ,
    due_date    DATE,
    tags        TEXT[]
);

CREATE INDEX idx_tasks_status_priority ON tasks (status, priority DESC);
CREATE INDEX idx_tasks_due_date ON tasks (due_date) WHERE status = 'active';

Индекс по статусу и приоритету покрывает основной запрос интерфейса — «покажи все активные задачи, отсортированные по важности». А частичный индекс на due_date ускоряет выборку просроченных задач без нагрузки на архив.

Я бывало и на стороне, где хранили задачи в Redis с TTL-счётчиками. Удобно, пока не понадобится отчёт за квартал. С PostgreSQL всё проще: SELECT COUNT(*) FROM tasks WHERE status = 'done' AND completed_at >= '2024-01-01' — и готово.

Если нужна репликация или бэкапы, подключаю [DeepSQL](/guides/razvertyvanie-deepsql-размещение на домашних серверах-dba-agent-dlya-postgresql-i-mysql-uf6iti) как внешнего наблюдателя. Он не пишет в базу, только следит за метриками и шлёт алерты в Telegram, если рост таблицы tasks вдруг вышел за привычный диапазон.

Инфраструктурные решения

Само приложение 3 & Done — это один бинарник на Go, но окружение вокруг него требует подхода. Я запускаю всё на домашнем сервере «Сова» (Dell PowerEdge R730, как раз тот, с чего началось), в контейнере под управлением systemd.

ini
# /etc/systemd/system/three-and-done.service
[Unit]
Description=3 & Done task manager
After=postgresql.service network-online.target
Wants=network-online.target

[Service]
Type=simple
User=tasks
WorkingDirectory=/opt/three-and-done
ExecStart=/opt/three-and-done/bin/app
EnvironmentFile=/opt/three-and-done/.env
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Файл .env содержит только строку подключения и секрет для JWT:

env
DATABASE_URL=postgres://tasks:p@ssw0rd@localhost:5432/tasks?sslmode=disable
JWT_SECRET=сгенерировать_через_pwgen_256_символов

SSL не включаю внутри домашней сети — трафик между контейнером и PostgreSQL идёт по Unix-сокету, а внешние запросы проксирует Caddy с автоматическим Let's Encrypt.

Если захотите масштабировать — перенесите таблицу tasks в отдельный PostgreSQL-инстанс, а приложение разверните на k3s. Я уже пробовал: [связка из локального стека](/articles/размещение на домашних серверах-ai-workflow-db-ollama-sql) с Ollama и PostgreSQL работает стабильно, если дать каждому сервису свои ресурсы через cgroups.

Git-интеграция

Каждая задача — это не только запись в базе, но и файл в Git-репозитории. При создании задачи приложение генерирует Markdown-файл с метаданными и коммитит его в ветку tasks/active. Это позволяет использовать Git как журнал изменений и бэкап.

bash
# Пример структуры репозитория
tasks/
├── 0012-analyzirovat-logi-s-pomoshchyu-promql.md
├── 0013-nastroit-backup-na-truenas.md
└── 0014-obnovit-konfigi-nginx.md

Файл задачи выглядит так:

markdown
---
id: 12
title: Анализировать логи с помощью PromQL
priority: 4
created_at: 2024-03-15T10:30:00Z
due_date: 2024-03-20
tags: [monitoring, grafana]
---

Нужно построить дашборд в Grafana, который будет показывать
количество 5xx-ошибок за последние 24 часа.

Коммиты автоматизированы через pre-commit хук:

bash
#!/bin/sh
# .git/hooks/pre-commit

# Проверяем, что все файлы задач валидны
for file in $(git diff --cached --name-only -- 'tasks/*.md'); do
    if ! python3 scripts/validate_task.py "$file"; then
        echo "Ошибка валидации: $file"
        exit 1
    fi
done

С практической точки зрения, Git-интеграция решает две задачи. Во-первых — вы можете откатиться к любой версии задачи, если кто-то случайно удалил важное поле. Во-вторых — репозиторий можно зеркалировать на GitHub или GitLab, и тогда даже если домашний сервер «Сова» сгорит, вы не потеряете данные.

Я храню репозиторий задач на отдельном томе ZFS, а еженочью делаю снапшот через systemd-таймер:

ini
# /etc/systemd/system/tasks-git-snapshot.timer
[Unit]
Description=Daily snapshot of tasks Git repo

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Практические шаги по внедрению

Настройка локального сервера

Сервер поднимаю на той же ноде, где крутится Proxmox — виртуалка с 2 ГБ ОЗУ и 20 ГБ диска хватает за глаза. Система — Debian 12, всё как обычно.

Приложение 3 & Done работает с PostgreSQL, поэтому сначала ставим СУБД и создаём базу. Я обычно не парюсь с postgresql-contrib — в стандартной поставке хватает.

bash
apt update && apt install postgresql postgresql-contrib

Создаю пользователя и базу под приложение:

bash
sudo -u postgres createuser tnd --interactive
sudo -u postgres createdb tnd -O tnd

Во время установки 3 & Done попросит connection string. Я использую такой:

postgresql://tnd:tnd_password@localhost:5432/tnd

Пароль задаю через psql:

bash
sudo -u postgres psql -c "ALTER USER tnd WITH PASSWORD 'tnd_password';"

Далее — firewall. Порт 5432 слушает только localhost, наружу не вешаю. Если понадобится доступ из контейнера, пробрасываю через systemd-юнит или socat.

Настраиваю автозапуск PostgreSQL на загрузку:

bash
systemctl enable postgresql

Само приложение ставлю в отдельный systemd-юнит — предсказуемость конфигураций, как я уже говорил, не случайность.

Импорт данных и первая задача

Первым делом импортирую старые задачи из CSV. Формат прост: title,completed,created_at.

bash
psql -d tnd -c "\copy tasks(title,completed,created_at) FROM '/tmp/tasks.csv' WITH (FORMAT csv, HEADER true)"

Проверяю, что всё попало:

bash
psql -d tnd -c "SELECT count(*) FROM tasks;"

Первую задачу создаю прямо в интерфейсе — «Настроить бэкапы для TrueNAS». Голосовой ввод включаю сразу: сижу за ноутом, говорю «три и доне, новая задача, настроить бэкапы для трунас» — и через пару секунд она появляется в списке.

Чтобы не терять данные при сбое, настраиваю резервное копирование базы через cron:

bash
0 2 * * * pg_dump tnd | gzip > /backup/tnd_$(date +\%Y\%m\%d).sql.gz

А ещё — экспорт в Git. Да, я один из тех, кто хранит задачи в репозитории. Не для всякого, но для 3 & Done это работает: экспортирую состояние базы раз в сутки и пушу в приватный репозиторий на [размещение на домашних серверах AI: локальный стек DB, Ollama и SQL](/articles/размещение на домашних серверах-ai-workflow-db-ollama-sql).

bash
pg_dump tnd --inserts > /git/tnd/tasks.sql
cd /git/tnd && git add tasks.sql && git commit -m "daily dump" && git push

Через пару дней понимаю: система не просто хранит задачи — она устраняет рутину. Никаких «а я её где-то записал» или «блин, забыл синхронизировать». Всё предсказуемо, как и должно быть.

Часто задаваемые вопросы

Почему три источника задач — это не произвольное число?

Три канала — это компромисс между тем, чтобы не потерять важное, и не размыть внимание лишним. Один канал (например, только голос) приводит к тому, что срочные задачи из чатов или писем остаются вне поля зрения. Пять каналов — и вы тратите больше времени на перераспределение, чем на выполнение. Три покрывают основные сценарии: то, что приходит в ум (голос), то, что назначают другие (письма, чаты) и то, что вы планируете заранее (ручной ввод).

Как система обрабатывает задачи из разных источников?

Все задачи попадают в единый поток, но не в одну кучу. Голосовые записи автоматически транскрибируются и попадают в сегмент «Сегодня», если вы говорите «сегодня» или «важно». Задачи из писем и чатов проходят лёгкую классификацию: если есть упоминание срока — они идут в календарь, если нет — в «На потом». Ручной ввод попадает в «Сегодня» только если вы явно ставите галочку. Так вы не теряете срочное, но не перегружаете текущий день.

Что делать, если задача требует больше одного действия?

Система 3 & Done не запрещает разбивать задачи, но делает это осознанно. Если вы видите, что «обновить Docker» требует остановки контейнеров, обновления образов и проверки логов — вы разбиваете её на три подзадачи сразу, а не по мере выполнения. Это устраняет иллюзию прогресса: вы видите, сколько шагов осталось, и не забываете про мелочи вроде перезагрузки сервисов на «Сове».

Как хранить задачи без риска потерять данные?

Все задачи сохраняются в локальном файле в формате JSON с ежедневным бэкапом на TrueNAS. Голосовые записи хранятся в зашифрованном виде, доступ к ним есть только у вас. Никаких облаков, никаких сторонних сервисов. Если вы переживаете, что файл повредится — настраиваете синхронизацию с резервной копией на второй ноде кластера Proxmox. Предсказуемость конфигурации здесь важнее удобства.

Поделиться:TelegramX / TwitterVK

Читайте также