Thanks to visit codestin.com
Credit goes to github.com

Skip to content

StoreSync is a multi-location marketing operations platform that replaces spreadsheet-based campaign management with automated workflows and AI-powered content generation.

Notifications You must be signed in to change notification settings

stephen-taylor-dev/storesync

Repository files navigation

StoreSync

A multi-location marketing operations platform for retail chains to centrally manage location-specific marketing campaigns with AI-powered content generation and sophisticated approval workflows.

alt text

Work in Progess ⚠️

Important

This project is one of my experiments with Claude Code! It's still needs polishing. It's currently a work in progress.

The Problem

Retail chains with multiple locations face significant challenges in marketing operations:

  • Inconsistent Messaging: Each store creates its own marketing content, leading to brand inconsistency
  • Manual Processes: Campaign creation, approval, and deployment are time-consuming manual tasks
  • No Visibility: Corporate has limited visibility into what marketing is being used at each location
  • Scalability Issues: As the number of locations grows, managing campaigns becomes exponentially harder
  • Content Quality: Not every location has skilled marketers to create compelling content

The Solution

StoreSync provides a centralized platform where:

  1. Corporate teams create reusable campaign templates with brand guidelines
  2. Location managers customize campaigns for their specific stores
  3. Brand managers review and approve campaigns before they go live
  4. AI assists in generating high-quality, on-brand content
  5. Everyone has visibility into campaign status across all locations

Features

Campaign Management

  • Create reusable templates with Jinja2-style variables ({{location_name}}, {{discount_percentage}})
  • Customize campaigns per location while maintaining brand consistency
  • Schedule campaigns for future activation
  • Track campaign status across all locations

Approval Workflow

Complete 7-stage workflow with full audit trail:

Draft → Pending Review → Approved → Scheduled → Active → Completed
                      ↘ Rejected → (back to Draft)
  • Role-based permissions (Admin, Brand Manager, Location Manager, Viewer)
  • Required comments for rejections
  • Complete history of all approval decisions

AI Content Generation

  • Template Rendering: Automatically populate templates with location-specific data
  • AI-Enhanced Content: Generate creative marketing copy using GPT-4
  • RAG (Retrieval-Augmented Generation): Uses successful past campaigns as context for better results
  • Semantic Search: Find similar campaigns using vector embeddings

AI HTML Email Marketing

  • HTML Email Generation: AI converts plain text campaigns into responsive, brand-styled HTML emails
  • Campaign-Aware Styling: Email colors and mood automatically match campaign type (seasonal, clearance, grand opening, etc.)
  • Email Preview: Desktop/mobile preview with regeneration capability
  • Recipient Management: Add recipients via bulk input, track delivery status
  • Batch Sending: Rate-limited email delivery with status tracking (pending, sent, failed)
  • Test Emails: Send preview emails before full campaign delivery

Multi-Brand Support

  • Manage multiple brands from a single platform
  • Brand-specific templates and settings
  • Location hierarchies under each brand
  • Bulk import locations via CSV/Excel

Tech Stack

Backend

Technology Purpose
Django 5.0 Web framework
Django REST Framework REST API
PostgreSQL + pgvector Database with vector search
Celery + Redis Background task processing
LangChain + OpenAI AI content generation
django-fsm Workflow state machine

Frontend

Technology Purpose
Next.js 14 React framework
TypeScript Type safety
Tailwind CSS Styling
Zustand State management
React Query Server state & caching
React Hook Form + Zod Form handling & validation

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                         Frontend (Next.js)                       │
│                        localhost:3000                            │
└─────────────────────────────────────────────────────────────────┘
                                 │
                                 ▼
┌─────────────────────────────────────────────────────────────────┐
│                      Django REST API                             │
│                       localhost:8000                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐  │
│  │    Auth     │  │   Brands    │  │       Campaigns         │  │
│  │  (JWT)      │  │  Locations  │  │  Templates, Approvals   │  │
│  └─────────────┘  └─────────────┘  └─────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘
         │                   │                      │
         ▼                   ▼                      ▼
┌─────────────┐    ┌─────────────────┐    ┌─────────────────┐
│  PostgreSQL │    │      Redis      │    │     OpenAI      │
│  + pgvector │    │  (Task Broker)  │    │   (LLM + RAG)   │
└─────────────┘    └─────────────────┘    └─────────────────┘
                           │
                           ▼
                   ┌─────────────────┐
                   │  Celery Workers │
                   │  - Content Gen  │
                   │  - Scheduling   │
                   │  - Notifications│
                   └─────────────────┘

Data Model

┌──────────────────────────────────────────────────────────────────────────┐
│                              MODELS                                      │
├──────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌─────────────┐    ┌─────────────┐    ┌──────────────────┐              │
│  │    User     │    │    Brand    │    │ CampaignTemplate │              │
│  ├─────────────┤    ├─────────────┤    ├──────────────────┤              │
│  │ id (BigInt) │    │ id (UUID)   │    │ id (UUID)        │              │
│  │ email       │    │ name        │    │ brand_id → Brand │              │
│  │ role        │    │ slug        │    │ name             │              │
│  │ preferences │    │ logo        │    │ content_template │              │
│  │ brands (M2M)│───►│ settings    │◄───│ campaign_type    │              │
│  └─────────────┘    └─────────────┘    └──────────────────┘              │
│         │                  │                    │                        │
│         │                  ▼                    │                        │
│         │           ┌─────────────┐             │                        │
│         │           │  Location   │             │                        │
│         │           ├─────────────┤             │                        │
│         │           │ id (UUID)   │             │                        │
│         │           │ brand_id ───┼─► Brand     │                        │
│         │           │ name        │             │                        │
│         │           │ store_number│             │                        │
│         │           │ address     │             │                        │
│         │           │ attributes  │             │                        │
│         │           └──────┬──────┘             │                        │
│         │                  │                    │                        │
│         │                  ▼                    ▼                        │
│         │        ┌───────────────────────────────────┐                   │
│         │        │       LocationCampaign            │                   │
│         │        ├───────────────────────────────────┤                   │
│         │        │ id (UUID)                         │                   │
│         │        │ location_id ──────► Location      │                   │
│         │        │ template_id ──────► CampaignTemplate                  │
│         └───────►│ created_by_id ────► User          │                   │
│                  │ status (FSM)                      │                   │
│                  │ generated_content                 │                   │
│                  │ generated_html_email              │                   │
│                  │ content_embedding (Vector 1536)   │                   │
│                  │ scheduled_start / scheduled_end   │                   │
│                  └───────────────┬───────────────────┘                   │
│                                  │                                       │
│                       ┌──────────┴──────────┐                            │
│                       ▼                     ▼                            │
│              ┌─────────────────┐   ┌─────────────────┐                   │
│              │  ApprovalStep   │   │ EmailRecipient  │                   │
│              ├─────────────────┤   ├─────────────────┤                   │
│              │ id (UUID)       │   │ id (UUID)       │                   │
│              │ campaign_id ────┼─► │ campaign_id ────┼─► LocationCampaign│
│              │ approver_id ────┼─► User              │                   │
│              │ decision        │   │ email           │                   │
│              │ comments        │   │ name            │                   │
│              │ previous_status │   │ status          │                   │
│              │ new_status      │   │ sent_at         │                   │
│              └─────────────────┘   │ error_message   │                   │
│                                    └─────────────────┘                   │
└──────────────────────────────────────────────────────────────────────────┘

Key Relationships

Relationship Type Description
Brand → Locations 1:N A brand has many store locations
Brand → CampaignTemplates 1:N A brand has many reusable templates
User ↔ Brands M:N Users can manage multiple brands (via junction table)
Location → Campaigns 1:N A location has many campaigns
Template → Campaigns 1:N A template is used by many campaigns
User → Campaigns 1:N A user creates many campaigns (created_by)
Campaign → ApprovalSteps 1:N A campaign has an audit trail of approvals
User → ApprovalSteps 1:N A user makes many approval decisions (approver)
Campaign → EmailRecipients 1:N A campaign has many email recipients

Getting Started

Prerequisites

  • Docker and Docker Compose
  • Node.js 18+ (for local frontend development)
  • OpenAI API key (for AI features)

Quick Start with Docker

  1. Clone the repository

    git clone <repository-url>
    cd storesync
  2. Set up environment variables

    cp .env.example .env
    # Edit .env and add your OPENAI_API_KEY
  3. Start all services

    docker compose up -d
  4. Run database migrations

    docker compose exec backend python manage.py migrate
  5. Create a superuser

    docker compose exec backend python manage.py createsuperuser
  6. Access the application

Local Development

Backend

# Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements/local.txt

# Set environment variables
export DATABASE_URL=postgres://storesync:storesync@localhost:5432/storesync
export REDIS_URL=redis://localhost:6379/0
export OPENAI_API_KEY=your-key-here

# Run migrations
python manage.py migrate

# Start development server
python manage.py runserver

Frontend

cd frontend

# Install dependencies
npm install

# Start development server
npm run dev

API Overview

Authentication

POST /api/v1/auth/token/           # Login (returns JWT tokens)
POST /api/v1/auth/token/refresh/   # Refresh access token
POST /api/v1/auth/register/        # Register new user
GET  /api/v1/auth/me/              # Get current user

Brands & Locations

GET/POST     /api/v1/brands/
GET/PATCH    /api/v1/brands/{id}/
GET/POST     /api/v1/brands/{id}/locations/
POST         /api/v1/brands/{id}/locations/bulk_import/

Campaign Templates

GET/POST     /api/v1/campaigns/templates/
GET/PATCH    /api/v1/campaigns/templates/{id}/

Campaigns

GET/POST     /api/v1/campaigns/
GET/PATCH    /api/v1/campaigns/{id}/

# Workflow Actions
POST         /api/v1/campaigns/{id}/submit/
POST         /api/v1/campaigns/{id}/approve/
POST         /api/v1/campaigns/{id}/reject/
POST         /api/v1/campaigns/{id}/schedule/

# AI Features
POST         /api/v1/campaigns/{id}/generate_content/
POST         /api/v1/campaigns/similar/

# HTML Email
POST         /api/v1/campaigns/{id}/generate_html_email/
GET          /api/v1/campaigns/{id}/email_preview/
POST         /api/v1/campaigns/{id}/add_recipients/
GET          /api/v1/campaigns/{id}/recipients/
POST         /api/v1/campaigns/{id}/send_emails/
POST         /api/v1/campaigns/{id}/send_test_email/
GET          /api/v1/campaigns/{id}/email_status/
DELETE       /api/v1/campaigns/{id}/clear_recipients/

Full API documentation available at /api/docs/ (Swagger UI) or /api/redoc/.

Project Structure

storesync/
├── apps/
│   ├── users/          # User authentication & roles
│   ├── brands/         # Brand & location management
│   ├── campaigns/      # Templates, campaigns, approvals
│   │   └── services/   # AI content generation, similarity search
│   └── core/           # Shared utilities
├── config/             # Django settings & URLs
├── frontend/
│   ├── src/
│   │   ├── app/        # Next.js pages (App Router)
│   │   ├── components/ # React components
│   │   ├── hooks/      # Custom React hooks
│   │   ├── lib/        # API client, utilities
│   │   ├── stores/     # Zustand stores
│   │   └── types/      # TypeScript types
│   └── e2e/            # Playwright tests
├── requirements/       # Python dependencies
└── docker-compose.yml  # Docker services

Testing

Backend Tests

# Run all tests
docker compose exec backend pytest

# Run with coverage
docker compose exec backend pytest --cov=apps --cov-report=html

Frontend Tests

cd frontend

# Unit tests
npm test

# Unit tests with coverage
npm run test:coverage

# E2E tests (requires running application)
npm run test:e2e

Environment Variables

Variable Description Required
SECRET_KEY Django secret key Yes
DEBUG Enable debug mode No (default: False)
DATABASE_URL PostgreSQL connection URL Yes
REDIS_URL Redis connection URL Yes
OPENAI_API_KEY OpenAI API key for AI features No*
ALLOWED_HOSTS Allowed host headers Yes (production)
CORS_ALLOWED_ORIGINS Allowed CORS origins Yes
EMAIL_HOST SMTP server hostname No**
EMAIL_PORT SMTP server port No (default: 587)
EMAIL_HOST_USER SMTP username No**
EMAIL_HOST_PASSWORD SMTP password No**
EMAIL_USE_TLS Use TLS for SMTP No (default: True)
DEFAULT_FROM_EMAIL Default sender address No

*AI features will be disabled without an OpenAI API key

**Email sending features require SMTP configuration

User Roles

Role Permissions
Admin Full system access
Brand Manager Approve/reject campaigns, manage templates
Location Manager Create and submit campaigns
Viewer Read-only access

Background Tasks

StoreSync uses Celery for background processing:

On-Demand Tasks

  • Content Generation: Async AI content generation with retries
  • HTML Email Generation: Convert plain text to responsive HTML emails
  • Email Batch Sending: Rate-limited email delivery (5 emails/second)
  • Test Email: Send preview emails to verify content
  • Embedding Computation: Batch vector embedding generation

Scheduled Tasks (Celery Beat)

Task Schedule Description
Activate Campaigns Every 5 min Transition scheduled → active
Complete Campaigns Every 5 min Transition active → completed (past end date)
Approval Digest Daily 9 AM Email summary of pending approvals
Data Cleanup Weekly (Sun 2 AM) Remove old approval history (>1 year)

Monitor tasks at http://localhost:5555 (Celery Flower).

License

This project is proprietary software. All rights reserved.

About

StoreSync is a multi-location marketing operations platform that replaces spreadsheet-based campaign management with automated workflows and AI-powered content generation.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •