feat(bot): add multi-household setup flow

This commit is contained in:
2026-03-09 03:40:20 +04:00
parent f3991fe7ce
commit e63d81cda2
21 changed files with 3337 additions and 9 deletions

View File

@@ -0,0 +1,118 @@
# ADR-003: Database-Backed Multi-Household Telegram Configuration
## Status
Accepted
Decision Date: 2026-03-09
Owners: Stanislav Kalishin
## Context
The current runtime assumes one household per deployment. `HOUSEHOLD_ID`,
`TELEGRAM_HOUSEHOLD_CHAT_ID`, `TELEGRAM_PURCHASE_TOPIC_ID`, and
`TELEGRAM_FEEDBACK_TOPIC_ID` are injected as environment variables and then used
globally by the bot.
That model is not viable for the intended product:
- one bot should support multiple Telegram groups
- onboarding should not require Terraform edits or redeploys
- topic ids should be captured from real Telegram updates, not copied manually
- mini app and bot features must resolve household context per chat/member
## Decision
Move household Telegram configuration out of environment variables and into the
application database.
Keep environment variables only for deployment-global concerns:
- `TELEGRAM_BOT_TOKEN`
- `TELEGRAM_WEBHOOK_SECRET`
- `DATABASE_URL`
- scheduler auth settings
- logging and infrastructure settings
Persist household-specific Telegram configuration as data:
- Telegram group/supergroup chat id
- topic bindings by role (`purchase`, `feedback`, later `reminders`)
- household state and setup status
- member-to-household Telegram identity linkage
Bootstrap household setup through bot interactions:
- bot added to a Telegram group
- admin runs `/setup`
- admin runs topic binding commands inside target topics
- members DM `/start` to link their Telegram identity
## Boundary Rules
- Domain stays unaware of Telegram ids and setup flows.
- Application owns setup use-cases and authorization rules.
- Ports expose household configuration and membership repositories.
- Telegram-specific extraction of chat ids, topic ids, and admin checks remains
in adapters/app entrypoints.
## Data Model Direction
Add database-backed configuration entities around the existing `households`
table, likely including:
- `telegram_households` or equivalent mapping from Telegram chat to household
- `household_topics` keyed by household + role
- richer `members` onboarding/link status fields if needed
Exact table shapes remain implementation work, but the model must support:
- many Telegram groups per deployment
- unique chat id ownership
- unique topic role per household
- idempotent setup commands
## Rationale
- Removes deploy-time coupling between infrastructure and household onboarding.
- Matches real Telegram behavior, where chat and topic identifiers are only
known after bot interaction.
- Keeps the production architecture aligned with a multi-tenant SaaS model.
- Simplifies future mini app settings screens because configuration is already
stored as data.
## Consequences
Positive:
- one deployed bot can support many households
- onboarding is self-serve through Telegram commands and later mini app UI
- infrastructure configuration becomes smaller and safer
Negative:
- requires schema changes and migration from the current single-household model
- setup authorization rules become a real application concern
- finance/reminder flows must resolve household context dynamically
## Risks and Mitigations
Risk:
- Mixing old env-based household logic with new DB-backed logic creates an
inconsistent runtime.
Mitigation:
- Introduce an explicit migration phase with fallback rules documented in the
spec.
- Remove household-specific env usage after setup flows are shipped.
Risk:
- Unauthorized users could bind topics or hijack setup.
Mitigation:
- Require Telegram group admin privileges for setup and topic binding commands.
- Persist an owning admin/member relation and audit setup actions.

View File

@@ -63,6 +63,25 @@ Exit criteria:
- Purchase messages are ingested and persisted.
- Monthly statement can be produced via command.
## Phase 2.5 - Multi-Household Setup
Goal: remove single-household deploy assumptions and support real Telegram group
onboarding.
Deliverables:
- Database-backed Telegram group and topic configuration.
- Group bootstrap command (`/setup`).
- Topic binding commands executed inside the target topic.
- Member DM onboarding and household linkage flow.
- Removal of household-specific runtime env requirements.
Exit criteria:
- One bot deployment can support multiple household groups.
- New households can be configured without Terraform edits or redeploy.
- Purchase and anonymous feedback topics are bound from real Telegram updates.
## Phase 3 - Reminders and Scheduling
Goal: automate key payment reminders.

View File

@@ -0,0 +1,154 @@
# HOUSEBOT-070: Multi-Household Telegram Setup and Configuration
## Summary
Replace the current single-household env configuration with database-backed
household registration, topic binding, and member onboarding so one deployed bot
can serve multiple Telegram groups.
## Goals
- Register a household from a real Telegram group without redeploying
- Bind purchase and feedback topics from in-topic admin commands
- Link real Telegram users to household members through DM onboarding
- Resolve household context dynamically in bot and mini app flows
## Non-goals
- Full settings UI in the mini app
- Multi-household reminders customization beyond topic role binding
- Cross-household user accounts beyond Telegram identity linkage
## Scope
- In:
- group bootstrap command
- topic binding commands
- persistent Telegram chat/topic configuration
- member DM onboarding and pending linkage flow
- migration away from global household/topic env vars
- Out:
- advanced role management UI
- invite links and QR onboarding
- reminders topic configuration UI
## Interfaces and Contracts
Telegram commands:
- `/setup`
- `/bind_purchase_topic`
- `/bind_feedback_topic`
- `/status`
- `/start`
Expected command behavior:
- `/setup` in a group:
- creates or reuses a household bound to `chat.id`
- records setup initiator
- returns current setup state
- `/bind_purchase_topic` in a topic:
- stores `message.chat.id` + `message.message_thread_id` as purchase topic
- `/bind_feedback_topic` in a topic:
- stores `message.chat.id` + `message.message_thread_id` as feedback topic
- `/start` in DM:
- records Telegram identity
- lists pending household memberships or onboarding status
Mini app/API implications:
- session resolution must locate the callers household membership from stored
membership data, not a deployment-global `HOUSEHOLD_ID`
- household dashboard endpoints must accept or derive household context safely
## Domain Rules
- One Telegram group chat maps to exactly one household
- Topic role binding is unique per household and role
- Only Telegram group admins can run setup and topic binding commands
- Topic binding commands must be executed inside a topic message thread
- Setup commands are idempotent
- Member linkage must use the callers actual Telegram user id
## Data Model Changes
Add tables or equivalent structures for:
- household-to-Telegram chat mapping
- topic bindings by household and role
- member onboarding/link status if current `members` shape is insufficient
Indexes/constraints should cover:
- unique Telegram chat id
- unique `(household_id, role)` for topic bindings
- unique `(household_id, telegram_user_id)` for members
Migration direction:
- keep current `households` and `members`
- backfill the existing demo household into the new config model if useful for
development
- remove runtime dependency on household/topic env vars after cutover
## Security and Privacy
- Verify group admin status before setup mutations
- Reject topic binding attempts outside the target group/topic
- Log setup and binding actions with actor Telegram id
- Do not expose household membership data across households
- Keep anonymous feedback sender privacy unchanged
## Observability
Required logs:
- household setup started/completed
- topic binding created/updated
- member onboarding started/linked
- rejected setup attempts with reason
Useful metrics:
- setup command success/failure count
- topic binding count by role
- unlinked member count
## Edge Cases and Failure Modes
- Bot added to a group without admin permissions
- Bot present in a group with privacy mode still enabled
- Topic binding command sent in main chat instead of a topic
- Duplicate `/setup` on an already configured household
- Member DMs `/start` before the household exists
- Same Telegram user belongs to multiple households
## Test Plan
- Unit:
- setup authorization rules
- topic binding validation
- member link resolution rules
- Integration:
- repository operations for chat/topic binding persistence
- Telegram command handlers with realistic update payloads
- E2E:
- group setup -> topic binding -> member DM onboarding -> command success
## Acceptance Criteria
- [ ] Bot can create or load household config from a group `/setup` command
- [ ] Admin can bind the purchase topic without manual id lookup
- [ ] Admin can bind the feedback topic without manual id lookup
- [ ] Member DM onboarding stores real Telegram user identity for later linkage
- [ ] Existing finance and feedback flows can resolve household context from DB
- [ ] Household-specific env vars are no longer required in deployed runtime
## Rollout Plan
- Add new schema and repositories first
- Ship setup and topic binding commands behind the existing bot deployment
- Migrate bot runtime reads from env vars to DB-backed config
- Remove household/topic env vars from Terraform examples and runbooks after
cutover