[object Object]

← back to Shopify Apps

initial scaffold (gitify-all 2026-05-06)

a7a5c9a26efcbb4f043c3be456cc1885e188cd6f · 2026-05-06 10:25:47 -0700 · Steve Abrams

Files touched

Diff

commit a7a5c9a26efcbb4f043c3be456cc1885e188cd6f
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed May 6 10:25:47 2026 -0700

    initial scaffold (gitify-all 2026-05-06)
---
 .gitignore             |  12 ++
 color-dots/APP-SPEC.md | 480 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 492 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7e6a9c3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+node_modules/
+.env
+.env.local
+.env.*.local
+.env.*
+tmp/
+*.log
+.DS_Store
+dist/
+build/
+.next/
+*.bak
diff --git a/color-dots/APP-SPEC.md b/color-dots/APP-SPEC.md
new file mode 100644
index 0000000..ebc6dc4
--- /dev/null
+++ b/color-dots/APP-SPEC.md
@@ -0,0 +1,480 @@
+# Color Dots by DW -- Shopify App Specification
+
+## Overview
+
+**App Name:** Color Dots by DW
+**Type:** Shopify App (Theme App Extension + Backend)
+**Status:** Future Product (spec phase)
+
+Color Dots displays AI-analyzed color swatches as hex dot circles below product images on Shopify product pages. Each dot represents a color found in the product image, labeled with its hex code and the percentage of the image it occupies.
+
+---
+
+## How It Works
+
+1. Store owner installs the app from the Shopify App Store.
+2. The app adds a Theme App Extension (app block) that renders color dots on the product page.
+3. The app backend uses Gemini AI vision to analyze product images.
+4. Results are stored as product metafields: `color_dots.color_details` (JSON array of `[{name, hex, pct}]`).
+5. The theme block reads the metafield and renders colored circles.
+6. Colors also auto-populate product tags for Smart Collection integration.
+
+---
+
+## Technical Architecture
+
+### Theme App Extension (Frontend)
+
+- **App block:** `color-dots-block.liquid` -- renders dots from metafield data.
+- No JavaScript framework needed -- vanilla JS reads a data attribute and creates DOM elements.
+- Responsive design, works on all Shopify Online Store 2.0 themes.
+- Merchant-configurable settings:
+  - Dot size (small / medium / large)
+  - Max colors to display (1--8)
+  - Show/hide color name labels
+  - Show/hide percentage labels
+  - Position (below images, below title, in sidebar, custom)
+
+### App Backend (Node.js)
+
+- **Shopify App Bridge + Polaris** for the embedded settings UI inside Shopify Admin.
+- **Gemini 2.0 Flash** integration for image analysis (vision model).
+- Bulk analysis queue with progress tracking.
+- Webhook listener for `products/create` and `products/update` -- auto-analyze new products.
+- Rate limiting and cost tracking per store.
+- OAuth 2.0 install flow with session tokens.
+
+### Data Flow
+
+```
+Product Image
+    |
+    v
+Gemini 2.0 Flash (Vision API)
+    |
+    v
+Color extraction: [{name, hex, pct}, ...]
+    |
+    +---> Shopify Metafield (color_dots.color_details)
+    |
+    +---> Shopify Product Tags (color names)
+    |
+    v
+Theme App Block reads metafield --> renders dots on storefront
+```
+
+---
+
+## Metafield Schema
+
+```json
+{
+  "namespace": "color_dots",
+  "key": "color_details",
+  "type": "json",
+  "value": [
+    { "name": "Coral", "hex": "#F05B4A", "pct": 45 },
+    { "name": "Olive Green", "hex": "#D2D687", "pct": 30 },
+    { "name": "Cream", "hex": "#FFF5E1", "pct": 15 },
+    { "name": "Charcoal", "hex": "#36454F", "pct": 10 }
+  ]
+}
+```
+
+Each entry:
+- `name` (string) -- Human-readable color name (e.g., "Coral", "Dusty Rose").
+- `hex` (string) -- Hex color code including `#` prefix.
+- `pct` (integer) -- Percentage of the image occupied by this color (0--100). Values should sum to approximately 100.
+
+---
+
+## API Endpoints
+
+| Method | Path | Description |
+|--------|------|-------------|
+| POST | `/api/analyze` | Analyze a single product image. Accepts `{product_id}` or `{image_url}`. Returns color data. |
+| POST | `/api/bulk-analyze` | Queue bulk analysis for an entire catalog or a filtered set of products. Returns `{job_id}`. |
+| GET | `/api/progress` | Bulk analysis progress. Returns `{job_id, total, completed, failed, status}`. |
+| GET | `/api/colors/:product_id` | Get color data for a specific product. Returns the metafield JSON. |
+| POST | `/api/settings` | Update app settings (dot size, max colors, auto-tag toggle, etc.). |
+| POST | `/api/webhooks/products` | Webhook receiver for `products/create` and `products/update` events. |
+
+### Authentication
+
+All API endpoints require a valid Shopify session token (App Bridge) or webhook HMAC verification.
+
+---
+
+## Pricing Tiers
+
+### Free Plan
+
+- 50 product analyses per month
+- Basic color dots display
+- Up to 4 colors per product
+- Standard dot sizes
+
+### Pro Plan -- $9.99/month
+
+- Unlimited product analyses
+- Up to 8 colors per product
+- Color-based Smart Collection auto-builder (create collections like "Blue Products", "Earth Tones")
+- "Search by Color" storefront page (color picker that filters products)
+- Pinterest Rich Pin color data integration
+- Priority analysis queue
+
+### Enterprise Plan -- $29.99/month
+
+- Everything in Pro
+- API access for headless / Hydrogen stores
+- Color trend analytics dashboard (most popular colors in your catalog, seasonal trends)
+- Custom color matching / brand palette enforcement (flag products that deviate from brand colors)
+- White-label (remove "Color Dots" branding)
+- Priority support (24h response)
+
+---
+
+## Competitive Advantage
+
+- **AI-powered** -- competitors rely on manual color tagging or basic pixel sampling.
+- **Hex codes with percentages** -- not just vague color names; precise data for each color.
+- **Background color identification** -- unique feature that separates background from subject colors.
+- **Feeds into search, collections, and external channels** -- colors become actionable data, not just display.
+- **Zero manual work** -- fully automated from install to rendering.
+- **Proven at scale** -- prototype already tested on 388K+ product catalog.
+
+---
+
+## Development Stack
+
+| Layer | Technology |
+|-------|-----------|
+| Backend | Node.js + Express |
+| App Framework | Shopify CLI + App Bridge |
+| Admin UI | Shopify Polaris (React components) |
+| AI Vision | Gemini 2.0 Flash API |
+| Database | PostgreSQL (analysis cache, deduplication, job queue) |
+| Frontend (storefront) | Theme App Extension -- Liquid + vanilla JS |
+| Hosting | Railway / Fly.io / self-hosted VPS |
+| Queue | Bull (Redis-backed) or pg-boss (PostgreSQL-backed) |
+
+---
+
+## MVP Features (v1.0)
+
+1. **Theme app block** -- color dot circles rendered from metafield data on the product page.
+2. **Single product analysis** -- analyze one product at a time via the app UI in Shopify Admin.
+3. **Bulk analysis** -- analyze the entire catalog with a progress bar in the admin UI.
+4. **Settings panel** -- configure dot size, max colors, label visibility, and position.
+5. **Auto-tag products** -- automatically add color name tags to products after analysis.
+6. **Webhook auto-analysis** -- new products are analyzed automatically on creation.
+
+---
+
+## Future Features (v2.0+)
+
+- **Search by Color page** -- a storefront page with a color picker; selecting a color shows matching products.
+- **Color palette generator** -- "products that match this color scheme" recommendations.
+- **Shopify Flow integration** -- trigger on new product creation to auto-analyze (Flow connector).
+- **Multi-language color names** -- localized color names (EN, FR, DE, ES, JP, etc.).
+- **Color accessibility checker** -- WCAG contrast ratio checks for text-over-image scenarios.
+- **Color trend reports** -- monthly email digest showing catalog color distribution and trends.
+- **Complementary product suggestions** -- "This product pairs well with..." based on color harmony rules.
+- **Inventory-by-color dashboard** -- view stock levels grouped by dominant color.
+
+---
+
+## Existing Prototype
+
+A working prototype is deployed on the DW development store:
+
+- **Store:** designer-laboratory-sandbox.myshopify.com
+- **Snippet:** `snippets/color-dots.liquid`
+- **Backend enrichment:** `/root/DW-Agents/vendor-scrapers/enrich-ai-tags.js`
+- **Tracking table:** `enrichment_tracking` (388K+ products, deduplication built in)
+- **Test product:** Thibaut T75490 -- 4 colors with hex codes and percentages rendering correctly.
+
+The prototype validates the core concept and AI analysis pipeline. The Shopify App packaging (OAuth, App Bridge, Theme App Extension, billing) is what remains for productization.
+
+---
+
+## Theme App Block -- Rendering Specification
+
+### Liquid Template (`color-dots-block.liquid`)
+
+The block reads `product.metafields.color_dots.color_details` and renders a row of circular swatches.
+
+```liquid
+{% assign color_data = product.metafields.color_dots.color_details.value %}
+{% if color_data != blank %}
+<div class="color-dots-container" data-colors='{{ color_data | json }}'>
+  {% for color in color_data limit: block.settings.max_colors %}
+    <div class="color-dot-item">
+      <span class="color-dot"
+            style="background-color: {{ color.hex }};
+                   width: {{ block.settings.dot_size }}px;
+                   height: {{ block.settings.dot_size }}px;">
+      </span>
+      {% if block.settings.show_label %}
+        <span class="color-dot-label">{{ color.name }}</span>
+      {% endif %}
+      {% if block.settings.show_pct %}
+        <span class="color-dot-pct">{{ color.pct }}%</span>
+      {% endif %}
+    </div>
+  {% endfor %}
+</div>
+{% endif %}
+```
+
+### Block Settings Schema
+
+```json
+{
+  "name": "Color Dots",
+  "target": "section",
+  "settings": [
+    {
+      "type": "range",
+      "id": "dot_size",
+      "label": "Dot size (px)",
+      "min": 16,
+      "max": 48,
+      "step": 4,
+      "default": 28
+    },
+    {
+      "type": "range",
+      "id": "max_colors",
+      "label": "Max colors to display",
+      "min": 1,
+      "max": 8,
+      "step": 1,
+      "default": 4
+    },
+    {
+      "type": "checkbox",
+      "id": "show_label",
+      "label": "Show color name",
+      "default": true
+    },
+    {
+      "type": "checkbox",
+      "id": "show_pct",
+      "label": "Show percentage",
+      "default": false
+    }
+  ]
+}
+```
+
+### CSS
+
+```css
+.color-dots-container {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 12px;
+  margin: 16px 0;
+  align-items: center;
+}
+
+.color-dot-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 4px;
+}
+
+.color-dot {
+  display: inline-block;
+  border-radius: 50%;
+  border: 2px solid #e0e0e0;
+  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
+  cursor: pointer;
+  transition: transform 0.15s ease;
+}
+
+.color-dot:hover {
+  transform: scale(1.15);
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
+}
+
+.color-dot-label {
+  font-size: 11px;
+  color: #666;
+  text-align: center;
+  max-width: 60px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.color-dot-pct {
+  font-size: 10px;
+  color: #999;
+}
+```
+
+---
+
+## Gemini AI Analysis -- Prompt Specification
+
+The image analysis prompt sent to Gemini 2.0 Flash:
+
+```
+Analyze this product image and identify the distinct colors present.
+
+For each color, provide:
+- name: A human-readable color name (e.g., "Dusty Rose", "Navy Blue", "Sage Green")
+- hex: The hex color code (e.g., "#F05B4A")
+- pct: The approximate percentage of the image this color occupies (integer, 0-100)
+
+Return ONLY a JSON array. No markdown, no explanation. Example:
+[
+  {"name": "Coral", "hex": "#F05B4A", "pct": 45},
+  {"name": "Olive Green", "hex": "#D2D687", "pct": 30},
+  {"name": "Cream", "hex": "#FFF5E1", "pct": 15},
+  {"name": "Charcoal", "hex": "#36454F", "pct": 10}
+]
+
+Rules:
+- Return between 2 and 8 colors.
+- Percentages should sum to approximately 100.
+- Order by percentage descending (most dominant first).
+- Use descriptive, customer-friendly color names (not "Color 1").
+- Identify background colors separately from product colors.
+```
+
+---
+
+## Database Schema (PostgreSQL)
+
+```sql
+CREATE TABLE color_analyses (
+  id SERIAL PRIMARY KEY,
+  shop_domain TEXT NOT NULL,
+  product_id BIGINT NOT NULL,
+  image_url TEXT NOT NULL,
+  image_hash TEXT,                -- SHA256 for dedup
+  color_data JSONB NOT NULL,     -- [{name, hex, pct}]
+  model_used TEXT DEFAULT 'gemini-2.0-flash',
+  tokens_used INTEGER,
+  analysis_cost NUMERIC(8,6),
+  created_at TIMESTAMPTZ DEFAULT NOW(),
+  updated_at TIMESTAMPTZ DEFAULT NOW(),
+  UNIQUE(shop_domain, product_id)
+);
+
+CREATE TABLE analysis_jobs (
+  id SERIAL PRIMARY KEY,
+  shop_domain TEXT NOT NULL,
+  job_type TEXT NOT NULL,         -- 'single' or 'bulk'
+  status TEXT DEFAULT 'pending',  -- pending, running, completed, failed
+  total_products INTEGER DEFAULT 0,
+  completed_products INTEGER DEFAULT 0,
+  failed_products INTEGER DEFAULT 0,
+  started_at TIMESTAMPTZ,
+  completed_at TIMESTAMPTZ,
+  created_at TIMESTAMPTZ DEFAULT NOW()
+);
+
+CREATE TABLE app_settings (
+  id SERIAL PRIMARY KEY,
+  shop_domain TEXT UNIQUE NOT NULL,
+  plan TEXT DEFAULT 'free',       -- free, pro, enterprise
+  auto_analyze BOOLEAN DEFAULT TRUE,
+  auto_tag BOOLEAN DEFAULT TRUE,
+  max_colors INTEGER DEFAULT 4,
+  dot_size INTEGER DEFAULT 28,
+  show_labels BOOLEAN DEFAULT TRUE,
+  show_pct BOOLEAN DEFAULT FALSE,
+  monthly_analyses_used INTEGER DEFAULT 0,
+  monthly_reset_at TIMESTAMPTZ,
+  installed_at TIMESTAMPTZ DEFAULT NOW(),
+  updated_at TIMESTAMPTZ DEFAULT NOW()
+);
+
+CREATE INDEX idx_color_analyses_shop ON color_analyses(shop_domain);
+CREATE INDEX idx_color_analyses_product ON color_analyses(product_id);
+CREATE INDEX idx_analysis_jobs_shop ON analysis_jobs(shop_domain);
+```
+
+---
+
+## Shopify App Configuration
+
+### `shopify.app.toml`
+
+```toml
+name = "Color Dots"
+client_id = ""  # Assigned on app creation
+application_url = "https://colordots.app"
+embedded = true
+
+[access_scopes]
+scopes = "read_products,write_products"
+
+[auth]
+redirect_urls = ["https://colordots.app/auth/callback"]
+
+[webhooks]
+api_version = "2025-01"
+
+  [webhooks.subscriptions]
+  topics = ["products/create", "products/update", "app/uninstalled"]
+  uri = "/api/webhooks"
+
+[app_proxy]
+url = "https://colordots.app/api/proxy"
+subpath = "color-dots"
+prefix = "apps"
+
+[pos]
+embedded = false
+```
+
+### Required Shopify Scopes
+
+- `read_products` -- Read product data and images for analysis.
+- `write_products` -- Write metafields and tags back to products.
+
+---
+
+## Billing Integration
+
+Use Shopify Billing API (`recurring_application_charge`) for subscription management.
+
+- Free plan: no charge created.
+- Pro plan: `$9.99/month`, `test: true` in development.
+- Enterprise plan: `$29.99/month`, `test: true` in development.
+- Usage charges for overage on free plan (optional future feature).
+- 7-day free trial on Pro and Enterprise.
+
+---
+
+## Security Considerations
+
+- All webhook payloads verified via HMAC-SHA256.
+- Session tokens validated on every API request.
+- Gemini API key stored as environment variable, never exposed to client.
+- Product image URLs fetched server-side only (no client-side AI calls).
+- Rate limiting: max 10 single analyses per minute per store, bulk limited to 1 concurrent job.
+- GDPR compliance: `/api/gdpr/customers-data-request`, `/api/gdpr/customers-redact`, `/api/gdpr/shop-redact` endpoints.
+
+---
+
+## App Store Listing (Draft)
+
+**Name:** Color Dots -- AI Color Swatches
+**Tagline:** Automatically display AI-detected color swatches on your product pages.
+**Category:** Store design
+
+**Key Benefits:**
+- Zero manual work -- colors detected automatically from product images.
+- Beautiful color dot circles display on any Online Store 2.0 theme.
+- Powers Smart Collections by color ("All Blue Products", "Earth Tones").
+- Increases search relevance with accurate color tags.
+- Gives customers instant visual color information.
+
+**Keywords:** color swatch, color picker, product colors, AI color detection, color tags, smart collections, color search

(oldest)  ·  back to Shopify Apps  ·  (newest)