Skip to content
Back to skills

Ecom Integrations

ASecurity

Ecommerce integration patterns and decomposer/composer

  • 666 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added February 8, 2026
developmentjavatesting

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill ecom-integrations --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ecom Integrations?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ecom Integrations
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-ecom-integrations/badge)](https://www.skillsdirectory.com/skills/majiayu000-ecom-integrations)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ecom-integrations
description: Ecommerce integration patterns and decomposer/composer
---

# Decomposer/Composer Patterns

## Decomposer Pattern

Decomposers transform **external platform data → Violet canonical models**.

### Interface
```java
public interface Decomposer<P, V> {
    V decompose(P platformEntity);
    List<V> decomposeList(List<P> platformEntities);
}
```

### Example: Shopify Product Decomposer
```java
public class ShopifyProductDecomposer implements Decomposer<ShopifyProduct, Offer> {

    public static Offer decompose(ShopifyProduct shopifyProduct) {
        Offer offer = new Offer();
        offer.setExternalId(String.valueOf(shopifyProduct.getId()));
        offer.setName(shopifyProduct.getTitle());
        offer.setDescription(shopifyProduct.getBodyHtml());
        offer.setVendor(shopifyProduct.getVendor());
        offer.setSkus(decomposeVariants(shopifyProduct.getVariants()));
        offer.setImages(decomposeImages(shopifyProduct.getImages()));
        offer.setTags(parseTags(shopifyProduct.getTags()));
        offer.setStatus(mapStatus(shopifyProduct.getStatus()));
        return offer;
    }

    private static OfferStatus mapStatus(String shopifyStatus) {
        return switch (shopifyStatus) {
            case "active" -> OfferStatus.AVAILABLE;
            case "draft" -> OfferStatus.DRAFT;
            case "archived" -> OfferStatus.UNAVAILABLE;
            default -> OfferStatus.UNKNOWN;
        };
    }
}
```

### Key Principles
1. **Pure functions** - No side effects, static methods
2. **Null safety** - Check every field before accessing
3. **Status mapping** - Translate platform statuses to Violet statuses
4. **Field normalization** - Convert to consistent formats (currency, units)

## Composer Pattern

Composers transform **Violet canonical models → external platform formats**.

### Interface
```java
public interface Composer<V, P> {
    P compose(V violetEntity);
    List<P> composeList(List<V> violetEntities);
}
```

### Example: Shopify Order Composer
```java
public class ShopifyOrderComposer implements Composer<Order, ShopifyOrderInput> {

    public static ShopifyOrderInput compose(Order violetOrder) {
        ShopifyOrderInput input = new ShopifyOrderInput();
        input.setEmail(violetOrder.getCustomer().getEmail());
        input.setLineItems(composeLineItems(violetOrder.getItems()));
        input.setShippingAddress(composeAddress(violetOrder.getShippingAddress()));
        input.setBillingAddress(composeAddress(violetOrder.getBillingAddress()));
        input.setFinancialStatus(mapFinancialStatus(violetOrder.getPaymentStatus()));
        input.setFulfillmentStatus(mapFulfillmentStatus(violetOrder.getFulfillmentStatus()));
        return input;
    }

    private static String mapFinancialStatus(PaymentStatus status) {
        return switch (status) {
            case PAID -> "paid";
            case PENDING -> "pending";
            case REFUNDED -> "refunded";
            case PARTIALLY_REFUNDED -> "partially_refunded";
            default -> "pending";
        };
    }
}
```

### Key Principles
1. **Idempotent** - Same input always produces same output
2. **Complete** - Include all required platform fields
3. **Validated** - Output should pass platform validation
4. **Documented** - Every field mapping documented

## Testing Patterns

### Decomposer Tests
```java
@Test
void decompose_shouldMapAllFields() {
    ShopifyProduct input = createTestProduct();

    Offer result = ShopifyProductDecomposer.decompose(input);

    assertThat(result.getExternalId()).isEqualTo("123");
    assertThat(result.getName()).isEqualTo("Test Product");
    assertThat(result.getStatus()).isEqualTo(OfferStatus.AVAILABLE);
}

@Test
void decompose_shouldHandleNullFields() {
    ShopifyProduct input = new ShopifyProduct();
    input.setId(123L);
    // Other fields null

    Offer result = ShopifyProductDecomposer.decompose(input);

    assertThat(result.getExternalId()).isEqualTo("123");
    assertThat(result.getName()).isNull();
}
```

### Composer Tests
```java
@Test
void compose_shouldProduceValidPlatformInput() {
    Order violetOrder = createTestOrder();

    ShopifyOrderInput result = ShopifyOrderComposer.compose(violetOrder);

    assertThat(result.getEmail()).isNotNull();
    assertThat(result.getLineItems()).isNotEmpty();
}

@Test
void compose_shouldMapStatusCorrectly() {
    Order order = new Order();
    order.setPaymentStatus(PaymentStatus.PAID);

    ShopifyOrderInput result = ShopifyOrderComposer.compose(order);

    assertThat(result.getFinancialStatus()).isEqualTo("paid");
}
```

## Status Mapping Tables

Every integration must document status mappings:

### Order Status Example
| Violet Status | Shopify | BigCommerce | WooCommerce |
|---------------|---------|-------------|-------------|
| PENDING | unfulfilled | Awaiting Fulfillment | pending |
| PROCESSING | in_progress | Awaiting Shipment | processing |
| SHIPPED | fulfilled | Shipped | completed |
| DELIVERED | fulfilled | Delivered | completed |
| CANCELLED | cancelled | Cancelled | cancelled |

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.