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>
Initialize workspace for email server worker service
- Polls MongoDB for email status changes
- Sends verification and notification emails
- Updates email statuses
- Runs as standalone background worker
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Initialize empty workspace for Mailgun webhook handler service
- Processes email verification and status updates
- Communicates with web-app via shared MongoDB
- Handles Mailgun webhook events
🤖 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>
- Added DB integration details for external email system
- Clarified share-id validation (404 on invalid)
- Enhanced subsequent matching to include tenantEmail
- Specified exact UI placement for email status indicators
- Fixed typo: EmailStatus.Verifies → EmailStatus.Verified
🤖 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>
Removed npm workspace configuration in favor of simple multi-project repository.
Each project (web-app, housekeeping) is now completely self-contained.
## Changes
- Removed root package.json and package-lock.json
- Added VS Code workspace file for better project organization
- Updated documentation to reflect independent project structure
- Each project manages its own dependencies without workspace linking
## Structure
- web-app/: Self-contained Next.js application
- housekeeping/: Self-contained DB maintenance scripts
- No workspace management or dependency sharing
- Monorepo is purely for Git organization
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed shared dependencies from root package.json. Each workspace now
manages its own dependencies independently.
- Removed prettier from root devDependencies
- Removed prettier scripts from root (available in web-app workspace)
- Root package.json now only manages workspace configuration
🤖 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>
- Reorder card-2 text to lead with the value proposition (Gmail sign-in)
- Update Croatian translations to consistently use "aplikacija" instead of "alat"
- Improve sentence flow for better readability in both languages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Removed documentation links section (tailwindcss, heroicons, daisyui)
- Reorganized footer links into horizontal flex layout
- Simplified footer structure to single column with app branding and main links
- Cleaned up CSS classes for cleaner appearance
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Updated privacy-policy page component to render all 16 sections
- Expanded Croatian translations with comprehensive GDPR-compliant privacy policy
- Expanded English translations with comprehensive GDPR-compliant privacy policy
- Added sections covering: data controller, data collection, legal bases, cookies,
hosting location, data sharing, EU transfers, security, data retention,
GDPR rights, rights exercise, complaint rights, children's privacy, and policy changes
- Restructured existing sections with intro paragraphs and detailed list items
- Maintained proper rich text formatting for email links and emphasis
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add title: 'rezije.app' to metadata in layout
- Sets browser tab title for all pages across the application
- Applies to all locales (Croatian and English)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace <a> tags with Next.js Link component for email links
- Update translation tags from <a> to <emailLink> in both en and hr
- Add no-underline class to prevent default prose underline
- Add hover:underline to show underline only on hover
- Apply consistent styling across both terms-of-service and privacy-policy pages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Extract all privacy-policy text content into messages/en.json and messages/hr.json
- Add complete Croatian translation for privacy policy
- Update privacy-policy page to use next-intl translations with t.rich()
- Rename component from ConsentPage to PrivacyPolicyPage for clarity
- Replace hardcoded text with translation keys for full i18n support
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Extract all terms-of-service text content into messages/en.json and messages/hr.json
- Update terms-of-service page to use next-intl translations with t.rich()
- Replace dangerouslySetInnerHTML with proper t.rich() formatting
- Add Croatian translation for terms-of-service page
- Increase disclaimer max-width from 20rem to 30rem for better readability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Restructure login-page content to match Croatian version (remove card-3, add disclaimer)
- Update main-card text structure from text-1/text-2 to single text field
- Update image references and add image-alt attributes
- Add missing translation fields in home-page and location-edit-form
- Remove duplicate card-2.text render in landing page
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Extract reusable components: EnterOrSignInButton, paragraphFormatFactory, getProviders
- Fix React hooks usage: remove useMemo from async Server Components
- Update landing page content for Croatian and English translations
- Reorganize terms/policy pages into locale-aware directories
- Update PageFooter to use locale-aware links and make component async
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Force white background on print preview page regardless of color scheme
- Exclude paid bills from print view
- Add proper spacing for printed barcodes
- Remove legacy barcodeImage support
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>