CycleCore product information platform
CycleCore2024

Intro

Product information gets messy faster than it looks.

As a catalog grows, product data starts living across spreadsheets, storefronts, folders, and different teams. Updating one product can mean repeating the same work in several places, while keeping everything consistent becomes harder over time.

I wanted to explore what a product data platform could feel like if that complexity stayed in the system instead of reaching the user.

That became CycleCore: a B2B SaaS designed to centralize, structure, enrich, and distribute product information from one place.

CycleCore product catalog overview

My role

I owned the product end to end, from understanding the problem to designing, building, testing, and deploying the platform.

  • Product discovery and user conversations
  • Product strategy and feature definition
  • User flows and information architecture
  • Product and interaction design
  • Design system
  • Full-stack engineering
  • API and data model design
  • Third-party integrations
  • Testing and quality
  • Cloud infrastructure and deployment
  • Product demos and beta feedback
  • Documentation and onboarding

The interesting part was never just designing an interface or implementing a feature. It was deciding what the product should do, how the system should behave behind it, and how both could stay understandable as the platform grew.

Process

I did not start with screens.

The first step was understanding how brands were already handling product information: where their data lived, how it moved between tools, where manual work appeared, and what became painful as catalogs grew.

I spoke with people from around ten companies and used those conversations to challenge the initial idea.

Some assumptions survived. Others did not.

One of the biggest changes was architectural. CycleCore initially revolved around individual users. As collaboration became more important, I redesigned the model around organizations instead, allowing users to belong to multiple workspaces with their own roles, permissions, products, and integrations.

That decision changed far more than the database. It affected onboarding, navigation, authentication, permissions, billing, and almost every workflow in the product.

From there, my process usually followed the same loop:

Understand → structure → prototype → build → test → show → refine.

CycleCore iterative product design process

Most features started in Figma, but I tried not to separate design from implementation too much. Working across both meant technical constraints could influence the design early, while UX problems discovered during development could still reshape the underlying system.

External demos and beta testing then became another part of that loop. Feedback led to layout changes, simpler workflows, and new priorities around integrations and data exchange.

The product evolved through those iterations rather than through one fixed specification.

Design system

As the interface grew, designing screens independently stopped making sense.

I created a reusable design system across three Figma libraries:

Foundations:
Typography, spacing, colors, tokens, and the basic visual language of the product.

CycleCore design system foundations

Base UI Kit:
Reusable components such as inputs, buttons, tables, navigation elements, status patterns, and controls.

CycleCore reusable UI components

Layouts & Patterns:
Higher-level structures for recurring product workflows and complex screens.

CycleCore layouts and product patterns

The goal was not to build a design system for its own sake.

CycleCore contains dense interfaces: product tables, attributes, filters, imports, integrations, permissions, media, and configuration screens. Consistency was a way of reducing the amount of new information users had to process each time they moved through the product.

Because I was also implementing the interfaces, the system had to work both visually and technically. Components needed to stay reusable in Figma and translate naturally into React.

CycleCore

At the center of CycleCore is the product catalog.

Products, variants, attributes, categories, and media can all be structured from one workspace instead of being maintained independently across different channels.

But centralizing the data was only one part of the problem.

Getting data in

Starting with an empty PIM is not particularly useful.

I designed onboarding around getting an existing catalog into the platform quickly, either through spreadsheet imports or commerce integrations.

For CSV and Excel files, users can map their existing columns to CycleCore's data structure before importing them. The system validates values and relationships, transforms the data, and surfaces structured errors when something cannot be imported.

The important part was making the system adapt to the user's existing data rather than expecting the user to restructure everything beforehand.

Mapping spreadsheet columns during a CycleCore import

Keeping data useful

Once products are inside the platform, completeness and validation help identify what is missing before information is distributed elsewhere.

Search, filters, bulk actions, media management, and change history were designed around catalogs where managing products individually would quickly become inefficient.

The more data the platform handled, the more I became interested in designing for operations rather than isolated actions.

Managing a product catalog in CycleCore

Connecting the catalog

One of the main product questions became:

If CycleCore is the source of truth, how should it communicate with everything around it?

That led to a bidirectional Shopify integration.

Products, variants, images, categories, collections, and attribute-based data can move between both systems through manual or scheduled synchronization.

I designed the integration layer using adapters and factories so the application would not be tightly coupled to Shopify. The same underlying architecture could support platforms with completely different data structures later.

That was one of the moments where product thinking and software architecture became almost impossible to separate.

CycleCore commerce integration settings

Permissions without losing simplicity

Collaboration introduced another challenge.

Different organizations need different ways of controlling access, so I built configurable role-based permissions rather than hardcoding a small set of predefined roles.

Organization administrators can create roles, attach permissions to them, and assign multiple roles to the same user.

Behind the interface, every protected request also validates the active organization, membership, roles, and required permissions.

The UI stays relatively simple because most of the complexity lives underneath it.

Lessons

Talk to users before protecting your assumptions.

Some of the most important changes in CycleCore came from conversations rather than implementation.

Discovery pushed me toward stronger integration capabilities, a different organization model, and simpler product workflows.

Building more was not always the answer. Sometimes the right move was changing the structure underneath what already existed.

Product decisions become architecture decisions surprisingly quickly.

A seemingly simple question like “Can one user work with several organizations?” eventually touches authentication, database relationships, permissions, navigation, billing, and APIs.

Owning the product end to end taught me to think about those consequences much earlier.

Complexity does not need to disappear. It needs to move.

Product data is inherently complex.

The goal was never to pretend otherwise. It was to move as much of that complexity as possible into the system so that the interface could remain understandable.

That principle ended up influencing both the design and the engineering.

Tech stack

Frontend
TypeScriptReactNext.jsTailwind CSSShadCNTanStackMotion
Backend
Node.jsNestJSREST APIsZodSwagger / OpenAPI
Integrations
ShopifyStripeSupabaseOpenAI APIWebhooks
Testing
JestUnit TestingIntegration TestingPostman
Infrastructure
AWSEC2RDSS3CloudFrontCloudWatchDocker
Delivery
GitGitHubGitHub ActionsContinuous Integration
Data
PostgreSQLPrisma
Product & Design
FigmaNotion
Back
HomeCycleCore