Файли
2026-11-07 21:15:39 +00:00

63 рядки
2.5 KiB
Markdown

# pllist
Access-based Telegram bot for creating and managing lists of planned purchases.
A user owns lists. A list contains items. Items can be added, marked done, and
reserved by the person responsible for buying them. Items carry an urgency
level. An owner can share a list with other users as a reader or an editor.
Bot access itself is allowlisted: the owner runs `/allow` and `/kick`.
The codebase stays small but extensible.
- Architecture: `docs/architecture.md`
- Infrastructure: `docs/infra.md`
- MVP plan: `docs/roadmap-mvp.md`
- Other notes: `docs/temp-*.md`
## Stack
- Go 1.27
- `github.com/mymmrac/telego` for the Telegram Bot API, long polling
- GORM with PostgreSQL
- `github.com/joho/godotenv` for local environment loading
- Docker Compose for local development
- Gitea for version control and CI, Dokploy for deployment
## Commands
```sh
cp .env.example .env # fill values
make build # build bin/bot
make run # run bin/bot
go test ./... # unit tests
go vet ./... # static checks
gofmt -l . # formatting check
```
## Engineering rules
1. Use constructor injection. Build concrete types in `cmd/bot/main.go` and
pass dependencies down. No package-level globals and no `init()` side
effects.
2. Define small interfaces where they are consumed, not next to the
implementation.
3. Keep business rules in `internal/domain` and `internal/service`. Handlers
parse input and render output only.
4. Route every list operation through one authorization function. Do not
reimplement access checks in handlers or repositories.
5. Implement item changes as domain methods (`Reserve`, `Release`, `Complete`,
`Reopen`, `SetUrgency`). Do not assign state fields from handlers.
6. Apply DRY to behavior: one callback-data codec, one keyboard builder per
view, one error-to-message mapper.
7. Use sentinel domain errors (`ErrNotFound`, `ErrForbidden`, `ErrConflict`,
`ErrInvalidInput`) and map them in the Telegram layer. Never leak database
errors to users.
8. Revalidate authorization on every callback. Callback data is untrusted and
limited to 64 bytes.
9. Reserve items with a conditional database update, not read-then-write.
10. Emit future side effects through `events.Publisher`. Services never call
Telegram directly.
11. Keep Telegram types out of `domain` and `service`.
12. Test every access-matrix row and every item transition.
13. Never commit secrets. `.env` is ignored; keep `.env.example` current.
14. Update the docs when a design decision changes.