Skip to content
Business Forge Engineer logo

Business Forge Engineer

Especialista en Business Forge: gestión de assets post-magia, Fusion Engine y generación de visuales.

SKILL.md

Full skill instructions

Business Forge Engineer - Platform AI Solutions

1. Concepto: The Business Forge

Filosofía

El Business Forge es el estudio post-magia donde los usuarios refinan y utilizan los assets generados por el proceso de "Hacer Magia".

Capacidades

  • Canvas: Visualizar assets generados (branding, scripts, ROI, visuals)
  • Smart Catalog: Browser de productos brutos de Tienda Nube
  • Fusion Engine: Generación de imágenes publicitarias on-demand
  • Reality vs Dream Mode: Overlay de producto real sobre fondo IA

Arquitectura

Frontend (BusinessForge.tsx)
    ↓
Tab System (Canvas | Smart Catalog)
    ↓
Canvas → GET /​admin/​assets (filtrado por type)
    ↓
Smart Catalog → GET /​admin/​products
    ↓
Fusion Engine → POST /​admin/​generate-image
    ↓
Google Imagen 3 → Visual Asset

2. Frontend: Tab System

BusinessForge Component

const BusinessForge: React.FC = () => {
  const [activeTab, setActiveTab] = useState<'canvas' | 'catalog'>('canvas');
  const [assets, setAssets] = useState<Asset[]>([]);
  const [products, setProducts] = useState<Product[]>([]);
  
  useEffect(() => {
    if (activeTab === 'canvas') {
      loadAssets();
    } else {
      loadProducts();
    }
  }, [activeTab]);
  
  const loadAssets = async () => {
    const data = await useApi<Asset[]>({
      method: 'GET',
      url: '/​admin/​assets'
    });
    setAssets(data);
  };
  
  const loadProducts = async () => {
    const data = await useApi<Product[]>({
      method: 'GET',
      url: '/​admin/​products'
    });
    setProducts(data);
  };
  
  return (
    <div className="forge-container">
      {/​* Tab Navigation */​}
      <div className="tabs">
        <button
          className={activeTab === 'canvas' ? 'active' : ''}
          onClick={() => setActiveTab('canvas')}
        >
          🎨 Canvas
        </​button>
        <button
          className={activeTab === 'catalog' ? 'active' : ''}
          onClick={() => setActiveTab('catalog')}
        >
          📦 Smart Catalog
        </​button>
      </​div>
      
      {/​* Content */​}
      <div className="forge-content">
        {activeTab === 'canvas' ? (
          <CanvasView assets={assets} />
        ) : (
          <CatalogView products={products} />
        )}
      </​div>
    </​div>
  );
};

3. Canvas View (Assets Generados)

Filtrado por Tipo

const CanvasView: React.FC<{ assets: Asset[] }> = ({ assets }) => {
  const [filter, setFilter] = useState<AssetType>('all');
  
  const filteredAssets = filter === 'all'
    ? assets
    : assets.filter(a => a.type === filter);
  
  return (
    <div className="canvas-view">
      {/​* Filtros */​}
      <div className="filters">
        <button onClick={() => setFilter('all')}>All</​button>
        <button onClick={() => setFilter('branding')}>🧬 Branding</​button>
        <button onClick={() => setFilter('scripts')}>📝 Scripts</​button>
        <button onClick={() => setFilter('roi')}>💰 ROI</​button>
        <button onClick={() => setFilter('visuals')}>🎨 Visuals</​button>
      </​div>
      
      {/​* Asset Grid */​}
      <div className="asset-grid">
        {filteredAssets.map(asset => (
          <AssetCard key={asset.id} asset={asset} />
        ))}
      </​div>
    </​div>
  );
};

Asset Card (Polymorphic Renderer)

const AssetCard: React.FC<{ asset: Asset }> = ({ asset }) => {
  const renderContent = () => {
    switch (asset.type) {
      case 'branding':
        return <BrandingAsset content={asset.content} />;
      
      case 'scripts':
        return <ScriptsAsset content={asset.content} />;
      
      case 'roi':
        return <ROIAsset content={asset.content} />;
      
      case 'visuals':
        return <VisualsAsset content={asset.content} />;
      
      default:
        return <JSONView data={asset.content} />;
    }
  };
  
  return (
    <div className="asset-card">
      <div className="asset-header">
        <h3>{asset.type}</​h3>
        <span className="timestamp">
          {new Date(asset.created_at).toLocaleDateString()}
        </​span>
      </​div>
      
      <div className="asset-body">
        {renderContent()}
      </​div>
    </​div>
  );
};

Branding Asset

const BrandingAsset: React.FC<{ content: BrandingContent }> = ({ content }) => {
  return (
    <div className="branding-asset">
      <div className="section">
        <h4>MISIÓN</​h4>
        <p>{content.mission}</​p>
      </​div>
      
      <div className="section">
        <h4>VISIÓN</​h4>
        <p>{content.vision}</​p>
      </​div>
      
      <div className="section">
        <h4>VOZ DE MARCA</​h4>
        <p>{content.voice}</​p>
      </​div>
      
      <div className="section">
        <h4>VALORES</​h4>
        <ul>
          {content.values.map((v, i) => (
            <li key={i}>{v}</​li>
          ))}
        </​ul>
      </​div>
      
      <div className="color-palette">
        <h4>PALETA DE COLORES</​h4>
        <div className="colors">
          {content.color_palette.map((color, i) => (
            <div
              key={i}
              className="color-swatch"
              style={{ backgroundColor: color }}
              title={color}
            />
          ))}
        </​div>
      </​div>
    </​div>
  );
};

Visuals Asset (Social Posts)

const VisualsAsset: React.FC<{ content: VisualsContent }> = ({ content }) => {
  return (
    <div className="visuals-grid">
      {content.social_posts.map((post, i) => (
        <FusionItem key={i} post={post} />
      ))}
    </​div>
  );
};

4. Fusion Engine (Generación On-Demand)

FusionItem Component

interface FusionPost {
  product_id: string;
  product_name: string;
  image_url: string;  // URL de la imagen generada por IA
  base_image?: string;  // URL original del producto (para overlay)
  prompt_used: string;
}

const FusionItem: React.FC<{ post: FusionPost }> = ({ post }) => {
  const [viewMode, setViewMode] = useState<'dream' | 'reality'>('dream');
  
  return (
    <div className="fusion-item">
      <div className="image-container">
        {viewMode === 'dream' ? (
          // Imagen pura de IA (puede alucinar detalles)
          <img src={post.image_url} alt={post.product_name} />
        ) : (
          // Overlay: fondo IA + producto real
          <div className="reality-overlay">
            <img
              src={post.image_url}
              className="background"
              alt="AI Background"
            />
            <img
              src={post.base_image}
              className="product-overlay"
              alt={post.product_name}
              style={{
                position: 'absolute',
                top: '50%',
                left: '50%',
                transform: 'translate(-50%, -50%)',
                maxWidth: '60%',
                maxHeight: '60%',
                mixBlendMode: 'multiply'
              }}
            />
          </​div>
        )}
      </​div>
      
      <div className="fusion-controls">
        <button
          onClick={() => setViewMode(viewMode === 'dream' ? 'reality' : 'dream')}
        >
          {viewMode === 'dream' ? '🌟 Dream' : '✨ Reality'}
        </​button>
      </​div>
      
      <div className="product-info">
        <h4>{post.product_name}</​h4>
        <p className="prompt-hint">{post.prompt_used}</​p>
      </​div>
    </​div>
  );
};

Generar Nueva Imagen (Fusion Button)

const ProductCard: React.FC<{ product: Product }> = ({ product }) => {
  const [generating, setGenerating] = useState(false);
  
  const handleIgniteFusion = async () => {
    setGenerating(true);
    
    try {
      const prompt = `
Professional advertising shot of ${product.name}.
Luxury aesthetic, soft lighting, minimal background.
High-end product photography, studio quality.
`;
      
      const response = await useApi({
        method: 'POST',
        url: '/​admin/​generate-image',
        data: {
          prompt: prompt,
          image_url: product.image_url
        }
      });
      
      if (response.status === 'success') {
        // Guardar en assets
        await saveGeneratedVisual(response.url, product);
        alert('Visual generated!');
      }
      
    } catch (error) {
      alert('Generation failed');
    } finally {
      setGenerating(false);
    }
  };
  
  return (
    <div className="product-card">
      <img src={product.image_url} alt={product.name} />
      <h3>{product.name}</​h3>
      <p>${product.price}</​p>
      
      <button
        onClick={handleIgniteFusion}
        disabled={generating}
        className="fusion-btn"
      >
        {generating ? 'Generating...' : '🔥 Ignite Fusion'}
      </​button>
    </​div>
  );
};

5. Backend: Fusion Engine

generate-image Endpoint

# orchestrator_service/​app/​api/​v1/​endpoints/​forge.py

@router.post("/​admin/​generate-image")
async def generate_image(
    payload: ImageGenerationRequest,
    current_user = Depends(verify_admin_token)
):
    """
    Genera imagen publicitaria usando Google Imagen 3
    """
    tenant_id = await resolve_tenant(current_user.id)
    
    # Validar credencial de Google
    google_key = await get_tenant_credential(
        tenant_id=tenant_id,
        category="google",
        name="API_KEY"
    )
    
    if not google_key:
        raise HTTPException(
            status_code=400,
            detail="Google API key not configured"
        )
    
    # Opcionalmente, descargar imagen base para context
    base_image_data = None
    if payload.image_url:
        img_response = await httpx.get(payload.image_url)
        base_image_data = img_response.content
    
    # Llamar a Google Imagen 3
    try:
        response = await httpx.post(
            "https://generativelanguage.googleapis.com/​v1beta/​models/​imagen-3.0:generate",
            headers={
                "Authorization": f"Bearer {google_key}",
                "Content-Type": "application/​json"
            },
            json={
                "prompt": payload.prompt,
                "num_images": 1,
                "aspect_ratio": "1:1",
                "safety_filter": "medium"
            },
            timeout=60.0
        )
        
        if response.status_code != 200:
            raise HTTPException(
                status_code=response.status_code,
                detail=f"Google Imagen API error: {response.text}"
            )
        
        data = response.json()
        generated_url = data['images'][0]['url']
        
        return {
            "status": "success",
            "url": generated_url
        }
        
    except Exception as e:
        logger.error(f"Image generation failed: {str(e)}")
        raise HTTPException(
            status_code=500,
            detail=f"Generation failed: {str(e)}"
        )

6. Smart Catalog (Product Browser)

Catalog View

const CatalogView: React.FC<{ products: Product[] }> = ({ products }) => {
  const [categoryFilter, setCategoryFilter] = useState<string | null>(null);
  
  // Extraer categorías únicas
  const categories = Array.from(
    new Set(products.map(p => p.category).filter(Boolean))
  );
  
  const filteredProducts = categoryFilter
    ? products.filter(p => p.category === categoryFilter)
    : products;
  
  return (
    <div className="catalog-view">
      {/​* Filtro de categorías */​}
      <div className="category-filters">
        <button
          className={!categoryFilter ? 'active' : ''}
          onClick={() => setCategoryFilter(null)}
        >
          All Products
        </​button>
        {categories.map(cat => (
          <button
            key={cat}
            className={categoryFilter === cat ? 'active' : ''}
            onClick={() => setCategoryFilter(cat)}
          >
            {cat}
          </​button>
        ))}
      </​div>
      
      {/​* Grid de productos */​}
      <div className="product-grid">
        {filteredProducts.map(product => (
          <ProductCard key={product.id} product={product} />
        ))}
      </​div>
    </​div>
  );
};

7. Persistencia de Assets

Backend: Assets Endpoint

@router.get("/​admin/​assets")
async def list_assets(
    current_user = Depends(verify_admin_token),
    type_filter: Optional[str] = None,
    session: AsyncSession = Depends(get_session)
):
    """
    Lista assets generados
    """
    tenant_id = await resolve_tenant(current_user.id)
    
    # Query base
    stmt = select(BusinessAsset).where(
        BusinessAsset.tenant_id == tenant_id
    )
    
    # Filtro opcional por tipo
    if type_filter:
        stmt = stmt.where(BusinessAsset.type == type_filter)
    
    # Ordenar por más reciente
    stmt = stmt.order_by(BusinessAsset.created_at.desc())
    
    result = await session.execute(stmt)
    assets = result.scalars().all()
    
    return [
        {
            "id": a.id,
            "type": a.type,
            "content": a.content,
            "created_at": a.created_at.isoformat()
        }
        for a in assets
    ]

Guardar Visual Generado

@router.post("/​admin/​assets", status_code=201)
async def save_asset(
    payload: AssetCreate,
    current_user = Depends(verify_admin_token),
    session: AsyncSession = Depends(get_session)
):
    tenant_id = await resolve_tenant(current_user.id)
    
    asset = BusinessAsset(
        tenant_id=tenant_id,
        type=payload.type,
        content=payload.content
    )
    
    session.add(asset)
    await session.commit()
    await session.refresh(asset)
    
    return {
        "id": asset.id,
        "status": "saved"
    }

8. Reality vs Dream Mode (CSS Magic)

CSS Implementation

/​* Reality Mode: Overlay */
.reality-overlay {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  overflow: hidden;
}

.reality-overlay .background {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.9);  /​* Oscurecer ligeramente fondo */
}

.reality-overlay .product-overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  max-width: 60%;
  max-height: 60%;
  object-fit: contain;
  mix-blend-mode: multiply;  /​* Mezclar con fondo */
  filter: drop-shadow(0 10px 30px rgba(0,0,0,0.3));  /​* Sombra realista */
}

9. Export & Download

Exportar Asset

const exportAsset = async (asset: Asset) => {
  if (asset.type === 'visuals') {
    // Descargar imagen
    const imageUrl = asset.content.social_posts[0].image_url;
    
    const link = document.createElement('a');
    link.href = imageUrl;
    link.download = `visual_${asset.id}.jpg`;
    link.click();
    
  } else {
    // Descargar JSON
    const blob = new Blob(
      [JSON.stringify(asset.content, null, 2)],
      { type: 'application/​json' }
    );
    
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = `${asset.type}_${asset.id}.json`;
    link.click();
  }
};

10. Troubleshooting

"No se ve la imagen generada"

Causa: URL de Google Imagen tiene CORS restrictivo
Solución: Proxy la imagen a través del backend o guardarla en storage

"Fusion falla silenciosamente"

Causa: Google API quota excedida
Solución: Verificar quota en Google Cloud Console

"Overlay no se ve bien"

Causa: Imagen original tiene fondo blanco (no transparente)
Solución: Usar productos con PNGs transparentes o aplicar remove-bg

"Assets no cargan"

Causa: tenant_id incorrecto
Solución: Verificar resolve_tenant en backend

11. Checklist de Implementación

Frontend

  • Tab system (Canvas / Catalog)
  • Asset grid con filtros
  • Polymorphic asset renderer
  • Fusion button funcional
  • Reality vs Dream toggle
  • Category filters en Catalog
  • Export/​Download assets

Backend

  • GET /​admin/​assets (con filtros)
  • POST /​admin/​generate-image
  • GET /​admin/​products (desde TiendaNube)
  • POST /​admin/​assets (guardar generados)
  • Google Imagen 3 integration
  • Validación de credenciales

Visuals

  • Branding asset renderer
  • Scripts asset renderer
  • ROI asset renderer
  • Social posts grid
  • CSS overlay effect
  • Product cards con imagen

Tip: Para mejores resultados en Fusion, usar prompts específicos con estilo deseado (ej: "minimalist white background", "luxury studio lighting").

More Other skills

Delegate independent tasks to specialized agents working concurrently with isolated context.

295.4K 206.3K
View

Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.

179.7K 100.1K
View

Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.

179.7K 89.5K
View

A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.).

179.7K 76.1K
View

Fundamental design principles for writing maintainable, testable Python code.

40.2K 21.9K
View

Modern responsive layouts using container queries, fluid typography, CSS Grid, and mobile-first strategies.

40.2K 20K
View

Generate Playwright tests from scenarios using interactive browser exploration and validation.

39.7K 18.2K
View

Modern React state management with Redux Toolkit, Zustand, Jotai, and React Query for every state category.

40.2K 14.7K
View

GDPR-compliant data handling with consent management, data subject rights, and privacy controls.

40.2K 14.3K
View

Python error handling patterns including input validation, exception hierarchies, and partial failure handling. Use when implementing validation logic, designing exception strategies, handling batch processing failures, or building robust APIs.

40.2K 13.5K
View

Detailed multi-file refactor planning with safety checks and rollback guidance.

39.7K 13K
View