Commit Graph

130 Commits

Author SHA1 Message Date
jamey
e6d4fce656 refactor: extract ThemeHook to eliminate mount duplication
on_mount hook assigns theme_settings, generated_css, logo_image,
header_image, and mode for all public shop LiveViews. Removes
~70 lines of identical boilerplate and 18 unused aliases across
7 LiveViews.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 11:59:33 +00:00
jamey
dd19281f4f docs: add codebase metrics and impact analysis to DRY refactor plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 11:42:58 +00:00
jamey
5b08591a55 docs: add DRY refactor plan and update progress
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 11:18:58 +00:00
jamey
db02c0b414 refactor: use assigns spread in page LiveView render functions
Replace verbose explicit attr passing with {assigns} spread for
home, contact, cart, product show and checkout success LiveViews.
Collection skipped (inline rendering, no template component).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 10:53:06 +00:00
jamey
5a43cfc761 feat: add default content pages for delivery, privacy and terms
Replace one-off ShopLive.About with generic ShopLive.Content that
handles all static content pages via live_action. Add delivery &
returns, privacy policy, and terms of service pages with sample
content. Update footer help links and theme editor preview.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 10:47:54 +00:00
jamey
0af8997623 feat: add transactional emails for order confirmation and shipping
Plain text emails via Swoosh OrderNotifier module. Order confirmation
triggered from Stripe webhook after payment, shipping notification
from Printify shipment webhook with polling fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 10:17:19 +00:00
jamey
3e19887499 feat: add Printify order submission and fulfilment tracking
Submit paid orders to Printify via provider API with idempotent
guards, Stripe address mapping, and error handling. Track fulfilment
status through submitted → processing → shipped → delivered via
webhook-driven updates (primary) and Oban Cron polling fallback.

- 9 fulfilment fields on orders (status, provider IDs, tracking, timestamps)
- OrderSubmissionWorker with retry logic, auto-enqueued after Stripe payment
- FulfilmentStatusWorker polls every 30 mins for missed webhook events
- Printify order webhook handlers (sent-to-production, shipment, delivered)
- Admin UI: fulfilment column in table, fulfilment card with tracking info,
  submit/retry and refresh buttons on order detail
- Mox provider mocking for test isolation (Provider.for_type configurable)
- 33 new tests (555 total), verified against real Printify API

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 09:51:51 +00:00
jamey
02cdc810f2 feat: add order management admin with list and detail views
Admin UI at /admin/orders to view, filter, and inspect orders.
Adds list_orders/1 and count_orders_by_status/0 to the Orders
context, status filter tabs, clickable order table with streams,
and a detail page showing items, totals, and shipping address.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 21:59:14 +00:00
jamey
e6f8d7fa2a docs: add prioritised roadmap with all planned features
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 20:28:28 +00:00
jamey
d65eb725f7 docs: update progress with Stripe setup and checkout completion
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 18:04:18 +00:00
jamey
eede9bb517 feat: add encrypted settings, guided Stripe setup, and admin credentials page
Store API keys and secrets encrypted in the SQLite database via the
existing Vault module (AES-256-GCM). The only external dependency is
SECRET_KEY_BASE — everything else lives in the portable DB file.

- Add encrypted_value column to settings table with new "encrypted" type
- Add put_secret/get_secret/delete_setting/secret_hint to Settings context
- Add Secrets module to load encrypted config into Application env at startup
- Add Stripe.Setup module with connect/disconnect/verify_api_key flow
  - Auto-creates webhook endpoints via Stripe API in production
  - Detects localhost and shows Stripe CLI instructions for dev
- Add admin credentials page at /admin/settings with guided setup:
  - Not configured: single Secret key input with dashboard link
  - Connected (production): status display, webhook info, disconnect
  - Connected (dev): Stripe CLI instructions, manual signing secret input
- Remove Stripe env vars from dev.exs and runtime.exs
- Fix CSSCache test startup crash (handle_continue instead of init)
- Add nav link for Credentials page

507 tests, 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 17:12:53 +00:00
jamey
ff1bc483b9 feat: add Stripe checkout, order persistence, and webhook handling
Stripe-hosted Checkout integration with full order lifecycle:
- stripity_stripe ~> 3.2 with sandbox/prod config via env vars
- Order and OrderItem schemas with price snapshots at purchase time
- CheckoutController creates pending order then redirects to Stripe
- StripeWebhookController verifies signatures and confirms payment
- Success page with real-time PubSub updates from webhook
- Shop flash messages for checkout error feedback
- Cart cleared after successful payment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 08:30:17 +00:00
jamey
cff21703f1 fix: update demo content, fix broken links, and add cart item product links
- Replace all placeholder text with demo-aware copy that signals "replace me"
- Update USPs for POD accuracy (made to order, quality materials)
- Fix broken footer links (/delivery, /returns → /contact)
- Add real platform URLs to social icons with target="_blank"
- Make cart item images and names link to product pages
- Switch about page image to responsive_image component
- Add missing cart_status to collection page cart drawer
- Unify search hint text across all page templates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 23:33:22 +00:00
jamey
1bc08bfb23 feat: add cart page, cart drawer, and shared cart infrastructure
- Cart context with pure functions for add/remove/update/hydrate
- Price formatting via ex_money (replaces all float division)
- CartHook on_mount with attach_hook for shared event handlers
  (open/close drawer, remove item, PubSub sync)
- Accessible cart drawer with focus trap, scroll lock, aria-live
- Cart page with increment/decrement quantity controls
- Preview mode cart drawer support in theme editor
- Cart persistence to session via JS hook + API endpoint
- 19 tests covering all Cart pure functions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 19:39:37 +00:00
jamey
880e7a2888 feat: add dynamic variant selector with color swatches
- Fix Printify options parsing (Color/Size were swapped)
- Add extract_option_types/1 for frontend display with hex colors
- Filter option types to only published variants (not full catalog)
- Track selected variant in LiveView with price updates
- Color swatches for color-type options, text buttons for size
- Disable unavailable combinations
- Add startup recovery for stale sync status

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 22:17:48 +00:00
jamey
1b49b470f2 feat: add product image download pipeline for PageSpeed 100%
Downloads Printify CDN images via ImageDownloadWorker, processes
through Media pipeline (WebP conversion, AVIF/WebP variant generation),
and links to ProductImage via new image_id FK.

- Add image_id to product_images table
- ImageDownloadWorker downloads and processes external images
- sync_product_images preserves image_id when URL unchanged
- PreviewData uses local images for responsive <picture> elements
- VariantCache enqueues pending downloads on startup
- mix simpleshop.download_images backfill task

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 00:26:19 +00:00
jamey
c818d0399c feat: wire shop LiveViews to real product data
PreviewData now queries the Products context when real products exist,
falling back to mock data otherwise. Shop pages automatically display
synced Printify products.

Fixes:
- Printify image position was string ("front"), now uses index
- Category extraction improved to match more Printify tags
- ProductShow finds products by slug for real data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:07:37 +00:00
jamey
81520754ee docs: update progress with completed webhook endpoint
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 22:41:45 +00:00
jamey
a9c15ea6ae feat: add Printify webhook endpoint for real-time product updates
- Add /webhooks/printify endpoint with HMAC-SHA256 signature verification
- Add Webhooks context to handle product:updated, product:deleted events
- Add ProductDeleteWorker for async product deletion
- Add webhook API methods to Printify client (create, list, delete)
- Add register_webhooks/2 to Printify provider
- Add mix register_webhooks task for one-time webhook registration
- Cache raw request body in endpoint for signature verification

Usage:
1. Generate webhook secret: openssl rand -hex 20
2. Add to provider connection config as "webhook_secret"
3. Register with Printify: mix register_webhooks https://yourshop.com/webhooks/printify

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 22:41:15 +00:00
jamey
a2157177b8 docs: correct webhook support for personal API tokens
Webhooks work with personal tokens when webhooks.read and webhooks.write
scopes are enabled during token generation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 22:17:35 +00:00
jamey
5b736b99fd feat: add admin provider setup UI with improved product sync
- Add /admin/providers LiveView for connecting and managing POD providers
- Implement pagination for Printify API (handles all products, not just first page)
- Add parallel processing (5 concurrent) for faster product sync
- Add slug-based fallback matching when provider_product_id changes
- Add error recovery with try/rescue to prevent stuck sync status
- Add checksum-based change detection to skip unchanged products
- Add upsert tests covering race conditions and slug matching
- Add Printify provider tests
- Document Printify integration research (product identity, order risks,
  open source vs managed hosting implications)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 22:08:34 +00:00
jamey
bbd748f123 chore: enable sqlite wal mode for dev and prod
better concurrency and crash recovery for web workloads

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 14:30:27 +00:00
jamey
a44790362a fix: resolve sqlite database busy errors in tests
- enable WAL journal mode for better concurrent access
- increase busy_timeout to 10s
- reduce pool_size to 1 to prevent write conflicts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 14:29:24 +00:00
jamey
51d9504f6b docs: add admin provider setup task and update project guidelines
- add detailed task spec for /admin/providers UI with webhook integration
- add product sync strategy with manual, webhook, and scheduled sync
- update PROGRESS.md to prioritise admin provider UI as next task
- add writing style guidelines (british english, sentence case, concise)
- add commit guidelines (atomic, imperative, suggest at checkpoints)
- add pragmatic testing guidelines (test boundaries, skip trivial)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 14:25:06 +00:00
jamey
336b2bb81d chore: apply mix format to codebase
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 14:24:58 +00:00
jamey
d97918d66a docs: consolidate project tracking into PROGRESS.md
- Create PROGRESS.md as single source of truth for status
- Slim ROADMAP.md to vision only (~100 lines, down from ~500)
- Expand CLAUDE.md with streams, auth routing, forms, workflow
- Convert AGENTS.md to stub pointing to CLAUDE.md
- Update plan files with status headers, remove progress trackers

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 14:06:07 +00:00
jamey
153f3d049f chore: add MCP config for Claude Code + Tidewave integration
Enables Claude Code to connect to the Tidewave MCP server
for live application introspection during development.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 13:49:07 +00:00
jamey
c1e19889d4 fix: add Oban Lifeline plugin to rescue orphaned jobs
Jobs stuck in "executing" state after server restarts will now be
automatically rescued after 5 minutes. This prevents jobs from
being permanently orphaned when the server restarts mid-execution.

Also updates tidewave 0.5.3 -> 0.5.4 and related dependencies.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 13:48:04 +00:00
jamey
ee1da08941 fix: enable Tidewave remote access properly
Pass allow_remote_access option directly to the Tidewave plug
instead of using application config (which was not being read).
Remove the ineffective config line from dev.exs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 13:47:58 +00:00
jamey
c2df13ff79 docs: add CLAUDE.md for Claude Code guidance
Provides essential commands, architecture overview, and coding guidelines
for AI assistants working in this codebase.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 09:58:36 +00:00
c5c06d9979 feat: add Products context with provider integration (Phase 1)
Implement the schema foundation for syncing products from POD providers
like Printify. This includes encrypted credential storage, product/variant
schemas, and an Oban worker for background sync.

New modules:
- Vault: AES-256-GCM encryption for API keys
- Products context: CRUD and sync operations for products
- Provider behaviour: abstraction for POD provider implementations
- ProductSyncWorker: Oban job for async product sync

Schemas: ProviderConnection, Product, ProductImage, ProductVariant

Also reorganizes Printify client to lib/simpleshop_theme/clients/ and
mockup generator to lib/simpleshop_theme/mockups/ for better structure.

134 tests added covering all new functionality.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 20:32:20 +00:00
62faf86abe docs: update ROADMAP with completed quick wins
Moved PageSpeed optimizations from "in progress" to "completed":
- Image optimization pipeline
- Font preloading
- Lazy loading
- Cache headers
- CSS bundle split

Added new completed items:
- Image Optimization Pipeline
- Themed Form Components

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 19:18:09 +00:00
7d5896a1e3 refactor: add themed form components for consistent shop styling
Adds reusable Phoenix components (shop_input, shop_textarea, shop_select,
shop_button, shop_card) backed by semantic CSS classes (.themed-input,
.themed-button, etc.) to eliminate repeated inline styles across templates.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 19:09:49 +00:00
1b12dc3e7f perf: split CSS bundles for shop and admin pages
Create separate CSS bundles to reduce shop page load times:
- app-shop.css (45KB/7.8KB gzip): Shop pages only, no daisyUI
- app.css (139KB): Admin pages with daisyUI and theme editor

Key changes:
- Add app-shop.css with targeted @source paths for shop files only
- Move .preview-frame rules from theme-layer2-attributes.css to app.css
- Delete fonts.css (fonts now generated inline by CSSGenerator)
- Add inline all-fonts generation in theme editor for typography switching
- Configure separate Tailwind profiles and watchers for both bundles

Shop pages now load 54% less CSS by excluding:
- daisyUI components (admin only)
- .preview-frame theme switching rules (editor only)
- Admin-specific Tailwind utilities

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 11:36:20 +00:00
b1635c7313 chore: ignore digested mockup variants in .gitignore
Add pattern to ignore Phoenix-digested versions of mockup files
(files with 32-char hash in filename from mix phx.digest).
Also changed thumb pattern to catch all extensions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 09:33:29 +00:00
9783199691 perf: use digested font paths in CSS and preloads
Add path_resolver parameter to font generation functions so both
font preloads and CSS @font-face declarations use the same digested
paths in production. This prevents duplicate font downloads when
preloads were using digested paths but CSS used non-digested paths.

- Add path_resolver parameter to Fonts.generate_font_faces/2,
  Fonts.preload_links/2, and Fonts.generate_all_font_faces/1
- Update CSSGenerator.generate/2 to accept path_resolver
- Update CSSCache.warm/0 to use Endpoint.static_path/1
- Move CSSCache to start after Endpoint in supervision tree
- Add 1-year cache headers for static assets

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 09:32:06 +00:00
03fb98afc4 chore: add UI styles and update documentation
- Add cart drawer and product gallery thumbnail CSS
- Remove redundant type="text/javascript" attribute
- Update image optimization plan to reflect completion

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 00:34:04 +00:00
364ac8fa0e fix: improve accent color contrast for WCAG AA compliance
Add WCAG AA compliant accent color variants and update default accent
to meet 4.5:1 contrast ratio requirements.

- Add --t-accent-text (darker for text on light backgrounds)
- Add --t-accent-button (darker for button backgrounds with white text)
- Change default accent from #3b82f6 to #2563eb (better contrast)
- Update presets and tests for new default

These changes ensure accent colors meet accessibility standards while
maintaining visual consistency with the brand palette.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 00:33:52 +00:00
2c3d8f5647 perf: use responsive images for theme preview mockups
Update theme preview to use optimized responsive images with modern
format support (AVIF/WebP with JPEG fallback).

- Change mockup URLs from .jpg to base paths for srcset generation
- Add source_width to preview products for proper variant selection
- Add responsive_image component with <picture> element
- Update image_text_section to use optimized 800px WebP variant

This ensures the theme preview loads optimal image formats and sizes,
matching the production responsive image behavior.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 00:33:38 +00:00
0ade34d994 feat: add centralized fonts module for dynamic font loading
Create a DRY Fonts module that centralizes all font definitions and
generates @font-face declarations dynamically based on typography preset.

- Add Fonts module with typography font mappings
- Generate @font-face CSS in CSSGenerator based on active preset
- Add font preload links in shop_root layout for performance
- Remove hardcoded font-face declarations from CSS

This improves font loading performance by only loading fonts for the
active typography preset and preloading critical fonts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 00:33:24 +00:00
2bc05097b9 feat: enhance image optimization with on-demand JPEG fallbacks
Improve the image optimization pipeline with better compression and
smarter variant generation:

- Change to_lossless_webp → to_optimized_webp (lossy, quality 90)
- Auto-resize uploads larger than 2000px to save storage
- Skip pre-generating JPEG variants (~50% disk savings)
- Add on-demand JPEG generation for legacy browsers (<5% of users)
- Add /images/:id/variant/:width route for dynamic serving
- Add VariantCache to supervision tree for startup validation
- Add image_cache to static paths for disk-based serving

The pipeline now stores smaller WebP sources and generates AVIF/WebP
variants upfront, with JPEG generated only when legacy browsers request it.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 00:33:09 +00:00
252ca2268a feat: optimize mockup images with WebP and auto-regeneration
Convert mockup source images from JPG to WebP format for 76% size
reduction (20MB → 4.7MB). Variants are now auto-generated on startup
via Oban, keeping the same DRY approach as database images.

Changes:
- Add OptimizeWorker.enqueue_mockup/1 for filesystem images
- Extend VariantCache to check mockup sources on startup
- Update MockupGenerator to save source as optimized WebP
- Update .gitignore to ignore generated variants
- Convert 55 source mockups from JPG to WebP

The mockup pipeline now uses the same code paths as database images:
- Optimizer.to_optimized_webp/1 for source conversion
- Optimizer.process_file/3 for variant generation
- OptimizeWorker for Oban background processing
- VariantCache for startup cache validation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 00:30:42 +00:00
2b5b749a69 feat: add image optimizer module
- Add Optimizer module with lossless WebP conversion
- Generate responsive variants at [400, 800, 1200] widths
- Only create sizes <= source dimensions (no upscaling)
- Support AVIF, WebP, and JPEG output formats
- Add disk cache at priv/static/image_cache/
- Add comprehensive test suite (12 tests)
- Add image fixtures helper for testing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 22:16:21 +00:00
cefec1aabd feat: add image metadata fields for optimization pipeline
- Add source_width, source_height, variants_status fields to images table
- Remove thumbnail_data (now derived to disk cache)
- Add Oban tables via Oban.Migration.up(version: 12)
- Update Image schema changeset to include new fields

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 22:08:19 +00:00
dbadd2a376 feat: add oban dependency for background jobs
Add Oban ~> 2.18 with SQLite support (Oban.Engines.Lite) for durable
background job processing. Configure aggressive pruning (60s max_age)
to keep database lean, with a dedicated images queue.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 22:01:08 +00:00
adaa564f4c docs: add image optimization pipeline plan
Detailed implementation plan for automatic image optimization:
- Lossless WebP storage in SQLite (26-41% smaller than PNG)
- AVIF/WebP/JPEG responsive variants generated to disk cache
- Oban for durable async processing with SQLite
- 10-phase incremental implementation with checkpoints
- Comprehensive test coverage strategy

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 21:56:30 +00:00
7fbde87c5b perf: improve SEO and accessibility for PageSpeed
- Add meta description tag with theme_settings.site_description fallback
- Add site_description field to ThemeSettings schema
- Fix color contrast on tertiary text (WCAG AA compliance)
  - Clean mood: #a3a3a3 → #737373
  - Warm mood: #a8a29e → #78716c
  - Cool mood: #94a3b8 → #64748b
- Add width/height attributes to product images to prevent CLS:
  - Product cards: 600x600
  - Cart items: 96x96
  - Gallery thumbnails: 150x150
  - Lightbox: 1200x1200

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 21:55:55 +00:00
f29772010e fix: resolve nested HTML documents causing LiveView binding errors
The shop.html.heex and shop_root.html.heex were both full HTML documents.
When nested (root layout + live layout), this created invalid HTML with
duplicate <!DOCTYPE>, <html>, <head>, and <body> tags.

This caused:
- "Cannot bind multiple views to the same DOM element" console errors
- Failed Lighthouse audits
- Potential rendering issues

Fix:
- shop_root.html.heex: Now contains the full HTML document with theme
  settings, CSS variables, and data attributes
- shop.html.heex: Now just passes through @inner_content

Results:
- Console errors: Gone
- Best Practices: 96 → 100
- Total Blocking Time: 140ms → 30ms
- HTML validation: Passes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 20:20:39 +00:00
5faa6c4c09 perf: self-host fonts and add /admin route
Self-hosted fonts:
- Download all 10 typefaces (35 font files, 728KB) from Google Fonts
- Create @font-face declarations in assets/css/fonts.css
- Remove Google Fonts external dependency from layouts
- Privacy improvement (no Google tracking)
- Performance improvement (no DNS lookup to fonts.googleapis.com)
- GDPR compliant (no third-party requests)

Admin access:
- Add /admin route that redirects to /admin/theme (requires auth)
- Remove Admin link from footer (too visible for visitors)
- Shop owners can bookmark or type /admin directly

Layout improvements:
- Create shop_root.html.heex as minimal root for shop pages
- Shop pages no longer show admin nav bar

Other:
- Update .gitignore to exclude digested static files
- Add PageSpeed 100% task to ROADMAP.md
- Fix test to check /users/settings instead of shop homepage

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 22:54:07 +00:00
8ab7169c1a docs: update ROADMAP and README with recent features
- Add Mobile Bottom Navigation section to ROADMAP
- Update routes table in README (collections routes)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 22:12:55 +00:00