2026-01-31 14:06:07 +00:00
# SimpleShop Progress
> Single source of truth for project status and task tracking.
## Current Status
**Working:**
- Theme editor with 8 presets, instant switching, full customization
- Image optimization pipeline (AVIF/WebP/JPEG responsive variants)
2026-02-07 08:30:17 +00:00
- Shop pages (home, collections, products, cart, about, contact, error)
2026-01-31 14:06:07 +00:00
- Mobile-first design with bottom navigation
- 100% PageSpeed score
2026-02-05 22:11:16 +00:00
- Variant selector with color swatches and size buttons
2026-02-07 08:30:17 +00:00
- Session-based cart with real variant data (add/remove/quantity, cross-tab sync)
- Cart drawer and cart page with hydrated product info
2026-02-07 18:04:18 +00:00
- Stripe Checkout with order persistence and webhook handling
- Admin credentials page with guided Stripe setup flow
- Encrypted settings for API keys and secrets
2026-02-07 08:30:17 +00:00
- Search modal with keyboard shortcut
2026-02-08 10:17:19 +00:00
- Transactional emails (order confirmation, shipping notification)
2026-02-07 08:30:17 +00:00
- Demo content polished and ready for production
2026-01-31 14:06:07 +00:00
2026-02-08 10:17:19 +00:00
**Next up:** Default content pages — terms, privacy, delivery policy (Tier 1, Roadmap #4 )
2026-01-31 14:06:07 +00:00
2026-02-07 20:28:28 +00:00
## Roadmap
2026-01-31 14:06:07 +00:00
2026-02-07 20:28:28 +00:00
### Tier 1 — MVP (can take real orders and fulfil them)
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
1. ~~**Order management admin**~~ — ✅ Complete (02cdc81). Admin UI at `/admin/orders` with status filter tabs, streamed order table, and detail view showing items, totals, and shipping address.
2. ~~**Orders & fulfilment**~~ — ✅ Complete. Submit paid orders to Printify, track fulfilment status (submitted → processing → shipped → delivered), webhook-driven status updates with polling fallback, admin UI with submit/refresh actions.
2026-02-08 10:17:19 +00:00
3. ~~**Transactional emails**~~ — ✅ Complete. Plain text order confirmation (on payment via Stripe webhook) and shipping notification (on dispatch via Printify webhook + polling fallback). OrderNotifier module, 10 tests.
2026-02-07 20:28:28 +00:00
4. **Default content pages** — Static pages for terms of service, delivery & refunds policy, and privacy policy. Needed for legal compliance before taking real orders. Can be simple markdown-rendered pages initially, upgraded to editable via page editor later.
### Tier 2 — Production readiness (can deploy and run reliably)
5. **Hosting & deployment** — Fly.io or similar deployment config. Release configuration, runtime env setup, health checks. Observability: structured logging, error tracking (Sentry or similar), basic metrics.
6. **Litestream / SQLite replication** — Litestream for continuous SQLite backup to S3-compatible storage. Point-in-time recovery. Simple sidecar process, no code changes needed, works with vanilla SQLite. For the hosted platform (Tier 5), evaluate [Turso ](https://turso.tech/ ) (libSQL fork of SQLite) with embedded read replicas via [ecto_libsql ](https://github.com/ocean/ecto_libsql ) adapter — gives multi-node reads without a separate replication daemon, but adds a dependency on the libSQL fork.
7. **CI pipeline** — All checks implemented as mix aliases (`mix ci` wrapping `mix precommit` + credo + dialyzer). CI config is a thin wrapper that calls `mix ci` — portable across GitHub Actions, Forgejo Actions, Woodpecker, or plain SSH. No proprietary CI dependencies. Custom mix tasks for anything project-specific (e.g. `mix lighthouse` ). Oban stays for runtime background jobs, not CI.
8. **PageSpeed in CI** — Lighthouse CI to catch regressions. Fail the build if score drops below threshold. Protects the current 100% score.
9. **End-to-end tests** — Wallaby or similar for browser-based tests of critical flows: browse → add to cart → checkout → order confirmation. Covers the full happy path plus key error cases.
### Tier 3 — Compliance & quality
10. **Accessibility (a11y)** — Audit against WCAG 2.1 AA. Focus management, ARIA labels, keyboard navigation, colour contrast. Axe-core integration in CI.
11. **Privacy-respecting analytics** — Self-hosted, cookie-free analytics. Plausible, Umami, or a lightweight custom solution. No Google Analytics, no third-party tracking. GDPR-friendly by design.
12. **AGPL licensing & code hosting** — Currently AGPL-3.0. Decide on GitHub vs Codeberg vs self-hosted Forgejo. Set up proper LICENSE file, contribution guidelines, and release process.
13. **Security (Paraxial.io)** — Runtime application security monitoring for Elixir. Bot detection, rate limiting, vulnerability scanning. Evaluate whether it fits the self-hosted model.
### Tier 4 — Growth & content
14. **Page editor** — Database-driven pages with drag-and-drop sections. Extend the theme system to custom pages beyond the defaults. Replaces the static content pages from Tier 1 with editable versions.
15. **Newsletter & email marketing** — Email list collection (signup forms). Campaign sending for product launches, sales. Can be simple initially (collect emails, send via Swoosh) or integrate with a service.
16. **Product page improvements** — Pre-checkout variant validation (verify Printify availability). Cost change monitoring/alerts. Better image gallery (zoom, multiple angles).
### Tier 5 — Platform vision
17. **Hosted platform** — Marketing/brochure site for SimpleShop as a service. Subscribe/sign-up flow. Multi-tenancy with per-tenant databases. Stripe Connect for customer shops (each merchant connects their own Stripe account via OAuth).
18. **Migration & export** — Let shop owners export their data (products, orders, customers, theme settings). Import from other platforms (Shopify, WooCommerce). Portable data as a selling point for the self-hosted story.
19. **Internationalisation (i18n)** — Multi-language support via Gettext (already in Phoenix). Currency formatting (ex_cldr already in deps). RTL layout support. Per-shop locale configuration.
2026-01-31 14:06:07 +00:00
---
## Feature Areas
### Theme System
**Status:** Complete
- 8 theme presets (Gallery, Studio, Boutique, etc.)
- Three-layer CSS architecture (primitives, attributes, semantic)
- Instant theme switching via CSS custom property injection
- Logo/header image uploads with SVG recoloring
- Self-hosted fonts (10 typefaces, GDPR compliant)
- ETS-cached CSS generation
### Image Optimization
**Status:** Complete
- Oban background job processing
- Responsive `<picture>` element (AVIF/WebP/JPEG)
- Only generates sizes < = source dimensions
- Disk cache for variants (regenerable from DB)
- `mix optimize_images` task for mockups
- On-demand JPEG fallback generation
2026-02-01 00:26:19 +00:00
- Product image download pipeline (downloads Printify CDN images, processes through Media pipeline)
- ImageDownloadWorker downloads and links images to ProductImage
- PreviewData uses local images for responsive `<picture>` elements
- Startup recovery re-enqueues pending downloads
- `mix simpleshop.download_images` backfill task
2026-01-31 14:06:07 +00:00
See: [docs/plans/image-optimization.md ](docs/plans/image-optimization.md ) for implementation details
### Products & Provider Integration
2026-02-05 22:11:16 +00:00
**Status:** Complete
2026-01-31 14:06:07 +00:00
- [x] Products context with schemas (c5c06d9)
- [x] Provider abstraction layer
- [x] Printify client integration
- [x] Product/variant/image schemas
2026-01-31 22:08:34 +00:00
- [x] Admin Provider Setup UI (`/admin/providers`) - connect, test, sync
- [x] ProductSyncWorker with pagination, parallel processing, error recovery
- [x] Slug-based fallback matching for changed provider IDs
2026-01-31 23:07:37 +00:00
- [x] Printify webhook endpoint with HMAC verification (a9c15ea)
- Note: Printify only supports `product:deleted` and `product:publish:*` events (no `product:updated` )
2026-02-05 22:11:16 +00:00
- [x] Product image download pipeline (1b49b47)
2026-02-01 00:26:19 +00:00
- Downloads Printify CDN images via ImageDownloadWorker
- Processes through Media pipeline (WebP conversion, AVIF/WebP variants)
- Startup recovery and `mix simpleshop.download_images` backfill
2026-02-05 22:11:16 +00:00
- [x] Variant selector component (880e7a2)
- Color swatches with hex colors, size buttons
- Fixed Printify options parsing (Color/Size swap bug)
- Filters to only published variants (not full catalog)
- Price updates on variant change
- Startup recovery for stale sync status
2026-01-31 23:07:37 +00:00
2026-01-31 22:08:34 +00:00
#### Future Enhancements (post-MVP)
- [ ] Pre-checkout variant validation (verify availability before order)
- [ ] Cost change monitoring/alerts (warn if Printify cost increased)
- [ ] OAuth platform integration (appear in Printify's "Publish to" UI)
#### Technical Debt
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
- [x] Mox provider mocking for fulfilment tests (Provider.for_type configurable via app env)
2026-01-31 22:08:34 +00:00
2026-01-31 14:06:07 +00:00
See: [docs/plans/products-context.md ](docs/plans/products-context.md ) for implementation details
2026-01-31 22:08:34 +00:00
See: [docs/plans/printify-integration-research.md ](docs/plans/printify-integration-research.md ) for API research & risk analysis
2026-01-31 14:06:07 +00:00
### Cart & Checkout
2026-02-07 18:04:18 +00:00
**Status:** Complete
2026-02-07 08:30:17 +00:00
2026-02-07 18:04:18 +00:00
- [x] Cart drawer component with slide-over panel (1bc08bf)
- [x] Cart page with item list and order summary (1bc08bf)
- [x] Shared CartHook for cross-page cart events (1bc08bf)
2026-02-07 08:30:17 +00:00
- [x] CartPersist JS hook for localStorage backup
- [x] Add-to-cart with flash status feedback
- [x] Cart item links to product pages
2026-02-07 18:04:18 +00:00
- [x] Session-based cart with real variants (1bc08bf)
2026-02-07 08:30:17 +00:00
- Cart stores {variant_id, qty} tuples in session
- Hydrates with real product data via Products context
- Cross-tab sync via PubSub, session persistence via CartController API
2026-02-07 18:04:18 +00:00
- [x] Stripe Checkout integration (ff1bc48, stripity_stripe ~> 3.2)
2026-02-07 08:30:17 +00:00
- Stripe-hosted Checkout with redirect flow
- Webhook handler for checkout.session.completed/expired
- Signature verification via CacheRawBody + construct_event
- Shipping address collection during checkout
2026-02-07 18:04:18 +00:00
- [x] Order/OrderItem schemas and context (ff1bc48)
2026-02-07 08:30:17 +00:00
- Order number format: SS-YYMMDD-XXXX
- Payment status tracking (pending → paid/failed)
- Price snapshots in OrderItem (protects against changes)
- Idempotent webhook processing
- [x] Checkout success page with real-time PubSub updates
- [x] Cart clearing after successful payment
2026-01-31 14:06:07 +00:00
See: [ROADMAP.md ](ROADMAP.md ) for design notes
2026-02-07 18:04:18 +00:00
### Admin Settings & Stripe Setup
**Status:** Complete
- [x] Encrypted settings infrastructure (eede9bb)
- `encrypted_value` column on settings table
- `put_secret/2` , `get_secret/2` , `has_secret?/1` , `secret_hint/1`
- AES-GCM encryption via `SECRET_KEY_BASE`
- Secrets loaded into Application env on startup via `Secrets.load_all/0`
- [x] Guided Stripe setup flow (eede9bb)
- `Stripe.Setup` module: connect, disconnect, verify, auto-create webhook
- Three-state admin UI: not configured, connected (production), connected (dev/localhost)
- Auto-creates Stripe webhook endpoint on production hosts
- Dev mode shows Stripe CLI instructions for localhost
- Manual signing secret input for dev/advanced use
- API key verification via `Stripe.Balance.retrieve/2`
- [x] Admin credentials page at `/admin/settings` (eede9bb)
- Single Secret key input with "Connect Stripe" button
- Masked key hints (e.g. `sk_test_•••789` )
- Disconnect button clears keys from DB and Application env
- CSSCache test startup crash fixed (handle_continue pattern)
2026-02-07 20:28:28 +00:00
### Orders & Fulfilment
2026-02-08 10:17:19 +00:00
**Status:** Complete
2026-01-31 14:06:07 +00:00
2026-02-07 20:28:28 +00:00
- [x] Orders context with schemas (ff1bc48)
- [x] Stripe Checkout integration with webhook handling
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
- [x] Order management admin UI (02cdc81, Roadmap #1 )
- Order list with status filter tabs (all/paid/pending/failed/refunded) and counts
- Streamed table with row click navigation to detail
- Order detail with info card, shipping address, line items table with totals
- Nav link in admin bar, 15 tests
- [x] Printify order submission and fulfilment tracking (Roadmap #2 )
- 9 fulfilment fields on orders (status, provider_order_id, tracking, timestamps)
- `submit_to_provider/1` with idempotent guard, error handling, address mapping
- `refresh_fulfilment_status/1` polls provider for status updates
- OrderSubmissionWorker (Oban, :checkout queue, max_attempts: 3)
- FulfilmentStatusWorker (Oban Cron, every 30 mins, :sync queue)
- Printify order webhook handlers (sent-to-production, shipment:created, shipment:delivered)
- Stripe webhook auto-enqueues submission after payment confirmed
- Admin UI: fulfilment badge column, fulfilment card with tracking, submit/refresh buttons
- Mox provider mocking for test isolation, 33 new tests (555 total)
2026-02-08 10:17:19 +00:00
- [x] Transactional emails (Roadmap #3 )
- OrderNotifier module with plain text emails via Swoosh
- Order confirmation sent from Stripe webhook after payment + address/email updates
- Shipping notification sent from Printify shipment webhook + polling fallback
- Guards for missing customer_email, graceful tracking info handling
- 10 tests (565 total)
2026-01-31 14:06:07 +00:00
See: [docs/plans/products-context.md ](docs/plans/products-context.md ) for schema design
2026-02-07 20:28:28 +00:00
### Page Editor
**Status:** Future (Tier 4)
2026-01-31 14:06:07 +00:00
2026-02-07 20:28:28 +00:00
Database-driven pages with drag-and-drop sections. Initially, default content pages (terms, privacy, delivery) will be static templates (Tier 1), later made editable via the page editor.
2026-01-31 14:06:07 +00:00
See: [docs/plans/page-builder.md ](docs/plans/page-builder.md ) for design
---
## Completed Work Reference
| Feature | Commit | Notes |
|---------|--------|-------|
2026-02-08 10:17:19 +00:00
| Transactional emails | — | Plain text order confirmation + shipping notification, 10 tests |
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
| Printify order submission & fulfilment | — | Submit, track, webhooks, polling, admin UI, 33 tests |
| Order management admin | 02cdc81 | List/detail views, status filters, 15 tests |
2026-02-07 18:04:18 +00:00
| Encrypted settings & Stripe setup | eede9bb | Guided setup flow, encrypted secrets, admin credentials page |
| Stripe checkout & orders | ff1bc48 | Stripe Checkout, webhooks, order persistence |
2026-02-07 08:30:17 +00:00
| Demo content & link fixes | cff2170 | Broken links, placeholder text, responsive about image |
2026-02-07 18:04:18 +00:00
| Cart UI infrastructure | 1bc08bf | Cart drawer, cart page, CartHook, CartPersist |
2026-02-05 22:11:16 +00:00
| Variant selector | 880e7a2 | Color swatches, size buttons, price updates |
| Product image download | 1b49b47 | PageSpeed 100% with local images |
| Wire shop to real data | c818d03 | PreviewData uses Products context |
| Printify webhooks | a9c15ea | Deletion + publish events |
2026-01-31 14:06:07 +00:00
| Products context Phase 1 | c5c06d9 | Schemas, provider abstraction |
2026-01-31 22:41:45 +00:00
| Admin provider setup UI | 5b736b9 | Connect, test, sync with pagination |
2026-01-31 14:06:07 +00:00
| Oban Lifeline plugin | c1e1988 | Rescue orphaned jobs |
| Image optimization | Multiple | Full pipeline complete |
| Self-hosted fonts | - | 10 typefaces, 728KB |
| Mobile bottom nav | - | Fixed tab bar |
| PageSpeed 100% | - | All optimizations |
| Theme presets (8) | - | Gallery, Studio, etc. |