AI Image Studio, AI podcast Maker, AI product Marketing

This commit is contained in:
ajaysi
2025-11-28 14:33:52 +05:30
parent 77d7c0cde6
commit 49e2131715
122 changed files with 22311 additions and 4331 deletions

View File

@@ -22,41 +22,31 @@ class AssetType(enum.Enum):
class AssetSource(enum.Enum):
"""Source module/tool that generated the asset - covers ALL ALwrity tools."""
# Image Studio modules
IMAGE_STUDIO_CREATE = "image_studio_create"
IMAGE_STUDIO_EDIT = "image_studio_edit"
IMAGE_STUDIO_UPSCALE = "image_studio_upscale"
IMAGE_STUDIO_TRANSFORM = "image_studio_transform"
IMAGE_STUDIO_CONTROL = "image_studio_control"
IMAGE_STUDIO_SOCIAL = "image_studio_social"
IMAGE_STUDIO_BATCH = "image_studio_batch"
# Content Writers
"""Source module/tool that generated the asset."""
# Core Content Generation
STORY_WRITER = "story_writer"
BLOG_WRITER = "blog_writer"
LINKEDIN_WRITER = "linkedin_writer"
FACEBOOK_WRITER = "facebook_writer"
# Content Planning
CONTENT_PLANNING = "content_planning"
CONTENT_STRATEGY = "content_strategy"
# SEO Tools
SEO_DASHBOARD = "seo_dashboard"
SEO_TOOLS = "seo_tools"
# Research
RESEARCH = "research"
# Scheduler
SCHEDULER = "scheduler"
# Main Generation (legacy/fallback)
IMAGE_STUDIO = "image_studio"
MAIN_TEXT_GENERATION = "main_text_generation"
MAIN_IMAGE_GENERATION = "main_image_generation"
MAIN_VIDEO_GENERATION = "main_video_generation"
MAIN_AUDIO_GENERATION = "main_audio_generation"
# Social Media Writers
BLOG_WRITER = "blog_writer"
LINKEDIN_WRITER = "linkedin_writer"
FACEBOOK_WRITER = "facebook_writer"
# SEO & Content Tools
SEO_TOOLS = "seo_tools"
CONTENT_PLANNING = "content_planning"
WRITING_ASSISTANT = "writing_assistant"
# Research & Strategy
RESEARCH_TOOLS = "research_tools"
CONTENT_STRATEGY = "content_strategy"
# Product Marketing Suite
PRODUCT_MARKETING = "product_marketing"
class ContentAsset(Base):
@@ -87,18 +77,14 @@ class ContentAsset(Base):
description = Column(Text, nullable=True)
prompt = Column(Text, nullable=True) # Original prompt used for generation
tags = Column(JSON, nullable=True) # Array of tags for search/filtering
metadata = Column(JSON, nullable=True) # Additional module-specific metadata
asset_metadata = Column(JSON, nullable=True) # Additional module-specific metadata (renamed from 'metadata' to avoid SQLAlchemy conflict)
# Generation details
provider = Column(String(100), nullable=True, index=True) # AI provider used (e.g., "stability", "gemini")
model = Column(String(200), nullable=True, index=True) # Model used (full model path/name)
provider = Column(String(100), nullable=True) # AI provider used (e.g., "stability", "gemini")
model = Column(String(100), nullable=True) # Model used
cost = Column(Float, nullable=True, default=0.0) # Generation cost in USD
generation_time = Column(Float, nullable=True) # Time taken in seconds
# Status tracking
status = Column(String(50), default='completed', index=True) # completed, processing, failed, pending
error_message = Column(Text, nullable=True) # Error details if failed
# Organization
is_favorite = Column(Boolean, default=False, index=True)
collection_id = Column(Integer, ForeignKey('asset_collections.id'), nullable=True)
@@ -113,7 +99,11 @@ class ContentAsset(Base):
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
collection = relationship("AssetCollection", back_populates="assets", cascade="all, delete-orphan")
collection = relationship(
"AssetCollection",
back_populates="assets",
foreign_keys=[collection_id]
)
# Composite indexes for common query patterns
__table_args__ = (
@@ -141,5 +131,15 @@ class AssetCollection(Base):
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
assets = relationship("ContentAsset", back_populates="collection")
assets = relationship(
"ContentAsset",
back_populates="collection",
foreign_keys="[ContentAsset.collection_id]",
cascade="all, delete-orphan" # Cascade delete on the "one" side (one-to-many)
)
cover_asset = relationship(
"ContentAsset",
foreign_keys=[cover_asset_id],
uselist=False
)

View File

@@ -0,0 +1,155 @@
"""
Product Asset Models
Database models for storing product-specific assets (separate from campaign assets).
These models are for the Product Marketing Suite (product asset creation).
"""
from sqlalchemy import Column, Integer, String, DateTime, Float, Boolean, JSON, Text, ForeignKey, Index
from sqlalchemy.orm import relationship
from datetime import datetime
import enum
from models.subscription_models import Base
class ProductAssetType(enum.Enum):
"""Product asset type enum."""
IMAGE = "image"
VIDEO = "video"
AUDIO = "audio"
ANIMATION = "animation"
class ProductImageStyle(enum.Enum):
"""Product image style enum."""
STUDIO = "studio"
LIFESTYLE = "lifestyle"
OUTDOOR = "outdoor"
MINIMALIST = "minimalist"
LUXURY = "luxury"
TECHNICAL = "technical"
class ProductAsset(Base):
"""
Product asset model.
Stores product-specific assets (images, videos, audio) generated for product marketing.
"""
__tablename__ = "product_assets"
# Primary fields
id = Column(Integer, primary_key=True, autoincrement=True)
product_id = Column(String(255), nullable=False, index=True) # User-defined product ID
user_id = Column(String(255), nullable=False, index=True) # Clerk user ID
# Product information
product_name = Column(String(500), nullable=False)
product_description = Column(Text, nullable=True)
# Asset details
asset_type = Column(String(50), nullable=False, index=True) # image, video, audio, animation
variant = Column(String(100), nullable=True) # color, size, angle, etc.
style = Column(String(50), nullable=True) # studio, lifestyle, minimalist, etc.
environment = Column(String(50), nullable=True) # studio, lifestyle, outdoor, etc.
# Link to ContentAsset (unified asset library)
content_asset_id = Column(Integer, ForeignKey('content_assets.id', ondelete='SET NULL'), nullable=True, index=True)
# Generation details
provider = Column(String(100), nullable=True)
model = Column(String(100), nullable=True)
cost = Column(Float, default=0.0)
generation_time = Column(Float, nullable=True)
prompt_used = Column(Text, nullable=True)
# E-commerce integration
ecommerce_exported = Column(Boolean, default=False)
exported_to = Column(JSON, nullable=True) # Array of platform names
# Status
status = Column(String(50), default="completed", nullable=False) # completed, processing, failed
# Metadata
created_at = Column(DateTime, default=datetime.utcnow, nullable=False, index=True)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Additional metadata
metadata = Column(JSON, nullable=True) # Additional product-specific metadata
# Composite indexes
__table_args__ = (
Index('idx_user_product', 'user_id', 'product_id'),
Index('idx_user_type', 'user_id', 'asset_type'),
Index('idx_product_type', 'product_id', 'asset_type'),
)
class ProductStyleTemplate(Base):
"""
Brand style template for products.
Stores reusable brand style configurations for product asset generation.
"""
__tablename__ = "product_style_templates"
# Primary fields
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(String(255), nullable=False, index=True)
template_name = Column(String(255), nullable=False)
# Style configuration
color_palette = Column(JSON, nullable=True) # Array of brand colors
background_style = Column(String(50), nullable=True) # white, transparent, lifestyle, branded
lighting_preset = Column(String(50), nullable=True) # natural, studio, dramatic, soft
preferred_style = Column(String(50), nullable=True) # photorealistic, minimalist, luxury, technical
preferred_environment = Column(String(50), nullable=True) # studio, lifestyle, outdoor
# Brand integration
use_brand_colors = Column(Boolean, default=True)
use_brand_logo = Column(Boolean, default=False)
# Metadata
is_default = Column(Boolean, default=False) # Default template for user
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Composite indexes
__table_args__ = (
Index('idx_user_template', 'user_id', 'template_name'),
)
class EcommerceExport(Base):
"""
E-commerce platform export tracking.
Tracks product asset exports to e-commerce platforms.
"""
__tablename__ = "product_ecommerce_exports"
# Primary fields
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(String(255), nullable=False, index=True)
product_id = Column(String(255), nullable=False, index=True)
# Platform information
platform = Column(String(50), nullable=False) # shopify, amazon, woocommerce
platform_product_id = Column(String(255), nullable=True) # Product ID on the platform
# Export details
exported_assets = Column(JSON, nullable=False) # Array of asset IDs exported
export_status = Column(String(50), default="pending", nullable=False) # pending, completed, failed
error_message = Column(Text, nullable=True)
# Metadata
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
exported_at = Column(DateTime, nullable=True)
# Composite indexes
__table_args__ = (
Index('idx_user_platform', 'user_id', 'platform'),
Index('idx_product_platform', 'product_id', 'platform'),
)

View File

@@ -0,0 +1,162 @@
"""
Product Marketing Campaign Models
Database models for storing campaign blueprints and asset proposals.
"""
from sqlalchemy import Column, Integer, String, DateTime, Float, Boolean, JSON, Text, ForeignKey, Index, func
from sqlalchemy.orm import relationship
from datetime import datetime
import enum
from models.subscription_models import Base
class CampaignStatus(enum.Enum):
"""Campaign status enum."""
DRAFT = "draft"
GENERATING = "generating"
READY = "ready"
PUBLISHED = "published"
ARCHIVED = "archived"
class AssetNodeStatus(enum.Enum):
"""Asset node status enum."""
DRAFT = "draft"
PROPOSED = "proposed"
GENERATING = "generating"
READY = "ready"
APPROVED = "approved"
REJECTED = "rejected"
class Campaign(Base):
"""
Campaign blueprint model.
Stores campaign information, phases, and asset nodes.
"""
__tablename__ = "product_marketing_campaigns"
# Primary fields
id = Column(Integer, primary_key=True, autoincrement=True)
campaign_id = Column(String(255), unique=True, nullable=False, index=True)
user_id = Column(String(255), nullable=False, index=True) # Clerk user ID
# Campaign details
campaign_name = Column(String(500), nullable=False)
goal = Column(String(100), nullable=False) # product_launch, awareness, conversion, etc.
kpi = Column(String(500), nullable=True)
status = Column(String(50), default="draft", nullable=False, index=True)
# Campaign structure
phases = Column(JSON, nullable=True) # Array of phase objects
channels = Column(JSON, nullable=False) # Array of channel strings
asset_nodes = Column(JSON, nullable=True) # Array of asset node objects
# Product context
product_context = Column(JSON, nullable=True) # Product information
# Metadata
created_at = Column(DateTime, default=datetime.utcnow, nullable=False, index=True)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
proposals = relationship("CampaignProposal", back_populates="campaign", cascade="all, delete-orphan")
generated_assets = relationship("CampaignAsset", back_populates="campaign", cascade="all, delete-orphan")
# Composite indexes
__table_args__ = (
Index('idx_user_status', 'user_id', 'status'),
Index('idx_user_created', 'user_id', 'created_at'),
)
class CampaignProposal(Base):
"""
Asset proposals for a campaign.
Stores AI-generated proposals for each asset node.
"""
__tablename__ = "product_marketing_proposals"
id = Column(Integer, primary_key=True, autoincrement=True)
campaign_id = Column(String(255), ForeignKey('product_marketing_campaigns.campaign_id', ondelete='CASCADE'), nullable=False, index=True)
user_id = Column(String(255), nullable=False, index=True)
# Asset node reference
asset_node_id = Column(String(255), nullable=False, index=True)
asset_type = Column(String(50), nullable=False) # image, text, video, audio
channel = Column(String(50), nullable=False)
# Proposal details
proposed_prompt = Column(Text, nullable=False)
recommended_template = Column(String(255), nullable=True)
recommended_provider = Column(String(100), nullable=True)
recommended_model = Column(String(100), nullable=True)
cost_estimate = Column(Float, default=0.0)
concept_summary = Column(Text, nullable=True)
# Status
status = Column(String(50), default="proposed", nullable=False) # proposed, approved, rejected, generating
approved_at = Column(DateTime, nullable=True)
# Metadata
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
campaign = relationship("Campaign", back_populates="proposals")
generated_asset = relationship("CampaignAsset", back_populates="proposal", uselist=False)
# Composite indexes
__table_args__ = (
Index('idx_campaign_node', 'campaign_id', 'asset_node_id'),
Index('idx_user_status', 'user_id', 'status'),
)
class CampaignAsset(Base):
"""
Generated assets for a campaign.
Links to ContentAsset and stores campaign-specific metadata.
"""
__tablename__ = "product_marketing_assets"
id = Column(Integer, primary_key=True, autoincrement=True)
campaign_id = Column(String(255), ForeignKey('product_marketing_campaigns.campaign_id', ondelete='CASCADE'), nullable=False, index=True)
proposal_id = Column(Integer, ForeignKey('product_marketing_proposals.id', ondelete='SET NULL'), nullable=True)
user_id = Column(String(255), nullable=False, index=True)
# Asset node reference
asset_node_id = Column(String(255), nullable=False, index=True)
# Link to ContentAsset
content_asset_id = Column(Integer, ForeignKey('content_assets.id', ondelete='SET NULL'), nullable=True)
# Generation details
provider = Column(String(100), nullable=True)
model = Column(String(100), nullable=True)
cost = Column(Float, default=0.0)
generation_time = Column(Float, nullable=True)
# Status
status = Column(String(50), default="generating", nullable=False) # generating, ready, approved, published
approved_at = Column(DateTime, nullable=True)
published_at = Column(DateTime, nullable=True)
# Metadata
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
campaign = relationship("Campaign", back_populates="generated_assets")
proposal = relationship("CampaignProposal", back_populates="generated_asset")
# Composite indexes
__table_args__ = (
Index('idx_campaign_node', 'campaign_id', 'asset_node_id'),
Index('idx_user_status', 'user_id', 'status'),
)