- Create dedicated /admin/account page for user account management
- Move email, password, and 2FA settings from /admin/settings
- Add Account link to top of admin sidebar navigation
- Add TOTP-based two-factor authentication with NimbleTOTP
- Add TOTP verification LiveView for login flow
- Add AccountController for TOTP session management
- Remove Advanced section from settings (duplicated in dev tools)
- Remove user email from sidebar footer (replaced by Account link)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Hammer library for rate limiting with ETS backend
- Rate limit login (5/min), magic link (3/min), newsletter (10/min), API (60/min)
- Add themed 429 error page using bare shop styling
- Enable HSTS in production with rewrite_on for Fly proxy
- Add security hardening plan to docs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bump oban to 2.19+, add oban_web for real-time job monitoring.
Mounted behind admin auth with sidebar link under "Jobs".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move the 3 theme layer imports (primitives, layer2-attributes, semantic)
out of admin.css and shop.css into a new theme.css bundle loaded by all
root layouts. Eliminates 28 KB of duplication on admin pages where both
admin.css and shop.css were each embedding the same theme CSS.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stage 6 of the page builder: admin UI at /admin/pages for managing
page layouts. Page list shows all 14 pages grouped by category.
Editor supports reorder (up/down), add, remove, duplicate, save,
and reset to defaults. DirtyGuard JS hook warns on unsaved changes.
ARIA live regions announce block operations for screen readers.
Also: regenerate admin icons (81 rules via mix task with @layer
wrapping), add gen_smtp dep for SMTP email adapter, add :key to
page renderer block loop for correct LiveView diffing.
1309 tests, 0 failures.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
replace Tailwind CLI with esbuild for admin CSS bundling. admin now uses
hand-written utility classes (admin/utilities.css), static heroicon CSS
generated by mix generate_admin_icons, plain CSS colour themes extracted
from DaisyUI plugin config, and minimal resets. rename app.css to admin.css
for clarity alongside shop.css. delete vendor/daisyui-theme.js and
vendor/heroicons.js. no Tailwind dependency remains in the project.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace all Tailwind utilities in content.ex and collection.ex with
semantic CSS classes (content body, contact form, cards, reviews, etc.)
- Delete app-shop.css (Tailwind shop entry point)
- Remove shop Tailwind config from config.exs, dev.exs, mix.exs
- Remove shop Tailwind stylesheet link from shop_root.html.heex
- Add collection filter bar, empty state, and select dropdown styles
- Fix filter pill sizing (use theme font vars instead of hardcoded rem)
- Fix active pill contrast (tinted accent background + dark accent text)
- Fix --t-text-on-accent fallback for pill legibility
- Add padding/font-size to .themed-select
Shop pages now use zero Tailwind. Admin Tailwind remains for Phase 6.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- esbuild profile for shop.css bundling (dev watcher + build aliases)
- shop.css loaded as second stylesheet in shop_root layout
- LiveView display:contents rule in reset layer
- updated Lighthouse + Screenshots tasks for new esbuild target
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move LiveDashboard to /admin/dashboard behind session auth (all envs)
- Add ErrorTracker at /admin/errors for auto-captured exceptions
- Add Oban job and LiveView metrics to telemetry module
- Add logger_json for structured JSON logs in production
- Enable os_mon for CPU/disk/memory in LiveDashboard OS Data tab
- Extend logger metadata with oban_worker and oban_queue fields
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Alpine multi-stage Dockerfile (131 MB image)
- Release overlays (bin/server, bin/migrate), env.sh, Release module
- Health check endpoint at GET /health
- Fly.io config with SQLite volume mount
- Fix hardcoded paths in optimizer.ex and variant_cache.ex to use
Application.app_dir/2 (breaks in releases where Plug.Static serves
from a different directory than CWD)
- strip_beams: true in release config
- Optimised .dockerignore and .gitignore for mockup variants
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
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>
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>
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>
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>
- Update Theme Studio sidebar to use DaisyUI theme-aware classes for dark mode
- Convert Customise accordion to native details/summary elements for proper interaction
- Add "Current combination" card showing active theme settings
- Add SVG recolorer for logo color customization
- Add image controller for serving uploaded images
- Implement header background image controls (zoom, position)
- Add toggle_customise event handler to preserve accordion state across re-renders
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>