Changelog
All notable changes to the Kebab project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.16.1] - 2026-04-18 - Build Infrastructure Maintenance
No user-facing changes. This release exercises the new build-server infrastructure end-to-end and bundles accumulated CI, documentation, and dependency updates.
Technical
- Improved build workflow documentation
- Cleaned up post-migration documentation
- Added automated dependency updates
- Updated GitHub Actions dependencies
- Added test fixtures for import regression coverage
- First build and release produced on the new multi-host build infrastructure
[1.16.0] - 2026-04-10 - Import UX Overhaul and Edit Enhancements
Added
- Post-import action prompt - After importing items from a photo, a clear action sheet offers "Import Another Photo" or "Return to Ledger" instead of a plain success alert. Reduces friction for users processing multiple pages.
- Inline valuation editing during import - A new review phase after FMV auto-lookup lets users adjust any valuation amount before items are committed to the ledger. No more navigating away to fix a wrong value.
- Re-evaluate button on description edit - When an item description is changed in the edit view, a "Re-evaluate Value" button appears to re-run FMV lookup on the corrected text.
- Per-item date editing in groups - Individual items within a group can now have their date changed. A confirmation dialog explains the item will move to a different group, and the move happens atomically.
- Receipt photo attachment in edit view - Receipt photos can now be added, viewed, and deleted directly from the group edit screen via the existing receipt strip component.
- Grouped edit view defaults collapsed - Multi-item donation groups now start collapsed for easier scanning, with expand/collapse per item.
- Scroll-to-item in edit view - After adding a new item, the list auto-scrolls to the newly added row.
- Undo delete with configurable delay - Deleting an item shows a toast with an undo option, with a configurable delay before permanent deletion.
Fixed
- Ghost items in group edit view - Edit screen now loads all donations in a date+org group, not just the first. Items from multi-donation groups no longer appear missing.
- Year selector sync between tabs - Home and Reports tabs now share the selected year, preventing stale data after switching tabs.
- OCR date extraction from handwritten lists - Strengthened the vision prompt to actively search for dates anywhere on the page (top, bottom, margins). Added strict date validation rejecting impossible calendar dates.
- Implausible OCR quantities flagged - Quantities over 20 from OCR are now flagged for review, catching common misreads.
- Implausible OCR dates flagged - Dates outside the IRS amended-return window (3 years back to end of current year) are flagged instead of silently accepted.
- CSV error marker compatibility - Replaced the info marker character for better terminal rendering.
- Per-item date picker hidden for new items - Unsaved items no longer show a per-item date picker that would silently drop the change on save.
- Empty donations cleaned up after date-moves - Source donations left with zero items after per-item date moves are now automatically deleted.
- FMV review override errors surfaced - If value overrides fail to save during the import review phase, users now see a warning alert instead of silent failure.
Changed
- Reactive 429 re-validation - Rate-limited FMV requests now trigger background re-validation when the app returns to foreground, recovering stale items without user intervention.
- App Store title updated - Changed from "Kebab - The Donor App" to "Kebab Tax" for better discoverability.
Technical
- CI workflows consolidated to eliminate redundant runners
- Design and implementation plans added for ghost items, OCR validation, and edit enhancements
- Feature graphic replaced in store listing
[1.15.4] - 2026-04-07 - Import UX Fixes and Tier Accuracy
Fixed
- Quantity input no longer appends to default value - Tapping a quantity field after photo import now selects the text, so typing "5" replaces "1" instead of producing "15". Fix applies to both the import review screen and donation ledger editing.
- Custom date range honored on photo import - When a custom date range is selected before importing a photo, imported items now inherit that date instead of defaulting to today.
- "Unlimited AI valuations" copy corrected - Premium tier copy updated from "unlimited" to "up to 200 AI valuations per day" across App Store listings, in-app UI, and documentation. The annual quota remains genuinely unlimited.
Technical
- Tier enforcement test suite added as a release gate - 100 tests covering rate limits and tier boundary conditions
- Test pipeline stratification defined - Four layers documented with a new release gate workflow
[1.15.3] - 2026-04-06 - Import Reliability and Premium Stability
Added
- Intelligent CSV column mapping - CSV import now auto-detects and maps columns regardless of header naming, making imports from third-party tools more reliable.
Fixed
- Premium tier no longer lost on timeout - Premium subscribers could intermittently see free-tier rate limits when subscription service initialization timed out or encountered a store error. Cache fallback now triggers on all transient failures, not just network errors.
- CSV import accepts ISO 8601 dates - Dates in
YYYY-MM-DDformat (common from spreadsheets and bank exports) are now parsed correctly instead of silently failing every row. - CSV import handles filenames with spaces - Files with spaces in their name no longer cause a silent read failure on iOS.
- CSV import handles non-UTF-8 files - Files with Windows-1252 encoded characters (e.g. accented characters) no longer fail to read on iOS. Falls back to Latin-1 decoding when UTF-8 is rejected.
Technical
- CI: label-audit timeout increased for large repos
- CI: validate workflow installs deps before checks
- CI: night-shift branches excluded from push-triggered CI
[1.15.2] - 2026-03-30 - Quality of Life Improvements
Added
- Multi-device sync tip - Import/export screen now includes a hint explaining how to sync donations across devices using export and import.
Changed
- Photo upload button more prominent - Solid border, light background, and larger label make the add-receipt button easier to discover and tap.
- Donation summary shows item count - HomeScreen now displays "X donations (Y items)" so users with multi-item donations see a meaningful count.
Fixed
- Scroll gradient uses layout measurement - Edit form scroll indicator no longer relies on a hardcoded height constant; uses actual layout dimensions.
- Accessibility labels on tip cards - "Add Your First Donation" and "Keep Your Receipts" tip cards now have proper screen reader labels.
- Health check hardened - Moved to shared build-preflight, HTTP 4xx no longer treated as healthy, CI contexts auto-continue with warning.
- Staging profile allowlist dynamic - Reads allowed staging profiles from configuration instead of a hardcoded array.
[1.15.1] - 2026-03-30 - Subscription Sync and Import Fixes
Fixed
- Handwritten import tier mismatch race condition - When a new subscriber attempted handwritten list import, the server-side subscription check could fail for hours because the client reused a stale tier value. Now silently restores purchases, reads fresh tier from the App Store receipt, bails immediately if genuinely on free tier, and retries up to 3 times with exponential backoff.
- Batch FMV processing no longer errors on blank item names - Items with empty or whitespace-only names are now added directly to the unresolved items list instead of sending an invalid API request.
- Batch edit stale closure race condition - Rapidly removing the last two items from a batch edit could leave an orphaned zero-item donation due to a stale closure reading outdated state. Fixed with improved state management.
Changed
- Batch edit long-press is now limited to donations with 2+ items - Single-item donations use the single-item edit flow, avoiding confusion.
Technical
- Night shift tech debt: accessibility labels on tip cards, test race condition fix
- Added validation gate for night-shift type-checking
- CI: night-shift workflow with label audit and tech-debt automation
- Build tooling now supports separate reviewer notes
[1.15.0] - 2026-03-21 - Premium Rate Limit Fix
Fixed
- Premium subscribers no longer rate-limited to free-tier cap - All three AI endpoints now resolve the subscription tier correctly before rate limiting. Previously, the rate limiter defaulted every user to the free-tier cap of 50 requests/day.
- Rate-limit error dialog no longer shows upgrade CTA to premium users - The "Upgrade to PREMIUM" suggestion and button are now hidden for users who already have a premium subscription, using the local subscription state as source of truth.
- Subscription tier validator warns on unrecognized tier - Previously failed silently when encountering an unexpected tier value.
- iOS modal settle delay no longer runs on Android - The handwritten import modal dismiss delay is now guarded behind a platform check.
- Scoped item-name-input testID to new items only - Prevents test selector collisions when editing existing items.
Changed
- Extracted constant for modal dismiss timing
Technical
- Removed stale item-quota TODO and fixed documentation to remove references to a 20-item FREE tier limit
- Added regression test for error detection
- Night shift tech debt: 4 fixes across two batches
- Updated release process docs: strengthened gate for draft confirmation
- Fixed vacuous test
[1.14.1] - 2026-03-17 - Bug Fixes
Fixed
- Handwriting scan date inheritance - When scanning multiple pages of the same historical donation list, the date from the first successful scan now pre-fills subsequent scans instead of defaulting to today. Reduces manual date entry for multi-page scans.
- Stale donation total after batch edit - Editing a batch that mixes updated existing items with new items now always recalculates the donation total correctly. Previously the total could remain stale if both update paths ran together.
Technical
- Added unit test coverage for save path
- Fixed a vacuous regression test for the 40-second handwriting timeout boundary
- Closed post-trial entitlement sync race issue
[1.14.0] - 2026-03-12 - Batch Editing and Duplicate Detection
Added
- Batch editing - Edit saved multi-item donation batches directly: change the organization, date, notes, add new items, or remove existing ones. Multi-item donations in the ledger now open a dedicated edit screen; single-item donations retain the existing inline modal.
- Duplicate detection - New "Check for Duplicate Donations" screen in Settings scans all records and surfaces likely duplicates grouped by organization, date, and amount. Tap to delete a duplicate or keep both entries.
- Import duplicate warning - The CSV import preview now shows a duplicate count and warning banner when imported records overlap existing data.
- Getting Started tips - New "Add Donations" tip card explains how to use the green button (tap for cash, hold to choose a donation type). New users now see an explicit "Add Your First Donation" step. "Keep Your Receipts" tip now mentions that receipts can be attached directly to each donation.
- Batch edit discovery hint - After saving a multi-item donation batch, an info toast appears explaining how to edit it later: long-press the entry in Reports.
[1.13.1] - 2026-03-12 - TXF Export Fix
Fixed
- TXF export: noncash item donations now import correctly in TurboTax Desktop - All item donations now use the correct TXF reference number (Schedule A Line 17). Previously, donations were incorrectly tagged for amounts over $500 and under $500.
- Subscription activation after purchase - Fixed a race condition where entitlements sometimes did not activate immediately after purchase, requiring the user to restart the app.
- Rate app button - The "Rate Kebab" button in Settings now opens directly to the App Store/Play Store rating page instead of the app's main store listing.
Technical
- Build tooling: Android changelog now uploaded in metadata lane
- Tech debt: safety improvements, staging allowlist, telemetry
- Tech debt: stale documentation, unused import, planning doc clarification
[1.13.0] - 2026-03-10 - Receipt Photos
Added
- Receipt photo attachment - Attach photos of receipts to any cash or item donation. Up to 5 photos per donation. Photos are stored locally on device.
- Receipt photos on all plans - Receipt photo attachment is available to all users (not a premium feature).
Fixed
- Item edit: notes field - Notes field is now available when editing an item donation. A scroll indicator appears when the edit form extends below the visible area.
- Edit modal: clearing notes/purpose - Emptying the notes or purpose field in an edit modal now correctly saves the cleared value to the database instead of silently preserving the old value.
- Item donation ID parsing - Replaced fragile string splitting with regex parsing for item donation IDs, preventing edge-case misidentification.
- Build: dependency preflight - Build scripts now auto-install dependencies when needed, preventing silent exit failures.
Technical
- Extracted hook for shared pending receipt state management across Cash and Items screens
- Removed dead function
- Fixed gradient flash on short edit forms; scroll gradient now initializes hidden and appears only when content overflows
- Updated schema version comment to reference receipts table
- Updated release process runbook with correct commands for staging/production builds and metadata
[1.12.3] - 2026-03-06 - Maintenance
Fixed
- TXF export: two-file retry message - When a two-file TXF export's Part 2 share fails after Part 1 succeeds, the error now prompts to "re-export both files" rather than the previous vague "retry," reflecting that both files must be re-exported together.
Security
- Subscription tier cross-validation - The FMV valuation endpoints now cross-validate the client-supplied subscription tier against authentication, closing a potential spoofing vector where a free-tier user could claim premium access.
Technical
- TXF refactoring - Removed dead parameter; 4,000-record limit error now derived from constant with locale-safe formatting.
- Staging builds - Staging builds now fire iOS and Android builds in parallel, reducing staging round-trip time.
- Test coverage - Added auto-selection tests, disambiguation tests, fixed navigation, updated tests for accordion org picker.
[1.12.2] - 2026-03-06 - TXF Export Fix & Import Improvements
Fixed
- TXF Export: TurboTax Desktop import now works - The TXF file used an incorrect header format, causing TurboTax Desktop to reject it with "This import was unsuccessful." Exports now use the correct format and have been verified working in TurboTax Desktop for Mac.
- iPad Pro: "Enjoying Kebab?" modal oversized text - The review prompt modal scaled text using the full screen width (~1024px on iPad), producing oversized title text. Now scales relative to the modal's capped width.
- ItsDeductible import: M/D/YY date format - Imports from ItsDeductible with dates in
M/D/YYformat now parse correctly; previously they failed silently. Four-digit year format is also supported. - ItsDeductible import: Combined Report detection - Importing a Combined Report into the Items import flow now shows a clear, actionable error explaining how to export from ItsDeductible instead of a confusing column-mismatch error.
- TXF export: Android back button hangs spinner - Pressing the hardware back button on the two-file export warning dialog no longer leaves the loading spinner stuck permanently.
- TXF export: 4,000+ record limit - Exports exceeding 4,000 total records now show a descriptive error directing the user to filter by date range, instead of silently dropping records beyond the limit.
- TXF export: Part 2 failure message - When a two-file export's Part 2 share fails after Part 1 succeeds, the error now correctly identifies Part 2 as the failure.
- Review prompt: TestFlight and all-time count - The "Rate Kebab" button and in-app review prompt now fall back to the App Store URL when the native dialog is unavailable. The review trigger now uses all-time donation count instead of current-year count, so users with 10+ lifetime donations from prior years are correctly prompted.
[1.12.0] - 2026-03-02 - TurboTax Desktop Export
Added
- TurboTax Desktop Export - New TXF export lets users export their donations directly into TurboTax Desktop (File > Import > From TXF Files). Available on Standard and Premium plans. Exports split automatically into two files when donations exceed the 2,000-record TXF limit, with a pre-share alert explaining the two-file workflow.
Fixed
- Handwritten Import Reliability - Handwritten list imports now automatically retry on API overload responses with exponential backoff, reducing import failures during peak usage.
- TXF Field Sanitization - Newline characters embedded in donation data (org names, item names, etc.) are now stripped before TXF output, preventing malformed records that would fail to import.
- TXF Overflow Cap - Overflow TXF file (for exports exceeding 2,000 records) is now correctly capped at 2,000 records; previously the overflow file could exceed the limit when mileage donations were present.
Technical
- Deployment Tooling - Fixed deployment script compatibility with current CLI tooling.
Older entries (v1.11.2 and earlier) are in CHANGELOG-archive.md.