mirror of
https://github.com/whekin/household-bot.git
synced 2026-03-31 15:44:02 +00:00
docs: add roadmap, ADRs, and initial HOUSEBOT specs
This commit is contained in:
78
docs/specs/HOUSEBOT-001-monorepo-bootstrap.md
Normal file
78
docs/specs/HOUSEBOT-001-monorepo-bootstrap.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# HOUSEBOT-001: Monorepo Bootstrap and Quality Gates
|
||||
|
||||
## Summary
|
||||
Initialize the repository as a Bun workspace monorepo with strict TypeScript, Oxlint, CI quality gates, and architecture-oriented package layout.
|
||||
|
||||
## Goals
|
||||
- Establish baseline folder structure for hexagonal architecture.
|
||||
- Add root scripts for lint, typecheck, test, and build.
|
||||
- Enforce no-semicolon formatting style and strict linting.
|
||||
- Ensure CI runs on every push/PR.
|
||||
|
||||
## Non-goals
|
||||
- Implement business logic.
|
||||
- Implement Telegram handlers.
|
||||
- Create production cloud resources.
|
||||
|
||||
## Scope
|
||||
- In: repo skeleton, workspace config, root tooling config, CI workflow.
|
||||
- Out: feature code, database schema, external service integration.
|
||||
|
||||
## Interfaces and Contracts
|
||||
- Root scripts exposed via `package.json`:
|
||||
- `lint`
|
||||
- `typecheck`
|
||||
- `test`
|
||||
- `build`
|
||||
- Workspace packages must compile under shared TS config.
|
||||
|
||||
## Architecture Constraints
|
||||
- Workspace must include:
|
||||
- `apps/bot`
|
||||
- `apps/miniapp`
|
||||
- `packages/domain`
|
||||
- `packages/application`
|
||||
- `packages/ports`
|
||||
- `packages/contracts`
|
||||
- `packages/observability`
|
||||
- No cross-import from domain to adapters/apps.
|
||||
|
||||
## File Plan
|
||||
- Root:
|
||||
- `package.json`
|
||||
- `bunfig.toml`
|
||||
- `tsconfig.base.json`
|
||||
- `oxlint.json`
|
||||
- `.editorconfig`
|
||||
- `.gitignore`
|
||||
- CI:
|
||||
- `.github/workflows/ci.yml`
|
||||
- Workspace placeholders:
|
||||
- `apps/bot/src/index.ts`
|
||||
- `apps/miniapp/src/main.tsx`
|
||||
- `packages/*/src/index.ts`
|
||||
|
||||
## Security and Safety
|
||||
- No secrets in repo.
|
||||
- Add `.env.example` templates only.
|
||||
- CI must fail on type/lint/test failure.
|
||||
|
||||
## Test Plan
|
||||
- Unit: not applicable in this ticket.
|
||||
- Integration: not applicable.
|
||||
- Validation checks:
|
||||
- Workspace install succeeds.
|
||||
- All root scripts run locally.
|
||||
- CI workflow executes all checks.
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] Bun workspace initialized with declared workspaces.
|
||||
- [ ] Oxlint config present and root lint script works.
|
||||
- [ ] TypeScript strict base config is shared across workspaces.
|
||||
- [ ] CI workflow runs lint, typecheck, test, build.
|
||||
- [ ] Placeholder apps/packages compile.
|
||||
- [ ] Docs updated with local bootstrap commands.
|
||||
|
||||
## Rollout Plan
|
||||
- Merge to default branch.
|
||||
- Use as mandatory baseline for all subsequent tickets.
|
||||
68
docs/specs/HOUSEBOT-002-finance-domain-model.md
Normal file
68
docs/specs/HOUSEBOT-002-finance-domain-model.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# HOUSEBOT-002: Finance Domain Model
|
||||
|
||||
## Summary
|
||||
Define domain entities and invariants for rent, utilities, shared purchases, and monthly settlements.
|
||||
|
||||
## Goals
|
||||
- Create a deterministic model for monthly household accounting.
|
||||
- Encode money-safe arithmetic with integer minor units.
|
||||
- Support equal split by default with optional day-based utility override.
|
||||
|
||||
## Non-goals
|
||||
- Telegram command handlers.
|
||||
- Mini app rendering.
|
||||
|
||||
## Scope
|
||||
- In: domain entities, use-case contracts, and validation rules.
|
||||
- Out: persistence adapter implementation.
|
||||
|
||||
## Interfaces and Contracts
|
||||
- `Money` value object (`currency: GEL`, `amountMinor: bigint | number`).
|
||||
- `SettlementInput` contract with members, rent, utilities, purchases, overrides.
|
||||
- `SettlementResult` contract with per-member due and explanation lines.
|
||||
|
||||
## Domain Rules
|
||||
- Rent is fixed per cycle and split equally among active members.
|
||||
- Utilities split equally unless per-member day override is provided.
|
||||
- Shared purchases reduce payer due amount and distribute cost across members.
|
||||
- No floating-point operations.
|
||||
|
||||
## Data Model Changes
|
||||
- Define required table contracts (implemented in later DB ticket):
|
||||
- `billing_cycles`
|
||||
- `rent_rules`
|
||||
- `utility_bills`
|
||||
- `presence_overrides`
|
||||
- `purchase_entries`
|
||||
- `settlements`, `settlement_lines`
|
||||
|
||||
## Security and Privacy
|
||||
- Do not store unnecessary personal data.
|
||||
- Use internal IDs for members in calculations.
|
||||
|
||||
## Observability
|
||||
- Structured calculation logs (input hash, cycle id, result totals).
|
||||
- Error event on invalid settlement state.
|
||||
|
||||
## Edge Cases and Failure Modes
|
||||
- Member count is zero.
|
||||
- Utility day overrides sum to zero.
|
||||
- Negative amounts from malformed inputs.
|
||||
- Duplicate purchase entries.
|
||||
|
||||
## Test Plan
|
||||
- Unit:
|
||||
- money arithmetic and normalization
|
||||
- equal split and day-weighted split cases
|
||||
- purchase offsets and reconciliation checks
|
||||
- Integration: not in this ticket.
|
||||
- E2E: not in this ticket.
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] Value objects implemented and tested.
|
||||
- [ ] Settlement input/output contracts defined.
|
||||
- [ ] Deterministic settlement math covered by tests.
|
||||
- [ ] Edge cases produce explicit domain errors.
|
||||
|
||||
## Rollout Plan
|
||||
- Merge as dependency for settlement engine and bot handlers.
|
||||
74
docs/specs/HOUSEBOT-003-purchase-parser.md
Normal file
74
docs/specs/HOUSEBOT-003-purchase-parser.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# HOUSEBOT-003: Purchase Parser (Hybrid Rules + LLM Fallback)
|
||||
|
||||
## Summary
|
||||
Parse free-form purchase messages (primarily Russian) from the Telegram topic `Общие покупки` into structured ledger entries.
|
||||
|
||||
## Goals
|
||||
- High precision amount extraction with deterministic rules first.
|
||||
- Fallback to LLM for ambiguous or irregular message formats.
|
||||
- Persist raw input, parsed output, and confidence score.
|
||||
|
||||
## Non-goals
|
||||
- Receipt image OCR.
|
||||
- Full conversational NLP.
|
||||
|
||||
## Scope
|
||||
- In: parsing pipeline, confidence policy, parser contracts.
|
||||
- Out: bot listener wiring (separate ticket).
|
||||
|
||||
## Interfaces and Contracts
|
||||
- `parsePurchase(input): ParsedPurchaseResult`
|
||||
- `ParsedPurchaseResult`:
|
||||
- `amountMinor`
|
||||
- `currency`
|
||||
- `itemDescription`
|
||||
- `confidence`
|
||||
- `parserMode` (`rules` | `llm`)
|
||||
- `needsReview`
|
||||
|
||||
## Domain Rules
|
||||
- GEL is default currency when omitted.
|
||||
- Confidence threshold determines auto-accept vs review flag.
|
||||
- Never mutate original message text.
|
||||
|
||||
## Data Model Changes
|
||||
- `purchase_entries` fields:
|
||||
- `raw_text`
|
||||
- `parsed_amount_minor`
|
||||
- `currency`
|
||||
- `item_description`
|
||||
- `confidence`
|
||||
- `parser_mode`
|
||||
- `needs_review`
|
||||
|
||||
## Security and Privacy
|
||||
- Sanitize prompt inputs for LLM adapter.
|
||||
- Do not send unnecessary metadata to LLM provider.
|
||||
|
||||
## Observability
|
||||
- Parser mode distribution metrics.
|
||||
- Confidence histogram.
|
||||
- Error log for parse failures.
|
||||
|
||||
## Edge Cases and Failure Modes
|
||||
- Missing amount.
|
||||
- Multiple possible amounts in one message.
|
||||
- Non-GEL currencies mentioned.
|
||||
- Typos and slang variants.
|
||||
|
||||
## Test Plan
|
||||
- Unit:
|
||||
- regex extraction fixtures in RU/EN mixed text
|
||||
- confidence scoring behavior
|
||||
- Integration:
|
||||
- LLM fallback contract with mocked provider
|
||||
- E2E: consumed in bot ingestion ticket.
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] Rules parser handles common RU message patterns.
|
||||
- [ ] LLM fallback adapter invoked only when rules are insufficient.
|
||||
- [ ] Confidence and parser mode stored in result.
|
||||
- [ ] Tests include ambiguous message fixtures.
|
||||
|
||||
## Rollout Plan
|
||||
- Start with conservative threshold and monitor review rate.
|
||||
69
docs/specs/HOUSEBOT-004-reminders-and-scheduler.md
Normal file
69
docs/specs/HOUSEBOT-004-reminders-and-scheduler.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# HOUSEBOT-004: Reminders and Scheduler
|
||||
|
||||
## Summary
|
||||
Schedule and deliver household billing reminders to dedicated Telegram topics.
|
||||
|
||||
## Goals
|
||||
- Automate utility and rent reminders on configured dates.
|
||||
- Ensure idempotent sends and reliable retries.
|
||||
- Keep scheduling externalized via Cloud Scheduler.
|
||||
|
||||
## Non-goals
|
||||
- Dynamic natural-language reminder editing.
|
||||
- Per-user DM reminders in v1.
|
||||
|
||||
## Scope
|
||||
- In: scheduler endpoints, reminder generation, send guards.
|
||||
- Out: full statement rendering details.
|
||||
|
||||
## Interfaces and Contracts
|
||||
- HTTP endpoints triggered by Cloud Scheduler:
|
||||
- `/jobs/reminder/utilities`
|
||||
- `/jobs/reminder/rent-warning`
|
||||
- `/jobs/reminder/rent-due`
|
||||
- Job payload includes cycle and household references.
|
||||
|
||||
## Domain Rules
|
||||
- Utilities reminder target: day 3 or 4 (configurable).
|
||||
- Rent warning target: day 17.
|
||||
- Rent due target: day 20.
|
||||
- Duplicate-send guard keyed by household + cycle + reminder type.
|
||||
|
||||
## Data Model Changes
|
||||
- `reminder_dispatch_log`:
|
||||
- `household_id`
|
||||
- `billing_cycle`
|
||||
- `reminder_type`
|
||||
- `sent_at`
|
||||
- `telegram_message_id`
|
||||
|
||||
## Security and Privacy
|
||||
- Scheduler endpoints protected by shared secret/auth header.
|
||||
- No sensitive data in scheduler payloads.
|
||||
|
||||
## Observability
|
||||
- Job execution logs with correlation IDs.
|
||||
- Success/failure counters per reminder type.
|
||||
- Alert on repeated send failures.
|
||||
|
||||
## Edge Cases and Failure Modes
|
||||
- Telegram API temporary failure.
|
||||
- Scheduler retry causes duplicate call.
|
||||
- Missing household topic mapping.
|
||||
|
||||
## Test Plan
|
||||
- Unit:
|
||||
- date and reminder eligibility logic
|
||||
- Integration:
|
||||
- endpoint auth and idempotency behavior
|
||||
- E2E:
|
||||
- simulated month schedule through all reminder events
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] Scheduler endpoints implemented and authenticated.
|
||||
- [ ] Reminder sends are idempotent.
|
||||
- [ ] Logs and counters available for each job run.
|
||||
- [ ] Retry behavior validated.
|
||||
|
||||
## Rollout Plan
|
||||
- Deploy with dry-run mode first, then enable live sends.
|
||||
70
docs/specs/HOUSEBOT-005-anonymous-feedback.md
Normal file
70
docs/specs/HOUSEBOT-005-anonymous-feedback.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# HOUSEBOT-005: Anonymous Feedback Flow
|
||||
|
||||
## Summary
|
||||
Allow members to submit anonymous household feedback to the bot via DM, then repost sanitized messages to a configured topic.
|
||||
|
||||
## Goals
|
||||
- Protect sender identity in group output.
|
||||
- Reduce conflict by neutralizing wording.
|
||||
- Prevent abuse with rate limits and blocklist controls.
|
||||
|
||||
## Non-goals
|
||||
- Anonymous reactions.
|
||||
- Admin identity reveal path.
|
||||
|
||||
## Scope
|
||||
- In: DM intake, sanitize/rewrite, posting, moderation guardrails.
|
||||
- Out: full moderation panel UI.
|
||||
|
||||
## Interfaces and Contracts
|
||||
- Bot command in DM: `/anon <message>` (or conversational prompt flow).
|
||||
- Use-case: `PostAnonymousMessage`.
|
||||
- Result includes posted message id and moderation outcome.
|
||||
|
||||
## Domain Rules
|
||||
- Sender identity is never included in reposted content.
|
||||
- Per-user cooldown and daily cap enforced.
|
||||
- Blocklisted phrases reject or request rewrite.
|
||||
|
||||
## Data Model Changes
|
||||
- `anonymous_messages`:
|
||||
- `household_id`
|
||||
- `submitted_by_member_id` (internal only)
|
||||
- `raw_text`
|
||||
- `sanitized_text`
|
||||
- `moderation_status`
|
||||
- `posted_message_id`
|
||||
- timestamps
|
||||
|
||||
## Security and Privacy
|
||||
- Internal sender reference is never exposed via group features.
|
||||
- PII minimization and retention policy documented.
|
||||
- Abuse logging without public reveal.
|
||||
|
||||
## Observability
|
||||
- Submission volume metrics.
|
||||
- Rejection/acceptance rate metrics.
|
||||
- Error logs for rewrite or post failures.
|
||||
|
||||
## Edge Cases and Failure Modes
|
||||
- Message too short/too long.
|
||||
- Spam bursts.
|
||||
- Telegram post failure after rewrite.
|
||||
|
||||
## Test Plan
|
||||
- Unit:
|
||||
- moderation and cooldown policy
|
||||
- anonymization invariants
|
||||
- Integration:
|
||||
- DM ingestion to repost pipeline
|
||||
- E2E:
|
||||
- anonymous submission lifecycle in test group
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] DM to group repost works end-to-end.
|
||||
- [ ] Sender is hidden in group output.
|
||||
- [ ] Rate limit and blocklist enforced.
|
||||
- [ ] Sanitization pipeline tested.
|
||||
|
||||
## Rollout Plan
|
||||
- Start with strict moderation thresholds and tune based on false positives.
|
||||
75
docs/specs/README.md
Normal file
75
docs/specs/README.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Specs Guide
|
||||
|
||||
Each implementation ticket should have one spec file in `docs/specs/`.
|
||||
|
||||
## Naming
|
||||
Use `HOUSEBOT-<id>-<slug>.md`.
|
||||
|
||||
Example:
|
||||
- `HOUSEBOT-001-monorepo-bootstrap.md`
|
||||
|
||||
## Spec Template
|
||||
|
||||
```md
|
||||
# <Title>
|
||||
|
||||
## Summary
|
||||
Short description of the feature and user value.
|
||||
|
||||
## Goals
|
||||
- ...
|
||||
|
||||
## Non-goals
|
||||
- ...
|
||||
|
||||
## Scope
|
||||
- In: ...
|
||||
- Out: ...
|
||||
|
||||
## Interfaces and Contracts
|
||||
- Commands/events/APIs involved.
|
||||
- Input and output schemas.
|
||||
|
||||
## Domain Rules
|
||||
- Business constraints and invariants.
|
||||
|
||||
## Data Model Changes
|
||||
- Tables, fields, indexes, migrations.
|
||||
|
||||
## Security and Privacy
|
||||
- Auth, authorization, PII handling, abuse prevention.
|
||||
|
||||
## Observability
|
||||
- Required logs, metrics, traces, and alerts.
|
||||
|
||||
## Edge Cases and Failure Modes
|
||||
- Invalid input
|
||||
- External service failures
|
||||
- Duplicate/retry behavior
|
||||
|
||||
## Test Plan
|
||||
- Unit:
|
||||
- Integration:
|
||||
- E2E:
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] ...
|
||||
- [ ] ...
|
||||
|
||||
## Rollout Plan
|
||||
- Feature flags / staged rollout / backout plan.
|
||||
```
|
||||
|
||||
## Definition of Done
|
||||
- Spec exists and matches implementation.
|
||||
- Code follows architecture boundaries.
|
||||
- Tests for new behavior are included and passing.
|
||||
- Lint and typecheck pass in CI.
|
||||
- Docs/ADR updates included if behavior or architecture changed.
|
||||
- No TODOs without linked follow-up ticket.
|
||||
|
||||
## Boundary Rules (Hexagonal)
|
||||
- `packages/domain` must not import framework/DB/HTTP code.
|
||||
- `packages/application` depends only on domain + ports/contracts.
|
||||
- `packages/adapters-*` implement ports and may depend on external SDKs.
|
||||
- Wiring of concrete adapters happens only in app entrypoints.
|
||||
Reference in New Issue
Block a user