All checks were successful
deploy / deploy (push) Successful in 4m59s
- Per-page SEO controls: meta robots directives, focus keyword, OG image - Site-wide default OG image in admin settings - FAQ block type with FAQPage JSON-LD schema - Enhanced Organization JSON-LD with business info, contact, address - Image sitemap with product images - SEO preview panel with Google/social card mockups - SEO checklist with real-time scoring - Business info section in site editor - GSC integration scaffolding (OAuth, client, cache) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
13 KiB
13 KiB
Berrypod: Project Overview
Generated April 2026. For current status, see PROGRESS.md.
Technology Stack
| Layer | Technology |
|---|---|
| Framework | Phoenix 1.8, LiveView 1.1 |
| Language | Elixir 1.19, OTP 28 |
| Database | SQLite (via Ecto + ecto_sqlite3) |
| HTTP Server | Bandit |
| Background Jobs | Oban 2.19 |
| Payments | Stripe |
| Image Processing | Image (VIPS-based) |
| Asset Build | esbuild |
| Testing | ExUnit, Mox, LazyHTML |
Project Structure
lib/
├── berrypod/ # Core business contexts
│ ├── accounts/ # User auth, TOTP
│ ├── products/ # Products, variants, provider connections
│ ├── orders/ # Orders, line items, abandoned carts
│ ├── media/ # Image upload, optimization
│ ├── pages/ # CMS pages, block editor
│ ├── theme/ # CSS generation, presets
│ ├── settings/ # Site configuration
│ ├── analytics/ # Privacy-first tracking
│ ├── providers/ # Printify/Printful abstraction
│ ├── shipping/ # Rates, country detection
│ ├── newsletter/ # Subscribers, campaigns
│ ├── reviews/ # Product reviews
│ ├── activity_log/ # Event logging
│ └── redirects/ # URL redirects, 404 tracking
└── berrypod_web/ # Web layer
├── live/admin/ # Admin LiveViews
├── live/shop/ # Shop LiveViews
├── components/ # UI components
├── controllers/ # HTTP controllers
└── plugs/ # Request middleware
Core Business Contexts
Products (lib/berrypod/products/)
- Products synced from POD providers (Printify/Printful)
- Variants with pricing, cost, availability tracking
- Image optimization pipeline (WebP conversion, AVIF/JPEG variants at 400/800/1200px)
- Denormalized fields:
cheapest_price,in_stock,on_sale - Status flow: draft → active → archived → discontinued
Orders (lib/berrypod/orders/)
- Order numbers:
SS-YYMMDD-XXXXformat - Payment tracking: pending → paid → failed → refunded
- Fulfilment: unfulfilled → submitted → processing → shipped → delivered
- Abandoned cart recovery (24hr inactivity triggers)
- Stripe session/payment intent tracking
Media & Images (lib/berrypod/media/, lib/berrypod/images/)
- BLOB storage in SQLite
- Lossless WebP conversion on upload (26-41% smaller)
- Dominant color extraction for header images
- Async variant generation via Oban workers
- Usage tracking across products, pages, themes
Pages (lib/berrypod/pages/)
- 14 system pages + unlimited custom CMS pages
- Block-based editor with 26 block types (hero, text, gallery, grid, testimonials, etc.)
- ETS caching with DB fallback
- Auto-redirect creation when URLs change
- Navigation menu integration
Theme (lib/berrypod/theme/)
- 3-layer CSS architecture:
- Primitives (CSS custom properties)
- Attributes (theme-specific rules)
- Semantic (component styles)
- 8 presets: Gallery, Studio, Boutique, etc.
- Instant switching via CSS variable injection (no reload)
- WCAG contrast checking
Analytics (lib/berrypod/analytics/)
- Privacy-first: no cookies, no personal data, GDPR-friendly
- Visitor hashing with daily-rotating salt
- Event types: pageview, product_view, add_to_cart, checkout_start, purchase
- Metrics: unique visitors, bounce rate, top pages, sources, countries, devices
- E-commerce funnel tracking with revenue
Providers (lib/berrypod/providers/)
- Behaviour-based abstraction layer
- Printify: 800+ products from 90+ print providers
- Printful: In-house production with warehousing
- Operations: test connection, fetch products, submit orders, track status, fetch shipping rates
Reviews (lib/berrypod/reviews/)
- 1-5 star ratings with text + images (up to 3)
- Verified purchase badge
- Moderation workflow: pending → approved/rejected
- Rating denormalization to products
Newsletter (lib/berrypod/newsletter/)
- Double opt-in with confirmation emails
- Plain text only (no tracking pixels)
- Campaign scheduling and bulk sending
- Global suppression list
Database Schema (26 Schemas)
Core entities:
User,UserToken- AuthenticationProduct,ProductImage,ProductVariant- CatalogProviderConnection- POD credentials (encrypted)Order,OrderItem,AbandonedCart- CommercePage,NavItem,SocialLink- ContentImage,FaviconVariant- MediaShippingRate- Rates by country/providerReview- Product reviewsNewsletter.Subscriber,Newsletter.Campaign- EmailAnalytics.Event- TrackingActivityLog.Entry- System eventsRedirects.Redirect,BrokenUrl,DeadLink- URLsSetting- Configuration (JSON, encrypted)
Background Jobs (Oban)
Scheduled (cron)
| Schedule | Worker | Purpose |
|---|---|---|
| Every 30min | FulfilmentStatusWorker |
Poll provider for order updates |
| Every 6hr | ScheduledSyncWorker |
Product sync |
| Daily 3am | RetentionWorker |
Delete old analytics |
| Daily 3:30am | DeadLinkCheckerWorker |
Scan for broken links |
| Every 5min | ScheduledCampaignWorker |
Send scheduled campaigns |
On-demand
ProductSyncWorker- Sync products from providerImageDownloadWorker- Download product imagesOptimizeWorker- Generate image variantsOrderSubmissionWorker- Submit to fulfilmentReviewRequestWorker- Send review request after deliveryCampaignSendWorker- Newsletter campaigns
Web Layer
Admin LiveViews (/admin/*)
- Dashboard, Analytics, Orders, Products, Providers
- Settings, Media, Pages, Newsletter, Reviews
- Activity log, Backup, Redirects
Shop LiveViews (public)
- Home, Collections, Products, Cart, Checkout
- Contact (with order lookup), Search, Review forms
- Custom CMS pages via catch-all route
/:slug
Key Routes
| Path | Purpose |
|---|---|
/ |
Shop home |
/collections/:slug |
Category browsing |
/products/:id |
Product detail |
/cart |
Shopping cart |
/admin |
Admin dashboard |
/admin/orders |
Order management |
/admin/pages |
Page editor |
/admin/media |
Media library |
/admin/analytics |
Analytics dashboard |
/admin/theme |
Theme editor |
/:slug |
Custom pages (catch-all) |
Asset Pipeline
No Tailwind - Hand-written CSS with:
@layerfor cascade organization- Native CSS nesting
oklch()color function- CSS custom properties for theming
Bundles:
berrypod- Main JSberrypod_shop_css- Storefront stylesberrypod_admin_css- Admin stylesberrypod_theme_css- Dynamic theme CSS
Key Features
For Shop Owners
- Product sync from Printify/Printful with image optimization
- Block-based CMS page builder (26+ block types)
- Live theme editor with 8 presets
- Privacy-first analytics (no cookies, GDPR-friendly)
- Order management with fulfilment tracking
- Abandoned cart recovery emails
- Newsletter with double opt-in
- Product review system with moderation
- Activity log for system events
For Customers
- Product browsing with collections/filters
- Session-based shopping cart
- Stripe checkout
- Order lookup via email
- Review submissions
Security & Performance
Security
- Vault encryption for secrets
- CSRF protection, secure headers
- TOTP two-factor auth for admin
- Webhook signature verification (Stripe, Printify, Printful)
Performance
- ETS caching (settings, theme CSS, pages, redirects)
- Streams for LiveView collections
- Batch analytics flushing
- Image variants with lazy generation
- Pagination throughout
Outstanding Work
Active Plans (Ready to Implement)
1. Profit-Aware Pricing & Sales (plan) ~16h
| Task | Est | Status |
|---|---|---|
| Fix Printful cost sync (catalog API cross-reference) | 45m | planned |
Cost snapshot on orders (unit_cost, gross_profit) |
1.5h | planned |
| Exact Stripe fees from Balance Transaction API | 45m | planned |
| Tax toggle + Stripe Tax integration | 1.5h | planned |
| Admin profit dashboard (margins, P&L) | 3h | planned |
| Profit-aware price editor (live margin display) | 2h | planned |
| Sales & promotions (%, fixed, scoped, scheduled) | 3h | planned |
| Margin guard (prevent profit-killing discounts) | 1h | planned |
| Announcement bar for active sales | 1.5h | planned |
2. Competitive Gaps - Phase 1: Core Commerce (plan) ~17h
| Task | Est | Status |
|---|---|---|
| Customer authentication schema | 2h | planned |
| Customer auth flows (login, register, reset) | 3h | planned |
| Link orders to customers | 1.5h | planned |
| Customer account dashboard | 2h | planned |
| Saved addresses | 1.5h | planned |
| Guest checkout linking | 1h | planned |
| PayPal SDK integration | 2h | planned |
| PayPal checkout flow | 3h | planned |
| PayPal webhooks | 1.5h | planned |
3. Competitive Gaps - Phase 2: Retention & Growth ~14h
| Task | Est | Status |
|---|---|---|
| Returns schema | 1.5h | planned |
| Return request flow | 2h | planned |
| Return admin | 2h | planned |
| Return policy settings | 1h | planned |
| Email sequence schema | 2h | planned |
| Sequence triggers & sending | 3h | planned |
| Sequence admin | 2h | planned |
| Customer data export (GDPR) | 1.5h | planned |
| Customer data deletion (GDPR) | 2h | planned |
4. Competitive Gaps - Phase 3: Scale ~7h
| Task | Est | Status |
|---|---|---|
| Blog post type | 3h | planned |
| Staff accounts & RBAC | 4h | planned |
5. SEO Enhancements (plan) ~21h
| Task | Est | Status |
|---|---|---|
| Per-page noindex/nofollow + meta descriptions | 2h | planned |
| Enhanced Organization schema | 2h | planned |
| Image sitemap entries | 1h | planned |
| SEO preview panel (Google + social cards) | 4h | planned |
| Focus keyword & SEO score/checklist | 4h | planned |
| FAQ block with FAQPage schema | 2h | planned |
| Google Search Console OAuth integration | 6h | planned |
6. Draft-then-Publish Workflow (plan) ~31h
| Phase | Description | Est |
|---|---|---|
| 0 | Site-level publishing (coming soon → live) | 1.5h |
| 1 | Page versions and drafts (auto-save, publish/discard) | 7h |
| 2 | Theme drafts | 4h |
| 3 | Settings drafts | 4h |
| 4 | Version history and rollback (diff view, history panel) | 5.5h |
| 5 | Image soft delete and trash (usage check, restore, auto-purge) | 4.5h |
| 6 | Polish and pruning (conflict handling, retention worker) | 4.25h |
Key features: auto-save drafts, explicit publish, version history with rollback, image trash/recycle bin, tiered version retention.
Platform/Business Items
| Task | Status |
|---|---|
| Platform/marketing site (brochure, pricing, sign-up) | planned |
| Separation of platform site vs AGPL open source core | planned |
Production Hardening
| Item | Description |
|---|---|
| Litestream / SQLite replication | Continuous backup to S3, point-in-time recovery |
| End-to-end & accessibility tests | Wallaby browser tests, WCAG 2.1 AA |
| Security monitoring | Paraxial.io for runtime security, bot detection, rate limiting |
| AGPL licensing | LICENSE file, contribution guidelines, release process |
Future Enhancements
| Feature | Description |
|---|---|
| Multiple print providers | Route products to different providers based on cost/type |
| Product page improvements | Pre-checkout validation, cost monitoring, better gallery |
| Editable email templates | Admin UI for customizing transactional emails |
| Hosted platform infrastructure | Multi-tenancy, OAuth connect for providers/payments |
| Migration & export | Shopify/WooCommerce import, data export |
| Internationalisation | Multi-language (Gettext), currency formatting, RTL |
Summary by Priority
High priority (core commerce):
- Customer accounts + PayPal (~17h)
- Profit-aware pricing + sales (~16h)
Medium priority (polish): 3. SEO enhancements (~21h) 4. Draft-then-publish workflow (~31h) 5. Returns system (~6.5h) 6. Email sequences (~7h)
Lower priority (scale): 7. Blog post type (3h) 8. Staff accounts & RBAC (4h) 9. Platform site (TBD)
Total estimated remaining: ~100-120h of planned work, plus the larger platform vision items.
Design Philosophy
- "One theme, infinite variations" — one solid foundation with curated customisation
- Constrained creativity — limit choices to prevent poor design outcomes
- No professional photography required — works with product mockups
- Mobile-first — all features work on touch devices
- Ethical design — no dark patterns or fake urgency
- Privacy-first — cookie-free analytics, GDPR-compliant cart recovery, no tracking pixels