# Berrypod A customisable e-commerce storefront for print-on-demand sellers, built with Phoenix LiveView. Professional shops without design expertise, privacy-respecting by default, fully self-hostable. ## Features ### Shop Complete storefront with all the pages you need: - **Home** — hero banner, category navigation, featured products, newsletter - **Products** — grid layout with hover effects, sorting, filtering by collection - **Product detail** — image gallery with per-colour filtering, variant selector, related products - **Cart** — drawer + full page, quantity controls, shipping estimate, cross-tab sync - **Checkout** — Stripe-hosted checkout with shipping costs, order confirmation - **Custom pages** — CMS pages at any URL with 26 block types - **Legal pages** — auto-generated privacy, delivery, and terms from actual shop settings - **Search** — FTS5 full-text search with live modal, keyboard nav, ARIA - **Contact** — contact form with order status lookup ### Admin - **Theme editor** — 8 presets, real-time preview, comprehensive customisation - **Page builder** — drag-free block editor with undo/redo, live editing on shop pages - **Analytics** — privacy-first, cookie-free, comparison mode, CSV export - **Orders** — status tracking, fulfilment timeline, provider submission - **Media library** — image management with alt text, usage tracking, orphan detection - **Activity log** — global event feed, "needs attention" tab, contextual retry - **URL redirects** — auto-redirect on slug change, 404 monitoring, dead link scanning - **Email settings** — 10 adapter options, test email, env var precedence - **Print providers** — Printify + Printful with sync, orders, shipping, webhooks ### Technical highlights - Hand-written CSS with three-layer architecture (9.8 KB gzipped shop, 17.8 KB admin) - SQLite with BLOB storage, IMMEDIATE transactions, WAL, mmap - SQLCipher encryption at rest (AES-256, optional for dev, required for prod) - Image optimisation pipeline (AVIF/WebP/JPEG responsive variants via Oban) - ETS caching for CSS, pages, redirects, favicons - 99-100 PageSpeed mobile, no-JS support across all key flows - 1679+ tests, CI with credo + dialyzer ## Getting started ### Prerequisites - Elixir 1.19+ - Erlang/OTP 28+ - Node.js 20+ (for esbuild asset bundling) ### Setup ```bash git clone cd berrypod mix setup # install deps, create DB, run migrations, build assets mix phx.server # start dev server at localhost:4000 ``` Visit `http://localhost:4000/setup` to create your admin account and connect a print provider. ### Running tests ```bash mix test # all tests mix test path/to.exs # specific file mix precommit # compile warnings + format + test (run before committing) ``` ## Project structure ``` lib/berrypod/ # core business logic ├── accounts.ex # user accounts + auth ├── analytics.ex # privacy-first pageview tracking ├── activity_log.ex # system event logging ├── cart.ex # session-based cart ├── media.ex # image uploads, optimisation, media library ├── newsletter.ex # email list + campaigns ├── orders.ex # order lifecycle + fulfilment ├── pages.ex # page builder (blocks, cache, defaults) ├── products.ex # products, variants, categories ├── providers.ex # POD provider abstraction (Printify, Printful) ├── redirects.ex # URL redirects + dead link monitoring ├── search.ex # FTS5 full-text search ├── settings.ex # theme + shop settings ├── shipping.ex # shipping rates + country detection ├── theme/ # CSS generation, presets, ETS cache └── workers/ # Oban background jobs lib/berrypod_web/ # web layer ├── components/ │ ├── layouts/ # app, admin, and shop layouts │ ├── shop_components/ # shop UI (product cards, cart, gallery, etc.) │ └── block_editor_components.ex ├── live/ │ ├── admin/ # admin LiveViews (orders, pages, media, etc.) │ ├── shop/ # shop LiveViews (home, collection, product, etc.) │ └── auth/ # authentication ├── page_renderer.ex # generic block-to-component dispatch └── controllers/ # Stripe webhooks, favicons, images, cart API assets/css/ ├── shop/ # shop component styles ├── admin/ # admin component styles ├── theme-layer1-primitives.css # design tokens ├── theme-layer2-attributes.css # theme-specific values └── theme-layer3-semantic.css # component styles ``` ## Database encryption Berrypod uses SQLCipher to encrypt the entire SQLite database at rest. Two independent secrets provide defence in depth: | Secret | Purpose | |--------|---------| | `SECRET_KEY_BASE` | Phoenix sessions, Cloak field encryption | | `SECRET_KEY_DB` | SQLCipher whole-database encryption | ### Development Encryption is optional for development. To test locally with encryption: ```bash # Generate a key (hex-only recommended) openssl rand -hex 32 # Set environment variable export SECRET_KEY_DB="your-hex-key" # Recreate database with encryption mix ecto.reset mix phx.server ``` Without `SECRET_KEY_DB`, the database is unencrypted. ### Production Both secrets are required. Generate them: ```bash mix phx.gen.secret # → SECRET_KEY_BASE openssl rand -hex 32 # → SECRET_KEY_DB (or mix phx.gen.secret) ``` For Fly.io deployment: ```bash fly secrets set SECRET_KEY_BASE="..." SECRET_KEY_DB="..." ``` ### Backup and restore Admin > Backup provides: - Database stats (size, encryption status, table breakdown) - Download backup (encrypted with same key) - Restore from backup (validates key matches) **Key management:** - Lost key = lost data. No recovery possible. - Store keys securely (password manager, secrets manager). - Backups are portable — copy file + set same key = working shop. ## Stripe setup 1. Create a [Stripe account](https://dashboard.stripe.com/register) 2. Navigate to Admin > Settings in your shop 3. Paste your secret key and click "Connect Stripe" For local webhook testing: ```bash stripe listen --forward-to localhost:4000/webhooks/stripe ``` Test cards: `4242 4242 4242 4242` (success), `4000 0000 0000 0002` (declined). ## Documentation - [PROGRESS.md](PROGRESS.md) — current status and next tasks - [ROADMAP.md](ROADMAP.md) — future vision and planned features - [CLAUDE.md](CLAUDE.md) — coding guidelines and conventions - [docs/plans/](docs/plans/) — feature implementation plans ## License AGPL-3.0