66 lines
3.4 KiB
Markdown
66 lines
3.4 KiB
Markdown
# Пожитки
|
||
|
||
Telegram WebApp для учёта поступлений и расходов. Бот принимает записи через
|
||
`Telegram.WebApp.sendData`, сохраняет подтверждённый Telegram ID отправителя,
|
||
имя, username и аватар. WebApp показывает баланс, категории, общий рейтинг и
|
||
рейтинг среди друзей.
|
||
|
||
## Запуск
|
||
|
||
1. Создайте бота через BotFather и получите токен.
|
||
2. Скопируйте `.env.example` в `.env` и укажите:
|
||
|
||
```dotenv
|
||
TELEGRAM_TOKEN=123456789:your_token
|
||
BASE_APP_URL=https://example.com
|
||
```
|
||
|
||
3. Направьте DNS домена на сервер и откройте порты 80/443.
|
||
4. Запустите:
|
||
|
||
```bash
|
||
docker compose up -d --build
|
||
```
|
||
|
||
Caddy автоматически получает TLS-сертификат. WebApp доступен по
|
||
`https://example.com/app/`, read-only API — по `https://example.com/api/`.
|
||
|
||
Команда `/start` выводит reply-кнопку запуска WebApp. Это важно: Telegram
|
||
поддерживает `WebApp.sendData()` для приложения, открытого через
|
||
`KeyboardButton`, и присылает payload боту в `web_app_data`.
|
||
|
||
## API
|
||
|
||
- `GET /api/healthz` — проверка состояния;
|
||
- `GET /api/leaderboard?limit=100` — общий рейтинг;
|
||
- `GET /api/leaderboard?user_ids=1,2,3` — рейтинг выбранных пользователей;
|
||
- `GET /api/leaderboard?category=Продукты` — рейтинг по категории;
|
||
- `GET /api/categories` — категории, встречающиеся у участников;
|
||
- `GET /api/users/{id}/summary` — публичная сводка пользователя;
|
||
- `GET /api/users/{id}/categories` — сохранённые категории пользователя;
|
||
- `GET /api/users/{id}/transactions` — активные записи пользователя;
|
||
- `GET /api/users/{id}/friends` — Telegram ID друзей;
|
||
- `GET /api/avatars/{id}` — сохранённый аватар;
|
||
- `GET /api/docs` — OpenAPI UI.
|
||
|
||
Процент накоплений: `(поступления − расходы) / поступления × 100`. При нулевых
|
||
поступлениях он равен 0%. Суммы хранятся целым числом копеек, SQLite работает в
|
||
WAL-режиме, данные лежат в Docker volume `app-data`.
|
||
|
||
API намеренно не принимает операции записи. Пользовательский ID для операции
|
||
берётся из Telegram-сообщения, поэтому его нельзя подменить payload-ом WebApp.
|
||
При этом лидерборды и сводки публичны — не публикуйте там сведения, которые не
|
||
хотите показывать другим участникам.
|
||
|
||
## Разработка
|
||
|
||
Зависимости управляются `uv`:
|
||
|
||
```bash
|
||
uv sync
|
||
uv run pytest
|
||
TELEGRAM_TOKEN='' DATA_DIR=./data uv run uvicorn app.main:app --reload
|
||
```
|
||
|
||
Для браузерного предпросмотра можно открыть `/app/?user_id=123`. Отправка
|
||
операции вне Telegram специально отключена.
|