- Replaced the previous webapp with a new Mini App built using Next.js, improving performance and maintainability. - Updated the `.gitignore` to exclude Next.js build artifacts and node modules. - Revised documentation in `AGENTS.md`, `README.md`, and `architecture.md` to reflect the new Mini App structure and technology stack. - Enhanced Dockerfile to support the new build process for the Next.js application. - Updated CI workflow to build and test the Next.js application. - Added new configuration options for the Mini App, including `MINI_APP_SHORT_NAME` for improved deep linking. - Refactored frontend testing setup to accommodate the new structure and testing framework. - Removed legacy webapp files and dependencies to streamline the project.
114 lines
5.0 KiB
Plaintext
114 lines
5.0 KiB
Plaintext
---
|
|
description: Overall project architecture and context for duty-teller
|
|
globs:
|
|
- "**"
|
|
---
|
|
|
|
# Project — duty-teller
|
|
|
|
A Telegram bot for team duty shift calendar management and group reminders,
|
|
with a Telegram Mini App (webapp) for calendar visualization.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌──────────────┐ polling ┌──────────────────────┐
|
|
│ Telegram │◄────────────►│ python-telegram-bot │
|
|
│ Bot API │ │ (handlers/) │
|
|
└──────────────┘ └──────────┬───────────┘
|
|
│
|
|
┌──────────────┐ HTTP ┌──────────▼───────────┐
|
|
│ Telegram │◄────────────►│ FastAPI (api/) │
|
|
│ Mini App │ initData │ + static webapp │
|
|
│ (webapp-next/) │ auth └──────────┬───────────┘
|
|
└──────────────┘ │
|
|
┌──────────▼───────────┐
|
|
│ SQLite + SQLAlchemy │
|
|
│ (db/) │
|
|
└──────────────────────┘
|
|
```
|
|
|
|
- **Bot:** python-telegram-bot v22, async polling mode.
|
|
- **API:** FastAPI served by uvicorn in a daemon thread alongside the bot.
|
|
- **Database:** SQLite via SQLAlchemy 2.x ORM; Alembic for migrations.
|
|
- **Frontend:** Next.js (TypeScript, Tailwind, shadcn/ui) static export at `/app`; source in `webapp-next/`.
|
|
|
|
## Key packages
|
|
|
|
| Package | Role |
|
|
|---------|------|
|
|
| `duty_teller/handlers/` | Telegram bot command and message handlers |
|
|
| `duty_teller/api/` | FastAPI app, REST endpoints, Telegram initData auth, ICS feeds |
|
|
| `duty_teller/db/` | ORM models, repository (CRUD), session management, Pydantic schemas |
|
|
| `duty_teller/services/` | Business logic (import, duty pin) — receives Session |
|
|
| `duty_teller/importers/` | Duty schedule file parsers |
|
|
| `duty_teller/i18n/` | Bilingual translations (ru/en), `t()` function |
|
|
| `duty_teller/utils/` | Date helpers, user utilities, HTTP client |
|
|
| `duty_teller/cache.py` | TTL caches with pattern-based invalidation |
|
|
| `duty_teller/config.py` | Environment-based configuration |
|
|
| `webapp-next/` | Telegram Mini App (Next.js, Tailwind, shadcn/ui; build → `out/`) |
|
|
|
|
## API endpoints
|
|
|
|
| Method | Path | Auth | Purpose |
|
|
|--------|------|------|---------|
|
|
| GET | `/health` | None | Health check |
|
|
| GET | `/api/duties` | initData | Duties for date range |
|
|
| GET | `/api/calendar-events` | initData | External calendar events |
|
|
| GET | `/api/calendar/ical/team/{token}.ics` | Token | Team ICS feed |
|
|
| GET | `/api/calendar/ical/{token}.ics` | Token | Personal ICS feed |
|
|
| GET | `/app` | None | Static Mini App (HTML/JS/CSS) |
|
|
|
|
## Deployment
|
|
|
|
- **Docker:** Multi-stage build (`Dockerfile`), `docker-compose.prod.yml` for production.
|
|
- **Entrypoint:** `entrypoint.sh` runs `alembic -c pyproject.toml upgrade head`, then
|
|
starts `python main.py` as `botuser`.
|
|
- **Data:** SQLite DB persisted via Docker volume at `/app/data`.
|
|
- **Health:** `curl -f http://localhost:8080/health` every 30 s.
|
|
|
|
## CI/CD (Gitea Actions)
|
|
|
|
### Lint & test (`.gitea/workflows/ci.yml`)
|
|
|
|
Triggered on push/PR to `main` and `develop`:
|
|
|
|
1. **Ruff:** `ruff check duty_teller tests`
|
|
2. **Pytest:** `pytest tests/ -v` (80% coverage gate)
|
|
3. **Bandit:** `bandit -r duty_teller -ll` (security scan)
|
|
|
|
### Docker build & release (`.gitea/workflows/docker-build.yml`)
|
|
|
|
Triggered on `v*` tags:
|
|
|
|
1. Build and push image to Gitea registry.
|
|
2. Create release with auto-generated notes.
|
|
|
|
## Key environment variables
|
|
|
|
| Variable | Default | Required | Purpose |
|
|
|----------|---------|----------|---------|
|
|
| `BOT_TOKEN` | — | Yes | Telegram bot API token |
|
|
| `DATABASE_URL` | `sqlite:///data/duty_teller.db` | No | SQLAlchemy database URL |
|
|
| `MINI_APP_BASE_URL` | — | Yes (prod) | Public URL for the Mini App |
|
|
| `HTTP_HOST` | `127.0.0.1` | No | FastAPI bind host |
|
|
| `HTTP_PORT` | `8080` | No | FastAPI bind port |
|
|
| `ADMIN_USERNAMES` | — | No | Comma-separated admin Telegram usernames |
|
|
| `ALLOWED_USERNAMES` | — | No | Comma-separated allowed usernames |
|
|
| `DUTY_DISPLAY_TZ` | `Europe/Moscow` | No | Timezone for duty display |
|
|
| `DEFAULT_LANGUAGE` | `en` | No | Default UI language (`en` or `ru`) |
|
|
| `EXTERNAL_CALENDAR_ICS_URL` | — | No | External ICS URL for holidays |
|
|
| `CORS_ORIGINS` | `*` | No | Comma-separated CORS origins |
|
|
|
|
## Languages
|
|
|
|
- **Backend:** Python 3.12+
|
|
- **Frontend:** Next.js (TypeScript), Tailwind CSS, shadcn/ui; Vitest for tests
|
|
- **i18n:** Russian (default) and English
|
|
|
|
## Version control
|
|
|
|
- Git with Gitea Flow branching strategy.
|
|
- Conventional Commits for commit messages.
|
|
- PRs reviewed via Gitea Pull Requests.
|