Commit Graph

981 Commits

Author SHA1 Message Date
b50603a8fe refactor: optimize state initialization with lazy initializers
- Move billStates calculation into useState lazy initializer to prevent recalculation on re-renders
- Initialize allPaidMode based on billStates to reflect actual data state
- Use lazy initialization pattern for better performance
- Remove intermediate variables to simplify code

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-18 17:57:51 +01:00
0145a2030d feat: add multi-bill-edit page for batch bill status updates
- Add getLocationsByMonth server action with aggregation pipeline to calculate hasAttachment
- Add updateMonth server action for bulk bill status updates with path revalidation
- Create multi-bill-edit page at /home/multi-bill-edit/[year]/[month]
- Implement MultiBillEdit component with toggle functionality for all bills
- Add BillToggleBadge component integration for consistent bill display
- Add "set all as paid/unpaid" toggle button for batch operations
- Implement server-side redirect with success message after save
- Add Suspense boundary with loading skeleton
- Update translations for multi-bill-edit feature (Croatian and English)
- Ensure data freshness with unstable_noStore and revalidatePath

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-18 17:45:27 +01:00
e9ade045d8 feat: add separate unpaid and paid bill totals to location cards
- Display both unpaid and paid bill amounts in LocationCard and MonthCard
- Rename variables for clarity: totalUnpaid, totalPayed, unpaidTotal, payedTotal
- ViewLocationCard uses totalAmount for tenant bills (regardless of payment status)
- Update Croatian translations: "Ukupno neplaćeno" (unpaid), "Ukupno plaćeno" (paid)
- Add ShoppingCartIcon for unpaid amounts, BanknotesIcon for paid amounts
- Update HomePage to calculate and pass both totals to month cards

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-18 14:59:11 +01:00
Knee Cola
4e1bef30f5 Merge branch 'hotfix/2.13.1' 2025-12-08 01:37:57 +01:00
Knee Cola
c817c9be05 Merge branch 'hotfix/2.13.1' into develop 2025-12-08 01:37:57 +01:00
Knee Cola
7212425961 fix: use forEach instead of for-of to iterate Map entries 2025-12-08 01:36:41 +01:00
Knee Cola
f4793fa6d3 Merge branch 'release/2.13.0' 2025-12-08 01:25:43 +01:00
Knee Cola
a61ece9993 Merge branch 'release/2.13.0' into develop 2025-12-08 01:25:43 +01:00
Knee Cola
1c80caee9c 2.13.0 2025-12-08 01:24:22 +01:00
Knee Cola
b86713b71b Merge branch 'feature/improving-security' into develop 2025-12-08 01:23:56 +01:00
Knee Cola
927349e1d2 feat: add share link security environment variables to Docker configs
Changes:
- Add SHARE_LINK_SECRET (production secret, 64-char hex)
- Add SHARE_TTL_INITIAL_DAYS=10 (days before first tenant visit)
- Add SHARE_TTL_AFTER_VISIT_HOURS=1 (hours after tenant visits)
- Add UPLOAD_RATE_LIMIT_PER_IP=5 (max uploads per IP)
- Add UPLOAD_RATE_LIMIT_WINDOW_MS=3600000 (1 hour rate limit window)

Updated both:
- docker-compose-standalone.yaml
- docker-compose-swarm.yml

Production SHARE_LINK_SECRET generated with: openssl rand -hex 32

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 01:20:55 +01:00
Knee Cola
479df6e0a7 feat: add additional Bash commands to settings for enhanced functionality 2025-12-08 01:18:43 +01:00
Knee Cola
e978a5c2bf feat: add debug logging and improve proof-of-payment icon styling
Changes:
- Add console.log statements for shareId validation failures in locationActions
- Replace DocumentIcon with TicketIcon for proof-of-payment downloads (consistency)
- Add teal color to all proof-of-payment icons for visual distinction
- Adjust vertical alignment of icons for better visual alignment with text

Debug logging helps troubleshoot:
- shareId extraction failures
- Checksum validation failures
- Location not found errors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 01:17:03 +01:00
Knee Cola
bc336a9744 feat: secure attachment download route with shareId validation
Changes:
- Update attachment download link in UI to use shareId
- Add shareId validation to attachment download route
- Validate TTL before allowing attachment downloads
- Extract locationId from shareId using extractShareId helper

Security:
- Attachment downloads now validate checksum and TTL
- Prevents unauthorized access to bill attachment files
- Returns 404 for invalid/expired share links

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 01:02:20 +01:00
Knee Cola
f19e1bc023 feat: secure proof-of-payment download routes with shareId validation
Changes:
- Update download links in UI to use shareId instead of locationID
- Add shareId validation to per-bill proof download route
- Add shareId validation to combined proof download route
- Validate TTL before allowing downloads
- Extract locationId from shareId using extractShareId helper

Security:
- Download routes now validate checksum and TTL
- Prevents unauthorized access to proof-of-payment files
- Returns 404 for invalid/expired share links

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 01:01:38 +01:00
Knee Cola
669fb08582 fix: update bill detail page to support combined shareId
Changes:
- Extract shareId (40 chars) and billID from combined URL parameter
- Validate shareId using validateShareAccess before fetching bill
- Pass shareId to ViewBillCard for secure uploads
- Show error message if share link is invalid or expired

URL format: /share/bill/{shareId}-{billID}
  where shareId = locationId (24) + checksum (16) = 40 chars

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 01:00:06 +01:00
Knee Cola
81dddb526a feat: secure combined uploads and update UI components
Changes:
- Secure uploadUtilBillsProofOfPayment with checksum validation
- Update ViewLocationCard to accept and use shareId prop
- Update ViewBillCard to accept shareId and use it for uploads
- Update ViewBillBadge to pass shareId to bill detail pages
- Add client-side validation check for shareId before upload
- Update back button links to use shareId

Security improvements:
- Both per-bill and combined uploads now validate checksum and TTL
- IP-based rate limiting applied to both upload types
- PDF magic bytes validation for both upload types

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 00:25:26 +01:00
Knee Cola
844e386e18 refactor: use combined shareId (locationId + checksum) in URL
Changes:
- Add generateShareId() and extractShareId() helpers
- Share URLs now use single parameter: /share/location/{shareId}
- shareId = locationId (24 chars) + checksum (16 chars) = 40 chars total
- Update validateShareAccess() to extract locationId from shareId
- Update uploadProofOfPayment() to accept combined shareId
- Update LocationViewPage to validate and extract locationId from shareId

Benefits:
- Simpler URL structure (one parameter instead of two)
- Checksum extraction by length (deterministic, no parsing needed)
- Same security properties (HMAC-SHA256 validation)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 00:22:59 +01:00
Knee Cola
e497ad1da6 feat: implement secure uploadProofOfPayment with multi-layer validation
Security improvements:
- Add checksum validation (prevents unauthorized access)
- Add IP-based rate limiting (prevents abuse)
- Replace MIME type check with PDF magic bytes validation
- Add shareTTL expiry validation
- Add automatic cleanup of expired shares
- Sanitize error messages (generic responses to clients)

Breaking change: Function signature now requires checksum parameter

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 00:17:18 +01:00
Knee Cola
1cf1806955 feat: add share link generation and validation functions
- Add generateShareLink() for owners to create share URLs with checksums
- Add validateShareAccess() to validate checksum and TTL on tenant visits
- Implement automatic TTL reset (10 days → 1 hour after first visit)
- Include automatic cleanup of expired shares

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 00:15:30 +01:00
Knee Cola
a6ab35a959 feat: add core security utilities for checksum-based share links
- Add HMAC-SHA256 checksum generation and validation (shareChecksum.ts)
- Add PDF magic bytes validation to prevent file spoofing (pdfValidator.ts)
- Add IP-based rate limiting for upload abuse prevention (uploadRateLimiter.ts)
- Update BillingLocation interface with shareTTL and shareFirstVisitedAt fields
- Add environment variables for share link security and TTL configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 00:14:20 +01:00
Knee Cola
3638920be4 Merge branch 'release/2.12.1' 2025-12-07 18:54:48 +01:00
Knee Cola
4a5195c938 Merge branch 'release/2.12.1' into develop 2025-12-07 18:54:48 +01:00
Knee Cola
f8aa7233de 2.12.1 2025-12-07 18:54:30 +01:00
Knee Cola
68bdb2336c Merge branch 'feature/fixing-styling' into develop 2025-12-07 18:49:04 +01:00
Knee Cola
b46e23e4eb InfoBox: refactoring icon 2025-12-07 18:48:37 +01:00
Knee Cola
9d06de1265 (refactor) improving content responsivness 2025-12-07 18:41:20 +01:00
Knee Cola
808ea7a4c2 Merge branch 'release/2.12.0' 2025-12-07 17:05:01 +01:00
Knee Cola
51a64613ec Merge branch 'release/2.12.0' into develop 2025-12-07 17:05:01 +01:00
Knee Cola
621146f839 2.12.0 2025-12-07 17:03:59 +01:00
Knee Cola
05de1c7225 Merge branch 'feature/bill-attachment' into develop 2025-12-07 16:57:39 +01:00
Knee Cola
0f8b5678f4 Fix client-side cache staleness after proof of payment upload
Added cache revalidation to ensure ViewLocationCard reflects uploaded
proof of payment when navigating back from ViewBillCard:

- Server-side: Added revalidatePath() to upload actions in billActions
  and locationActions to invalidate Next.js server cache
- Client-side: Added router.refresh() calls in ViewBillCard and
  ViewLocationCard to refresh client router cache after successful upload

This maintains the current UX (no redirect on upload) while ensuring
fresh data is displayed on navigation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 16:57:00 +01:00
Knee Cola
cfa6a4c5b7 Add proof of payment display to BillEditForm
Added read-only proof of payment display in bill edit form:
- Shows download link when proofOfPaymentType is "per-bill" and proof exists
- Uses TicketIcon with teal color for visual distinction
- Links to /share/proof-of-payment/per-bill/ download route
- Handles housekeeping case (no display if filename missing)

This allows users to view and download existing proof of payment
while editing a bill, improving transparency and user experience.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 16:35:08 +01:00
Knee Cola
b3e4e3591c (refactor) locationAction: optimizing query not to return binary data 2025-12-07 16:05:42 +01:00
Knee Cola
47bea328e7 (bugfix) billAction: file type validation was failing if not file was attached 2025-12-07 16:05:10 +01:00
Knee Cola
25865cfae4 BillBage: implemented proof-of-payment indicator 2025-12-07 16:04:09 +01:00
Knee Cola
7994f9ebdb Add info box for billed-to selection in BillEditForm 2025-12-07 16:02:02 +01:00
Knee Cola
0b6555eff3 Update ViewLocationCard to use new combined proof download route
Changed proof of payment download link from old route structure
/share/proof-of-payment/[id]/ to new structure
/share/proof-of-payment/combined/[id]/

This aligns with the reorganized route structure that separates
combined and per-bill proof of payment downloads.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 13:40:11 +01:00
Knee Cola
534955a9fa Fix MongoDB projection error in uploadProofOfPayment
Fixed mixed inclusion/exclusion projection that caused error:
"Cannot do inclusion on field bills.proofOfPayment.uploadedAt in exclusion projection"

Changed projection to use exclusion-only:
- Exclude bills.attachment (not needed in upload context)
- Exclude bills.proofOfPayment.fileContentsBase64 (large file data)
- Include all other fields implicitly (including uploadedAt for existence check)

This reduces data transfer while maintaining MongoDB projection compatibility.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 13:38:48 +01:00
Knee Cola
65b5a1cdd5 Implement proof of payment download routes
Added two download routes for proof of payment files:

1. Combined route: /share/proof-of-payment/combined/[id]/
   - Downloads location-level proof of payment for all utilities
   - Queries utilBillsProofOfPayment from location
   - Optimized projection for efficient data transfer

2. Per-bill route: /share/proof-of-payment/per-bill/[id]/
   - Downloads proof of payment for individual bills
   - Parses composite ID format: locationID-billID
   - Finds specific bill in location's bills array
   - Returns bill.proofOfPayment

Both routes:
- Return PDF files with proper Content-Type and headers
- Handle 404 for missing locations/bills/proofs
- Use Base64 to binary conversion for file delivery
- Include Last-Modified header for caching
- Use optimized database projections

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 13:31:39 +01:00
Knee Cola
6a86ebd747 Fix per-bill proof of payment field name and add environment config
- Updated uploadProofOfPayment to expect 'proofOfPayment' field name
  instead of 'utilBillsProofOfPayment' for semantic clarity
- Removed old not-found.tsx from deprecated route structure
- Added required environment variables for file upload validation:
  - MAX_BILL_ATTACHMENT_UPLOAD_SIZE_KB=1024
  - MAX_PROOF_OF_PAYMENT_UPLOAD_SIZE_KB=1024
- Updated package-lock.json with peer dependency metadata

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 13:16:37 +01:00
Knee Cola
aa573c68a3 Implement per-bill proof of payment and update field names
Frontend changes:
- Added ViewBillCard proof of payment upload for per-bill mode
  - Conditional rendering based on proofOfPaymentType
  - File upload with PDF validation and loading states
  - Download link to /share/proof-of-payment/per-bill/
- Updated LocationCard to use new utilBillsProofOfPayment field structure

Backend changes:
- Updated locationActions with improved file validation
  - File size validation using MAX_PROOF_OF_PAYMENT_UPLOAD_SIZE_KB
  - PDF type validation before database operations
  - Enhanced serializeAttachment with FileAttachment type
  - Updated database projections for optimized queries
- Updated monthActions to use consolidated field name
- Updated proof-of-payment download route with new field names

Data structure migration:
- Replaced utilBillsProofOfPaymentAttachment + utilBillsProofOfPaymentUploadedAt
  with single utilBillsProofOfPayment object containing uploadedAt
- Consistent use of FileAttachment type across all upload functions

Translations:
- Added upload-proof-of-payment-legend and upload-proof-of-payment-label
  to bill-edit-form section in both English and Croatian

This completes the proof of payment feature implementation for both
combined (location-level) and per-bill modes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 13:11:17 +01:00
Knee Cola
0facc9c257 Add uploadProofOfPayment and improve file validation
- Implemented uploadProofOfPayment function for per-bill proof of payment
  - Validates file size using MAX_PROOF_OF_PAYMENT_UPLOAD_SIZE_KB env variable
  - Validates PDF file type
  - Prevents duplicate uploads with existence check
  - Uses optimized database projection to minimize data transfer
  - Updates specific bill using MongoDB array filters

- Refactored file validation in updateOrAddBill
  - Moved validation before serialization for fail-fast behavior
  - Added configurable file size limit from environment variable
  - Added PDF type validation
  - Improved error messages with specific validation failures

- Updated serializeAttachment function
  - Changed return type from BillAttachment to FileAttachment
  - Added uploadedAt timestamp to attachment object
  - Removed unsafe type cast

- Code formatting improvements throughout
  - Consistent spacing and indentation
  - Better TypeScript typing

This completes the per-bill proof of payment feature implementation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 12:24:52 +01:00
Knee Cola
a25a97f68b Add conditional rendering for proof of payment in ViewLocationCard
- Show upload section only when proofOfPaymentType is "combined"
- Updated field names to use new FileAttachment structure:
  - utilBillsProofOfPaymentAttachment → utilBillsProofOfPayment
  - utilBillsProofOfPaymentUploadedAt → utilBillsProofOfPayment.uploadedAt
- Updated FormData and input field names for consistency
- Improved code formatting and spacing throughout

This enables proper handling of the three proof of payment options:
- "none": No upload section shown
- "combined": Shows single proof upload for all utilities (this change)
- "per-bill": No upload section (handled per individual bill)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 11:36:27 +01:00
Knee Cola
1c7edabcbe Refactor types to support per-bill proof of payment
- Renamed BillAttachment to FileAttachment for better generalization
- Added uploadedAt field to FileAttachment (consolidates timestamp)
- Renamed utilBillsProofOfPaymentAttachment to utilBillsProofOfPayment
- Removed separate utilBillsProofOfPaymentUploadedAt field (now in FileAttachment)
- Added rentProofOfPayment field to BillingLocation for rent-specific proof
- Added proofOfPayment field to Bill interface for per-bill attachments
- Removed unused imports (ObjectId, inter)

This refactoring enables both "combined" (location-level) and "per-bill"
proof of payment attachment strategies.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 11:30:23 +01:00
Knee Cola
dd4c92be77 Add "none" option for proof of payment type
Enhanced the proof of payment attachment feature with the following improvements:

- Renamed field from `proofOfPaymentAttachmentType` to `proofOfPaymentType` for consistency
- Added "none" option allowing users to disable proof of payment attachments
- Changed default value from "combined" to "none" for better UX
- Repositioned section in form after payment instructions (more logical flow)
- Added conditional warning when "combined" is selected without payment method
- Updated translations with emojis and improved tooltips for all options
- Backend validation and database operations updated to support new field structure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 11:19:51 +01:00
Knee Cola
2483b7bca5 locationEditForm: added proofOfPaymentAttachmentType 2025-12-07 01:29:48 +01:00
Knee Cola
81077b2ebf Merge branch 'release/2.11.0' 2025-11-29 13:16:00 +01:00
Knee Cola
4dfed827b1 Merge branch 'release/2.11.0' into develop 2025-11-29 13:16:00 +01:00
Knee Cola
9b5dd98c6c 2.11.0 2025-11-29 13:14:33 +01:00