KATURA
Your browser is not supported. Please update your iPad to the latest iOS version, or visit us on a newer device.
How to update your iPad Skip to main content JOIN THE WORLD OF KATURA Be the first to discover new collections, exclusive events, and the stories behind our legendary creations.
KaturaβCrafting timeless treasures since 1999.
The technology behind Katura is built in-house. K99 is our jewelry business platform β available to other jewelers.
Β© 2026 KATURA. All rights reserved.
πΊπΈ English EN πΊπΈ United States $
Software Updates Β· KATURA | KATURA
Live from GitHub Β· Refreshed continuously
Software Updates Every change we ship to katura1999.com β features, fixes, security patches, the lot. Pulled straight from our private GitHub repository so you can see exactly what was built and when.
By the numbers Lines of code
828,292
Web platform β TypeScript, React, Prisma, CSS
iOS
78,204
Swift + SwiftUI lines
Android
3,117
Kotlin + Jetpack Compose lines
All platforms
909,613
Web + iOS + Android combined (44.5Γ the King James Bible)
Characters written
35.04M
35,041,420 total characters
Updates pushed
1,893
exact commit count on main
Current version
v1.18.93
build 1893 Β· 1c76417
Database models
392
across 47 schema files β most SaaS platforms have 20β50
API endpoints
955
individually routed β Stripe's public API has ~400
Translated strings
82,512
every string, in 24 languages
System permutations
10^287
2^955 endpoint combinations β more than atoms in the observable universe (10^80)
Project age
6mo 15d
since Dec 14, 2025
Pre-AI dev hours
30.3K hrs
909,613 lines Γ· 30 LOC/hr β equivalent to 14.6 years (senior engineer, no AI)
With-AI dev hours
7.6K hrs
4Γ AI productivity multiplier (2024β2026 studies) β equivalent to 948 days
Equivalent firm cost
$7,859,393
live ticker Β· Katura rate: $60 USD/hr
Hours estimated from source line count at 30 LOC/hr (industry benchmark for production-quality TypeScript/React without AI assistance), with a 4Γ multiplier for AI-assisted development per published 2024β2026 enterprise studies. Equivalent Firm Cost uses a $250/hr loaded billable rate reflecting a premium engineering firm building enterprise-grade SaaS β and ticks up live, because the project is still being actively built.
Commit history
1,893 updates pushed Showing page 16 of 40 Β· 751β800 of 2,000 fetched
Monday, April 6, 2026 11 updates pushed
Feature 3:23 PM Β· ZRosserMcIntosh
Edge-Killer sprint β 15 jeweler-focused features 30 DDL statements (StaffAlert, TradeIn, MemoOut, MemoOutItem, OrderSalesperson, ProductAppraisal, ParkedTransaction tables) Order fields: visitReason, saleAttribution, linkedPersonId, hidePricesOnReceipt, expanded OrderType enum orders, engagement, inventory, customers, auth, saas-tenants, products staff-alerts (CRUD), trade-ins (CRUD), memo-out (CRUD w/ item actions) parked-transactions (CRUD), appraisals (GET/POST) order-salespeople (commission splits), customer duplicate check aged inventory analysis staff-alert-popup, staff-alert-manager, visit-reason-select trade-in-dialog, memo-out-dialog, commission-split parked-transactions-tray, customer-duplicate-checker customer-summary-card orders/new, customer detail, services client, orders API POST create-order-dialog, product detail EDGE-KILLER-PLAN.md (15 features across 5 phases) K99-ADMIN-PARITY-AUDIT-2026-07.md (184 vs 64 pages, ~55% parity) Update 1:26 PM Β· ZRosserMcIntosh
employee login welcome message + CAD folder upload reliability Replace router.push + router.refresh with window.location.href for proper full-page navigation after credential sign-in β ensures the server-side auth() in the admin layout reads the fresh session cookie Clear sessionStorage 'katura-admin-welcomed' key on login so the welcome splash animation always fires on fresh sign-in Remove unused useRouter import Add concurrency control: upload 2 files at a time instead of sequentially (avoids overwhelming Vercel serverless functions) Add retry logic: up to 2 retries with exponential backoff for server errors (500) and rate limits (429) Only retry server-side errors, not client errors (400/403/409) Apply same fix to both file input upload and drag-and-drop upload Add maxDuration=60 to CAD API route for large STL file uploads Feature 1:18 PM Β· ZRosserMcIntosh
full employee profile page with tabs β profile, compensation, agreements, tax docs, access controls New dynamic route /admin/team/[id] with full-page employee profile 5-tab layout: Profile, Compensation (owner-only), Agreements, Tax Documents, Access Controls Profile tab: personal info, work details, address, manager assignment, photo upload Compensation tab: salary/hourly, currency (all supported), commission %, pay schedule Agreements tab: NDA, Non-Compete, IP Assignment, Offer Letter, Contractor Agreement (upload placeholders) Tax Documents tab: W-2, 1099-NEC, W-8BEN, W-4, W-9, Informe de Rendimentos (upload placeholders) Access Controls tab: 28 admin pages grouped by category with View/Edit/Delete checkboxes Quick actions: Grant View All, Full Access, Revoke All Permission hierarchy enforced: owners manage anyone, managers manage employees only SQL migration for AdminPagePermission table with userId+pageSlug unique constraint New /api/admin/permissions API (GET + PUT) with role-based security Team table: Edit button and employee names now link to profile page Fixed missing image field in team page server query (avatars wouldn't load) Feature 12:53 PM Β· ZRosserMcIntosh
employee photo avatars, email signatures & account setup Avatar bubbles with camera overlay for photo upload on hover Photos upload to Supabase 'employees' bucket via existing API Initials fallback when no photo is set Thread view sender bubbles now show employee photos (avatarUrl) Settings account list shows avatars for accounts with photos Avatar component imported and wired up with graceful fallback Upload-photo API now syncs avatarUrl to all email accounts owned by user Email accounts PATCH API now supports avatarUrl field updates Converts zachary@katura1999.com from ALIAS β PERSONAL (separate inbox) Creates lee@katura1999.com as PERSONAL account Creates marketing@katura1999.com as ALIAS β stella's inbox Professional HTML signatures for all 5 accounts: Β· Lee Wiser McIntosh β President β Atlanta, GA Β· Zachary Rosser β CTO β zachary@ β SΓ£o Paulo Β· Z. Rosser McIntosh β CTO β rosser@ β SΓ£o Paulo Β· Stella Mary Barbosa β CMO β stella@ β SΓ£o Paulo Β· Stella Mary Barbosa β CMO β marketing@ β SΓ£o Paulo Signatures use table layout with Katura logo, navy/gold brand colors Feature 12:39 PM Β· ZRosserMcIntosh
navy branding, email dark mode + fullscreen compose, CAD folder upload Homepage: swap hero buttons (Design Your Ring left, Explore right) CSS: change --primary from black to navy #0B1527 (oklch 0.197 0.039 261.4) CSS: update --secondary-foreground, --accent-foreground, --sidebar-primary to match All default buttons site-wide (Add to Bag, etc.) now navy instead of black Hero fallback: text-black β text-[#0B1527] Email compose: fix dark mode (text-foreground on container, editor, From select) Email compose: add fullscreen/maximize toggle (Gmail-style, inset-4 rounded-xl) Email compose: Maximize2/Minimize2 icons in title bar Design page: folder upload via webkitdirectory input attribute Design page: preserve relative folder structure on upload (webkitRelativePath) Design page: improved upload error handling (per-file errors, success/fail counts) CAD API: surface actual Supabase error messages (bucket not found, policy, duplicate) 10:54 AM Β· ZRosserMcIntosh
Platform hardening: dark mode audit (96 files), i18n completeness (24 locales), email types extraction, labels API, repairs SEO, E2E expansion, dead dep cleanup [dark-mode] Replaced 479 hardcoded light-mode Tailwind classes across 96 admin files with semantic tokens (text-foreground, text-muted-foreground, bg-card, bg-muted, border-border) [i18n] Added repairs translation to 22 locale files [i18n] Added missing cookiePolicy + doNotSell to 23 locale files [email] Extracted types/config/utilities to email/types.ts (~120 lines) [email] Created /api/admin/email/labels CRUD for custom folder persistence (was localStorage-only) [email] Rewired custom folders to API-first with localStorage fallback [seo] Added JSON-LD LocalBusiness + OfferCatalog structured data to repairs page [e2e] Added tests for /repairs, /sell-gold-silver, /cookie-policy, /do-not-sell, 404 handling, API catch-all [deps] Removed dead isomorphic-dompurify + @types/dompurify (replaced by custom sanitize-html.ts) [docs] Updated session changelog with Session 2 details Update 10:06 AM Β· ZRosserMcIntosh
SQL User table name (quoted "User"), add session changelog Fix SQL: 'users' β '"User"' (Prisma default case-sensitive table name) Add docs/CHANGELOG-2026-04-06.md with comprehensive session summary Update 10:03 AM Β· ZRosserMcIntosh
SQL mailbox table name, dark mode, 3D preview, welcome animation, repairs page Fix SQL: use email_mailbox_members (not email_account_members), joinedAt column Fix SQL: remove non-existent tenantId from email_accounts INSERT Health monitor: comprehensive dark mode fix (50+ class replacements) 3D viewer: replace Environment preset=studio (CDN HDR) with hemisphereLight Dashboard: first name only, remove Sparkles icon, text-foreground color Dashboard: add framer-motion welcome splash (locale-aware, session-scoped) Audit page: add Email category, dark mode fixes, new Email tab in detail Email page: desktop notifications, custom folders with drag-and-drop Footer: sorted shortest-to-longest, added repairs link Repairs page: new /repairs route with services, trust signals, CTA Root layout: SSR lang/dir from URL locale (RTL support) Check-email: resilient error handling (rate limiter, DB fallback) API catch-all: JSON 404 for unmatched /api/* routes Privacy & terms pages: comprehensive legal rewrites Timepiece sourcing: added timepieces@ mailto CTA Precious metals: wired metals@ mailbox CTA Fix privacy page escaped backticks from heredoc Feature 8:59 AM Β· ZRosserMcIntosh
email standardization + legal pages overhaul Replace jewelryadvisor@ β concierge@katura1999.com site-wide Replace service@ β clientcare@katura1999.com Replace support@ β clientcare@katura1999.com Add engagement@katura1999.com to engagement page CTA Add department-specific addresses to siteConfig (clientCare, engagement, legal, concierge) Update ObfuscatedEmail default, Brevo fallback, email templates, abandoned cart, system email previews Update Supabase auth templates (invite, password reset, magic link, etc.) Update mobile app config, gift cards, consultation route, seed data SQL migration: prisma/rename-email-accounts.sql (service@ β clientcare@) Complete rewrite from raw prose to professional layout Sticky sidebar navigation with section icons Quick summary card (never sell data, PCI DSS, CCPA/GDPR compliant) Security measures grid (TLS, PCI, RLS, SOC 2) CCPA/GDPR callout cards with legal@katura1999.com Cookie breakdown (essential/analytics/marketing) Contact card with legal@ and clientcare@ addresses Related policies footer links /cookie-policy β Full cookie inventory table, management instructions /do-not-sell β CCPA compliance page, rights explanation, no-sale commitment Add Cookie Policy and Do Not Sell My Info links to footer bottom bar Add cookie-policy and do-not-sell to sitemap Add translation keys for new footer links Feature 12:48 AM Β· ZRosserMcIntosh
email signatures, undo send, keyboard shortcuts, drive preview & multi-select, global spellcheck Signature editor per account (PATCH API + settings UI, auto-appends on compose) Configurable undo send timer (0/5/10/20/30s, localStorage persisted, sonner toast with Undo) Gmail-style keyboard shortcuts (c=compose, r=reply, a=reply all, f=forward, e=archive, #=delete, s=star, j/k/u=navigate, /=search, ?=help) Move to folder dropdown in message detail toolbar Save email attachments to Drive (HardDrive button per attachment) Keyboard shortcuts help dialog (? key or settings reference) File preview panel (Sheet: image/PDF/video/audio preview + details grid + actions) Multi-select with checkboxes + bulk toolbar (star, move, download, trash) Move to folder dialog with folder tree picker Browser spellcheck enabled on all Input (text) and Textarea components Jewelry-specific spellcheck dictionary (130+ corrections: Colombian vs Columbian, pavΓ©, sapphire, etc.) SpellCheckInput / SpellCheckTextarea wrapper components with popover suggestions + Fix All Feature 12:18 AM Β· ZRosserMcIntosh
Katura Drive + Email enhancements β full workspace integration Schema: DriveFolder, DriveFile, DriveFolderShare, DriveFileShare API: CRUD, upload, file operations (rename/move/star/trash/share) UI: Full file browser with sidebar, grid/list views, drag-and-drop Features: folder tree, breadcrumbs, search, share links, storage meter Attachment upload API with 25MB/file, 50MB total limits Attach from Katura Drive integration Email Templates API (CRUD + shared team templates) 5 pre-seeded templates: Welcome, Quote Follow-up, Appointment, etc. Template picker in compose toolbar Schedule send with date/time picker in compose UI Cron job (every minute) processes scheduled messages via Brevo Snooze with preset durations (3h/24h/72h/168h) Cron job (every 5 min) un-snoozes messages back to inbox Snooze fields on EmailMessage schema (snoozedUntil, isSnoozed) Create calendar events from email (pre-fills title, attendees) Send calendar invitations via email with ICS file generation Beautiful HTML invite template with event details SQL migration: add-drive-templates-snooze.sql Vercel cron config: scheduled send + snooze check Cron auth: supports both header and query param secret Sunday, April 5, 2026 17 updates pushed
Feature email 11:51 PM Β· ZRosserMcIntosh
conversation threads, tracking toggle, dark mode, autocomplete, reply all Update 10:13 PM Β· ZRosserMcIntosh
use blob URLs for STL preview to bypass CORS/CSP entirely Fetch signed URL from our API, then fetch binary, then create blob: URL Three.js STLLoader loads from blob: URL (always same-origin, zero CORS) Fallback to proxy route if direct Supabase fetch fails Add loading toast while downloading CAD files Add blob URL cleanup (revokeObjectURL) when dialogs close Show raw error message in error boundary for debugging Assembly view also uses blob URL pattern with fallback Update
Saturday, April 4, 2026 9 updates pushed
Update 2:18 PM Β· ZRosserMcIntosh
resolve all 5 critical production failures from health alert Blog article SSR 500: findUnique cannot filter on non-unique fields. Article.status is not part of any unique constraint, so prisma.article.findUnique({ slug, status: 'PUBLISHED' }) throws a Prisma validation error at runtime. Changed to findFirst in both [slug]/page.tsx (generateMetadata + ArticlePage) and /api/articles/[slug]/route.ts. Vector Search 500: runLexicalSearch() is a module-level function that referenced `db` (tenantPrisma scoped inside GET handler). The variable was undefined when the function executed. Replaced all `db.product` with `prisma.product` and removed unused tenantPrisma/TENANT_ZERO_ID imports. Slug test crash: prisma.product.count({ slug: null as unknown as string }) was invalid because slug is a required String (never null) in the schema. Removed the null check, kept empty-string check only. 2:09 PM Β· ZRosserMcIntosh
add inline Add to Bag + trust strip to Izzy journey page Meta ad traffic from /journeys/izzy now converts faster: 1. INLINE ADD TO BAG β every product card now has a direct 'Add to Bag' button alongside 'View Details'. Visitors can purchase without navigating away from the landing page. The button resolves the product slug β DB ID via a new /api/products/by-slug/[slug] endpoint (cached 1hr) then calls cart context addItem, which fires Meta Pixel Friday, April 3, 2026 3 updates pushed
Update 6:17 PM Β· ZRosserMcIntosh
check-email synthetic test failure β www redirect causing 500 Root cause: APP_URL fallback was 'https://www.katura1999.com' but Vercel 308-redirects www β non-www. POST body gets lost in redirect, causing request.json() to throw β caught β 500. Feature 1:46 AM Β· ZRosserMcIntosh
unified admin vector + lexical search API, hook, and command palette Add /api/admin/search with blended vector+lexical product search, customer search (User model, role=CUSTOMER), order search, article search Add useAdminSearch hook with debounced queries and AbortController Rewrite admin command palette to show live data results grouped by type with product images, prices, search method badge, and response time Fix schema mismatches: User not Customer, total not totalAmount, user relation not customer, email directly on Order Thursday, April 2, 2026 8 updates pushed
Feature 7:22 PM Β· ZRosserMcIntosh
journeys analytics β sitemap, Meta Pixel tracking, Stella dashboard section Add /journeys and /journeys/izzy to sitemap with weekly changefreq Add Meta Pixel ViewContent + custom ViewIzzyJourney event to Izzy page Add GA4 view_journey custom event to Izzy page Create Izzy layout with OG metadata for social sharing Add Journeys Performance section to Stella marketing dashboard Tracking status badges (Meta Pixel, GA4, Sitemap) Copyable landing URL and UTM example 7-step Meta Custom Conversion setup instructions Add 13 new i18n keys (EN + PT) for journeys section Security deep-audit-v5 6:03 PM Β· ZRosserMcIntosh
10 vulnerabilities fixed Fix open redirect in login callbackUrl (CVE-class: CWE-601) Fix JSON-LD XSS via </script> injection in serializeJsonLd Fix SSRF in ShipStation webhook resource_url fetch Fix Brevo admin webhook db scoping bug (ReferenceError) Brevo admin webhook: fail-closed when secret not configured Hero-aggregation cron: timing-safe secret comparison Upload endpoints: magic byte validation (not just MIME type) Wednesday, April 1, 2026 2 updates pushed
Feature 11:35 PM Β· ZRosserMcIntosh
Izzy White β 5 white-themed luxury landing pages with real product images Cinematic scroll, Reveal curtains, Gallery exhibition, Editorial magazine, Lookbook grid All 13 ACTIVE Izzy products with real Supabase CDN images (no placeholders) Orange first β Yellow last per Stella's direction Fixed lookbook filter bug (necklaces β necklace) Added Izzy White entry to developer hub 6:54 PM Β· ZRosserMcIntosh
Fix burst stars: zero animation delay β all 20 fire at the exact same instant Burst stars: removed animationDelay entirely, all 20 start at frame 0 Visual variety comes from different durations (0.6-2.0s), not stagger Meteors: reduced stagger from 0.12s to 0.02s (all 15 within 0.28s) cBurst keyframe starts at opacity:1 so stars are visible immediately 10:05 PM Β· ZRosserMcIntosh
proxy CAD files through same-origin API to fix 3D preview CORS/CSP Add /api/admin/cad/proxy route that streams binary from Supabase Storage Update design page to use proxy URL instead of signed Supabase URL Three.js STLLoader now fetches from same origin (no CORS/CSP blocking) Add retryKey + key props to CanvasErrorBoundary for proper re-mount on retry Both single file preview and assembly view use proxy Download links still use signed URLs (browser download, not Three.js fetch) Feature 9:57 PM Β· ZRosserMcIntosh
rewrite inbound email webhook from Brevo to Mailgun Parse Mailgun multipart/form-data instead of Brevo JSON HMAC-SHA256 signature verification via MAILGUN_WEBHOOK_SIGNING_KEY Parse 'Name <email>' format from Mailgun's from/To/Cc fields All business logic preserved: dedup, account matching, aliasβparent routing, thread management, spam rules, folder routing Brevo stays for outbound email (no changes to brevo.ts or send route) 9:46 PM Β· ZRosserMcIntosh
Fix STL viewer crash β add error boundary + CSP fixes stl-viewer.tsx: Wrap both Canvas components in CanvasErrorBoundary class component so STL load failures show a friendly 'Failed to load 3D preview' message with retry button instead of crashing the entire page middleware.ts: Add 'blob:' to connect-src and add worker-src directive for Three.js web workers and blob URL fetches admin/error.tsx: Add admin-specific error boundary so crashes in admin routes stay within the admin layout instead of hitting the global error boundary 9:21 PM Β· ZRosserMcIntosh
Phase 7: Google Calendar clone β schema, API routes, full UI prisma/schema/calendar.prisma: 4 models (Calendar, CalendarShare, CalendarEvent, CalendarEventAttendee) + 5 enums prisma/schema/auth.prisma: Added 4 calendar relations to User model prisma/add-calendar-system.sql: Full migration with tables, indexes, seed calendars + events API routes: /api/admin/calendar/calendars (GET/POST), /api/admin/calendar/events (GET/POST), /api/admin/calendar/events/[eventId] (GET/PATCH/DELETE) Calendar page: Full Google Calendar clone with Day/Week/4-Day/Month/Schedule views, sidebar mini calendar, calendar visibility toggles, event creation/edit dialog, event detail popover, color picker, all-day events, now indicator, click-to-create on time grid Feature 9:04 PM Β· ZRosserMcIntosh
Gmail-like email UI rewrite + assign stella email Complete Gmail clone layout: left sidebar folders (pill-shaped), message list with checkbox/star/sender/subject/snippet/date rows, full-screen detail view with back navigation Compose popup anchored bottom-right (like Gmail), minimizable Full formatting toolbar: bold, italic, underline, strikethrough, font size (small/normal/large/huge), text color palette, bullet & numbered lists, alignment (left/center/right), links Bulk actions: select all/none/unread/read/starred, archive/spam/trash Gmail-style smart dates: 'h:mm a' today, 'Yesterday', 'MMM d', 'MMM d, yyyy' Shared mailboxes in sidebar (not big cards): sales, service, engagement, concierge, returns, press, careers, legal Personal accounts + aliases in sidebar Send API now returns snippet, direction, folder, isRead in GET SQL migration to assign stella@katura1999.com to Stella's User record and add her as MEMBER of all shared mailboxes Feature 8:52 PM Β· ZRosserMcIntosh
Business Tools suite β Gmail-like email, calendar & storage placeholders New 'Business Tools' nav group (email, calendar, tasks, storage) Full email client: inbox/sent/drafts/starred/spam/trash/archive folders Three-panel Gmail layout: sidebar + message list + detail pane Compose with From picker (personal/alias/shared accounts) Email account types: PERSONAL, SHARED, ALIAS Shared mailboxes: sales@, service@, engagement@, concierge@, returns@, press@, careers@, legal@ Alias support: zachary@katura1999.com β rosser@katura1999.com Brevo inbound webhook for receiving emails Spam filtering engine with configurable rules (domain/email/subject/body patterns) Auto-read marking, star toggle, folder moves, permanent delete Tracking stats in detail pane (opens, unique opens, forwards, timeline) Calendar placeholder page (Coming Soon) Storage placeholder page (Coming Soon) SQL migration: prisma/upgrade-email-system.sql Feature 8:33 PM Β· ZRosserMcIntosh
internal email system with Brevo SMTP + tracking pixel Add /admin/email with full compose, send, draft, and tracking UI Prisma schema: EmailAccount, EmailMessage, EmailThread, EmailTrackingEvent, EmailAttachment Seed rosser@katura1999.com and stella@katura1999.com accounts Send via Brevo SMTP with custom sender identity per account 1Γ1 tracking pixel injected into outgoing HTML emails Open/forward detection with IP + user-agent fingerprinting API routes: send, list, detail, accounts, star/tag, delete Admin nav: Email added to Sales & CRM group Migration SQL: prisma/add-email-system.sql Update 8:15 PM Β· ZRosserMcIntosh
comprehensive dark mode text audit β override all dark text classes for navy-blue admin theme text-gray/stone/slate/neutral/zinc-700/800 β admin-text text-black β admin-text text-blue-800/900 β lighter blue text-green-800/900 β lighter green text-red-800/900 β lighter red text-yellow-700/800/900 β lighter yellow text-orange-700/800/900 β lighter orange text-amber-600/700/800/900 β lighter amber text-purple-600/700/800/900 β lighter purple text-indigo-700/800/900 β lighter indigo text-violet-700/800/900 β lighter violet text-cyan-700/800/900 β lighter cyan text-teal-700/800/900 β lighter teal text-emerald-700/800/900 β lighter emerald text-rose-700/800/900 β lighter rose text-pink-700/800/900 β lighter pink bg-amber/purple/indigo/violet/cyan/teal/emerald/rose/pink/slate-100 bg-amber-200, bg-blue-200, bg-green-200 bg-amber/blue/green/red-50 bg-stone-100 .fill-black (star ratings) β gold .border-gray-300 β admin-border Feature 8:01 PM Β· ZRosserMcIntosh
add production type classification and variant management to jewelry projects New ProductionType enum: COMMISSIONED_ONE_OFF, HIGH_JEWELRY_ONE_OFF, LIMITED_PRODUCTION, STANDARD_PRODUCTION New JewelryProjectVariant model with metal, stone, size, pricing, quantity, status tracking New JewelryVariantStatus enum: PLANNED, IN_PROGRESS, COMPLETED, LINKED_TO_PRODUCT, CANCELLED Added plannedQuantity field to JewelryProject for production run sizing Full CRUD API for variants at /api/admin/jewelry-projects/:id/variants Updated PATCH whitelist to include productionType and plannedQuantity New Variants tab (12th tab) on project detail page with: Add/edit/delete variant forms Summary cards (count, units, est cost, est retail) Status management per variant (planned β in progress β completed β linked) Margin calculations per variant Production Classification section in Overview tab with type selector and quantity input Production type badges on projects list page (desktop table + mobile cards) Production type selector on new project form with planned quantity field SQL migration: prisma/add-production-type-and-variants.sql (executed) 7:43 PM Β· ZRosserMcIntosh
Admin UI redesign: dark mode (#0B1527 navy), theme toggle, collapsible sidebar, Framer Motion page transitions, shared PageHeader/Breadcrumb/StatusPill/EmptyState components, streamlined header, dashboard greeting refinements Dark mode scoped to #admin-root with Katura footer navy blue (#0B1527) Theme toggle (Sun/Moon) with localStorage persistence, defaults to light Sidebar: collapsible nav groups, narrowed w-60, accent left-border active state, dark gradient Header: consolidated to fewer items, language/clock-in moved to avatar dropdown, glass blur in dark mode Dashboard: time-of-day greeting, color-accented stat cards (emerald/blue/amber/violet), removed Quick Actions Framer Motion AnimatePresence page transitions in admin shell New admin-ui.tsx: AdminBreadcrumb, PageHeader, EmptyState, StatusPill, PageTransition PageHeader with breadcrumbs integrated into Orders, Products, Customers, Leads pages CSS: warm light mode tones, dark mode overrides for tables/forms/badges/dialogs/charts bg-background tokens replacing hardcoded bg-stone-50 Feature 7:24 PM Β· ZRosserMcIntosh
3D STL viewer, project pipeline tabs, art & product phases Add Three.js STL viewer component (metal presets, assembly view, exploded view, screenshot) Integrate 3D preview into /admin/design page with per-file and per-folder assembly viewing Add Pipeline tab to project detail: visual 6-phase tracker (Art β Stones β CAD β Casting β Bench β Product) Add Art & Concept tab: drag-drop upload for sketches, inspiration, AI renders, scanned drawings Add Product tab: cost summary, margin calculator, product flags, product search & link Create API routes for project assets (upload/delete) and product links (link/unlink) Install three, @react-three/fiber, @react-three/drei Feature 6:48 PM Β· ZRosserMcIntosh
add Journey Performance dashboard with real-time stats + Meta UTM tracking Add journeyStats queries: per-journey product views, cart adds, orders, revenue Track both 'All Traffic' and 'Meta / Paid' (facebook, instagram, meta UTM sources) Daily trends for both all-traffic and Meta-attributed views Top products within journey by views + buy clicks Uses ProductView slug LIKE 'izzy-%' for collection attribution Meta attribution: utmSource in (facebook,instagram,fb,ig,meta), utmMedium in (paid,cpc,cpm), or utmCampaign LIKE '%izzy%' Cart/order attribution via Cart.referrerChannel + Order.referrerChannel Add JourneyStats interface with all/meta breakdowns, daily trends, top products Replace static Izzy journey card with data-driven JourneyPerformanceCard All Traffic / Meta Paid toggle to compare organic vs paid performance KPI tiles: views, add-to-bag, orders, revenue with period-over-period change Dual daily trend charts (all traffic vs Meta) Top products bar chart within journey Fallback JourneyStaticCard when no data yet Retain UTM copy links and Meta Custom Conversion setup guide 6:31 PM Β· ZRosserMcIntosh
add detailed diamond specs to Izzy necklace descriptions 3Γ 0.50ct round brilliant, 1Γ 1ct round brilliant, 1Γ 1ct cut stone Colored necklaces (orange, pink, blue): princess cut diamond Classic necklaces (rose gold, platinum, yellow gold): asscher cut diamond Include metal + 'setting and chain' to match earring description style Feature 5:51 PM Β· ZRosserMcIntosh
add Atlanta Magazine logo to press rows Copy white-on-transparent ATLA logo to public/brand/press/ Add to homepage 'As Featured In' section with CSS invert Add to in-the-press page publication logos bar Add to about page 'As Featured In' section Links to https://www.modernluxury.com/ Update 5:29 PM Β· ZRosserMcIntosh
replace isomorphic-dompurify with zero-dep sanitizer (fixes blog SSR 500) Uses the same ALLOWED_TAGS and ALLOWED_ATTRS as before Strips disallowed tags, filters attributes, neutralises javascript: URIs Zero dependencies, works everywhere (Node, Edge, browser) Keeps isomorphic-dompurify in serverExternalPackages (not bundled)
AddToCart + GA4 add_to_cart events automatically.
2. TRUST STRIP β below the hero: Complimentary Shipping, Secure Checkout,
Handcrafted to Order, Lab-Grown Diamonds. Addresses cold-traffic
hesitations immediately.
3. FIXED BROKEN OG IMAGE β was pointing to wrong Supabase project
(wjsjbnxfkzcmfnpbdaqs β dpbrczhugdkvchigxxqs). Facebook/Instagram
ad previews were showing a broken image.
4. STRONGER CLOSING CTA β 'Find Your Izzy' with 'Shop All 13 Pieces'
primary button + 'Need Help Choosing?' email secondary.
5. SEO TITLE FIX β removed '| Katura' from layout title to avoid
double suffix from root layout template. Added 'starting at $7,000'
to OG/Twitter descriptions for price anchoring in social previews.
New API: GET /api/products/by-slug/[slug] β returns { id, name, price }
for Katura storefront products. Cached aggressively. 2:00 PM Β· ZRosserMcIntosh
fix sitemap β stable lastModified, 4 missing pages, product images Replace new Date() with concrete STATIC_CONTENT_DATE (2025-06-15) for all 39 static pages. Google ignores lastModified when every crawl shows 'just now' β a stable date makes the signal trustworthy. Add 4 missing public pages to sitemap: /precious-metals, /high-jewelry, /timepiece-sourcing, /wedding-sites Include product hero image in sitemap via images[] property, which Next.js renders as <image:image> tags β helps Google Image Search index jewelry product photography. Clean up explicit type annotations on Prisma map callbacks (inferred). Feature 1:52 PM Β· ZRosserMcIntosh
add missing structured data and OG images for SEO Add Organization JSON-LD (Google Knowledge Panel, brand entity) Add WebSite JSON-LD (sitelinks search box in Google) Add LocalBusiness/JewelryStore JSON-LD (local results, rich data) These 3 schemas were already built in structured-data.ts but never wired up to any page β now on the homepage. Add OG image to OpenGraph metadata so social shares show the brand image instead of blank preview Add BreadcrumbList JSON-LD for breadcrumb rich results in Google Update 1:31 PM Β· ZRosserMcIntosh
remove duplicate KATURA suffix from all SEO titles Remove '| KATURA' from all 267 title strings in SEO_TEMPLATES and CATEGORY_SEO across all 24 locales Remove '| KATURA' from getProductSEO, getBlogPostSEO, getCollectionSEO, and getCategorySEO fallback Change homepage from { absolute: seo.title } to seo.title so it goes through the layout template uniformly Fix 2 platform marketing pages with same issue Fix AI description seoTitle generator Perf 1:14 PM Β· ZRosserMcIntosh
fix 3 slow synthetic tests β search API, products API, PDP TTFB pg_trgm GIN indexes on name, description, metalType, gemstone, slug (accelerates ILIKE/contains in search API from seq scan to index scan) Composite B-tree: (status, createdAt DESC) for product listings Composite B-tree: (status, featured DESC, name) for featured sort Partial index: shopifyHandle WHERE NOT NULL (PDP fallback) Expression index: lower(slug) for case-insensitive PDP lookup Partial index: (jewelryType, status) WHERE ACTIVE (related products) 12:30 PM Β· ZRosserMcIntosh
unify navy color (#0B1527), replace text press logos with images, add Flower Magazine Brand Story section: bg-[#030712] β bg-[#0B1527] to match footer navy Hero tile: text-black/bg-black β text-[#0B1527]/bg-[#0B1527] for heading & buttons Homepage 'As Featured In': replace text-only JCK & Garden & Gun with actual logo images Add Flower Magazine to homepage press bar and /in-the-press page Add Flower Magazine logo SVG to public/brand/press/ Update press page metadata, structured data, and designer bio for Flower Magazine Feature monitoring 12:14 PM Β· ZRosserMcIntosh
add 40+ non-critical defense-in-depth synthetic tests /en/authenticate, /en/precious-metals, /en/timepiece-sourcing /en/checkout/success, /en/education (hub), /en/employee-login /en/wholesale-login, /en/journeys, /en/journeys/izzy /en/account, /en/account/orders, /en/account/settings Blog article SSR with real slug from /api/articles Collection detail SSR with real slug from /api/collections /api/articles/categories, /api/products/collage /api/search/vector, /api/reports, /api/developer/cert-parse /api/developer/metal-prices, /video-sitemap.xml Article by slug (real), Collection by slug (real) Product social proof (real), Wedding site public lookup Articles have content (not empty bodies) Collections have products (not all empty) Active products have slugs (PDP links work) Active products have variants (add-to-cart works) Articles API returns array with slug+title fields Cart API returns valid JSON object Checkout page TTFB (<5s), Blog hub TTFB (<5s) Product detail page TTFB (<5s, with real slug) Blog article has <title> and meta description Product page has JSON-LD structured data Homepage has canonical URL Video sitemap is valid XML OpenAI embeddings configured + vector search alive Supabase Storage public endpoint reachable Arabic (RTL) page has dir=rtl attribute Hebrew (RTL) page has dir=rtl attribute Japanese page has lang=ja attribute 404 page renders (not 500 crash, not soft 200) API 404 returns JSON (not HTML error page) Feature monitoring 1:30 AM Β· ZRosserMcIntosh
add 8 mission-critical synthetic tests Gap-fill for identified monitoring blind spots: 1. Stripe webhook signature verification β ensures constructEvent() returns 400 (not 500), proving signature checking actually runs. Tests both missing header and fake signature scenarios. 2. Order-by-payment-intent lookup β post-checkout critical path. If this 500s, customers see blank success page after paying. 3. Order-by-session lookup β fallback checkout success path. Used when payment_intent param is missing. 4. Product authentication (invalid serial) β public endpoint where customers verify pieces are authentic. Must return 200 with authenticated:false, never 500. 5. Product authentication (empty body) β must return 400 for missing serial number, not crash. 6. Checkout page render β verifies /en/checkout loads (200/3xx), catches SSR crashes that block all purchases. 7. Product detail page render (real slug) β fetches a real product slug from API, then verifies the actual Next.js PDP renders. Catches SSR/metadata/structured-data failures. Total test count: ~505 β ~513 Update 1:29 AM Β· ZRosserMcIntosh
hero mosaic pin search broken β variants.select.price β variantPrice Fixed variant field name (price β variantPrice) Added jewelryType, gemstone, description to searchable fields Added word-splitting for multi-word queries ('gold ring' β OR match) Added limit query parameter support Better error logging and UI feedback (no more silent failures) Shows 'No products found' message instead of empty silence
Upload endpoints: filename extension sanitization
Remove debug-mw page (information disclosure)
Remove empty upload-test route (dead code) Update 12:57 PM Β· ZRosserMcIntosh
add isomorphic-dompurify/jsdom to serverExternalPackages Fixes Turbopack build error: NftJsonAsset: cannot handle filepath node:worker_threads jsdom (used by isomorphic-dompurify for SSR) references node:worker_threads which Turbopack's Node File Trace cannot resolve. Marking these as external skips the trace and uses the installed node_modules at runtime. 12:54 PM Β· ZRosserMcIntosh
Security audit fixes + Izzy Journey page + developer password protection Fix GraphQL injection in Nivoda client (parameterized auth, sanitizeGqlString) Remove hardcoded fallback JWT secrets Add auth gates to 6 unprotected developer/admin test endpoints Add auth to Brevo products admin, cert-parse, Stripe webhook test Change fail-open to fail-closed: reCAPTCHA, cron auth, webhook auth Add Brevo webhook secret verification Create sanitize-html.ts (DOMPurify) and sanitize-css.ts Sanitize all dangerouslySetInnerHTML: blog, products, email builder, section renderer Sanitize tenant custom CSS Remove /__mw_debug information disclosure endpoint Add /journeys landing page and /journeys/izzy cinematic product page Izzy page leads with products (not hero text), tighter spacing per Stella Add 'Journeys' link to footer Company column (all 24 locales) Password-protect /developer pages (static passwords: lee, stella, rosser) Persists auth in localStorage for session convenience Feature 10:31 AM Β· ZRosserMcIntosh
Katura Authentication & Serialization system Serial number generator (K99-YYMM-NNNN-CC format with check digits) Prisma schema: SerializedUnit, StoneCertificate, SerialNumberCounter Admin inventory management (/admin/products/[id]/inventory) Add/edit/delete serialized units with auto-generated serials Per-unit cost breakdown (diamond, setting, labor, metal, other) Attach multiple GIA/IGI certificates per unit Status tracking (IN_STOCK, RESERVED, SOLD, RETURNED, etc.) Public authentication page (/authenticate) Cream-themed luxury verification page Serial number lookup with product & certificate display Never exposes costs or internal data API routes: CRUD for units + certificates, public verify endpoint Product editor: replaced Inventory + Diamond Cert with link card Footer: added Katura Authentication link in Company column Updated all 24 i18n locale files SQL migration executed (tables, indexes, RLS policies) Feature 9:57 AM Β· ZRosserMcIntosh
engagement ring checkbox + engagement-only switch in product editor Shows on /creations/engagement-rings alongside jewelryType matches Unchecking auto-removes engagement-only tag too Only visible when Engagement Ring is checked Hides product from /creations/rings while keeping it on engagement page Styled with indented rose border for clear parent/child relationship /creations/engagement-rings now includes products tagged 'engagement-ring' /creations/rings now excludes products tagged 'engagement-only' Uses existing tags system (no schema migration needed) Update 9:35 AM Β· ZRosserMcIntosh
timepiece sourcing hero mosaic β missing images, Cartier logo, right cutoff 1. Added 3 missing watch images: jaeger.jpg, rolex-daytona.jpg, submariner.jpg 2. Added Cartier brand logo (cartier.png) for brand carousel 3. Replaced Vacheron Constantin (non-white bg) with Rolex Day-Date Rose Gold 128235 4. Fixed right-side image cutoff: overflow-hidden on cells, overflow-clip on section 5. Changed object-cover β object-contain so watches display fully without cropping 6. Grid rows changed from 1fr β auto for proper aspect ratio sizing Update 8:47 AM Β· ZRosserMcIntosh
white header for izzy-white pages, move Pre-Owned Watches to Shop, richer navy footer 1. Header: izzy-white sub-pages now get the light header instead of dark developer header 2. Footer: moved 'Pre-Owned Luxury Timepieces' from Client Care to Shop column (below Trunk Show) 3. Footer: changed bg from #030712 (near-black) to #0B1527 (rich navy, vintage Tiffany-inspired)