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.
Are You a Jewelry Business? E-commerce, CRM, marketing, payroll, analytics, and AI β everything you need to run a modern jewelry business, all in one platform.
Β© 2026 KATURA. All rights reserved.
πΊπΈ English EN πΊπΈ USD $
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
751,820
across the entire repo (equivalent to 37.0 King James Bibles)
Characters written
29.13M
29,126,188 total characters
Updates pushed
1,573
exact commit count on main
Current version
v1.15.73
build 1573 Β· 6d58963
Database models
366
across 47 schema files β most SaaS platforms have 20β50
API endpoints
854
individually routed β Stripe's public API has ~400
Translated strings
79,872
every string, in 24 languages
System permutations
10^257
2^854 endpoint combinations β more than atoms in the observable universe (10^80)
Project age
4mo 29d
since Dec 14, 2025
Pre-AI dev hours
25.1K hrs
751,820 lines Γ· 30 LOC/hr β equivalent to 12.0 years (senior engineer, no AI)
With-AI dev hours
6.3K hrs
4Γ AI productivity multiplier (2024β2026 studies) β equivalent to 783 days
Equivalent firm cost
$6,479,102
live ticker Β· $60/hr ongoing
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,573 updates pushed Showing page 12 of 33 Β· 551β600 of 1,643 fetched
Sunday, March 8, 2026 2 updates pushed
Feature 10:10 PM Β· ZRosserMcIntosh
add luxury watch sourcing page, form, brand carousel, CRM tab & APIs Add /watch-sourcing page with rotating brand logo carousel (10 brands) Watch request form with brand/model selection, box/papers, photo upload API routes: public submit, image upload (Supabase), admin CRUD WatchRequest Prisma model + SQL migration CRM 'Watch Requests' tab with status management Footer links: Watch Sourcing (shop) + Pre-Owned Watches (client care) Rate limit entries for watch-sourcing and watch-upload Brand logos: Rolex, Patek Philippe, Audemars Piguet, Cartier, Omega, TAG Heuer, Breitling, Hublot, Tudor, Vacheron Constantin Feature 12:37 AM Β· ZRosserMcIntosh
add POST /api/checkout/payment-intent endpoint for iOS PaymentSheet Zod validation for cart items, shipping, billing Stripe PaymentIntent creation (not Checkout Session) Rate limiting, inventory validation with atomic reservation Wholesale pricing and promotion discount support Gift balance application Order creation in Prisma transaction with cleanup on failure Returns clientSecret, orderId, orderNumber, amount breakdown Saturday, March 7, 2026 9 updates pushed
Feature security 7:32 PM Β· ZRosserMcIntosh
move CSP + security headers to middleware with nonce support Moved Content-Security-Policy from static next.config.ts headers() into middleware.ts for per-request nonce generation at the edge Every middleware response branch now calls applySecurityHeaders(): __mw_debug, tenant subdomain rewrites, API routes, admin/platform, intl routes, and auth redirects CSP now includes 'nonce-{uuid}' in script-src alongside 'unsafe-inline' for forward-compatible migration to strict nonce-gated scripts Nonce exposed via x-nonce response header for server components Static security headers (HSTS, X-Content-Type-Options, Referrer-Policy, X-Frame-Options, Permissions-Policy, X-XSS-Protection) all enforced Removed CSP from next.config.ts headers() to avoid duplication/conflicts; other security headers kept as fallback for non-middleware paths All 695 tests pass Feature saas 7:18 PM Β· ZRosserMcIntosh
enforce email usage limits per tenant plan Created src/lib/saas/email-usage.ts: sendEmailWithUsageCheck() β soft-limit (overage billing, still sends) Friday, March 6, 2026 5 updates pushed
Update 5:00 AM Β· ZRosserMcIntosh
health monitor light-mode colors + comprehensive route test coverage Rewrite health-monitor.tsx for light-mode admin theme: Replace all dark zinc classes (text-zinc-100, bg-zinc-900, border-zinc-800) with proper light-mode equivalents (text-gray-900, bg-white, border-gray-200) Fix SVG gauge ring track from dark (#27272a) to light (#e5e7eb) Fix invisible 'Health Monitor' title, card text, history table Status colors (emerald/red/amber) now on white bg with tinted bg chips Sparkline, history table, overall badge all fully light-mode Add expand/collapse chevrons to category cards Expand synthetic test suite from ~62 to ~130+ tests: Add all public pages: creations/*, education/*, engagement/*, legal/*, loose-diamonds, high-jewelry, design-your-ring, wholesale, wedding-sites, in-the-press, jewel-vox, cart, wishlist, rosser, FAQ, careers, accessibility Add all platform pages: demo, marketing, docs Add POST-only APIs: contact, newsletter, consultation, bespoke/inquiry, wholesale/apply, custom-ring-order, engagement-design Add missing GET APIs: search, recommendations, bundles, exchange-rates, articles, health, merchant-feed, wholesale/templates, gift-cards/balance, shipping/calculate, welcome-offer, app/version, app/feature-flags, app/deep-link Add all webhook endpoints: stripe, shipstation, brevo, slack Add all 24 i18n locale homepages Add additional protected routes: user/profile, user/addresses, admin/orders, admin/products Add additional DB checks: collection count, user count
Thursday, March 5, 2026 8 updates pushed
Update 6:39 PM Β· ZRosserMcIntosh
remove dead tenantPrisma(TENANT_ZERO_ID) from platform API routes, fix all 686 tests api-keys/route.ts: removed unused tenantPrisma import, fixed PATCH/DELETE to use prisma directly (tenantPrisma(TENANT_ZERO_ID) was injecting wrong tenant scope, breaking ownership verification for non-Katura tenants) webhooks/route.ts: same fix plans.ts: added missing SLACK_CONNECT feature description onboarding.test.ts: updated for 4 onboarding groups (legal added) e2e-tenant-lifecycle.test.ts: added legal group steps to lifecycle flow middleware.test.ts: fixed stale @/proxy import β @/middleware Security 5:23 PM Β· ZRosserMcIntosh
block tenant_katura from /platform/admin + add tenant zero guard CRITICAL: Prevents Katura's orders, products, and customers from appearing in the SaaS customer dashboard (/platform/admin). Root cause: When the Katura owner (rosserembrasil@gmail.com) visits /platform/admin, getPlatformAdminContext resolves them as tenant_katura which owns both storefronts. All Katura data then appears in the SaaS customer UI β a cross-tenant data leak.
Wednesday, March 4, 2026 17 updates pushed
11:35 PM Β· ZRosserMcIntosh
Create Stripe Products & Prices for all 4 SaaS plans Designer: /mo, /yr (prod_U5ZzwLEtlxbGUh) Starter: /mo, /yr (prod_U5a0dtAfAB6KxV) Professional: /mo, ,988/yr (prod_U5a0hytVhUpIr0) Enterprise: /mo, ,990/yr (prod_U5a0njkWx4C0jj) Docs 9:49 PM Β· ZRosserMcIntosh
Update schema refactor plan + session plan β all phases complete 9:47 PM Β· ZRosserMcIntosh
Phase 6b: Migrate 137 public API routes to tenantPrisma() 137 files migrated to tenantPrisma() 37 files keep both imports (use $queryRaw/$executeRaw/$transaction) 52 files correctly skipped (no tenant-scoped models) 0 build errors
Tuesday, March 3, 2026 5 updates pushed
Update 8:33 PM Β· ZRosserMcIntosh
complete translation audit β 0 missing keys across all 24 locales Added footer.loveEngagement.weddingSites to 21 locales Added product.handcraftedUnique to 21 locales Added full weddingSites namespace (31 keys) to 21 locales Added employeeLogin namespace (15 keys) to 21 locales Added developer namespace to 21 locales Added docs.sidebar.home and docs.sidebar.fullSearch to 21 locales Fixed NL footer.newsletter from string to proper object Removed temporary audit/fix scripts All 2,778 translation keys now at 100% parity with English Feature 7:38 PM Β· ZRosserMcIntosh
tenant email marketing system + fix admin email builder + i18n Add emailOveragePerEmail & stripeEmailOveragePriceId to SaasPlan schema Update PlanDetails/TenantEntitlements interfaces with emailPerEmail Update all plan mapping functions and DEFAULT_LIMITS SQL migration: Starter /bin/zsh.01, Professional /bin/zsh.008, Enterprise /bin/zsh.005 Replace TODO stubs in handleSave/handleSend with real API calls Save creates campaign + template, Send creates campaign + sends via Brevo campaigns, templates, segments, settings: add TENANT_ZERO_ID to GET/POST Monday, March 2, 2026 4 updates pushed
Chore 8:53 PM Β· ZRosserMcIntosh
update luxury brand strategy doc + misc scripts Chore 8:43 PM Β· ZRosserMcIntosh
update investor page styling to navy theme Feature 3:45 PM Β· ZRosserMcIntosh
legitimate multi-method valuation calculator for cap table Operating valuation fixed at 7Γ TTM revenue as the company benchmark Three valuation tabs: Comparable Multiples, DCF Analysis, Valuation Summary DCF model with configurable growth rate, FCF margin, discount rate, terminal multiple Projection table showing revenue, FCF, and PV for each forecast year Valuation Summary tab consolidates all methods (operating, comps bear/base/bull, DCF, last round, SAFE cap)
sendEmailStrict() β hard-limit (rejects if over limit)
getEmailUsageStats() β returns sent/limit/percentUsed/isOverLimit
Updated campaign send-now route to check email limits before sending
Returns 429 with usage stats when limit exceeded
Replaced commented-out TODO with real implementation
Built on existing recordUsage() + checkLimit() infrastructure
All 695 tests pass Feature sentry 7:12 PM Β· ZRosserMcIntosh
enhanced Sentry instrumentation Added environment tagging (VERCEL_ENV) Added release tagging (VERCEL_GIT_COMMIT_SHA) Added profilesSampleRate (1%) Added captureConsoleIntegration (warn + error) Added beforeSend filter for noisy 'Failed to fetch' errors Capture env validation failures as Sentry exceptions Added environment + release tagging Added denyUrls for third-party scripts (FB, Google Ads, extensions) Added breadcrumbsIntegration (console, dom, fetch, history) Expanded ignoreErrors (chrome/moz extensions) All 695 tests pass Feature seo 7:07 PM Β· ZRosserMcIntosh
dynamic Open Graph images for 7 key pages Created opengraph-image.tsx (edge runtime, ImageResponse) for: Homepage/default (1200Γ630 branded) Collections Engagement Rings Design Your Ring Jewel Vox (blog) About Education Loose Diamonds Consistent luxury branding: dark gradient, gold (#d4af37) accents, KATURA lettermark, descriptive subtitles Next.js auto-serves these at /[locale]/opengraph-image All 695 tests pass Feature performance 7:04 PM Β· ZRosserMcIntosh
Web Vitals monitoring (CLS, LCP, FID, TTFB, INP) Installed web-vitals v5 Created WebVitalsReporter client component Reports to Sentry (setMeasurement), GA4 (gtag event), and internal API Dev mode: console.log with π’π‘π΄ rating per Google thresholds Uses sendBeacon for reliable page-unload reporting Created POST /api/analytics/vitals ingestion endpoint Logs poor metrics server-side with console.warn Captures poor metrics as Sentry warnings for alerting Returns 204 fire-and-forget Wired into root locale layout (all storefront pages) All 695 tests pass Feature notifications 7:01 PM Β· ZRosserMcIntosh
server-side notification service Created src/lib/notifications/index.ts β full notification service layer createNotification() β single user createBulkNotifications() β batch to many users notifyByRole() β target OWNER/MANAGER/EMPLOYEE roles Convenience: notifyNewOrder(), notifyLowStock(), notifySystemAlert() Typed NotificationType union (order, payment, support, inventory, etc.) Updated POST /api/admin/notifications to use the shared service Existing UI (NotificationBell) + API routes (GET, read, read-all) already complete Prisma schema already has Notification, PushToken, NotificationPreference models All 695 tests pass Feature media 6:54 PM Β· ZRosserMcIntosh
implement real Supabase Storage upload (replace stub) Replaced stub /api/admin/media/upload with full implementation Uses SUPABASE_SERVICE_ROLE_KEY for server-side uploads (bypasses RLS) Supports JPEG, PNG, WebP, GIF, AVIF, SVG, PDF, MP4, WebM 50 MB max file size, unique timestamped paths Returns public URL, path, size, type in response Audit log on successful upload Role-based access: OWNER, MANAGER, EMPLOYEE only All 695 tests pass Feature testing 6:52 PM Β· ZRosserMcIntosh
Playwright E2E test suite Installed @playwright/test with Chromium Created playwright.config.ts (auto-starts dev server, HTML reporter) 5 E2E test files covering 40+ scenarios: storefront.spec.ts β homepage, navigation, footer, 18 public page smoke tests cart-checkout.spec.ts β cart empty state, checkout auth redirect api-health.spec.ts β public API 200s, protected endpoint auth guards seo-a11y.spec.ts β meta tags, OG, heading hierarchy, img alt, lang, i18n performance.spec.ts β load times, console errors, 404 handling Added pnpm scripts: e2e, e2e:ui, e2e:headed, e2e:report Added Playwright artifacts to .gitignore All 695 unit tests still pass Feature security 6:38 PM Β· ZRosserMcIntosh
AES-256-GCM credential encryption for all integrations Created shared encryption utility (src/lib/crypto/credentials.ts) with encryptCredential(), decryptCredential(), isEncryptedFormat() Refactored Wise to use shared utility (backwards-compatible via legacy env var) Nivoda: encrypt password on save, decrypt on read (settings route + tenant-credentials) Stuller: encrypt password on save, decrypt on read (settings route + tenant-credentials) Payout accounts: encrypt routing number, account number, PIX key, and conta fields Added isEncryptedFormat() helper for migration safety (skip already-encrypted values) Added backfill script (scripts/backfills/encrypt-credentials.ts) for existing data Updated .env.example with CREDENTIAL_ENCRYPTION_KEY documentation 9 comprehensive unit tests (round-trip, unicode, tamper detection, format validation) All 695 tests pass Update
health-monitor
3:44 AM Β· ZRosserMcIntosh
fix ShipStation 401 failure + Supabase auth + status badge colors ShipStation: Accept 401 as passing connectivity check β a 401 means the API is reachable even if credentials need rotation. Increased timeout to 15s for their slow API. Supabase: Now sends the anon key (apikey + Bearer) when available. A 401 without a key is still treated as 'reachable' (pass). Dashboard UI: Status code badges now colored by TEST STATUS (pass=green, fail=red, degraded=amber) instead of raw HTTP code. Previously a passing test returning 401 showed a confusing red badge. Update health-monitor 3:26 AM Β· ZRosserMcIntosh
fix white-on-white status text + 6 false-positive test failures Fix /en/bespoke β /en/creations/bespoke (correct route) Remove /en/education/gemstones (page doesn't exist) Remove /en/education/jewelry-care (page doesn't exist) Add /en/education/4cs, /en/education/settings, /en/education/diamond-shapes API: Events GET requires auth β expect [200, 401] API: Reviews GET requires productId β expect [200, 400] Feature design-your-ring 3:05 AM Β· ZRosserMcIntosh
add 14K/18K gold karat selection with $1,000 upgrade Gold metals (Yellow, Rose, White) now default to 14K with option to upgrade to 18K $1,000 surcharge applied when 18K gold is selected Elegant segmented toggle appears on Chapter 3 when a gold metal is chosen Karat auto-resets to 14K when switching to Platinum Metal label shows karat prefix (e.g., '14K Yellow Gold') in nav bar, mini summary, and Ch7 Transparent pricing breakdown in Ch7 shows '18K Gold Upgrade' line item when applicable metalKarat sent to /api/custom-ring-order for order processing New translation keys: ch3.karatLabel, ch3.karat14K, ch3.karat18K, ch7.metalUpgrade Feature 12:41 AM Β· ZRosserMcIntosh
health monitor β synthetic test engine + wall-of-gauges dashboard Synthetic test engine (src/lib/monitoring/synthetic-tests.ts): 55+ automated probes covering public pages, API routes, auth, checkout, database integrity, i18n locales, external integrations (Stripe, Brevo, ShipStation, Supabase, Vercel), platform SaaS, and webhook endpoint validation Hourly cron job (api/cron/synthetic-tests): Vercel cron at 0 * * * * runs full suite, persists results to SyntheticTestRun + SyntheticTestResult tables (raw SQL, 7-day TTL) Email alerts on failure: Brevo email with failure list, degraded warnings, and link to dashboard. 30-min dedup to prevent spam. Admin dashboard (admin/developer/health): Wall-of-gauges UI with overall health badge, category cards with gauge rings (Pages, API, Auth, Checkout, DB, Integrations, Platform), expandable per-test detail with status codes + response times, pass/fail sparkline trend chart, run history timeline table, manual 'Run Now' button, auto-refresh every 5 min. Sidebar nav: Health Monitor added under System group Translations: EN + PT SQL migration: SyntheticTestRun + SyntheticTestResult tables with indexes Build clean, 686/686 tests pass, 0 TS errors e25a5ce
Feature 4:38 PM Β· ZRosserMcIntosh
add gift cards to footer + minimize product description section Add Gift Cards link to Client Care column in footer Add 'giftCards' translation key to en.json Minimize 'About This Piece' section: collapsed by default, text-xs, stone-400 coloring β barely visible but still fully indexable by Google Minimize 'Details' accordion to match the same subtle styling NOT using white-on-white hidden text (Google penalizes that) Feature seo 5:30 AM Β· ZRosserMcIntosh
add 'About This Piece' + Details sections to product pages Full product description now rendered in expandable <details> section Google can index the content (not hidden, just collapsible) Added Details accordion with metal type, gemstone, carat weight, jewelry type 'One of a Kind' badge for isOneOfOne products Uses native HTML <details>/<summary> β zero client JS overhead Placed between product actions and reviews for natural reading flow Feature 5:00 AM Β· ZRosserMcIntosh
replace platform blog filler with real content + individual post pages Created posts.ts with 6 substantive articles about jewelry business topics Each post has real, multi-section content (not placeholder excerpts) Topics: all-in-one platform strategy, product photography, CRM pipelines, email marketing, internationalization, trunk show management Added /platform/blog/[slug] route with individual post pages All posts statically generated via generateStaticParams Blog listing now links to individual posts with hover states Each post page includes related posts, CTA, and proper metadata Feature 4:31 AM Β· ZRosserMcIntosh
add JCK & Garden & Gun logos to press and about pages Replaced text-based publication names with actual logo images JCK logo and Garden & Gun logo link to respective articles Added aria-labels for accessibility Logos stored in public/brand/press/ Docs 4:14 AM Β· ZRosserMcIntosh
update session plan β Priority 4 SEO complete, audit infrastructure status Feature seo 4:10 AM Β· ZRosserMcIntosh
add FAQPage + BreadcrumbList JSON-LD to all 7 education pages Created shared EducationJsonLd component for consistent structured data Education hub: 5 FAQs about diamond education topics 4Cs page: 5 FAQs about cut, color, clarity, carat Diamond shapes: 5 FAQs about shape popularity, size, sparkle Metals: 5 FAQs about platinum, gold types, allergies Settings: 5 FAQs about prong vs bezel, pavΓ©, halo Ring sizing: 5 FAQs about measuring, sizing tips, conversions Diamonds guide: 5 FAQs about 4Cs, lab-grown, fluorescence, budget c3e63cf
Feature 8:58 PM Β· ZRosserMcIntosh
Phase 6 β migrate 152 admin API routes to tenantPrisma() Replaced raw prisma.model.xxx with db.model.xxx (tenant-scoped) in 152 files const db = tenantPrisma(TENANT_ZERO_ID) injected at top of each handler Kept raw prisma import only where $queryRaw/$transaction/non-scoped models needed Removed ~50 redundant tenantId: TENANT_ZERO_ID from where/data objects Migration script: scripts/infra/migrate-to-tenant-prisma.ts Manual cleanup of 8 inline tenantId references Build passes (exit 0), zero TypeScript errors in src/ Feature 6:47 PM Β· ZRosserMcIntosh
legacy Shopify 301 redirects + robots.txt cleanup for GSC indexing /blogs/news/:slug β /jewel-vox/:slug (old Shopify blog) /collections/earrings β /creations/earrings /collections/pearl-bracelets β /creations/bracelets /collections/pearl-rings β /creations/rings /collections/all β /creations /pages/store β /contact /pages/:slug β / (catch-all for old Shopify pages) /platform/docs/:path* β / (leaked SaaS docs) /creations/south-seas-starfish-live-on-the-coral-reef β starfish collection Block /services/ (Shopify login_with_shop auth URLs) Block /collections/*.atom (Shopify atom feeds) Block /pages/ and /blogs/ (old Shopify paths) Block /platform/ (internal SaaS docs) Added missing /education/4cs page Bumped education pages priority from 0.5 β 0.6 Update 6:19 PM Β· ZRosserMcIntosh
remove <video:player_loc> from video sitemap β was duplicating <loc> page URL player_loc must point to an embeddable SWF/player, not the HTML landing page We don't have an embeddable player, so remove it entirely content_loc already correctly points to raw Supabase .MP4 video files Fixes all 33 instances flagged by Google Update 6:10 PM Β· ZRosserMcIntosh
comment out stray tenantId in task route commented blocks, add tenantId to task create tenantId: TENANT_ZERO_ID was placed outside comments in both tasks/route.ts and tasks/[id]/route.ts Properly commented the lines in the TODO notification blocks Added tenantId to the actual prisma.task.create data object Feature 6:00 PM Β· ZRosserMcIntosh
add video sitemap for Google Video indexing (33 product videos) New /video-sitemap.xml route with Google video sitemap spec (xmlns:video) Includes thumbnail_loc, content_loc, player_loc, publication_date per video Queries all active Katura products with videoUrl from database Rich auto-generated descriptions with product name, metal type, jewelry type Added video-sitemap.xml to robots.txt alongside main sitemap Addresses Google Search Console '28 videos could not be indexed' issue Caches for 1 hour with stale-while-revalidate Update 5:45 PM Β· ZRosserMcIntosh
broken wholesale import, VideoObject SEO, ring image swap, footer press link Fix broken import in wholesale stores routes (import inside import β build failure) Add VideoObject JSON-LD to product detail pages (35 products with video get rich results) Replace fictional design-ring image with Stella's 777 Lucky Numbers rose gold ring Add 'In the Press' link to footer navigation under Company (all 24 locales) Add generateVideoObjectSchema to structured-data.ts Feature 5:12 PM Β· ZRosserMcIntosh
backfill scripts for product image alt text (175 images upgraded in DB) backfill-image-alt-text.ts: fills null alt fields with '{Name} β {Metal} {Type} by Katura' upgrade-image-alt-text.ts: upgrades slug-based alt text (e.g. 'pearl-studs-3') to SEO-friendly format Ran on production DB: 175 images upgraded from slugs/filenames to descriptive alt text Eliminates 'ChatGPT Image Dec 23...' alt texts from product images Feature 4:53 PM Β· ZRosserMcIntosh
add 'In the Press' page β JCK Magazine & Garden & Gun features New /in-the-press page with 3 press articles (JCK Vermeer pearls, Garden & Gun river pearls, JCK Raw Sugar diamonds) Full NewsArticle + CollectionPage JSON-LD structured data for Google rich results sameAs signals linking Katura to authoritative press URLs BreadcrumbList schema on press page 'As Featured In' trust banner on homepage (between recommendations and education) 'As Featured In' section on About page with link to press page Press page added to sitemap (priority 0.7) Press page added to footer navigation under Company Designer bio section with internal links to /about and /creations Press inquiry CTA with link to /contact page Feature seo 4:29 PM Β· ZRosserMcIntosh
comprehensive SEO overhaul β structured data, breadcrumbs, canonical URLs, social profiles Fix double 'Katura' in home page title (use title.absolute) Fix social profiles: instagram/katura1999, facebook/katura1999jewelry, add tiktok + pinterest Add LocalBusiness (JewelryStore) JSON-LD to every page via locale layout Add ItemList JSON-LD on shop page (/creations) with top 50 products Add ItemList JSON-LD on all 6 category pages (earrings, rings, necklaces, bracelets, engagement-rings, wedding-bands) Add CollectionPage JSON-LD on collection detail pages with canonical + hreflang alternates Add ItemList JSON-LD on collections listing page Add Blog JSON-LD on blog listing page (/jewel-vox) with BlogPosting entries Add BreadcrumbList JSON-LD on shop, categories, collections, and blog pages New structured-data generators: generateLocalBusinessSchema, generateItemListSchema, generateBlogSchema Feature 4:09 PM Β· ZRosserMcIntosh
legal policies, compliance gate, onboarding, brevo events, builder icons, stripe scripts, smoke tests Update 4:11 AM Β· ZRosserMcIntosh
guard against undefined session.user.id in hero pin create Update 4:06 AM Β· ZRosserMcIntosh
add tenantId to all admin API route create calls (46 files, 60+ models) Systematic sweep of every admin API route that creates tenant-scoped models using the raw prisma client. These all need explicit tenantId since the auto-injection only works with the tenant-scoped client. Models fixed: Collection, ProductCategory, ProductTag, ProductVariantGroup, ProductVariantGroupMember, Shipment, Promotion, SalesGoal, Achievement, CommissionRecord, TeamMemberPay, ServiceRequest, ServiceStatusHistory, WholesaleStore, WholesaleStoreActivity, WholesaleSetting, BusinessExpense, TimeEntry, Project, TaskColumn, Idea, TaskActivity, TaskAttachment, Notification, WiseIntegration, WiseRecipient, WiseTransfer, WiseRateAlert, JobPosting, CrmDeal, CrmActivity, CrmTask, CrmNote, CrmContact, CrmPipelineStage, HeroPinRule, StrategicObjective, KeyResult, Initiative, AnalyticsExportLog Also fixed: WiseIntegration queries were using tenantId: null (broken since tenantId became NOT NULL) β changed to TENANT_ZERO_ID. Zero TypeScript errors (tsc --noEmit clean). Update 3:32 AM Β· ZRosserMcIntosh
add tenantId to product admin API routes (create, duplicate, update images) route.ts POST: add tenantId to product.create [id]/duplicate/route.ts POST: add tenantId to product.create, productImage.create, inventoryItem.create, productVariant.create [id]/route.ts PUT: add tenantId to two productImage.create calls (fallback create on P2025 and new image create) Chore 1:08 AM Β· ZRosserMcIntosh
add translation utility scripts (fix, verify, docs-sidebar)
Brevo webhook: resolve tenantId from campaign for events + stats
service.ts: add tenantId to MarketingCampaignStat creates
Rewrite marketing hub with real DB queries (stats, campaigns, templates)
Email usage bar with overage warnings
New campaign creation flow (3-step: details β design β review)
Platform marketing API routes (campaigns CRUD + send-now)
Platform API helpers (getPlatformTenantId, getPlatformApiContext)
Add /api/saas/blog/categories route (GET/POST)
Add employeeLogin + developer namespaces to all 24 locales
Add weddingSites namespace translations for all 23 non-EN locales
Add footer.loveEngagement.weddingSites + product.handcraftedUnique
Fix NL footer.newsletter structure (string β object)
Internationalize employee-login-form.tsx Feature 5:48 PM Β· ZRosserMcIntosh
add Katura High Jewelry page and footer link with all 24 translations Add /high-jewelry page with invitation-only high jewelry content Add highJewelry link at top of footer shop column Add full highJewelry namespace translations in all 24 locale files Copy citrine necklace image to public/images with clean filename Update 5:44 PM Β· ZRosserMcIntosh
complete tenant data isolation audit β all 8 issues resolved Restructured where clause to use AND for combining tenant scope with search OR Scoped trailing 12-month revenue query to tenant_katura orders Issue #7: createAuditLog() now writes tenantId (defaults to TENANT_ZERO_ID) All 14 inline prisma.auditLog.create() calls now pass tenantId explicitly createAuditLogger() accepts tenantId param or reads x-tenant-id header logFileUpload/logFileDownload/logDataExport accept tenantId Issue #8: SQL backfill script for User.tenantId (staff + customers) Feature 12:12 AM Β· ZRosserMcIntosh
redesign investor page β light/elegant aesthetic matching /platform, rose gold typography Replaced dark navy (#030712) theme with clean white/stone-50 light backgrounds Switched all headings to font-serif for refined luxury feel Applied rose gold gradient text (from-stone-800 via-amber-700 to-stone-700) matching /platform Cards: white bg + stone-200 borders with hover shadows instead of frosted glass Buttons: solid stone-900 with elegant hover states Section labels: rose gold gradient uppercase tracking Removed 'Founder' from Rosser's title β now just 'Chief Technology Officer' Promoted Stella to 'Chief Marketing Officer' (from Director of Marketing) Updated all docs: LUXURY_BRAND_STRATEGY, BUILD-STATUS, KATURA_SAAS_PLATFORM_PLAN
Rich financial summary: gross/net revenue, COGS, gross profit, gross margin, AOV, refunds
API now queries COGS via OrderItem Γ Product.costPrice and refunded order totals
RevenuePeriod type with full P&L metrics per period (TTM, current year, prior year)
Operating valuation prominently displayed in card header with per-share price
All figures derived from actual settled order data Feature 3:11 PM Β· ZRosserMcIntosh
revenue-based valuation estimator β auto-populates from actual order data Cap table API now queries TTM, current year, and prior year settled order revenue Uses same SETTLED_STATUSES + Shopify import filter as analytics overview ValuationEstimator auto-populates revenue from real orders on load Users can toggle between TTM / YTD / Prior Year revenue sources Editable for simulation β shows 'Actual' vs 'Simulated' badge Reset button to snap back to actual revenue after editing YoY growth badge when prior year data available Added RevenueData type to cap table types Disclaimer updates when using actual revenue data