Developer/System & Architecture/System Architecture & Data Flows
System Architecture & Data Flows
ArchitectureDetailed analysis of Next.js 15 App Router architecture, ISR caching, cart management, and Fourthwall data reshaping.
Last revised: September 2026•Rory Skagen Art Studio Docs
End-to-End Data Flow
The storefront architecture separates product retrieval, cart session storage, and administrative sync into three decoupled layers:
[Visitor Browser]
│
▼
[Next.js 15 App Router Server] ──► (ISR Cache: 3600s / Tag Revalidation)
│
├─► Fourthwall Storefront API (https://storefront-api.fourthwall.com/v1)
│ │ (When NEXT_PUBLIC_FW_STOREFRONT_TOKEN is active)
│ ▼
│ [Live Fourthwall Storefront Service]
│
└─► Fallback In-Memory Catalog Engine (lib/fourthwall/index.ts)
│ (When token is placeholder or API offline)
▼
[lib/fourthwall/rory-artworks-data.json]
├── 137 Canonical Fine Artworks
├── Cloudinary / Supabase Media CDN
└── In-Memory Cart StoreServer vs Client Component Boundary
In accordance with Next.js 15 architectural best practices:
- Server Components (Default):
app/[currency]/page.tsxapp/[currency]/product/[handle]/page.tsxcomponents/grid/three-items.tsxcomponents/carousel.tsxapp/docs/[[...slug]]/page.tsx- Benefits: Zero client-side JavaScript overhead for catalog data, superior SEO, fast TTFB.
- Client Components (
'use client'): components/cart/modal.tsx(interactive cart drawer)components/cart/add-to-cart.tsx(optimistic variant selection)app/import/page.tsx(real-time sync dashboard with terminal output)components/layout/navbar/currency.tsx(currency switching dropdown)
Caching & ISR Strategy
Next.js 15 caching primitives are configured for high-traffic scalability:
ts
// lib/fourthwall/index.ts
export async function getCollectionProducts({ collection, currency, limit }) {
const res = await fourthwallGet(
`${API_URL}/collections/${collection}/products`,
{ currency, limit },
{ next: { revalidate: 3600, tags: [`collection-${collection}`] } }
);
return reshapeProducts(res.body.results);
}- Revalidation Window: 3600 seconds (1 hour) background stale-while-revalidate.
- On-Demand Cache Purging: Server actions call
revalidateTag(TAGS.cart, 'default')whenever items are added or modified in the user's cart.
Data Reshaping Pipeline
Raw Fourthwall Storefront API payloads are normalized into uniform internal TypeScript models (lib/types.ts) via lib/fourthwall/reshape.ts:
ts
// Raw Fourthwall Product -> Reshaped Application Product
export function reshapeProduct(product: FourthwallProduct): Product {
return {
id: product.id,
handle: product.slug,
title: product.name,
description: product.description,
descriptionHtml: product.description,
options: extractProductOptions(product.variants),
variants: product.variants.map(reshapeVariant),
images: product.images.map(reshapeImage),
featuredImage: reshapeImage(product.images[0]),
priceRange: calculatePriceRange(product.variants),
tags: extractTags(product),
updatedAt: product.updatedAt
};
}