Files
Sage/.planning/research/PITFALLS.md
Dani B bd477b0baa docs: complete project research (ecosystem analysis)
Research files synthesized:
- STACK.md: Flutter + Supabase + Riverpod recommended stack
- FEATURES.md: 7 table stakes, 6 differentiators, 7 anti-features identified
- ARCHITECTURE.md: Offline-first sync with optimistic locking, RLS multi-tenancy
- PITFALLS.md: 5 critical pitfalls (v1), 8 moderate (v1.5), 3 minor (v2+)
- SUMMARY.md: Executive synthesis with 3-phase roadmap implications

Key findings:
- Stack: Flutter + Supabase free tier + mobile_scanner + Open Food Facts
- Critical pitfalls: Barcode mismatches, timezone bugs, sync conflicts, setup complexity, notification fatigue
- Phase structure: MVP (core) → expansion (usage tracking) → differentiation (prediction + sales)
- All research grounded in ecosystem analysis (12+ competitors), official documentation, and production incidents

Confidence: HIGH
Ready for roadmap creation: YES

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-01-27 23:42:37 -05:00

40 KiB

Domain Pitfalls: Food & Household Inventory Tracking Apps

Domain: Multi-user food inventory tracking with expiration alerts and community data Researched: January 2026 Confidence: MEDIUM-HIGH (ecosystem survey completed, app-specific patterns confirmed via recent reviews and technical documentation)


Critical Pitfalls (v1 Must Address)

These mistakes cause rewrites, data loss, or app abandonment. Cannot defer.

Pitfall 1: Barcode Data Mismatches and Product Duplication

What goes wrong:

  • Scanning the same product yields different nutritional data, expiration dates, or categories on different scans
  • Duplicate products accumulate in the inventory (e.g., "Milk", "milk", "2% Milk", "Whole Milk" all registered as separate items)
  • Barcode APIs return incorrect data; users see wrong expiration dates or nutritional info pop up after scan
  • Multiple barcodes for the same product (UPC vs EAN) are treated as separate items

Why it happens:

  • Barcode databases (USDA FoodData Central, Open Food Facts, commercial APIs) have inconsistent entries, duplicates, and region-specific variants
  • Apps don't perform fuzzy matching or deduplication when adding items
  • Free barcode APIs (UPC Database, Barcode Lookup) have lower accuracy and less sanitization than paid alternatives
  • User behavior: manual entry of product names isn't normalized (capitalization, spacing, abbreviations vary)

Consequences:

  • Inventory reports become unreliable (user thinks they have 5 liters of milk, but it's split across 3 "products")
  • Expiration tracking fails (wrong product linked to wrong expiration date)
  • Multi-user conflicts spike (person A can't find the item person B added)
  • Users lose trust; many stop using the app after discovering inconsistencies

Real-world example:

  • FoodShiner and My Pantry Tracker users report that barcode scanning produces incorrect categorization (dry beans marked as refrigerated) and duplicate entries
  • NoWaste app crashes when users try bulk operations, losing all entered data

Prevention:

  1. Use a normalized product master database from day one:

    • Start with USDA FoodData Central (free, government-verified, includes barcodes)
    • Supplement with Open Food Facts (community data, barcode support) for coverage gaps
    • Cache results locally to reduce API calls and improve consistency
  2. Implement deduplication at entry time:

    • After user scans/enters product name, show "Did you mean...?" suggestions based on fuzzy string matching
    • Compare to user's existing inventory before adding new item
    • Merge duplicate items on discovery (with user confirmation)
  3. Normalize product naming:

    • Store canonical product name (from database) separately from user-given name
    • Display both on inventory view, but use canonical name for search and merging
    • Example: User enters "2% Milk", store as canonical "Milk, 2%"
  4. Validate barcode integrity:

    • Check barcode UPC/EAN check digits before API lookup
    • Log failed barcode lookups so you can investigate data quality issues
    • Reject lookups that differ wildly from expected product category
  5. Implement conflict resolution for multi-barcode products:

    • If scan returns multiple product candidates, show user the one closest to their search context
    • Store all barcode→product mappings (one product can have many barcodes)

Phase mapping:

  • v1 (MVP): Fuzzy matching + deduplication + normalized naming (required for data integrity)
  • v1.5: Better barcode database selection and caching strategy
  • v2: Machine learning to auto-merge suspicious duplicates

Detection (warning signs):

  • Users report "I added milk three times and the app has three separate milk items"
  • Expiration reports have items that don't match actual inventory counts
  • Search results return multiple hits for clearly the same product

Pitfall 2: Timezone and Expiration Date Logic Bugs

What goes wrong:

  • User sets "expires Jan 1, 2026" for milk, but app shows it as expired Dec 31, 2025 in another timezone
  • Items show as expired when they're not (or vice versa)
  • Multi-user households see different expiration dates depending on device timezone
  • Off-by-one errors: item expires "Jan 1" but app shows as expired on Dec 31
  • Date formats vary by locale (MM/DD vs DD/MM) leading to misinterpretation (1/2 = Jan 2 or Feb 1?)

Why it happens:

  • Date fields stored without timezone info (just "2026-01-15" with no UTC offset)
  • Comparing local device time against server time in different zones
  • Confusion between "date of expiration" vs "expiration timestamp" (e.g., "2026-01-15 00:00:00 in Tokyo" vs "2026-01-15 23:59:59 in New York")
  • Frontend/backend timezone mismatches
  • Legacy code that worked in one timezone but breaks in others

Consequences:

  • Expiration alerts fire early or late
  • Users can't trust alerts and disable notifications entirely
  • Multi-user households disagree on what's expired (person in NYC vs person in London)
  • Compliance issues if shared with restaurants/institutions that track food safety

Real-world example:

  • Atlassian Confluence observed license expiry discrepancies between US Central Time (UTC-6) and Australian Eastern Time (UTC+10)—same "date" was interpreted as different days
  • GitHub JWT discussions report tokens expiring unexpectedly due to auth server/resource server timezone mismatch

Prevention:

  1. Always use UTC timestamps with timezone awareness:

    • Store all dates as ISO 8601 UTC (e.g., 2026-01-15T23:59:59Z)
    • Never store "date only" without time component
    • Store user's local timezone separately if needed (e.g., "America/New_York")
  2. Clarify expiration semantics in code and UI:

    • Document: "Expires at 23:59:59 UTC on the date shown" (item is good until end of that day in UTC)
    • OR: "Expires at start of next day in user's local timezone"
    • Pick one semantic and stick to it everywhere
  3. Handle locale-specific date formats:

    • Accept user input in their locale (MM/DD or DD/MM) but convert to ISO format immediately
    • Store and transmit as ISO 8601 only
    • Display to user in their locale on the fly
  4. Test across timezones from day one:

    • Set up devices in multiple timezones or mock timezone offsets
    • Test edge cases: midnight UTC, daylight saving time transitions, leap seconds
    • Example test: Create item expiring in 5 minutes UTC, verify alerts fire consistently across all user timezones
  5. Implement a "time service" abstraction:

    • All code calls getCurrentTime() which returns current UTC moment
    • Single place to mock/override time for testing
    • Prevents scattered new Date() calls with different semantics

Phase mapping:

  • v1 (MVP): Use UTC throughout, store ISO 8601, test with multiple timezones (non-negotiable)
  • v1.5: Robust timezone conversion helpers; test DST transitions
  • v2+: Advanced features like "reminder 1 day before expiry in user's local timezone"

Detection (warning signs):

  • Expiration alerts fire at inconsistent times across devices
  • Users in different timezones report different expiration dates for same item
  • Off-by-one errors in tests ("item expires tomorrow but app says expired")

Pitfall 3: Multi-User Sync Conflicts and Race Conditions

What goes wrong:

  • Two users update inventory simultaneously (e.g., both "remove milk" at same time); one update is lost
  • Item quantity becomes inconsistent (both think they removed 1 liter, but system shows 0 liters removed)
  • Last-Write-Wins silently overwrites important changes (person A marks item as expired; person B removes it from list → person B's removal wins and item reappears)
  • Offline users have stale data; when they reconnect, their old changes conflict with newer data
  • "Ghost" deletions: one user deletes item, but another user's offline copy still exists and re-syncs it back

Why it happens:

  • Naive implementation uses timestamps only (whoever wrote last wins)
  • No optimistic locking or version tracking
  • Offline-first apps don't handle reconnection conflicts properly
  • Race condition: "check if item exists" and "decrement quantity" aren't atomic

Consequences:

  • Inventory counts become unreliable (users don't trust the app)
  • Multi-user households stop using shared features
  • Silent data loss (users think item was deleted but it reappears unexpectedly)
  • Difficult to debug; users report "weird behavior" that's hard to reproduce

Real-world example:

  • Sylius e-commerce platform documented race condition in inventory tracking: availability checked, then two orders decrement quantity simultaneously, overselling result
  • Mobile field service apps: field technician and dispatcher both edit same work order without syncing, last update wins and discards other person's changes

Prevention:

  1. Use optimistic locking with version numbers:

    • Every inventory item has a version field (e.g., version 3)
    • User sends update with version: 3
    • Server checks: if current version still 3, apply update and increment to 4
    • If version changed (someone else updated), reject with 409 Conflict and return current state
    • Client retries with new version number
  2. Make updates idempotent:

    • Updates should include operation_id (UUID)
    • Server tracks applied operation IDs; if same operation sent twice, it's a no-op
    • Prevents double-decrement if network request is retried
  3. Use CRDTs or operational transformation for offline-first:

    • For fully offline scenarios, use Conflict-free Replicated Data Types (e.g., CRDT) to merge updates automatically
    • Example: last-write-wins for quantity, but timestamps for expiry date
    • Only use LWW for data where recency truly matters
  4. Implement proper offline sync:

    • When offline, queue operations locally with operation IDs
    • When online, send all queued ops with timestamps
    • Server applies in order, detecting conflicts and notifying user if needed
    • Never silently discard updates
  5. Add audit logging:

    • Log every inventory change: who, what, when
    • Multi-user households can see "Sarah added milk at 3:15pm; John removed it at 3:16pm"
    • Helps debug conflicts and rebuilds trust

Phase mapping:

  • v1 (MVP): Optimistic locking + version numbers (required for multi-user trust)
  • v1.5: Idempotent operations; audit log
  • v2+: Full offline sync with CRDT or operational transformation

Detection (warning signs):

  • Users report items disappearing/reappearing
  • Multi-user households see different inventory counts
  • "I added milk but it's not showing up for my roommate"
  • Quantity counts don't match actual item counts

Pitfall 4: Setup Complexity Kills Adoption

What goes wrong:

  • User opens app, sees 15 fields to fill before adding first item (date purchased, quantity, unit, location, category, subcategory, notes, nutritional info, price paid, brand, barcode, expiry method...)
  • 50% of users abandon app during onboarding
  • Roommates set up the same app differently (one uses "Fridge", other uses "cold_storage"; can't share items)
  • App requires account creation, email verification before doing anything
  • Dark UX: no clear "add first item" button; users get lost in settings

Why it happens:

  • Product managers design for power users with full feature set
  • Each feature adds a required field
  • No progressive disclosure: "required" vs "optional" fields unclear
  • No guided onboarding; app assumes users know how to use it

Consequences:

  • App store reviews: "Looks promising but too complicated" (abandoned after 3 minutes)
  • Multi-user adoption fails: roommates give up trying to agree on data structure
  • Low feature adoption: users never reach the "aha moment" because they're stuck in setup

Real-world examples:

  • User research across home organization apps: "complexity was cited as a key reason customers don't engage with features"
  • My Pantry Tracker: required fields for scanning barcode, export options too many and confusing
  • KITCHENPAL and FoodShiner: users report "too many steps to add an item"

Prevention:

  1. Radically simplify MVP onboarding:

    • First item: only three fields - "name", "location", "expiry date" (optional)
    • All other fields deferred to settings or item edit screen
    • No account creation until user tries to sync with roommate
    • No email verification for v1
  2. Add progressive disclosure:

    • "Basic" mode (3 required fields) vs "Advanced" mode (enable all fields)
    • User can upgrade mid-session without friction
    • Smart defaults: if user scans barcode, offer to fill in category and nutrition (pre-filled, editable)
  3. Use smart onboarding:

    • First 3 screens: "Add your first item" walkthrough (not a settings tour)
    • Offer examples: "Here's a milk item someone else started with—you can edit it"
    • Then offer: "Add location (fridge, pantry, freezer)" with pre-set options
  4. Standardize shared fields in multi-user setup:

    • When roommate joins household, use exact same location names
    • Validate: if roommate enters "cold_storage" and you use "Fridge", warn and suggest merge
    • Provide preset location library (Fridge, Pantry, Freezer, Garage, Garden, etc.)
  5. Measure and iterate:

    • Track: % of users who add first item, time to first item, field abandonment rates
    • A/B test: 3-field vs 5-field forms
    • Survey users who abandoned: "What was confusing?"

Phase mapping:

  • v1 (MVP): 3-field MVP + simple onboarding (non-negotiable for adoption)
  • v1.5: Progressive disclosure; presets for shared fields
  • v2+: Advanced mode; user preferences

Detection (warning signs):

  • 50%+ of installs don't survive first 10 minutes
  • Users who add one item never add a second
  • "Looks good but too complicated" app store reviews

Moderate Pitfalls (v1 Should Consider, v1.5 Required)

Mistakes that cause delays, frustration, or technical debt.

Pitfall 5: Notification Fatigue and Irrelevant Alerts

What goes wrong:

  • User gets notified for every expiring item daily, then hourly as expiry approaches
  • Items show as "expires today" for 3 days (bad calendar logic or inconsistent alert rules)
  • No snooze/dismissal: once alert fires, it keeps firing
  • Alerts for items user doesn't care about (notification for baking soda expiring in 6 months)
  • Can't customize alert timing per household or per person

Why it happens:

  • Simple implementation: "if item expires in N days, notify"
  • No snooze logic; dismissed notification re-triggers
  • No ability to customize which items to alert on (temperature-sensitive vs non-perishable)
  • No "quiet hours" or quiet periods

Consequences:

  • Users disable all notifications
  • App becomes useless without notifications; users can't be nudged to use it
  • Notification fatigue leads to app uninstall

Real-world example:

  • General app research shows 46 notifications/day on average smartphone; apps with high-frequency alerts have 3-5x higher uninstall rates
  • Your Food app and NoWaste have customizable alert settings, suggesting this is a known pain point

Prevention:

  1. Implement smart alert rules:

    • Default: alert 3 days before expiry, once per day
    • User can customize: "alert me 1 day before", "alert only for perishables", "no alerts for pantry items"
    • Allow per-item overrides: "don't remind me about baking soda"
  2. Implement snooze/dismiss:

    • "Remind me in 1 day" button on alert
    • "Don't show again for this item" option
    • Dismissed alert doesn't re-trigger for 24 hours minimum
  3. Prioritize alerts:

    • High priority (expires tomorrow) vs low priority (expires in 5 days)
    • Only show high-priority in app badge; send low-priority to in-app feed only
    • User can configure priority threshold
  4. Respect quiet hours:

    • No notifications between 10pm-7am by default
    • User can change quiet hours in settings
  5. Segment by household preferences:

    • In multi-user household, let household admin set alert policy
    • Each user gets alerts for items they added or are responsible for
    • Prevent notification spam from roommate's items

Phase mapping:

  • v1 (MVP): Basic snooze + configurable alert timing (single alert rule)
  • v1.5: Per-item customization + priority levels + quiet hours
  • v2+: ML-based alert timing based on usage patterns

Detection (warning signs):

  • Users disable notifications
  • "Too many alerts" app store reviews
  • Uninstall correlates with notification frequency

Pitfall 6: Offline Sync Data Loss and Stale Data

What goes wrong:

  • User is offline, adds 5 items; when they reconnect, all 5 items vanish (network error during sync)
  • User is offline, deletes item; when online, item reappears (server state was newer)
  • User adds item while offline, roommate adds same item while online; duplicates appear after sync
  • App shows stale data after coming back online ("out of milk" even though you just added 3 liters)
  • No indication that data is stale; user relies on outdated info

Why it happens:

  • Offline queue not persisted to disk (data loss on app crash)
  • No retry mechanism or operation tracking
  • Naive "sync latest version" without conflict resolution
  • No UI indicator that data is syncing or is stale

Consequences:

  • Users lose trust (work they did while offline vanishes)
  • Multi-user households see inconsistent views
  • Silent data loss makes app unusable in areas with poor connectivity

Real-world example:

  • Field service apps report that 30% of conflicts occur during simultaneous updates; nearly 30% of businesses experience sync discrepancies
  • Offline-first apps using Last-Write-Wins can lose important updates without user knowing

Prevention:

  1. Persist offline queue to disk:

    • Every operation (add/remove/update) stored locally with operation ID before sending
    • If app crashes, queue survives
    • When online, retry unsent operations
  2. Implement operation-based sync (not state-based):

    • Instead of "send current item state", send "operation: remove 1 liter of milk at 3:15pm"
    • Server can apply operation in order, detect conflicts, and notify user
    • Prevents loss of concurrent updates
  3. Add retry mechanism with exponential backoff:

    • Failed operations retry every 5s, then 30s, then 5m
    • User can manually retry
    • Log failed operations so they're not dropped silently
  4. Show sync status to user:

    • "Syncing..." indicator when operations are pending
    • "Offline" badge when no connection
    • "Out of sync" warning if local data is stale (older than 1 hour)
    • Allow manual "refresh" to force sync
  5. Handle merge conflicts gracefully:

    • If offline and online changes conflict, show user both versions
    • "You added milk while offline; server shows you removed milk. Which is correct?"
    • Don't silently discard either version

Phase mapping:

  • v1 (MVP): Persistent offline queue + operation IDs + sync status indicator
  • v1.5: Retry mechanism; manual refresh; out-of-sync warning
  • v2+: Advanced conflict resolution UI

Detection (warning signs):

  • Users report "I added items while offline and they disappeared"
  • Multi-user households see different inventory views
  • Sync errors don't surface to user (silent data loss)

Pitfall 7: Bad Search and Item Lookup UX

What goes wrong:

  • User searches "milk" and gets 15 results: "Milk", "milk", "2% Milk", "Whole Milk", "Skim Milk", "Almond Milk", "Oat Milk"...
  • Can't find item despite it being in inventory (search is case-sensitive, needs exact spelling)
  • Search is slow (scanning through 500+ items takes 2+ seconds)
  • Autocomplete suggests irrelevant items ("mi" brings up "Minimum" instead of "Milk")
  • Barcode scanner results in wrong product (scanned a book, got a food item by accident)

Why it happens:

  • Simple linear search without indexing
  • Case-sensitive exact matching
  • No fuzzy matching or phonetic matching
  • No search analytics to improve relevance
  • Conflates "product name" with "brand name" with "user-entered notes"

Consequences:

  • Users add duplicate items because they can't find the original
  • Inventory reports are unreliable (user thinks they have 2 liters, but it's split across "Milk" and "milk")
  • Multi-user households can't collaborate (can't find each other's items)

Prevention:

  1. Use full-text search with stemming:

    • "2% Milk" should match "milk", "Milk", "2 percent", "two percent"
    • Use FTS (SQLite FTS5, PostgreSQL full-text search) with morphological analysis
    • Index on canonical product name + user-given name
  2. Implement fuzzy matching:

    • Typos: "mylk" should find "milk"
    • Abbreviations: "OJ" should find "orange juice"
    • Use Levenshtein distance or similar
  3. Optimize search performance:

    • Indexes on product names
    • Autocomplete from local cache (not live search)
    • Lazy-load results; show top 5 first
  4. Smart autocomplete:

    • Show items from user's household first ("Milk" you've added before)
    • Then show database suggestions (Open Food Facts top products)
    • Rank by frequency (items user adds often appear first)
  5. Disambiguate results:

    • Show product type/category alongside name ("Milk - Dairy" vs "Milk - Plant-based")
    • Show "you have this" indicator for items already in inventory
    • Show quantity/location ("2 liters in fridge")
  6. Add search analytics:

    • Track: which items users search for most
    • If "yogurt" search returns no results but user falls back to typing, add "yogurt" to database
    • Periodically review failed searches and improve database

Phase mapping:

  • v1 (MVP): Full-text search + fuzzy matching on canonical names
  • v1.5: Smart autocomplete with user history; search analytics
  • v2+: Ranking by frequency; ML-based relevance

Detection (warning signs):

  • Users report "can't find items I know are in my inventory"
  • High duplicate rate (users add "Milk" three times)
  • Search is noticeably slow (>1 second for autocomplete)

Pitfall 8: Barcode Scanning Mismatches and Failures

What goes wrong:

  • Barcode scan returns completely wrong product (scanned milk, got yogurt)
  • Scan returns expired or discontinued product entry
  • Wrong nutritional data, wrong category, wrong location
  • Barcode scanner glitches in multi-user app (doesn't work in split-view)
  • Camera doesn't focus on barcode; scan fails repeatedly

Why it happens:

  • Barcode database quality issues (duplicates, wrong mappings, region-specific entries)
  • Using free/cheap barcode APIs with poor accuracy
  • Barcode scanner library issues (not robust to angled barcodes, low light)
  • No fallback when scan fails (forced manual entry)
  • No way to report/correct bad scan results

Consequences:

  • User scans, gets wrong product, wastes time correcting it
  • User loses faith in barcode scanning feature
  • Manual entry becomes default; barcode feature becomes dead weight

Real-world example:

  • My Pantry Tracker users report "expiration date section glitch preventing visibility and selection"
  • FoodShiner users report "barcode scanner errors when using split-view mode"
  • KITCHENPAL and Pantry Check users report scanning returns wrong product frequently

Prevention:

  1. Choose a high-quality barcode database:

    • For free: USDA FoodData Central (government-verified, includes barcodes)
    • For paid: GS1 database (official UPC/EAN registry)
    • Never rely on a single API; fallback to secondary source if primary fails
  2. Validate barcode integrity:

    • Check UPC/EAN check digit before lookup
    • Reject if check digit invalid
    • Log all failed lookups so you can investigate
  3. Use a robust barcode scanning library:

    • iOS: AVFoundation's barcode detection
    • Android: ML Kit barcode scanning (handles rotation, distortion better)
    • Test with real-world barcodes: upside-down, angled, damaged, low-light
  4. Implement fallback and manual correction:

    • If scan fails, offer manual entry immediately
    • If scan returns product, allow user to "report wrong product" before saving
    • Store corrections in local database; future scans of that barcode are corrected
    • Example: "Scan returned milk, but you corrected it to yogurt? Save this for future scans of this barcode."
  5. Allow user-reported corrections to feed back to database:

    • Crowdsourced corrections (with moderation) improve database over time
    • After N users report correction, flag for admin review
    • For v1, keep crowd data separate from official database
  6. Show what was scanned:

    • "Scanned: [barcode number]" in UI
    • User can verify: "Did I scan what I thought?"
    • Makes it clear if user mispresented barcode

Phase mapping:

  • v1 (MVP): Use robust scanning library + validate check digits + fallback to manual entry
  • v1.5: User correction UI; local correction database
  • v2+: Crowdsourced corrections; secondary barcode API fallback

Detection (warning signs):

  • Users report "scanned item is completely wrong"
  • Barcode scanning feature has low usage (users default to manual entry)
  • Support requests for "why does scan show wrong product?"

Pitfall 9: Insufficient Permission and Sharing Controls

What goes wrong:

  • Roommate deletes another person's food items without consent
  • No audit trail; can't see who ate the milk
  • Items shared with wrong permission level (guest can delete, admin can't override)
  • Family member can see all nutrition/allergy data meant to be private
  • No concept of "ownership"; unclear who is responsible for item

Why it happens:

  • Simple binary permissions (can/can't view)
  • No write vs delete distinction
  • No audit logging
  • Roles not well-defined (what's the difference between "admin" and "owner"?)

Consequences:

  • Multi-user households distrust the app; stop using shared features
  • Arguments: "Who ate the last milk?" with no way to know
  • Privacy concerns: nutrition data shared with people who shouldn't see it

Prevention:

  1. Define clear permission model:

    • Owner: can add, edit, delete items they own; can transfer ownership
    • Editor: can add, edit items; can't delete others' items
    • Viewer: can only read
    • Guest: can add items only (no edit or delete)
    • Admin: can manage permissions and delete any item (with audit log)
  2. Implement audit logging:

    • Every change logged: who, what, when
    • Visible in app: "Sarah removed milk at 3:15pm"
    • Immutable log (can't delete history)
  3. Ownership and responsibility:

    • Each item has an owner (person who added it or is responsible)
    • Owner can edit/delete freely
    • Non-owner can edit but not delete (requires owner approval or admin override)
    • Roommate deletion requires explicit confirmation: "Remove Sarah's milk?"
  4. Role-based defaults:

    • New household members default to "Editor" role
    • Can be changed to "Viewer" if trusted with less responsibility
    • New guests default to "Viewer"
  5. Privacy controls per field:

    • Nutritional info visible to owner and household admin only
    • Allergy flags visible to household only (not to guests)
    • Price paid visible to admin only (housemates don't need to know)

Phase mapping:

  • v1 (MVP): Basic permission model (Owner/Editor/Viewer) + audit log
  • v1.5: Ownership transfer; delete confirmation
  • v2+: Fine-grained field-level privacy; guest roles

Detection (warning signs):

  • Multi-user households report "someone deleted my items"
  • Conflict: "I didn't delete that" with no audit trail to prove it
  • Users prefer separate accounts over shared household (breaks feature adoption)

Issues that cause annoyance but can be worked around or deferred.

Pitfall 10: API Cost Surprises and Vendor Lock-In

What goes wrong:

  • Nutrition API charges $0.001 per user; at 10K users, costs $100/month unexpectedly
  • Free barcode tier limited to 1,000 lookups/day; app hits limit at 2pm daily
  • Switching barcode APIs requires rewriting scanner integration

Why it happens:

  • Paid APIs have hidden volume limits on "free" tier
  • Per-user or per-API-call pricing scales unexpectedly with user growth
  • Using closed proprietary APIs with no fallback

Prevention:

  1. Use only free APIs in MVP:

    • USDA FoodData Central (free, unlimited, no key required)
    • Open Food Facts (free, community-sourced, barcode support)
    • Google Cloud Vision (free tier: 1,000 requests/month; paid after)
    • No paid tier dependencies in v1
  2. Plan for self-hosted fallbacks:

    • Can you cache USDA data locally?
    • Can you run barcode scanning on-device without API?
    • Design API dependency as pluggable (today USDA, tomorrow custom)
  3. Monitor API usage:

    • Log all API calls with user context
    • Alert when approaching rate limits
    • Weekly cost estimate (if paid API is used)
  4. Defer to v2:

    • Commercial API integrations (better data quality)
    • Advanced features like image recognition
    • In v1, use free/open alternatives only

Phase mapping:

  • v1 (MVP): Free APIs only; estimate future costs
  • v1.5: Implement caching to reduce API calls
  • v2+: Optional paid integrations; no required paid dependencies

Detection (warning signs):

  • API bill is growing faster than user base
  • Free tier hit during testing; unexpected charges in production

Pitfall 11: Poor Search Performance and Battery Drain

What goes wrong:

  • Item search takes 2+ seconds to return results (app is searching every item linearly)
  • App battery drains 10% per hour (full-text search indexes aren't optimized)
  • On older phones, autocomplete feels sluggish
  • Barcode scanning drains battery (constant camera polling)

Why it happens:

  • No indexing or caching of search results
  • Syncing happens too frequently (every 10 seconds instead of every 60 seconds)
  • Camera-based features not optimized for low-power modes
  • Large result sets loaded into memory at once

Prevention:

  1. Index aggressively:

    • SQLite FTS5 or similar on product names
    • Cache autocomplete results locally
    • Pre-compute common searches
  2. Optimize syncing:

    • Batch updates: sync every 60 seconds, not every change
    • Only sync if there are pending changes
    • Respect device low-power mode (disable non-essential syncs)
  3. Optimize camera and connectivity:

    • Camera polling only when scanning (not always-on)
    • Disable background updates in low-signal areas (don't drain battery searching for network)
    • Use WorkManager (Android) or BackgroundTasks (iOS) to schedule updates during charging
  4. Profile and test:

    • Benchmark search latency on low-end devices
    • Measure battery impact of syncing, searching, camera
    • Set performance targets: search <500ms, sync <10% battery/hour

Phase mapping:

  • v1 (MVP): Basic indexing and caching
  • v1.5: Battery profiling; sync optimization
  • v2+: Advanced performance tuning; background task optimization

Detection (warning signs):

  • Search takes >1 second
  • App uses >20% battery in 1 hour of usage
  • Autocomplete is noticeably slow on older phones

Pitfall 12: AI Purchase Prediction Overfitting and False Positives

What goes wrong:

  • ML model trained on single user's data makes terrible predictions for another user
  • Model predicts you'll buy milk weekly because you did so for 3 months; then predicts forever even after you stop
  • Predictions clog the shopping list (10 irrelevant items for 1 relevant)
  • Model doesn't account for seasonality (Christmas cookies predicted year-round)

Why it happens:

  • Small sample size per user (N=30 purchase events) leads to overfitting
  • Training data becomes stale (model doesn't account for changing habits)
  • No concept of "recency" (old data weighted equally with recent data)

Consequences:

  • Users turn off predictions; feature goes unused
  • Cluttered shopping list is worse than no predictions

Prevention:

  1. Start simple; add ML only if needed:

    • v1: Manual shopping list only
    • v1.5: Suggest items from user's past purchases (heuristic, not ML)
    • v2+: ML predictions only if you have 500+ prediction-worthy items per user
  2. Use simple heuristics instead of complex ML:

    • "Items purchased in last 6 months" → suggest them again
    • "Items purchased on Mondays" → suggest on Sunday
    • No model needed; explainable and less prone to overfitting
  3. If using ML, use robust techniques:

    • K-fold cross-validation to detect overfitting
    • Regularization to prefer simpler models
    • Use recency weighting (recent purchases > old purchases)
  4. Account for data drift:

    • Retrain model monthly (not once and forget)
    • Monitor: are predictions accurate for recent purchases? If not, retrain
    • Use Population Stability Index to detect when model is stale
  5. Limit prediction spam:

    • Show top 3 predicted items, not all 20
    • Require user confirmation before adding predicted item to shopping list
    • "Do you want to add milk?" instead of automatically adding it
  6. Make predictions explainable:

    • "Suggested because you buy milk every Monday"
    • "Suggested because you bought this 4 weeks ago"
    • User can provide feedback: "I don't buy this anymore" → don't suggest

Phase mapping:

  • v1 (MVP): No predictions; manual list only
  • v1.5: Simple heuristic suggestions (items from last 6 months)
  • v2+: ML predictions only with strong safeguards; limited to 3-5 items

Detection (warning signs):

  • Users turn off predictions
  • Shopping list clogged with irrelevant suggestions
  • Predictions don't match actual purchasing behavior

Pitfall 13: Community Data Spam, Privacy Leaks, and Moderation Burden

What goes wrong:

  • Sales/price database polluted with spam ("BEST DEALS CLICK HERE")
  • Bad actors add thousands of fake products
  • Real user data (household names, allergies) accidentally exposed in shared databases
  • No moderation; requires hiring team to handle reports
  • Privacy: food data is personal; can infer health conditions, pregnancy, diets

Why it happens:

  • Community contributions not validated before publication
  • No identity verification (same person spamming with 100 accounts)
  • No privacy controls on shared databases
  • Moderation not built in from day one; becomes firefighting later

Consequences:

  • Community data becomes unusable (too much spam)
  • Regulatory risk (GDPR, health privacy violations if personal data exposed)
  • Cost scaling issue (need moderation team as user base grows)

Prevention:

  1. Don't build community features in v1:

    • v1: App-only, no community sales database
    • v1.5: Internal sales database curated by team only
    • v2+: Consider community contributions with strong safeguards
  2. If you build community features:

    • Require user identity verification (not anonymous)
    • Karma/reputation system (new users' contributions require approval)
    • Report and flag system; flagged items quarantined
    • Automatic spam detection (duplicate entries, suspicious patterns)
  3. Privacy controls:

    • Never share household names or personal health data
    • Only share product names and prices
    • User can opt-out of price/sales sharing entirely
  4. Moderation scalability:

    • Build moderation UI from day one
    • Automated filters catch 90% of spam before human review
    • Community mods (trusted users) can review and approve
    • Clear escalation path if needed

Phase mapping:

  • v1 (MVP): No community features; internal database only
  • v1.5: Internal sales database; team-curated only
  • v2+: Community features with identity verification and moderation

Detection (warning signs):

  • Community data has spam
  • Privacy concerns from users
  • Moderation requiring full-time team member

Phase-Specific Recommendations

For v1 MVP (Must Handle)

Focus on these pitfalls to launch with:

  1. Barcode Data Mismatches → Fuzzy matching + deduplication
  2. Timezone/Expiration Bugs → UTC timestamps from day one
  3. Multi-User Sync → Optimistic locking + version numbers
  4. Setup Complexity → 3-field MVP onboarding
  5. Notification Fatigue → Snooze button + configurable timing

These five are non-negotiable. If you skip them, app won't be usable in multi-user households.

For v1.5 (Stabilization)

After MVP feedback, address:

  • Offline sync with persistent queue
  • Barcode scanner fallback and correction UI
  • Better permission model with audit logging
  • Permission model with audit logs
  • Improved search performance and UX
  • Advanced alert customization

For v2+ (Growth Phase)

Only after v1 is stable:

  • ML-based predictions (with safeguards)
  • Community features (if privacy/moderation plan is solid)
  • Advanced permission roles
  • Performance optimization for 1M+ items

Summary: Implementation Priority Matrix

Pitfall Severity Effort Phase Notes
Barcode mismatches Critical Med v1 Kills data integrity; users abandon after discovering duplicates
Timezone bugs Critical Low v1 One-time fix; becomes tech debt otherwise
Sync conflicts Critical Med v1 Makes multi-user unusable; cascades to trust issues
Setup complexity Critical Low v1 50% onboarding dropout without it
Notification fatigue High Low v1 Users disable notifications; feature dies
Offline sync High Med v1.5 Causes data loss; impacts adoption
Search UX High Med v1.5 Drives duplicate creation; frustrates users
Barcode failures High Med v1.5 Falls back to manual entry; undermines scanner value
Permissions High Med v1.5 Required for multi-user trust
API costs Medium Low v2 Can defer but plan for it
Performance Medium Low v1.5 Impacts older devices; battery drain
AI predictions Low High v2 Nice-to-have; don't build until v1 stable
Community spam Low Med v2 Defer; address when you have users to moderate

Sources