Catalog Import Pipeline & Data Migration
Data PipelineTechnical breakdown of extracting 137 fine art pieces from jadenblack/roryskagenart.com into Fourthwall.
Source System Analysis
The source artwork catalog was located in the repository https://github.com/jadenblack/roryskagenart.com, a Next.js / Express web application using a Supabase PostgreSQL database and a media asset pipeline distributed across Cloudinary and Supabase Storage.
Key source files identified and parsed:
data/archive/portfolioPostsData.updated.json: 137 raw catalog entries containing titles, dates, mediums, dimensions, and Cloudinary URLs.supabase/migrations/2026_09_13_cms_v2_source_of_truth_backfill.sql: Full narrative descriptions and historical notes for each artwork.src/data/assetRegistry.ts: 1MB asset registry containing optimized WebP rendition links hosted on Supabase public buckets.
Extraction & Normalization
We executed an automated ingestion script that merged the structured metadata from portfolioPostsData.updated.json with the rich narrative text extracted from the SQL backfill migration.
Transformation Rules Applied:
1. Title & Slugs: Canonical database slugs preserved (e.g. greetings-from-austin, gianondor, austin-2019).
2. Series Classification: Mapped each item's series into store collection handles:
- Monsters & Kaiju →
monsters-kaiju - Austin Iconic & Texas Pop →
austin-iconic - Pop Surrealism & Folklore →
pop-surrealism - Atomic Pop & Sci-Fi →
atomic-sci-fi - All pieces also belong to
all.
3. Launch Selection: 13 flagship pieces (including the Austin mural, Skyline, Godzilla, and giant Kaiju) were assigned to the launch collection to power the homepage hero and carousel.
4. Description Formatting: Stripped markdown frontmatter and obsidian wiki-links ([[...]]) to generate clean, customer-facing product descriptions.
5. Pricing Matrix: Computed tier-based pricing based on original artwork dimensions:
- Standard pieces: $45 USD base.
- Large-scale / mural works (e.g. 3.5ft × 5ft): $55 USD base.
Media Asset Resolution
Each artwork's primary image was validated for availability. Both Cloudinary and Supabase media hosts respond with HTTP 200:
- Cloudinary:
https://res.cloudinary.com/xjilp2pq/image/upload/... - Supabase:
https://orphcusijzkxpxkzapjp.supabase.co/storage/v1/object/public/artwork-images/...
Both hosts have been configured in next.config.js under images.remotePatterns to permit Next.js image optimization.
Canonical JSON Schema
The resulting artifact is stored in lib/fourthwall/rory-artworks-data.json. Structure of each entry:
interface RoryArtworkData {
id: string; // e.g. "rory-gianondor"
slug: string; // e.g. "gianondor"
title: string; // e.g. "Gianondor"
year: string; // e.g. "2019"
date: string; // e.g. "2019-07-12"
medium: string; // e.g. "Enamel"
dimensions: string; // e.g. "3.5ft x 5ft"
status: string; // e.g. "Available" | "Sold"
series: string; // e.g. "Monsters & Kaiju"
tags: string[]; // e.g. ["enamel", "kaiju", "monster", "2019"]
description: string; // Clean descriptive text
narrative: string; // Full markdown narrative
collections: string[]; // ["all", "monsters-kaiju", "launch"]
basePriceUSD: number; // 55
image: {
url: string;
transformedUrl: string;
width: number;
height: number;
altText: string;
};
variantOptions: {
name: string;
size: string;
priceMultiplier: number;
}[];
}