Created a new /share/rent-due/ page to display rent payment information
separately from utility bills.
Changes:
- Created /share/rent-due/[id]/ page structure with RentViewPage component
- Created ViewRentCard component to display rent amount and payment info
- Added uploadRentProofOfPayment action for tenant proof upload
- Added translation keys for rent-specific labels (en/hr)
- Updated rent email templates to link to /share/rent-due/ instead of /share/bills-due/
- Updated documentation to reflect new URL structure
The rent page displays:
- Rent amount
- IBAN or Revolut payment information with QR/barcode
- Rent proof of payment upload (when enabled)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Moved the language selector to appear before the email address field for better
UX flow. Users now select the notification language first, then enter the email
address that will receive notifications in that language.
Also applied right-alignment to the "new email" status indicator for consistency.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added justify-end to email status display to align icons and text to the right
side of the container for better visual hierarchy.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Improved UI organization by moving the language selector into the same fieldset
as the tenant email input, since both are related to email notifications. The
language selector now only appears when email notifications are enabled.
Changes:
- Move language selector inside tenant email fieldset (no separate fieldset)
- Add label for tenant email input field
- Simplify notification language label text
- Remove unused notification-language-legend translation key
- Language selector shares visibility condition with email field
This provides a more logical grouping of related settings and reduces visual
clutter when email notifications are disabled.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added ability to select the language for automatic notification emails sent to
tenants. Users can choose between Croatian (hr) and English (en). If not set,
defaults to the current UI language.
Changes:
- Add tenantEmailLanguage field to BillingLocation type (shared-code)
- Add language selector fieldset in LocationEditForm below email settings
- Add Zod validation for tenantEmailLanguage in locationActions
- Include field in all database insert and update operations
- Default to current locale if not explicitly set
- Add translation labels for language selector (EN/HR)
This allows tenants to receive bills and notifications in their preferred language
regardless of the landlord's UI language preference.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed unnecessary loop when checking if bill forwarding should be triggered.
Since we only need to determine if forwarding should happen once per location
(after all bills are updated), we can check with just the first paid bill
instead of looping through all updates.
Benefits:
- More efficient (no redundant checks for unpaid bills)
- Clearer logic (one check per location, not per bill update)
- Avoids confusion about checking bills that weren't marked as paid
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Created shared billForwardingHelpers module to avoid code duplication and
implemented automatic bill forwarding trigger in the multi-bill-edit feature.
Changes:
- Extract shouldUpdateBillFwdStatusWhenAttached and shouldUpdateBillFwdStatusWhenPayed
to new billForwardingHelpers.ts module
- Update billActions.ts to import from shared module instead of local definitions
- Add forwarding logic to monthActions.updateMonth to set billFwdStatus to "pending"
when all tenant bills are marked as paid
This ensures consistent bill forwarding behavior whether updating bills individually
or in bulk via the multi-bill-edit page.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed rent amount handling to use whole currency units throughout the application
instead of storing in cents. This simplifies data entry and aligns with Zod validation
requiring integer values.
Changes:
- Set rent input step to "1" (whole numbers only)
- Remove cents-to-currency conversion (/ 100) when formatting for email
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Made toggle labels more explicit by adding "to tenant automatically" to clearly
indicate the recipient and automatic nature of the notifications.
Changes:
- "forward utility bills" → "forward utility bills to tenant automatically"
- "send rent notification" → "send rent notification to tenant automatically"
- Fixed capitalization in Croatian: "obavjest O" → "obavjest o"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Location Edit Form:
- Add validation requiring user to select update scope when editing locations
- Add "no-scope-selected" as placeholder option that must be replaced with valid choice
- Display validation error if user attempts to submit without selecting scope
- Clarify update scope options with improved wording (e.g., "ALL months (past and future)")
Bill Form UX:
- Add emoji icons (👤 tenant, 🔑 landlord) to "who bears cost" options for visual clarity
Translation updates:
- Add "update-scope-required" validation message (EN/HR)
- Improve clarity of update scope option labels
- Standardize Croatian terminology ("zadani" instead of "trenutni" for current month)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Modified bill forwarding logic to only consider bills marked as "billed to tenant"
when determining if all bills are ready for forwarding. Bills billed to landlord
should not affect the forwarding trigger.
Changes:
- Filter out landlord bills before checking if all bills are paid/attached
- Improved status check to explicitly look for "pending" or "sent" status
- Added edge case handling when no tenant bills exist
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fix imports in app/lib/actions/ that were still using relative paths
('../db-types') instead of the shared-code package.
Updated files:
- billActions.ts
- emailActions.ts
- locationActions.ts
- monthActions.ts
- navigationActions.ts
- printActions.ts
- userSettingsActions.ts
All imports now correctly reference @evidencija-rezija/shared-code.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Update web-app to use @evidencija-rezija/shared-code for common types
and utilities instead of maintaining duplicate copies.
Changes:
- Add shared-code dependency to package.json
- Update all imports across 35+ files to use @evidencija-rezija/shared-code
- Remove duplicate db-types.ts and shareChecksum.ts files
This ensures type consistency between web-app and email-worker and
reduces maintenance burden.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add a reset button to the email verification failed status display, allowing users
to retry email verification after a failure. The button appears alongside the error
message and icon for easy access.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add English and Croatian translation keys for the verification-failed email status
that were missing from the previous UI implementation commit.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Display verification failed status in location cards and edit forms to provide
clear visual feedback when email verification fails. Uses red X icon and error
styling consistent with other failure states.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Enables automatic email notification trigger when all bills are marked as paid
under "when-payed" forwarding strategy. Complements the existing "when-attached"
strategy to support both notification workflows.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Enables automatic email notification trigger when the last bill receives an
attachment under "when-attached" forwarding strategy. This eliminates manual
intervention for marking locations ready for tenant notification.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implement strict validation to prevent unauthorized email status changes:
- Force status to Unverified when email address changes
- Only allow client to reset status to Unverified (via reset button)
- Block client from upgrading status (Unverified→Verified, etc.)
- All status upgrades must happen server-side via verification links
This prevents attackers from:
- Submitting new emails with fake "verified" status
- Bypassing email verification by modifying client requests
- Escalating email status without proper verification flow
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add tenantEmailStatus hidden field to LocationEditForm
- Update locationActions to persist email status across all scopes
- Add reset button for unsubscribed email status
- Improve email status display with new/modified indicators
- Update translations for email status messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
LocationCard:
- Include email status in card info section display condition
- Remove emoji suffixes (icons already convey status visually)
LocationEditForm:
- Enable autoBillFwd and rentDueNotification toggles
- Only show email status when displayed email matches saved email
- Show unverified status when email is changed or for new emails
- Remove emoji suffixes from status messages
- Add left margin to status display
Messages (EN/HR):
- More descriptive email status messages in both languages
- LocationCard: "tenant email not verified" vs "Email not verified"
- LocationEditForm: Clearer explanations like "this e-mail address
will need to be verified by the tenant"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added tenantEmail and tenantEmailStatus fields to the MongoDB projection
in fetchAllLocations() so LocationCard can display email status indicators.
Previously these fields were always undefined in LocationCard because they
weren't included in the aggregation pipeline's $project stage.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Security Enhancement:
- Server-side validation of email status before allowing verification
- Only allow verifying emails in VerificationPending state
- Show "Action not possible" message for invalid states
- Extract and validate share-id on server side
- Return 404 for invalid share-ids or missing tenant emails
Implementation:
- Convert page.tsx to async server component
- Fetch location and check tenantEmailStatus
- Pass isPending prop to client component
- Add bilingual "not-allowed" translations (same as unsubscribe page)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Make error message more generic and less specific:
- Change title from "Action Not Allowed" to "Action not possible"
- Simplify message to cover broader error cases
- Fix typo: "performe" → "performed"
- Apply same changes to Croatian version
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Security Enhancement:
- Server-side validation of email status before allowing unsubscribe
- Only allow unsubscribing from verified emails
- Show "Action Not Allowed" message for unverified/unsubscribed emails
- Extract and validate share-id on server side
- Return 404 for invalid share-ids or missing tenant emails
Implementation:
- Convert page.tsx to async server component
- Fetch location and check tenantEmailStatus
- Pass isVerified prop to client component
- Add bilingual "not-allowed" translations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Display all email statuses (Unverified, VerificationPending, Verified, Unsubscribed)
- Show appropriate icons and colors for each status
- Add bilingual translations for status labels
- Use UTF-8 emojis (⚠️⏳✅✉️) alongside Heroicons
- Position indicator before tenantEmail-error div
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Display email status when not Verified
- Show appropriate icons and colors for each status
- Add bilingual translations for status labels
- Use UTF-8 emojis (⚠️⏳✉️) alongside Heroicons
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Create /email/unsubscribe/[id] route with page and component
- Add share-id validation and 404 on invalid links
- Add bilingual translations (English/Croatian)
- Implement unsubscribe UI with success/error states
- Call unsubscribeTenantEmail server action on button click
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Create /email/verify/[id] route with page and component
- Add share-id validation and 404 on invalid links
- Add bilingual translations (English/Croatian)
- Implement verification UI with success/error states
- Call verifyTenantEmail server action on button click
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Export EmailStatus enum from db-types.ts
- Add verifyTenantEmail server action
- Add unsubscribeTenantEmail server action
- Both actions update current and all subsequent matching locations
- Match criteria: userId, name, tenantEmail, yearMonth >= current
- Share-id validation using existing shareChecksum utilities
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add EmailStatus enum and tracking fields to BillingLocation to support
email delivery monitoring (bounces, complaints, unsubscribes).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Update launch.json and tasks.json to use multi-root workspace folder syntax for correct path resolution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Moved Dockerfile, build.sh, and .dockerignore to web-app/ for better
project encapsulation. Each project now contains its own build configuration.
## Changes
- Moved Dockerfile to web-app/ and simplified paths
- Moved build.sh to web-app/
- Moved .dockerignore to web-app/
- Updated Dockerfile to work from web-app/ context (no workspace references)
- Updated documentation for new build workflow
## Build Workflow
- Build: Run from web-app/ directory (`cd web-app && ./build.sh 2.20.0`)
- Deploy: Run from repository root (`./deploy-standalone.sh 2.20.0`)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Restructured the repository into a monorepo to better organize application code
and maintenance scripts.
## Workspace Structure
- web-app: Next.js application (all app code moved from root)
- housekeeping: Database backup and maintenance scripts
## Key Changes
- Moved all application code to web-app/ using git mv
- Moved database scripts to housekeeping/ workspace
- Updated Dockerfile for monorepo build process
- Updated docker-compose files (volume paths: ./web-app/etc/hosts/)
- Updated .gitignore for workspace-level node_modules
- Updated documentation (README.md, CLAUDE.md, CHANGELOG.md)
## Migration Impact
- Root package.json now manages workspaces
- Build commands delegate to web-app workspace
- All file history preserved via git mv
- Docker build process updated for workspace structure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>