mirror of
https://github.com/whekin/household-bot.git
synced 2026-03-31 12:04:02 +00:00
feat: add quick payment action and improve copy button UX
Mini App Home Screen: - Add 'Record Payment' button to utilities and rent period cards - Pre-fill payment amount with member's share (rentShare/utilityShare) - Modal dialog with amount input and currency display - Toast notifications for copy and payment success/failure feedback Copy Button Improvements: - Increase spacing between icon and text (4px → 8px) - Add hover background and padding for better touch target - Green background highlight when copied (in addition to icon color change) - Toast notification appears when copying any value Backend: - Add /api/miniapp/payments/add endpoint for quick payments - Payment notifications sent to 'reminders' topic in Telegram - Include member name, payment type, amount, and period in notification Files: - New: apps/miniapp/src/components/ui/toast.tsx - Modified: apps/miniapp/src/routes/home.tsx, apps/miniapp/src/index.css, apps/miniapp/src/theme.css, apps/miniapp/src/i18n.ts, apps/bot/src/miniapp-billing.ts, apps/bot/src/server.ts Quality Gates: ✅ format, lint, typecheck, build, test Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
# Plan: Miniapp Home “Current Period” + Rent Credentials
|
||||
|
||||
## Summary
|
||||
|
||||
Implement a “current payment period” focused Home screen with three modes:
|
||||
|
||||
- **Utilities period** (between utilities reminder day and utilities due day, inclusive)
|
||||
- **Rent period** (between rent warning day and rent due day, inclusive)
|
||||
- **No payment period** (everything else)
|
||||
|
||||
Add **rent payment credentials** (one-or-more destinations) to the backend + database, editable by admins and visible to all members. Also add a **resident-accessible utility bill submission** flow surfaced on Home during the utilities window when no utility bills are recorded yet.
|
||||
|
||||
## Current State Analysis (repo-grounded)
|
||||
|
||||
### Miniapp UI and data flow
|
||||
|
||||
- Home route today is a single view rendering “Your balance”, optional rent FX, and latest activity, driven by `MiniAppDashboard` from `DashboardContext`.
|
||||
- [home.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/home.tsx#L1-L178)
|
||||
- [dashboard-context.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/contexts/dashboard-context.tsx#L240-L366)
|
||||
- `MiniAppDashboard` already carries `period`, `timezone`, `rentDueDay`, `utilitiesDueDay`, and `paymentBalanceAdjustmentPolicy`, but **does not include** `rentWarningDay` / `utilitiesReminderDay` or any payment destinations.
|
||||
- [miniapp-api.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/miniapp-api.ts#L95-L143)
|
||||
- Date helpers exist to compare “today in timezone” against a day inside a given `period` and to compute days remaining.
|
||||
- [dates.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/lib/dates.ts#L105-L172)
|
||||
|
||||
### Backend / domain
|
||||
|
||||
- Miniapp dashboard API maps `FinanceCommandService.generateDashboard()` into `MiniAppDashboard`.
|
||||
- [miniapp-dashboard.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/miniapp-dashboard.ts#L12-L150)
|
||||
- `FinanceDashboard` is built from billing settings + cycle state; it uses `rentWarningDay` and `utilitiesReminderDay` internally for FX lock dates, but it currently only exposes `rentDueDay` and `utilitiesDueDay` to the miniapp.
|
||||
- [finance-command-service.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/application/src/finance-command-service.ts#L287-L599)
|
||||
- Billing settings are persisted in Postgres via Drizzle table `household_billing_settings` (already includes rent/utilities due and reminder/warning days + timezone).
|
||||
- [schema.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/db/src/schema.ts#L24-L50)
|
||||
- Repository accessors: [household-config-repository.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/adapters-db/src/household-config-repository.ts#L944-L1066)
|
||||
- Utility bills are currently **admin-only** in the miniapp (`/api/miniapp/admin/utility-bills/add`) and the UI hides add/edit behind `effectiveIsAdmin()`.
|
||||
- UI: [ledger.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/ledger.tsx#L617-L652)
|
||||
- API handler: [miniapp-billing.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/miniapp-billing.ts#L721-L790)
|
||||
|
||||
## Proposed Changes (decision-complete)
|
||||
|
||||
### 1) Add rent payment destinations to DB + ports
|
||||
|
||||
**Decision:** store rent credentials as a JSON array on `household_billing_settings` to support multiple destinations without introducing a new table (pre-1.0 simplicity + cohesion with billing config).
|
||||
|
||||
- Add a new `jsonb` column on `household_billing_settings`:
|
||||
- `rent_payment_destinations` (nullable, default `null`)
|
||||
- Add a strongly-typed record shape in ports:
|
||||
- `HouseholdRentPaymentDestination`:
|
||||
- `label: string` (e.g., “TBC card”, “Bank transfer”)
|
||||
- `recipientName: string | null`
|
||||
- `bankName: string | null`
|
||||
- `account: string` (account number / card number / IBAN; stored as plain text)
|
||||
- `note: string | null`
|
||||
- `link: string | null` (optional URL/deeplink)
|
||||
- Add `rentPaymentDestinations?: readonly HouseholdRentPaymentDestination[] | null` to `HouseholdBillingSettingsRecord` and the `updateHouseholdBillingSettings` input.
|
||||
|
||||
Files:
|
||||
|
||||
- DB schema + migration:
|
||||
- [schema.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/db/src/schema.ts)
|
||||
- `packages/db/drizzle/00xx_*.sql` (new migration)
|
||||
- Ports:
|
||||
- [household-config.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/ports/src/household-config.ts)
|
||||
- DB adapter mapping:
|
||||
- [household-config-repository.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/adapters-db/src/household-config-repository.ts#L944-L1066)
|
||||
|
||||
### 2) Expose needed fields to the miniapp dashboard contract
|
||||
|
||||
**Goal:** let the miniapp compute “current period” locally and render period-specific UI consistently.
|
||||
|
||||
- Extend `FinanceDashboard` to include:
|
||||
- `rentWarningDay`
|
||||
- `utilitiesReminderDay`
|
||||
- `rentPaymentDestinations`
|
||||
- Return these from `buildFinanceDashboard(...)` using the persisted billing settings.
|
||||
- Extend bot miniapp dashboard handler serialization:
|
||||
- Include those fields in the `dashboard` JSON payload.
|
||||
- Extend miniapp client types:
|
||||
- `MiniAppDashboard` adds `rentWarningDay`, `utilitiesReminderDay`, and `rentPaymentDestinations`.
|
||||
- Update demo fixtures so the miniapp still renders in demo mode.
|
||||
|
||||
Files:
|
||||
|
||||
- Application:
|
||||
- [finance-command-service.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/application/src/finance-command-service.ts)
|
||||
- Bot:
|
||||
- [miniapp-dashboard.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/miniapp-dashboard.ts)
|
||||
- Miniapp API types + demo:
|
||||
- [miniapp-api.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/miniapp-api.ts)
|
||||
- [miniapp-demo.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/demo/miniapp-demo.ts)
|
||||
|
||||
### 3) Add admin editing UI for rent payment destinations
|
||||
|
||||
**Decision:** rent credentials are visible to everyone, but **only admins can edit** (implemented in Settings screen next to other billing settings).
|
||||
|
||||
- Extend the Settings “Billing settings” modal form state to include a list editor:
|
||||
- Add destination
|
||||
- Remove destination
|
||||
- Edit fields (label, recipient, bank, account, note, link)
|
||||
- Extend `updateMiniAppBillingSettings(...)` request/response types to carry the new field.
|
||||
- Extend backend handler that parses settings update payload and calls `updateHouseholdBillingSettings`.
|
||||
|
||||
Files:
|
||||
|
||||
- Miniapp:
|
||||
- [settings.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/settings.tsx)
|
||||
- [miniapp-api.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/miniapp-api.ts) (`MiniAppBillingSettings` + `updateMiniAppBillingSettings`)
|
||||
- [i18n.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/i18n.ts) (new strings)
|
||||
- Bot:
|
||||
- [miniapp-admin.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/miniapp-admin.ts) (payload parsing)
|
||||
- Application:
|
||||
- [miniapp-admin-service.ts](file:///Users/whekin/Projects/kojori-tg-bot/packages/application/src/miniapp-admin-service.ts) (include field into repository update input)
|
||||
|
||||
### 4) Implement “3 versions of Home” (utilities / rent / no payment)
|
||||
|
||||
**Decision:** Home determines an active mode as “Reminder→Due” (inclusive). It uses:
|
||||
|
||||
- `dashboard.period`
|
||||
- `dashboard.timezone`
|
||||
- `dashboard.utilitiesReminderDay` / `dashboard.utilitiesDueDay`
|
||||
- `dashboard.rentWarningDay` / `dashboard.rentDueDay`
|
||||
|
||||
#### 4.1 Utilities mode
|
||||
|
||||
- Show a primary “Utilities” card:
|
||||
- Amount to pay = utilities base share + purchase offset if policy is `utilities`
|
||||
- Show due date and days left using existing copy keys (`dueOnLabel`, `daysLeftLabel`, etc.)
|
||||
- If **no utility bills recorded yet** (`utilityLedger().length === 0`):
|
||||
- Show an inline “Fill utilities” call-to-action:
|
||||
- A simple add-utility-bill form embedded on Home (visible to all members).
|
||||
- After successful submission + refresh, the CTA disappears and the normal utilities card renders.
|
||||
- Optional: provide a link to the Ledger screen as fallback (if the user prefers to do it there).
|
||||
|
||||
#### 4.2 Rent mode
|
||||
|
||||
- Show a primary “Rent” card:
|
||||
- Amount to pay = rent base share + purchase offset if policy is `rent`
|
||||
- Show due date and days left/overdue visuals.
|
||||
- Show one-or-more “Payment destination” cards listing:
|
||||
- Label, recipient, bank, account, note/link
|
||||
|
||||
#### 4.3 No payment mode
|
||||
|
||||
- Show an “Upcoming” card:
|
||||
- Days until utilities reminder day
|
||||
- Days until rent warning day
|
||||
- Continue to show “Your balance” and latest activity as secondary content (so the screen stays useful).
|
||||
|
||||
Files:
|
||||
|
||||
- [home.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/home.tsx)
|
||||
- Potentially add a tiny helper in `apps/miniapp/src/lib/` for `computeHomePeriodMode(...)` if Home gets too large.
|
||||
- [i18n.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/i18n.ts) (strings for new cards/actions)
|
||||
|
||||
### 5) Allow non-admin utility bill submission (for Home CTA)
|
||||
|
||||
**Decision:** add a new miniapp endpoint that allows any authorized member to add a utility bill, used by the Home CTA. Admin endpoints remain unchanged for editing/deleting.
|
||||
|
||||
- Add a new bot handler:
|
||||
- `POST /api/miniapp/utility-bills/add` (name can be finalized during implementation)
|
||||
- Auth: authorized member session required
|
||||
- Action: call `FinanceCommandService.addUtilityBill(billName, amountMajor, memberId, currency)`
|
||||
- Response: `{ ok, authorized, cycleState }` or `{ ok, error }`
|
||||
- Wire it into the bot server router.
|
||||
- Add a miniapp client function to call it (parallel to `addMiniAppUtilityBill`, but non-admin path).
|
||||
- Home CTA uses this endpoint, then triggers `refreshHouseholdData(true, true)` so the dashboard updates.
|
||||
|
||||
Files:
|
||||
|
||||
- Bot:
|
||||
- [miniapp-billing.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/miniapp-billing.ts) (new handler)
|
||||
- [server.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/server.ts) (new route option + dispatch)
|
||||
- [index.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/bot/src/index.ts) (compose and pass the new handler into `createBotWebhookServer`)
|
||||
- Miniapp:
|
||||
- [miniapp-api.ts](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/miniapp-api.ts) (new function)
|
||||
- [home.tsx](file:///Users/whekin/Projects/kojori-tg-bot/apps/miniapp/src/routes/home.tsx) (use it)
|
||||
|
||||
## Assumptions & Decisions
|
||||
|
||||
- Period selection is **Reminder→Due inclusive** (utilities: `utilitiesReminderDay..utilitiesDueDay`, rent: `rentWarningDay..rentDueDay`).
|
||||
- Rent payment credentials are **structured** and stored as **plain text** fields (no secrets); they are visible to all household members and editable by admins only.
|
||||
- Utilities “fill” flow is initially “rent-only credentials now”; utilities destinations are out of scope.
|
||||
- Utility bill submission from Home is allowed for any authorized member; edit/delete remains admin-only.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
- Typecheck, lint, test, build (repo quality gates):
|
||||
- `bun run format:check`
|
||||
- `bun run lint`
|
||||
- `bun run typecheck`
|
||||
- `bun run test`
|
||||
- `bun run build`
|
||||
- Manual miniapp checks:
|
||||
- Home renders correctly in all 3 modes by adjusting due/reminder days in Settings.
|
||||
- Utilities window + no bills: Home CTA allows submission and then switches to normal utilities view after refresh.
|
||||
- Rent window: rent credentials render correctly; multiple destinations show; admin edits persist and reload.
|
||||
Reference in New Issue
Block a user