docs: add roadmap, ADRs, and initial HOUSEBOT specs

This commit is contained in:
2026-03-05 00:47:18 +04:00
commit 768400214e
10 changed files with 653 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
# ADR-001: V1 Tech Stack
## Status
Accepted
## Context
The project needs to be modern, modular, and scalable while still delivering v1 quickly.
## Decision
- Runtime/package manager/test runner: Bun
- Language: TypeScript (strict mode)
- Bot framework: grammY
- Database: Supabase Postgres
- Deployment runtime: Google Cloud Run
- Scheduling: Google Cloud Scheduler
- Frontend mini app: SolidJS (Vite SPA) + Tailwind
- Validation: Zod
- Linting: Oxlint
- Error tracking: Sentry
- Logging/metrics baseline: Cloud Logging/Monitoring
## Rationale
- Bun provides a fast unified developer workflow.
- grammY is TypeScript-friendly with strong middleware patterns.
- Supabase keeps SQL-first data modeling while reducing ops overhead.
- Cloud Run + Scheduler offers serverless simplicity and predictable scheduling.
- Solid SPA provides modern UI performance with lightweight runtime cost.
- Oxlint enables fast linting suitable for small-commit workflow.
## Consequences
Positive:
- Strong portfolio architecture with pragmatic service count.
- Clear path to production without heavy platform ops.
Negative:
- Some enterprise tooling (Prometheus/Grafana/K8s) is deferred.
- Serverless constraints require disciplined idempotency and stateless design.
## Alternatives Considered
- Fly.io runtime: good DX, but Cloud Run better matches serverless objective.
- Convex backend: strong DX, but SQL/reporting fit is weaker for financial ledger.
- Telegraf bot framework: mature ecosystem, but less desirable TS ergonomics.

View File

@@ -0,0 +1,50 @@
# ADR-002: Hexagonal Architecture (Ports and Adapters)
## Status
Accepted
## Context
The project combines domain-heavy finance logic, Telegram integration, mini-app APIs, and scheduled jobs. Without strict boundaries, framework and infrastructure concerns will leak into core logic.
## Decision
Adopt hexagonal architecture with explicit layers:
- Domain: pure business model and invariants.
- Application: use-case orchestration.
- Ports: interfaces for repositories/services.
- Adapters: Telegram, DB, LLM, scheduler, HTTP.
- Composition root: runtime wiring only.
## Boundary Rules
- Domain cannot import adapters, SDKs, HTTP, or SQL clients.
- Application cannot import concrete adapter implementations.
- Adapters can depend on SDKs and infra concerns but must implement ports.
- Entry points create dependency graph and pass ports to use-cases.
## Module Layout
- `packages/domain`
- `packages/application`
- `packages/ports`
- `packages/adapters-*`
- `apps/*` for composition and delivery endpoints
## Rationale
- Keeps financial logic testable and framework-independent.
- Enables incremental replacement of adapters (e.g., parser provider).
- Supports clean growth from v1 to larger-scale architecture.
## Consequences
Positive:
- High maintainability and clear ownership of concerns.
- Better interview-readability of architecture.
Negative:
- Requires initial discipline and more explicit interfaces.
- Slight boilerplate overhead for small features.
## Risks and Mitigations
Risk:
- Overengineering through too many tiny abstractions.
Mitigation:
- Create ports only for external boundaries and meaningful seams.
- Keep use-cases focused; avoid generic base classes.

109
docs/roadmap.md Normal file
View File

@@ -0,0 +1,109 @@
# Household Bot Roadmap
## Vision
Build a clean, modular Telegram household finance platform with a mini app, designed for real use and portfolio-grade engineering quality.
## Principles
- Hexagonal architecture with strict ports/adapters boundaries.
- Small, composable modules and strong type safety.
- Incremental delivery with small commits and always-green CI.
- Money-safe calculations (integer minor units only).
- Pragmatic v1, explicit enterprise extensions in later phases.
## Phase 0 - Foundation
Goal: establish architecture, tooling, and delivery guardrails.
Deliverables:
- Bun workspace monorepo layout.
- TypeScript strict base config.
- Oxlint setup and formatting conventions (no semicolons).
- CI pipeline for typecheck, lint, tests, and build.
- Initial ADRs and spec template.
Exit criteria:
- Fresh clone can run quality checks with one command.
- CI passes on default branch.
- Architecture boundaries are documented.
## Phase 1 - Finance Core
Goal: implement deterministic domain logic for monthly settlements.
Deliverables:
- Domain value objects (`Money`, `BillingPeriod`, IDs).
- Settlement engine for rent + utility + purchase offsets.
- Default equal utility split, with optional day-based override.
- Domain unit tests covering edge cases.
Exit criteria:
- Settlement logic is adapter-independent.
- Domain test suite covers normal and failure paths.
## Phase 2 - Telegram Bot Core
Goal: process household activity and manage billing cycles in Telegram.
Deliverables:
- grammY bot webhook service.
- Topic listener for `Общие покупки`.
- Utility and rent commands.
- Billing cycle commands and statements.
- Idempotent message processing.
Exit criteria:
- Purchase messages are ingested and persisted.
- Monthly statement can be produced via command.
## Phase 3 - Reminders and Scheduling
Goal: automate key payment reminders.
Deliverables:
- Cloud Scheduler jobs.
- Reminder handlers for day 3/4 utilities, day 17 rent notice, day 20 due date.
- Dedicated topic posting for reminders.
Exit criteria:
- Scheduled reminders fire reliably.
- Duplicate sends are prevented.
## Phase 4 - Mini App V1
Goal: deliver a usable household dashboard.
Deliverables:
- SolidJS mini app shell.
- Telegram initData verification and membership gate.
- Ledger view, balances, and settlement preview.
- RU/EN localization.
Exit criteria:
- Active group members can view current month balances.
- Financial views are consistent with bot calculations.
## Phase 5 - Anonymous Feedback + Safety
Goal: support safer household communication.
Deliverables:
- Anonymous DM flow to bot.
- Sanitized/rephrased repost to group topic.
- Rate limits and blocklist moderation.
Exit criteria:
- Sender identity is hidden from group users.
- Abuse controls prevent spam and obvious misuse.
## Phase 6 - Hardening and Portfolio Polish
Goal: production readiness and strong showcase quality.
Deliverables:
- Sentry integration and structured logging.
- Integration and end-to-end tests.
- Runbooks and operational docs.
- Architecture diagram and demo instructions.
Exit criteria:
- Incident/debug workflow is documented.
- Repo can be reviewed as a coherent system design case study.
## Deferred (Post-v1)
- House wiki pages (Wi-Fi, rules, how-to).
- Cleaning/karma workflow.
- Advanced analytics and trend insights.
- Prometheus/Grafana/Kubernetes stack.

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

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

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

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

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

18
docs/tasks/foundation.md Normal file
View File

@@ -0,0 +1,18 @@
# Foundation Task Breakdown
## Epic: Platform Foundation
1. HOUSEBOT-001 - Monorepo Bootstrap and Quality Gates
- Output: Bun workspaces, strict TS, Oxlint, CI skeleton.
2. HOUSEBOT-002 - Local Dev Workflow
- Output: unified dev scripts, env templates, runbook for local startup.
3. HOUSEBOT-003 - Package Boundary Enforcement
- Output: import path policy and boundary lint checks.
4. HOUSEBOT-004 - Testing Harness Setup
- Output: test runner configuration for unit/integration/e2e layers.
5. HOUSEBOT-005 - Release/Branching Conventions
- Output: commit conventions, PR template, branch naming guide.