← back to Shopify Apps
color-dots/APP-SPEC.md
481 lines
# 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