Codex/whe 15 bootstrap workspace (#1)

* feat(WHE-15): bootstrap bun workspace with app and package scaffolds

* chore(WHE-17): switch workspace typecheck to tsgo

* chore(WHE-16): configure oxlint and oxfmt no-semicolon style

* chore: address CodeRabbit review feedback

* chore: apply coderabbit fixes and add review script

* docs: add ADR decision metadata
This commit is contained in:
Stas
2026-03-05 00:56:24 +03:00
committed by GitHub
parent 768400214e
commit 4a26ac81d6
48 changed files with 1057 additions and 1 deletions

View File

@@ -1,12 +1,18 @@
# ADR-001: V1 Tech Stack
## Status
Accepted
Decision Date: 2026-03-05
Owners: Stanislav Kalishin
## 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
@@ -20,6 +26,7 @@ The project needs to be modern, modular, and scalable while still delivering v1
- 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.
@@ -28,15 +35,19 @@ The project needs to be modern, modular, and scalable while still delivering v1
- 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

@@ -1,13 +1,20 @@
# ADR-002: Hexagonal Architecture (Ports and Adapters)
## Status
Accepted
Decision Date: 2026-03-05
Owners: Stanislav Kalishin
## 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.
@@ -15,12 +22,14 @@ Adopt hexagonal architecture with explicit layers:
- 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`
@@ -28,23 +37,30 @@ Adopt hexagonal architecture with explicit layers:
- `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.
- Easier to explain architecture decisions in interviews.
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.

View File

@@ -1,9 +1,11 @@
# 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.
@@ -11,9 +13,11 @@ Build a clean, modular Telegram household finance platform with a mini app, desi
- 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).
@@ -21,27 +25,33 @@ Deliverables:
- 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.
@@ -49,60 +59,74 @@ Deliverables:
- 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.

View File

@@ -0,0 +1,45 @@
# Development Setup
## Requirements
- Bun 1.3+
- Node.js 22+
## First-time setup
```bash
bun install
```
## Workspace commands
```bash
bun run lint
bun run lint:fix
bun run format
bun run format:check
bun run typecheck
bun run test
bun run build
```
## App commands
```bash
bun run dev:bot
bun run dev:miniapp
```
## Review commands
```bash
bun run review:coderabbit
```
## Notes
- Type checking uses `tsgo` (`@typescript/native-preview`).
- Linting uses `oxlint`.
- Formatting uses `oxfmt` with no-semicolon style.
- AI review uses CodeRabbit CLI in `--prompt-only` mode against `main`.
- `WHE-19` will add CI checks for the same root commands.

View File

@@ -1,24 +1,29 @@
# 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`
@@ -27,6 +32,7 @@ Initialize the repository as a Bun workspace monorepo with strict TypeScript, Ox
- Workspace packages must compile under shared TS config.
## Architecture Constraints
- Workspace must include:
- `apps/bot`
- `apps/miniapp`
@@ -38,6 +44,7 @@ Initialize the repository as a Bun workspace monorepo with strict TypeScript, Ox
- No cross-import from domain to adapters/apps.
## File Plan
- Root:
- `package.json`
- `bunfig.toml`
@@ -53,11 +60,13 @@ Initialize the repository as a Bun workspace monorepo with strict TypeScript, Ox
- `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:
@@ -66,6 +75,7 @@ Initialize the repository as a Bun workspace monorepo with strict TypeScript, Ox
- 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.
@@ -74,5 +84,6 @@ Initialize the repository as a Bun workspace monorepo with strict TypeScript, Ox
- [ ] Docs updated with local bootstrap commands.
## Rollout Plan
- Merge to default branch.
- Use as mandatory baseline for all subsequent tickets.

View File

@@ -1,33 +1,40 @@
# 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`
@@ -37,20 +44,24 @@ Define domain entities and invariants for rent, utilities, shared purchases, and
- `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
@@ -59,10 +70,12 @@ Define domain entities and invariants for rent, utilities, shared purchases, and
- 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

@@ -1,22 +1,27 @@
# 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`
@@ -27,11 +32,13 @@ Parse free-form purchase messages (primarily Russian) from the Telegram topic `
- `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`
@@ -42,21 +49,25 @@ Parse free-form purchase messages (primarily Russian) from the Telegram topic `
- `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
@@ -65,10 +76,12 @@ Parse free-form purchase messages (primarily Russian) from the Telegram topic `
- 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

@@ -1,22 +1,27 @@
# 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`
@@ -24,12 +29,14 @@ Schedule and deliver household billing reminders to dedicated Telegram topics.
- 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`
@@ -38,20 +45,24 @@ Schedule and deliver household billing reminders to dedicated Telegram topics.
- `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:
@@ -60,10 +71,12 @@ Schedule and deliver household billing reminders to dedicated Telegram topics.
- 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

@@ -1,32 +1,39 @@
# 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)
@@ -37,21 +44,25 @@ Allow members to submit anonymous household feedback to the bot via DM, then rep
- 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
@@ -61,10 +72,12 @@ Allow members to submit anonymous household feedback to the bot via DM, then rep
- 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.

View File

@@ -3,9 +3,11 @@
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
@@ -14,53 +16,67 @@ Example:
# <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.
@@ -69,6 +85,7 @@ Short description of the feature and user value.
- 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.

View File

@@ -3,16 +3,21 @@
## 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.