Files
2026-11-06 16:36:07 +00:00

2.5 KiB

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. 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

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.