Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tasks — приложение задач

Приложение задач под Windows: headless-бэкенд на Go + десктоп-клиент на Wails. Любые задачи — от «убраться дома» до цепочек закрепления знаний (spaced repetition). Часть экосистемы activization: владеет данными о задачах, публикует события в Kafka для бота, отдаёт ICS-фид для внешних календарей.

Прототип и источник идей модели — планер в Google Таблицах: planer.md (темы, форматы повторений, перенос невыполненных со сдвигом цепочки).

Структура

tasks/
├── backend/            Go-сервис: REST + MCP + генератор вхождений + outbox-релей
│   ├── cmd/tasks/      точка входа
│   ├── internal/       config, handler, service, repository, models, kafka
│   ├── migrations/     SQL-миграции (golang-migrate, встроены в бинарник)
│   └── Dockerfile      multi-stage сборка
├── desktop/            Wails v2 приложение (React + TS + Tailwind)
│   ├── frontend/       UI: календарь, дерево тем и задач, темы
│   └── main.go         окно + биндинг адреса бэкенда
├── docker-compose.yml  postgres:16 (порт 5433) + backend (порт 8081)
└── planer.md           UX-прототип (Google Apps Script)

Запуск

Docker (через WSL)

Команды выполняются из каталога tasks/ (WSL наследует текущий каталог). Compose подключается к внешней сети ecosystem — на чистой машине её нужно создать один раз:

wsl -d Ubuntu-22.04 -- docker network create ecosystem   # однократно
wsl -d Ubuntu-22.04 -- docker compose up -d --build

Поднимает Postgres на localhost:5433 и бэкенд на http://localhost:8081. Kafka не обязательна: события копятся в outbox и уходят, когда брокер появится (общая Kafka — infra/docker-compose.yml экосистемы).

Локально без Docker

wsl -d Ubuntu-22.04 -- docker compose up -d postgres
cd backend
go run ./cmd/tasks

Десктоп

cd desktop
& "$env:USERPROFILE\go\bin\wails.exe" dev     # разработка
& "$env:USERPROFILE\go\bin\wails.exe" build   # сборка → build\bin\tasks-desktop.exe

Клиент ходит на http://localhost:8081 (переопределяется переменной TASKS_API_URL).

Конфигурация

.env в каталоге backend/ (или корне tasks/), переменные окружения поверх. Префикс TASKS_:

Переменная Default Смысл
TASKS_HTTP_PORT 8081 порт REST + MCP
TASKS_DB_HOST / PORT / USER / PASSWORD / NAME localhost / 5433 / tasks / tasks / tasks Postgres
TASKS_KAFKA_BROKERS localhost:9094 брокеры через запятую
TASKS_KAFKA_TOPIC tasks.events топик CloudEvents
TASKS_TIMEZONE Europe/Moscow локальная TZ пользователя
TASKS_WINDOW_DAYS 60 окно материализации вхождений
TASKS_OUTBOX_INTERVAL_SECONDS 5 период outbox-релея
TASKS_DB_DRIVER postgres postgres или sqlite (мобильное)
TASKS_DB_PATH tasks.db путь к файлу SQLite (при driver=sqlite)
TASKS_SYNC_URL URL сервера-источника для синхронизации (пусто = не синхронизировать)
TASKS_SYNC_TOKEN bearer-токен эндпоинтов /api/v1/sync
TASKS_SYNC_INTERVAL_SECONDS 60 период push/pull синхронизации

Мобильное приложение (Android)

Тот же самый бэкенд и тот же самый фронтенд (desktop/frontend), только упакованные под телефон — без переписывания и дублирования UI.

  • backend/mobile/ — gomobile-пакет: весь бэкенд задач на SQLite (ncruces/go-sqlite3 — чистый Go/WASM без сисколлов, иначе seccomp Android убивает процесс) слушает 127.0.0.1:18081 и сам раздаёт собранный desktop/frontend как статику.
  • android/ — тонкая Kotlin-обёртка: WebView открывает локальный бэкенд; в меню — настройки синхронизации (URL сервера ПК + токен).
  • api.ts фронта сам выбирает транспорт: в Wails — через биндинг, в мобильном/браузере — same-origin по /healthz, иначе localhost:8081.

Синхронизация с ПК (internal/syncer): двусторонняя, REST /api/v1/sync/changes (GET отдаёт изменения с курсора, POST принимает). Конфликты — last-write-wins по updated_at; удаления через sync_tombstones (сервер ретранслирует их другим устройствам); ID вхождений детерминированные (uuid5 от task_id+date), поэтому одно и то же вхождение не двоится на двух устройствах.

Сборка APK (окружение — C:\Users\pavel\android-tools, ничего в систему не ставится):

deploy\build-android.ps1

Скрипт собирает фронт → кладёт в backend/mobile/webdistgomobile bind в android/app/libs/tasks.aar → gradle APK в android/app/build/outputs/apk/.

API (кратко)

REST /api/v1 (JSON snake_case, ошибки {"error":{"code","message"}}): CRUD /topics, /tasks; GET /occurrences?from&to&status; POST /occurrences/{id}/complete|skip; POST /tasks/{id}/reschedule-missed; GET /plans/{date}; PUT /plans/{date}/items; POST /plans/{date}/commit; GET /calendar.ics; GET /healthz.

MCP (streamable HTTP /mcp): list_tasks, create_task (плоские поля повторений + effort_minutes, requires_pomodoro, topic/parent_topic), complete_occurrence, skip_occurrence, list_due, get_day_plan, commit_day_plan, reschedule_missed, create_topic (с родителем — дерево тем), list_topics.

Подробности — в backend/README.md и docs/contracts.md экосистемы. Модель данных — docs/data-model.md.

Тесты

cd backend
go test ./...

Покрыто: генератор повторений (все 9 видов, monthly-прижатие, SR c series_step), перенос невыполненных, план дня, outbox-релей с mock-продюсером, REST-хендлеры (httptest).

About

Task planner where a task is a recurrence rule, nine kinds including spaced repetition, materialized into daily occurrences. Go backend with REST, MCP and a Kafka outbox, Wails desktop client, and the same Go core with the same React UI repacked for Android via gomobile, with two-way sync between devices.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages