{"id":2313,"date":"2026-03-17T08:40:11","date_gmt":"2026-03-17T06:40:11","guid":{"rendered":"https:\/\/commerce-consulting-services.com\/en\/?post_type=project&#038;p=2313"},"modified":"2026-03-24T14:57:30","modified_gmt":"2026-03-24T12:57:30","slug":"smart-packing-list-cross-platform-mobile-app","status":"publish","type":"project","link":"https:\/\/commerce-consulting-services.com\/lv\/project\/smart-packing-list-cross-platform-mobile-app\/","title":{"rendered":"From Idea to App Store: Building a Cross-Platform Packing List App"},"content":{"rendered":"\n[et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Hero&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;8363d3a1-7f13-4aae-8984-26124f93e21c&#8221; background_color_gradient_stops=&#8221;#1d3557 80%|#ffffff 80%&#8221; bottom_divider_style=&#8221;waves2&#8243; bottom_divider_color=&#8221;#FFFFFF&#8221; box_shadow_style=&#8221;preset7&#8243; box_shadow_horizontal=&#8221;0px&#8221; box_shadow_vertical=&#8221;-10vw&#8221; box_shadow_color=&#8221;#FFFFFF&#8221; locked=&#8221;off&#8221; collapsed=&#8221;on&#8221; global_colors_info=&#8221;{%22gcid-36fd78a7-34bc-404d-873c-dafa34efaae5%22:%91%22colorEnd%22%93}&#8221;][et_pb_row _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;5138c454-be54-4233-bd3b-f8e6a8747976&#8243; max_width=&#8221;800px&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;73121f80-a3ef-4484-8763-c3f18e3c56d2&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;From Idea to App Store: Building a Cross-Platform Packing List App&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;ddeb8c09-9078-4424-bc15-2efb6572e28e&#8221; title_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; title_text_align=&#8221;center&#8221; title_text_color=&#8221;#FFFFFF&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_heading][et_pb_text _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;0504de1e-f5ff-4281-ba60-cbbe4edf98bc&#8221; text_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; quote_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_2_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_3_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_4_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_5_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_6_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; text_orientation=&#8221;center&#8221; hover_enabled=&#8221;0&#8243; locked=&#8221;off&#8221; sticky_enabled=&#8221;0&#8243;]<p><span style=\"color: #000000;\">Discover how we designed, built, and launched a production-grade mobile app from scratch, covering product strategy, offline-first architecture, multi-platform deployment, subscription monetization, and localization into 36 languages.<\/span><\/p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Text&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; background_color=&#8221;#000000&#8243; locked=&#8221;off&#8221; collapsed=&#8221;on&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;5138c454-be54-4233-bd3b-f8e6a8747976&#8243; custom_padding=&#8221;||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16.1&#8243; _module_preset=&#8221;73121f80-a3ef-4484-8763-c3f18e3c56d2&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;Project Overview&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;f0c675ea-2574-4d0e-b725-30f8550a8550&#8243; title_level=&#8221;h4&#8243; title_font=&#8221;IBM Plex Sans|IBM Plex Sans Condensed_weight||on|||||&#8221; title_text_color=&#8221;#457b9d&#8221; title_font_size=&#8221;14px&#8221; title_letter_spacing=&#8221;1px&#8221; title_line_height=&#8221;1.4em&#8221; custom_margin=&#8221;||10px||false|false&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{%22#457b9d%22:%91%22title_text_color%22%93}&#8221;][\/et_pb_heading][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16.1&#8243; _module_preset=&#8221;73121f80-a3ef-4484-8763-c3f18e3c56d2&#8243; global_colors_info=&#8221;{}&#8221;][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;5138c454-be54-4233-bd3b-f8e6a8747976&#8243; custom_padding=&#8221;0px|||||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16.1&#8243; _module_preset=&#8221;73121f80-a3ef-4484-8763-c3f18e3c56d2&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;A Solo Full-Stack Product: Concept to App Store&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;ba4a6336-701f-47b8-bf5c-09da0ce28016&#8243; title_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; title_text_color=&#8221;#FFFFFF&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_heading][et_pb_button button_url=&#8221;#intro&#8221; button_text=&#8221;Learn More&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;1bffc0fc-42a0-49d1-bd9a-ae3ade2d7206&#8243; button_bg_color=&#8221;#1d3557&#8243; button_font=&#8221;IBM Plex Sans|700|||||||&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_button][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16.1&#8243; _module_preset=&#8221;73121f80-a3ef-4484-8763-c3f18e3c56d2&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;0504de1e-f5ff-4281-ba60-cbbe4edf98bc&#8221; text_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; quote_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_2_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_3_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_4_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_5_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_6_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; locked=&#8221;off&#8221;]<p>Smart Packing List is a cross-platform mobile and web application that helps travelers organize their packing with reusable lists, hierarchical categories, and real-time cloud sync across devices. It works completely offline and syncs seamlessly when connectivity returns.<\/p>\n<p>What sets this project apart from our typical consulting engagements is scope: this was a complete product built from the ground up. Every decision, from database schema to App Store pricing, was ours to make. The result is a production app available on iOS, Android, and the web, serving real users today.<\/p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Project&#8221; module_id=&#8221;intro&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; collapsed=&#8221;on&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;Mobile App Development&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;f0c675ea-2574-4d0e-b725-30f8550a8550&#8243; title_level=&#8221;h4&#8243; title_font=&#8221;IBM Plex Sans|IBM Plex Sans Condensed_weight||on|||||&#8221; title_text_color=&#8221;#1d3557&#8243; title_font_size=&#8221;14px&#8221; title_letter_spacing=&#8221;1px&#8221; title_line_height=&#8221;1.4em&#8221; custom_margin=&#8221;||10px||false|false&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{%22#1d3557%22:%91%22title_text_color%22%93}&#8221;][\/et_pb_heading][et_pb_heading title=&#8221;What Makes This Project Unique&#8221; module_class=&#8221;ai_ignore_all&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;ba4a6336-701f-47b8-bf5c-09da0ce28016&#8243; title_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_heading][et_pb_text quote_border_color=&#8221;#457b9d&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;2c55a9c4-feed-423b-9edb-ae0b5b365cac&#8221; text_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; link_font=&#8221;|IBM Plex Sans_weight|||||||&#8221; link_text_color=&#8221;#1d3557&#8243; quote_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_2_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_3_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_4_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_5_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_6_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;]<p>Unlike a typical consulting engagement where scope is defined by a client, this project required wearing every hat simultaneously:<\/p>\n<ul>\n<li><strong>Product Manager<\/strong> &#8211; Defined the feature roadmap, prioritized MVP scope, made pricing decisions<\/li>\n<li><strong>UX Designer<\/strong> &#8211; Created user flows, designed the category hierarchy system, built progressive disclosure patterns<\/li>\n<li><strong>Full-Stack Developer<\/strong> &#8211; Wrote every line of frontend, backend, and infrastructure code<\/li>\n<li><strong>DevOps Engineer<\/strong> &#8211; Set up CI\/CD, managed Supabase environments (dev\/prod), configured Edge Functions<\/li>\n<li><strong>Release Manager<\/strong> &#8211; Navigated Apple App Store and Google Play submission processes, handled compliance requirements<\/li>\n<\/ul>\n<p>This breadth demonstrates not just coding ability, but the capacity to own and deliver an entire product lifecycle.<\/p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Text&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;51px|||||&#8221; locked=&#8221;off&#8221; collapsed=&#8221;on&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;5138c454-be54-4233-bd3b-f8e6a8747976&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;73121f80-a3ef-4484-8763-c3f18e3c56d2&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;Challenges &#038; Objectives&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;f0c675ea-2574-4d0e-b725-30f8550a8550&#8243; title_level=&#8221;h4&#8243; title_font=&#8221;IBM Plex Sans|IBM Plex Sans Condensed_weight||on|||||&#8221; title_text_color=&#8221;#457b9d&#8221; title_font_size=&#8221;14px&#8221; title_letter_spacing=&#8221;1px&#8221; title_line_height=&#8221;1.4em&#8221; custom_margin=&#8221;||10px||false|false&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{%22#457b9d%22:%91%22title_text_color%22%93}&#8221;][\/et_pb_heading][et_pb_heading title=&#8221;Overcoming Obstacles&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;c33f07d9-41e0-421a-8799-5799df695cce&#8221; title_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; title_text_color=&#8221;#0e0c19&#8243; locked=&#8221;off&#8221; global_colors_info=&#8221;{%22#0e0c19%22:%91%22title_text_color%22,%22title_text_color%22%93}&#8221;][\/et_pb_heading][et_pb_toggle title=&#8221;The Core Problem&#8221; open=&#8221;on&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<p>Existing packing list apps fall into two camps: oversimplified (just a checklist) or bloated with features that obscure the core task. We set out to build something in between &#8211; powerful enough to handle complex, reusable packing workflows, yet simple enough to use while rushing to catch a flight.<\/p>[\/et_pb_toggle][et_pb_toggle title=&#8221;Technical Objectives&#8221; open=&#8221;on&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<ul>\n<li><strong>Offline-first reliability<\/strong> &#8211; The app must work flawlessly with zero connectivity (airports, flights, remote areas), then sync transparently when back online<\/li>\n<li><strong>True cross-platform<\/strong> &#8211; A single codebase serving iOS, Android, and web with native look and feel on each<\/li>\n<li><strong>Subscription monetization on all platforms<\/strong> &#8211; Stripe on web, Apple IAP on iOS, Google Play Billing on Android, each with server-side receipt validation<\/li>\n<li><strong>Global reach<\/strong> &#8211; Localization into 36 languages from day one, not as an afterthought<\/li>\n<li><strong>Production quality<\/strong> &#8211; Not a side-project demo, but a real product with proper error handling, data migration, account management, and compliance (GDPR, App Store guidelines)<\/li>\n<\/ul>[\/et_pb_toggle][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;73121f80-a3ef-4484-8763-c3f18e3c56d2&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_number_counter title=&#8221;Platforms Shipped&#8221; number=&#8221;3&#8243; _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; title_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; number_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; number_text_color=&#8221;#1d3557&#8243; number_font_size=&#8221;60px&#8221; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; percent_sign=&#8221;off&#8221; sticky_enabled=&#8221;0&#8243;][\/et_pb_number_counter][et_pb_number_counter title=&#8221;Languages Supported&#8221; number=&#8221;36&#8243; _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; title_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; number_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; number_text_color=&#8221;#1d3557&#8243; number_font_size=&#8221;60px&#8221; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; percent_sign=&#8221;off&#8221; sticky_enabled=&#8221;0&#8243;][\/et_pb_number_counter][et_pb_number_counter title=&#8221;Code Sharing Across Platforms&#8221; number=&#8221;95&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; title_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; number_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; number_text_color=&#8221;#1d3557&#8243; number_font_size=&#8221;60px&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_number_counter][et_pb_number_counter title=&#8221;Payment Integrations&#8221; number=&#8221;3&#8243; _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; title_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; number_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; number_text_color=&#8221;#1d3557&#8243; number_font_size=&#8221;60px&#8221; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; percent_sign=&#8221;off&#8221; sticky_enabled=&#8221;0&#8243;][\/et_pb_number_counter][et_pb_number_counter title=&#8221;Edge Functions Deployed&#8221; number=&#8221;5&#8243; _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; title_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; number_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; number_text_color=&#8221;#1d3557&#8243; number_font_size=&#8221;60px&#8221; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; percent_sign=&#8221;off&#8221; sticky_enabled=&#8221;0&#8243;][\/et_pb_number_counter][et_pb_number_counter title=&#8221;Offline Capability&#8221; number=&#8221;100&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; title_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; number_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; number_text_color=&#8221;#1d3557&#8243; number_font_size=&#8221;60px&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_number_counter][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Solution&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; collapsed=&#8221;on&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;Solution &#038; Approach&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;ba4a6336-701f-47b8-bf5c-09da0ce28016&#8243; title_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_heading][et_pb_accordion _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_accordion_item title=&#8221;Offline-First Architecture with Real-Time Sync&#8221; open=&#8221;off&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<p>The most significant architectural decision was choosing an <strong>offline-first<\/strong> approach with <strong>PowerSync<\/strong> as the sync layer between a local SQLite database and Supabase PostgreSQL.<\/p>\n<p><strong>How it works:<\/strong><\/p>\n<ul>\n<li>Every read and write happens against the local SQLite database &#8211; instant, no network dependency<\/li>\n<li>PowerSync watches for local changes and uploads them to Supabase PostgreSQL<\/li>\n<li>Supabase changes (from other devices) flow back through PowerSync&#8217;s WebSocket connection<\/li>\n<li>Conflict resolution is handled automatically at the sync layer<\/li>\n<\/ul>\n<p>Users packing for a trip are often in transit &#8211; poor WiFi, airplane mode, spotty hotel connections. The app never shows a loading spinner for basic operations. Data just appears, and sync happens silently in the background.<\/p>[\/et_pb_accordion_item][et_pb_accordion_item title=&#8221;Database Design&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221; open=&#8221;off&#8221;]<ul>\n<li><strong>Soft deletes<\/strong> on all main entities (trips, items, categories) &#8211; preserving data integrity across sync<\/li>\n<li><strong>Many-to-many relationships<\/strong> &#8211; Items can belong to multiple categories; trips reference reusable category templates<\/li>\n<li><strong>Denormalized packing state<\/strong> &#8211; Each trip preserves item names and quantities at packing time, so editing a master item doesn&#8217;t retroactively alter a completed trip&#8217;s history<\/li>\n<li><strong>Database abstraction layer<\/strong> &#8211; A unified interface allows transparent switching between LocalDatabase (free tier, no sync) and SyncedDatabase (premium, with PowerSync)<\/li>\n<\/ul>[\/et_pb_accordion_item][et_pb_accordion_item title=&#8221;Multi-Platform Subscription Billing&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; open=&#8221;off&#8221; sticky_enabled=&#8221;0&#8243;]<p>Each platform has its own payment flow, but all converge to a single <code>user_subscriptions<\/code> table:<\/p>\n<p><strong>Web (Stripe):<\/strong> Stripe Checkout Session \u2192 webhook \u2192 Edge Function updates subscription status<\/p>\n<p><strong>iOS (Apple IAP):<\/strong> StoreKit purchase \u2192 App sends receipt to Edge Function \u2192 Apple receipt verification \u2192 Subscription updated<\/p>\n<p><strong>Android (Google Play):<\/strong> Google Play purchase \u2192 App sends token to Edge Function \u2192 Google API verification \u2192 Subscription updated<\/p>\n<p>All receipt validation happens server-side via Supabase Edge Functions. The client never self-validates a purchase, preventing tampering and ensuring a single source of truth.<\/p>[\/et_pb_accordion_item][et_pb_accordion_item title=&#8221;Capacitor: One Codebase, Native Experience&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221; open=&#8221;on&#8221;]<p>Using <strong>Capacitor 8<\/strong>, the React web app runs inside a native WebView on iOS and Android, with access to native plugins for:<\/p>\n<ul>\n<li>Apple Sign-In and Google Sign-In<\/li>\n<li>In-App Purchases (via cordova-plugin-purchase bridging StoreKit \/ Google Play Billing Library)<\/li>\n<li>App review prompts at optimal moments<\/li>\n<li>Safe area handling for modern device notches and home indicators<\/li>\n<\/ul>\n<p><strong>95%+ code sharing<\/strong> across all three platforms. Platform-specific code is isolated to thin service wrappers (e.g., <code>appleBillingService.ts<\/code>, <code>googlePlayBillingService.ts<\/code>, <code>stripeBillingService.ts<\/code>).<\/p>[\/et_pb_accordion_item][\/et_pb_accordion][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Hard Problems&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; collapsed=&#8221;on&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;Technical Deep Dive&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;f0c675ea-2574-4d0e-b725-30f8550a8550&#8243; title_level=&#8221;h4&#8243; title_font=&#8221;IBM Plex Sans|IBM Plex Sans Condensed_weight||on|||||&#8221; title_text_color=&#8221;#457b9d&#8221; title_font_size=&#8221;14px&#8221; title_letter_spacing=&#8221;1px&#8221; title_line_height=&#8221;1.4em&#8221; custom_margin=&#8221;||10px||false|false&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{%22#457b9d%22:%91%22title_text_color%22%93}&#8221;][\/et_pb_heading][et_pb_heading title=&#8221;Hard Problems Solved&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;c33f07d9-41e0-421a-8799-5799df695cce&#8221; title_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; title_text_color=&#8221;#0e0c19&#8243; locked=&#8221;off&#8221; global_colors_info=&#8221;{%22#0e0c19%22:%91%22title_text_color%22,%22title_text_color%22%93}&#8221;][\/et_pb_heading][et_pb_accordion _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_accordion_item title=&#8221;Capacitor WebView Silent Failures&#8221; open=&#8221;off&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<p><strong>Problem:<\/strong> The official Supabase client method for calling Edge Functions fails silently inside Capacitor&#8217;s WebView on mobile devices. No error, no response, just nothing.<\/p>\n<p><strong>Solution:<\/strong> Bypassed the Supabase client entirely for Edge Function calls. Used direct <code>fetch()<\/code> with manual <code>Authorization: Bearer<\/code> headers. This pattern is now used consistently across all mobile Edge Function interactions.<\/p>\n<p><strong>Takeaway:<\/strong> In hybrid mobile development, never assume a web SDK behaves identically inside a WebView. Always verify on-device.<\/p>[\/et_pb_accordion_item][et_pb_accordion_item title=&#8221;Apple Receipt Validation Across Environments&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221; open=&#8221;off&#8221;]<p><strong>Problem:<\/strong> Apple&#8217;s StoreKit 1 uses &#8220;unified receipts&#8221; (not the newer StoreKit 2 JWS tokens). The receipt data lives at an unexpected path, and sandbox vs. production receipt endpoints must be handled with a fallback strategy.<\/p>\n<p><strong>Solution:<\/strong> Built a validation Edge Function that attempts production validation first, then falls back to sandbox on status code 21007. Parses the unified receipt to extract <code>original_transaction_id<\/code> and <code>expires_date<\/code> for subscription tracking.<\/p>\n<p><strong>Takeaway:<\/strong> Apple IAP documentation is fragmented across StoreKit 1, StoreKit 2, and App Store Server API. Real-world implementation requires reading between the lines.<\/p>[\/et_pb_accordion_item][et_pb_accordion_item title=&#8221;Offline-to-Online Data Migration&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221; open=&#8221;off&#8221;]<p><strong>Problem:<\/strong> Free-tier users store data only in local SQLite. When they upgrade to premium, their existing local data must be uploaded to Supabase without losing anything, and without creating duplicates if the migration is interrupted.<\/p>\n<p><strong>Solution:<\/strong> Built a dedicated MigrationService with explicit state management (disabled, initializing, migrating, connecting, syncing). The service detects user changes, clears stale local data when switching accounts, and performs a one-time upload of local data to the cloud on first premium sync.<\/p>[\/et_pb_accordion_item][et_pb_accordion_item title=&#8221;Edge Function JWT Verification&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221; open=&#8221;off&#8221;]<p><strong>Problem:<\/strong> Supabase&#8217;s API gateway rejects valid ES256-signed JWTs from the auth service with a 401 error &#8211; a known edge case with certain token configurations.<\/p>\n<p><strong>Solution:<\/strong> Deployed Edge Functions with gateway JWT verification bypassed, then implemented token verification inside the function code itself. This provides the same security guarantee while avoiding the gateway bug.<\/p>[\/et_pb_accordion_item][et_pb_accordion_item title=&#8221;Dynamic Imports in iOS WebView&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221; open=&#8221;on&#8221;]<p><strong>Problem:<\/strong> Vite&#8217;s code-splitting produces dynamic import calls that break inside Capacitor&#8217;s iOS WebView when they use a Function constructor internally &#8211; blocked by WebView&#8217;s stricter CSP.<\/p>\n<p><strong>Solution:<\/strong> Configured the build to use standard import syntax and adjusted Vite&#8217;s chunking strategy to avoid the problematic construction pattern.<\/p>[\/et_pb_accordion_item][\/et_pb_accordion][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Features&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; collapsed=&#8221;on&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;5138c454-be54-4233-bd3b-f8e6a8747976&#8243; custom_margin=&#8221;|auto|-10px|auto|false|false&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.18.0&#8243; _module_preset=&#8221;73121f80-a3ef-4484-8763-c3f18e3c56d2&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;Technologies &#038; Tools&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;c33f07d9-41e0-421a-8799-5799df695cce&#8221; title_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; title_text_align=&#8221;center&#8221; title_text_color=&#8221;#0e0c19&#8243;][\/et_pb_heading][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;c948bff6-554d-4de7-99f0-8c1387a293a6&#8243; background_color=&#8221;#1d3557&#8243; border_radii=&#8221;off|6px|6px||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.24.2&#8243; _module_preset=&#8221;24385ca2-769f-4664-bda9-1443db945d08&#8243; background_color=&#8221;#1d3557&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_blurb title=&#8221;Frontend&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#xf0a9;||fa||900&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;ca79a742-981f-479f-a8a2-3a0292efaff0&#8243; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; body_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; background_mask_style=&#8221;diagonal&#8221;]React 19, TypeScript, TailwindCSS, i18next (36 languages)[\/et_pb_blurb][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.24.2&#8243; _module_preset=&#8221;24385ca2-769f-4664-bda9-1443db945d08&#8243; background_color=&#8221;#1d3557&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_blurb title=&#8221;Mobile&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#xf0a9;||fa||900&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;ca79a742-981f-479f-a8a2-3a0292efaff0&#8243; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; body_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; background_mask_style=&#8221;diagonal&#8221;]Capacitor 8, cordova-plugin-purchase (Apple IAP + Google Play), App Review prompts[\/et_pb_blurb][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;c948bff6-554d-4de7-99f0-8c1387a293a6&#8243; background_color=&#8221;#1d3557&#8243; border_radii=&#8221;off|6px|6px||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.24.2&#8243; _module_preset=&#8221;24385ca2-769f-4664-bda9-1443db945d08&#8243; background_color=&#8221;#1d3557&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_blurb title=&#8221;Backend &#038; Infrastructure&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#xf0a9;||fa||900&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;ca79a742-981f-479f-a8a2-3a0292efaff0&#8243; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; body_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; background_mask_style=&#8221;diagonal&#8221;]Supabase (PostgreSQL, Auth, Edge Functions), PowerSync, Stripe, Vercel[\/et_pb_blurb][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.24.2&#8243; _module_preset=&#8221;24385ca2-769f-4664-bda9-1443db945d08&#8243; background_color=&#8221;#1d3557&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_blurb title=&#8221;DevOps &#038; Quality&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#xf0a9;||fa||900&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;ca79a742-981f-479f-a8a2-3a0292efaff0&#8243; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; body_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; background_mask_style=&#8221;diagonal&#8221;]Vitest, Playwright, GitHub Actions CI\/CD, SonarCloud-style code quality checks[\/et_pb_blurb][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Text&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; locked=&#8221;off&#8221; collapsed=&#8221;on&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row column_structure=&#8221;3_5,2_5&#8243; custom_padding_last_edited=&#8221;on|desktop&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;5138c454-be54-4233-bd3b-f8e6a8747976&#8243; background_color=&#8221;#FFFFFF&#8221; custom_padding=&#8221;60px|60px|60px|60px|true|true&#8221; custom_padding_tablet=&#8221;30px|30px|30px|30px|true|true&#8221; custom_padding_phone=&#8221;20px|20px|20px|20px|true|true&#8221; border_radii=&#8221;on|6px|6px|6px|6px&#8221; box_shadow_style=&#8221;preset1&#8243; box_shadow_vertical=&#8221;24px&#8221; box_shadow_blur=&#8221;72px&#8221; box_shadow_spread=&#8221;-12px&#8221; box_shadow_color=&#8221;rgba(0,0,0,0.12)&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;3_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;73121f80-a3ef-4484-8763-c3f18e3c56d2&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;Key Achievements&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;f0c675ea-2574-4d0e-b725-30f8550a8550&#8243; title_level=&#8221;h4&#8243; title_font=&#8221;IBM Plex Sans|IBM Plex Sans Condensed_weight||on|||||&#8221; title_text_color=&#8221;#457b9d&#8221; title_font_size=&#8221;14px&#8221; title_letter_spacing=&#8221;1px&#8221; title_line_height=&#8221;1.4em&#8221; custom_margin=&#8221;||10px||false|false&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{%22#457b9d%22:%91%22title_text_color%22%93}&#8221;][\/et_pb_heading][et_pb_heading title=&#8221;Results &#038; Impact&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;c33f07d9-41e0-421a-8799-5799df695cce&#8221; title_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; title_text_color=&#8221;#0e0c19&#8243; locked=&#8221;off&#8221; global_colors_info=&#8221;{%22#0e0c19%22:%91%22title_text_color%22,%22title_text_color%22%93}&#8221;][\/et_pb_heading][et_pb_blurb title=&#8221;Production App on Three App Stores&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#x4e;||divi||400&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;65059203-12d3-44f6-8371-3f5cf61a0475&#8243; animation_style=&#8221;flip&#8221; global_colors_info=&#8221;{}&#8221;]The app is live and serving real users on the Apple App Store, Google Play Store, and as a web application &#8211; all from a single TypeScript codebase.[\/et_pb_blurb][et_pb_blurb title=&#8221;Offline-First Architecture That Actually Works&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#x4e;||divi||400&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;65059203-12d3-44f6-8371-3f5cf61a0475&#8243; animation_style=&#8221;flip&#8221; global_colors_info=&#8221;{}&#8221;]Unlike many &#8220;offline-capable&#8221; apps that degrade gracefully, Smart Packing List is designed offline-first. The network is a nice-to-have for sync, not a requirement for functionality.[\/et_pb_blurb][et_pb_blurb title=&#8221;Freemium Model with Server-Validated Subscriptions&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#x4e;||divi||400&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;65059203-12d3-44f6-8371-3f5cf61a0475&#8243; animation_style=&#8221;flip&#8221; global_colors_info=&#8221;{}&#8221;]A complete subscription system with server-side receipt validation, free trial support, and platform-specific billing &#8211; ensuring revenue integrity while keeping the free tier genuinely useful.[\/et_pb_blurb][\/et_pb_column][et_pb_column type=&#8221;2_5&#8243; _builder_version=&#8221;4.16&#8243; _module_preset=&#8221;73121f80-a3ef-4484-8763-c3f18e3c56d2&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_blurb title=&#8221;Global-Ready from Day One&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#x4e;||divi||400&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;65059203-12d3-44f6-8371-3f5cf61a0475&#8243; animation_style=&#8221;flip&#8221; global_colors_info=&#8221;{}&#8221;]With 36 locales supported at launch, the app is ready for users worldwide. Localization is part of the component architecture, with every user-facing string externalized.[\/et_pb_blurb][et_pb_blurb title=&#8221;95%+ Cross-Platform Code Sharing&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#x4e;||divi||400&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;65059203-12d3-44f6-8371-3f5cf61a0475&#8243; animation_style=&#8221;flip&#8221; global_colors_info=&#8221;{}&#8221;]A single TypeScript codebase serves iOS, Android, and web. Platform-specific code is isolated to thin service wrappers, keeping the shared core clean and maintainable.[\/et_pb_blurb][et_pb_blurb title=&#8221;Real Engineering, Not a Tutorial Project&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#x4e;||divi||400&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;65059203-12d3-44f6-8371-3f5cf61a0475&#8243; animation_style=&#8221;flip&#8221; global_colors_info=&#8221;{}&#8221;]The codebase handles real-world complexity: data migration between tiers, multi-device session management, soft deletes with sync, cross-platform IAP receipt validation, and App Store compliance requirements.[\/et_pb_blurb][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Learnings&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; collapsed=&#8221;on&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;Specific Features \/ Customizations&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221;][\/et_pb_heading][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_3,1_3,1_3&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_3&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_icon font_icon=&#8221;&#xf10d;||fa||900&#8243; align=&#8221;center&#8221; module_class=&#8221;ai_ignore_font_icon&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;c2c23269-d09e-4bca-9247-65cd5ecf15a9&#8243; global_colors_info=&#8221;{%22gcid-primary-color%22:%91%22icon_color%22%93}&#8221;][\/et_pb_icon][et_pb_text quote_border_color=&#8221;#457b9d&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;2c55a9c4-feed-423b-9edb-ae0b5b365cac&#8221; text_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; link_font=&#8221;|IBM Plex Sans_weight|||||||&#8221; link_text_color=&#8221;#1d3557&#8243; quote_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_2_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_3_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_4_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_5_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_6_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; text_orientation=&#8221;center&#8221; global_colors_info=&#8221;{}&#8221;]<p>Offline-first changes everything: designing for offline first simplifies many UX decisions but introduces sync complexity that must be handled at the architecture level<\/p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_3&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_icon font_icon=&#8221;&#xf10d;||fa||900&#8243; align=&#8221;center&#8221; module_class=&#8221;ai_ignore_font_icon&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;c2c23269-d09e-4bca-9247-65cd5ecf15a9&#8243; global_colors_info=&#8221;{%22gcid-primary-color%22:%91%22icon_color%22%93}&#8221;][\/et_pb_icon][et_pb_text quote_border_color=&#8221;#457b9d&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;2c55a9c4-feed-423b-9edb-ae0b5b365cac&#8221; text_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; link_font=&#8221;|IBM Plex Sans_weight|||||||&#8221; link_text_color=&#8221;#1d3557&#8243; quote_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_2_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_3_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_4_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_5_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_6_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; text_orientation=&#8221;center&#8221; global_colors_info=&#8221;{}&#8221;]<p>Hybrid mobile is viable with caveats: Capacitor delivers on code reuse, but WebView edge cases require on-device testing for every feature. Emulators are not enough.<\/p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_3&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_icon font_icon=&#8221;&#xf10d;||fa||900&#8243; align=&#8221;center&#8221; module_class=&#8221;ai_ignore_font_icon&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;c2c23269-d09e-4bca-9247-65cd5ecf15a9&#8243; global_colors_info=&#8221;{%22gcid-primary-color%22:%91%22icon_color%22%93}&#8221;][\/et_pb_icon][et_pb_text quote_border_color=&#8221;#457b9d&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;2c55a9c4-feed-423b-9edb-ae0b5b365cac&#8221; text_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; link_font=&#8221;|IBM Plex Sans_weight|||||||&#8221; link_text_color=&#8221;#1d3557&#8243; quote_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_2_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_3_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_4_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_5_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_6_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; text_orientation=&#8221;center&#8221; global_colors_info=&#8221;{}&#8221;]<p>Multi-platform billing is the hardest &#8220;simple&#8221; problem: three payment processors, three receipt formats, three validation flows, all converging to one subscription state<\/p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_3,1_3,1_3&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_3&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_icon font_icon=&#8221;&#xf10d;||fa||900&#8243; align=&#8221;center&#8221; module_class=&#8221;ai_ignore_font_icon&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;c2c23269-d09e-4bca-9247-65cd5ecf15a9&#8243; global_colors_info=&#8221;{%22gcid-primary-color%22:%91%22icon_color%22%93}&#8221;][\/et_pb_icon][et_pb_text quote_border_color=&#8221;#457b9d&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;2c55a9c4-feed-423b-9edb-ae0b5b365cac&#8221; text_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; link_font=&#8221;|IBM Plex Sans_weight|||||||&#8221; link_text_color=&#8221;#1d3557&#8243; quote_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_2_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_3_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_4_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_5_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_6_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; text_orientation=&#8221;center&#8221; global_colors_info=&#8221;{}&#8221;]<p>App Store compliance is a product concern, not just a checklist: Apple and Google&#8217;s requirements shaped actual product decisions around subscription transparency, account deletion, and privacy<\/p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_3&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_icon font_icon=&#8221;&#xf10d;||fa||900&#8243; align=&#8221;center&#8221; module_class=&#8221;ai_ignore_font_icon&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;c2c23269-d09e-4bca-9247-65cd5ecf15a9&#8243; global_colors_info=&#8221;{%22gcid-primary-color%22:%91%22icon_color%22%93}&#8221;][\/et_pb_icon][et_pb_text quote_border_color=&#8221;#457b9d&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;2c55a9c4-feed-423b-9edb-ae0b5b365cac&#8221; text_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; link_font=&#8221;|IBM Plex Sans_weight|||||||&#8221; link_text_color=&#8221;#1d3557&#8243; quote_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_2_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_3_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_4_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_5_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_6_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; text_orientation=&#8221;center&#8221; global_colors_info=&#8221;{}&#8221;]<p>AI-assisted development at scale: this project was developed with significant use of AI coding assistants, demonstrating how a solo developer can ship a complex, multi-platform product that would traditionally require a team<\/p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_3&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Testimonials&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; locked=&#8221;off&#8221; collapsed=&#8221;on&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;Project Summary&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221;][\/et_pb_heading][et_pb_text _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<div style=\"overflow-x: auto; -webkit-overflow-scrolling: touch;\">\n<table style=\"width: 100%; border-collapse: collapse; margin: 20px 0; font-size: 16px;\">\n<tbody>\n<tr style=\"background-color: #f8f9fa;\">\n<td style=\"padding: 12px 16px; border: 1px solid #dee2e6;\"><strong>Role<\/strong><\/td>\n<td style=\"padding: 12px 16px; border: 1px solid #dee2e6;\">Product Owner, Designer &amp; Full-Stack Developer<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 12px 16px; border: 1px solid #dee2e6;\"><strong>Duration<\/strong><\/td>\n<td style=\"padding: 12px 16px; border: 1px solid #dee2e6;\">2026 &#8211; ongoing<\/td>\n<\/tr>\n<tr style=\"background-color: #f8f9fa;\">\n<td style=\"padding: 12px 16px; border: 1px solid #dee2e6;\"><strong>Stack<\/strong><\/td>\n<td style=\"padding: 12px 16px; border: 1px solid #dee2e6;\">React 19, TypeScript, Capacitor 8, Supabase, PowerSync<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 12px 16px; border: 1px solid #dee2e6;\"><strong>Platforms<\/strong><\/td>\n<td style=\"padding: 12px 16px; border: 1px solid #dee2e6;\">iOS (App Store), Android (Google Play), Web (Vercel)<\/td>\n<\/tr>\n<tr style=\"background-color: #f8f9fa;\">\n<td style=\"padding: 12px 16px; border: 1px solid #dee2e6;\"><strong>Focus Area<\/strong><\/td>\n<td style=\"padding: 12px 16px; border: 1px solid #dee2e6;\">Offline-first sync, cross-platform IAP, 36-language localization, freemium monetization<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 12px 16px; border: 1px solid #dee2e6;\"><strong>Result<\/strong><\/td>\n<td style=\"padding: 12px 16px; border: 1px solid #dee2e6;\">Production app shipped to 3 platforms, demonstrating end-to-end product delivery capability<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;Reflection&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;c33f07d9-41e0-421a-8799-5799df695cce&#8221; title_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; title_text_color=&#8221;#0e0c19&#8243; locked=&#8221;off&#8221;][\/et_pb_heading][et_pb_testimonial quote_icon_color=&#8221;#1d3557&#8243; module_class=&#8221;ai_ignore_font_icon&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;0e35d7c8-43f7-4642-88fa-284809e5aebb&#8221; body_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; author_font=&#8221;IBM Plex Sans|700|||||||&#8221; position_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; company_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{%22gcid-36fd78a7-34bc-404d-873c-dafa34efaae5%22:%91%22icon_color%22,%22icon_color%22,%22icon_color%22,%22icon_color%22,%22icon_color%22,%22icon_color%22,%22icon_color%22,%22icon_color%22%93}&#8221;]<blockquote>This project represents the most comprehensive demonstration of our technical capabilities. While our SAP Commerce engagements showcase deep expertise in enterprise e-commerce, Smart Packing List proves we can take a product from a blank repository to a live, monetized, multi-platform application &#8211; handling everything from database schema design to App Store screenshot preparation. It also reflects a modern approach to software development: leveraging serverless infrastructure to build production-grade systems without managing servers, and using AI-assisted development to achieve the output of a small team as a solo developer. For consulting clients, this means we bring not just implementation skills, but product thinking &#8211; the ability to reason about trade-offs, prioritize ruthlessly, and ship something real.<\/blockquote>[\/et_pb_testimonial][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Call to Action&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; locked=&#8221;off&#8221; collapsed=&#8221;on&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;5138c454-be54-4233-bd3b-f8e6a8747976&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.6&#8243; _module_preset=&#8221;73121f80-a3ef-4484-8763-c3f18e3c56d2&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_cta title=&#8221;Interested in Building a Mobile App or Cross-Platform Product?&#8221; button_url=&#8221;@ET-DC@eyJkeW5hbWljIjp0cnVlLCJjb250ZW50IjoicG9zdF9saW5rX3VybF9wYWdlIiwic2V0dGluZ3MiOnsicG9zdF9pZCI6IjE0In19@&#8221; button_text=&#8221;Contact Us&#8221; _builder_version=&#8221;4.27.5&#8243; _dynamic_attributes=&#8221;button_url&#8221; _module_preset=&#8221;be0cc754-576a-4b1c-868d-f6226f85de4d&#8221; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_text_align=&#8221;left&#8221; body_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; body_text_align=&#8221;left&#8221; button_bg_color=&#8221;#1d3557&#8243; button_font=&#8221;IBM Plex Sans|700|||||||&#8221; button_alignment=&#8221;left&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{%22gcid-828accbb-1ed2-407d-95be-20ab4e191566%22:%91%22border_color_all%22%93,%22#0e0c19%22:%91%22header_text_color%22%93,%22#3c3a47%22:%91%22body_text_color%22%93,%22gcid-f2943306-fa6c-45f0-b632-5fc00151366a%22:%91%22button_text_color%22,%22button_text_color%22%93,%22gcid-36fd78a7-34bc-404d-873c-dafa34efaae5%22:%91%22button_text_color%22,%22button_text_color%22,%22button_text_color%22%93}&#8221;]<p>Whether you need a full product build, a mobile app strategy, or help integrating subscription billing into your existing platform &#8211; we bring hands-on experience from shipping real products. Let&#8217;s discuss your project.<\/p>[\/et_pb_cta][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.6&#8243; _module_preset=&#8221;73121f80-a3ef-4484-8763-c3f18e3c56d2&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_cta title=&#8221;Want to See More Projects?&#8221; button_url=&#8221;@ET-DC@eyJkeW5hbWljIjp0cnVlLCJjb250ZW50IjoicG9zdF9saW5rX3VybF9wYWdlIiwic2V0dGluZ3MiOnsicG9zdF9pZCI6IjEwIn19@&#8221; button_text=&#8221;View All Projects&#8221; _builder_version=&#8221;4.27.5&#8243; _dynamic_attributes=&#8221;button_url&#8221; _module_preset=&#8221;4c2ad5d0-871e-414e-a4be-aa9134d4ae8e&#8221; header_font=&#8221;IBM Plex Sans Condensed|IBM Plex Sans Condensed_weight|||||||&#8221; header_text_align=&#8221;left&#8221; body_font=&#8221;IBM Plex Sans|IBM Plex Sans_weight|||||||&#8221; body_text_align=&#8221;left&#8221; button_bg_color=&#8221;#1d3557&#8243; button_font=&#8221;IBM Plex Sans|700|||||||&#8221; button_alignment=&#8221;left&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{%22gcid-828accbb-1ed2-407d-95be-20ab4e191566%22:%91%22border_color_all%22%93,%22#0e0c19%22:%91%22header_text_color%22%93,%22#3c3a47%22:%91%22body_text_color%22%93,%22gcid-f2943306-fa6c-45f0-b632-5fc00151366a%22:%91%22button_text_color%22,%22button_text_color%22%93,%22gcid-36fd78a7-34bc-404d-873c-dafa34efaae5%22:%91%22button_text_color%22,%22button_text_color%22,%22button_text_color%22%93}&#8221;]<p>Explore how we&#8217;ve designed and developed modern, high-performing applications that strengthen digital presence and drive measurable results.<\/p>[\/et_pb_cta][\/et_pb_column][\/et_pb_row][\/et_pb_section]\n","protected":false},"excerpt":{"rendered":"<p>Discover how we designed, built, and launched a production-grade mobile app from scratch, covering product strategy, offline-first architecture, multi-platform deployment, subscription monetization, and localization into 36 languages.Smart Packing List is a cross-platform mobile and web application that helps travelers organize their packing with reusable lists, hierarchical categories, and real-time cloud sync across devices. It works [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1622,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"_et_pb_use_builder":"on","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"project_category":[51,40,50,29,27],"project_tag":[],"class_list":["post-2313","project","type-project","status-publish","has-post-thumbnail","hentry","project_category-android","project_category-information-technology","project_category-ios","project_category-project-type","project_category-technology"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/commerce-consulting-services.com\/lv\/wp-json\/wp\/v2\/project\/2313","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/commerce-consulting-services.com\/lv\/wp-json\/wp\/v2\/project"}],"about":[{"href":"https:\/\/commerce-consulting-services.com\/lv\/wp-json\/wp\/v2\/types\/project"}],"author":[{"embeddable":true,"href":"https:\/\/commerce-consulting-services.com\/lv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/commerce-consulting-services.com\/lv\/wp-json\/wp\/v2\/comments?post=2313"}],"version-history":[{"count":5,"href":"https:\/\/commerce-consulting-services.com\/lv\/wp-json\/wp\/v2\/project\/2313\/revisions"}],"predecessor-version":[{"id":2423,"href":"https:\/\/commerce-consulting-services.com\/lv\/wp-json\/wp\/v2\/project\/2313\/revisions\/2423"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/commerce-consulting-services.com\/lv\/wp-json\/wp\/v2\/media\/1622"}],"wp:attachment":[{"href":"https:\/\/commerce-consulting-services.com\/lv\/wp-json\/wp\/v2\/media?parent=2313"}],"wp:term":[{"taxonomy":"project_category","embeddable":true,"href":"https:\/\/commerce-consulting-services.com\/lv\/wp-json\/wp\/v2\/project_category?post=2313"},{"taxonomy":"project_tag","embeddable":true,"href":"https:\/\/commerce-consulting-services.com\/lv\/wp-json\/wp\/v2\/project_tag?post=2313"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}