Skip to main content

ModelOptix: Full Model Catalog + Portfolio Management Live

Published: January 24, 20265 min read
#Build in Public#Jamie Watters#Soloprenuer#LLM

Phase 2 Complete: Full Model Catalog + Portfolio Management Live

Building in public with ModelOptix - Day 5 update. The product is taking shape fast.


TL;DR

  • ✅ 10 tasks completed in 3 days - portfolio management + model catalog
  • ✅ Users can now add their AI products and browse 400+ models
  • ✅ Model data syncing daily from OpenRouter + Artificial Analysis
  • ✅ Side-by-side model comparison working
  • ✅ Dashboard shows your AI portfolio at a glance
  • 🎯 Next: Recommendation engine (the core value delivery)
  • 🚀 Try the savings calculator - see how much you could save

What We Shipped This Sprint

Phase 2 was all about giving users the tools to manage their AI stack and explore alternatives. The goal: make it dead simple to document what you're using and discover what else is out there.

What is ModelOptix? An independent AI model advisor that monitors your stack and alerts you when better/cheaper models appear. No affiliate commissions. No vendor bias. Just you vs. the market.

The Portfolio Management System

You can now add your AI products to ModelOptix and break them down into functions and use cases. This is the foundation for personalized recommendations.

The hierarchy:

Product (e.g., "TradingBot")
  ├─ Function (e.g., "Market Analysis")
  │   ├─ Use Case: Sentiment Analysis (GPT-4 Turbo)
  │   └─ Use Case: Signal Generation (Claude 3 Opus)
  └─ Function: "User Chat"
      └─ Use Case: Customer Q&A (GPT-4o)

Why this matters: Most AI products have multiple use cases with different requirements. Your chatbot needs fast response times (cheap models work). Your code generator needs accuracy (expensive models necessary). ModelOptix treats them separately.

What you can do now:

  1. Add Products - Name, description, live status
  2. Define Functions - What your product does with AI
  3. Specify Use Cases - Exact task, current model, volume, latency requirements
  4. Quick Start Flow - Guided onboarding to add your first product in < 3 minutes

The Model Catalog (400+ Models)

We're now syncing the full AI model catalog from OpenRouter daily. Every model. Every provider. Current pricing. Latest benchmarks.

Current catalog:

  • 400+ models from 15+ providers
  • 6 major providers profiled: OpenAI, Anthropic, Google, Meta, Mistral, Cohere
  • Daily pricing updates - catch price drops immediately
  • Weekly benchmark sync - quality scores from Artificial Analysis
  • Context windows - 2K to 2M tokens
  • Modalities - Text, vision, function calling, JSON mode

Browse features:

  • Filter by provider, modality, context window
  • Search by name or capabilities
  • Sort by price, benchmark score, context
  • View detailed specs per model
  • Compare up to 3 models side-by-side

Example comparison: GPT-4 Turbo vs Claude 3.5 Sonnet vs Gemini 1.5 Pro

Metric GPT-4 Turbo Claude 3.5 Gemini 1.5 Pro
Input price $10/1M $3/1M $1.25/1M
Output price $30/1M $15/1M $5/1M
Context 128K 200K 2M
Quality score 94.2 96.1 92.8

For general reasoning tasks, Claude 3.5 Sonnet costs 70% less than GPT-4 Turbo with higher quality scores. These are the insights ModelOptix surfaces automatically.

The Dashboard

Your command center. At a glance:

  • Products count - How many AI products you're monitoring
  • Total use cases - All AI tasks across your portfolio
  • Active functions - AI capabilities in production
  • Quick actions - Add product, browse catalog, view opportunities (coming Phase 3)

The dashboard is deliberately minimal right now. Phase 3 adds the killer feature: Opportunities - actual recommendations with savings calculations.


Technical Deep Dive (For The Builders)

CRUD Architecture

We built a standard hierarchical CRUD system with proper cascade deletes:

// Product owns Functions owns Use Cases
DELETE FROM products WHERE id = $1
  → CASCADE DELETE functions WHERE product_id = $1
    → CASCADE DELETE use_cases WHERE function_id IN (...)

Key decisions:

  • Soft deletes? No. Hard deletes with CASCADE. Keeps DB lean.
  • Optimistic UI? Yes. Delete locally, rollback on error.
  • Undo? No. Confirm dialog + toast warning is enough for MVP.

Model Sync Jobs

Two cron jobs keep the catalog fresh:

1. Model Catalog Sync (Daily, 3am UTC)

// src/app/api/jobs/sync-models/route.ts
export async function GET(request: Request) {
  const isAuthorized = checkCronSecret(request);
  if (!isAuthorized) return new Response('Unauthorized', { status: 401 });

  await runJobWithLock('sync-models', async () => {
    const models = await fetchOpenRouterModels();
    await upsertModelsToDatabase(models);
  });
}

Triggered via Railway cron: 0 3 * * * curl $APP_URL/api/jobs/sync-models

2. Pricing + Benchmark Sync (Weekly, Sunday 4am UTC)

// Fetches updated pricing from OpenRouter
// Fetches quality benchmarks from Artificial Analysis
// Updates models.benchmarks JSONB column

Job safety: Uses the distributed locking pattern from Phase 1 (PostgreSQL unique partial index). If multiple Railway instances try to run the job simultaneously, only one succeeds. Others skip gracefully.

Model Comparison UI

The comparison table is a single <Table> component with dynamic columns:

// Compare up to 3 models
const [selectedModels, setSelectedModels] = useState<Model[]>([]);

// Rows: Provider, Context, Input Price, Output Price, Quality, etc.
// Columns: Model 1, Model 2, Model 3
// Highlight: Lowest price in green, highest quality in blue

Challenge: Mobile responsiveness with 3 columns. Solution: Horizontal scroll on small screens, full table on desktop.

Database Schema Highlights

Hierarchical ownership with RLS:

-- User owns products
CREATE POLICY "users_select_own_products"
  ON products FOR SELECT
  USING (user_id = auth.uid());

-- User owns functions through products
CREATE POLICY "users_select_own_functions"
  ON functions FOR SELECT
  USING (
    EXISTS (
      SELECT 1 FROM products p
      WHERE p.id = functions.product_id
        AND p.user_id = auth.uid()
    )
  );

Nested RLS checks ensure users can only see their own data, even through joins. Use cases belong to functions, functions belong to products, products belong to users.

Public read for models:

-- Anyone can browse the catalog
CREATE POLICY "models_public_read"
  ON models FOR SELECT
  TO anon, authenticated
  USING (true);

Why This Phase Matters

The Problem Context

You're busy shipping features. You don't have time to:

  • Research 400+ AI models every week
  • Benchmark alternatives for your use cases
  • Track pricing changes across 15 providers
  • Know when a better model launches

Result: You picked GPT-4 in March and you're still using it in January, even though cheaper models now match or exceed its quality for your specific tasks.

The ModelOptix Approach

Phase 2 sets the foundation:

  1. You document your AI stack (5 minutes)
  2. ModelOptix learns your requirements (latency, cost, quality)
  3. We monitor the market (daily catalog sync, weekly benchmarks)
  4. You get notified when opportunities appear (Phase 3 - next week)

Phase 3 delivers the value:

  • "Switch from GPT-4 Turbo to Claude 3.5 Sonnet for summarization → Save $156/month"
  • "New model Llama 3.3 70B matches GPT-4 for classification at 1/10th the cost → Save $280/month"
  • "Gemini 1.5 Flash got a 40% price drop → Savings increased from $67 to $112/month"

We're building a system that works for you 24/7, watching for opportunities while you sleep.


What's Next: Phase 3

Core Value Loop (Recommendation Engine) - Target: 7 days

The big one. This is where ModelOptix earns its keep.

15 tasks to deliver:

  1. Recommendation Engine - FitScore algorithm, weighting system
  2. Opportunity Generation - Nightly job finds savings opportunities
  3. Opportunities List - See all recommendations ranked by savings
  4. Opportunity Detail - Compare current vs recommended with justification
  5. Sanity Check - Test models side-by-side on YOUR prompts before switching
  6. Act on Opportunity - Switch models with one click, track savings
  7. Trust Dashboard - Provider trust scores, editorial warnings
  8. Guest Sanity Check - Pre-signup testing (3 free tests)
  9. Quotas + Guardrails - Prevent runaway OpenRouter costs

The FitScore Algorithm:

For each use case, we calculate a FitScore (0-100) for every compatible model:

FitScore = weighted_sum(
  Quality Match: benchmark score vs. your requirements
  Cost Efficiency: price per task vs. budget
  Latency Match: response time vs. requirements
  Context Fit: window size vs. your prompts
  Trust Score: provider + model reliability
)

Models with FitScore > current model's score → become Opportunities.

Sanity Check Flow:

Before switching models, test them:

  1. Provide 3-5 sample prompts representative of your use case
  2. We run them against your current model + recommended model via OpenRouter
  3. You compare outputs side-by-side
  4. Decide: Switch (save money) or Dismiss (keep current)

Guest access: Try Sanity Check before signing up (3 tests free).


The Build-in-Public Strategy

I'm building ModelOptix entirely in public for three reasons:

1. Target Users Are Builders

You understand the AI pricing pain because you live it. You know the feeling of seeing a $2,000 OpenAI bill and wondering "Could I have used a cheaper model?"

Building in public means you see the product evolve and can shape it. Your feedback in Week 2 is worth 10x feedback in Month 6.

2. Trust Through Transparency

ModelOptix is an independent advisor. We make money from your subscription, not affiliate commissions. No vendor partnerships. No conflicts of interest.

Building in public proves that independence. You can see exactly how we build, what we prioritize, and why.

3. Speed Through Accountability

Public commits force shipping. If I say "Phase 3 in 7 days," I'm on the hook. No scope creep, no endless polish, no "just one more feature."

Ship → Measure → Iterate. That's the playbook.


Try ModelOptix Today

Landing page: modeloptix.com

Interactive features:

  1. Savings Calculator - Enter your API volume and see potential savings
  2. Trader7 Case Study - Real example: $747/month saved (40% reduction)
  3. Waitlist Signup - Join 150+ builders waiting for beta access

Beta launch: ~10 days (after Phase 3 complete)

Beta perks:

  • ✅ Free lifetime Solo tier ($9.95/mo value)
  • ✅ Early access to all features as they ship
  • ✅ Direct line to me for feedback/feature requests
  • ✅ Shape the product with your input

Join the waitlist - I'll email you when Phase 3 launches.


For Other Builders

If you're building in public too, here are some lessons from Phase 2:

1. CRUD Velocity

Standard CRUD is fast when you have:

  • Strong TypeScript types generated from database schema (Supabase does this)
  • shadcn/ui components (Form, Dialog, Table, Card - all pre-built)
  • RLS policies that handle auth (no manual permission checks in code)

Our velocity: ~4 hours per complete CRUD entity (products, functions, use cases).

2. Sync Jobs Are Simple

You don't need Kafka or RabbitMQ for daily syncs. A cron-triggered HTTP endpoint works perfectly:

# Railway cron.yaml
jobs:
  - schedule: "0 3 * * *"  # Daily 3am UTC
    command: "curl $APP_URL/api/jobs/sync-models"

Paired with distributed locking (PostgreSQL unique index), you get reliable, zero-config job orchestration.

3. Public Data = No Auth Complexity

The model catalog is public (anonymous SELECT allowed). This means:

  • No auth checks in catalog API routes
  • Fast page loads (no session validation)
  • Easy to share model links (no login wall)

Separate public data early in your schema design. It simplifies everything.

4. Feature Flags via Database

Instead of feature flags, we use database existence checks:

// Enable comparison only if models table has data
const catalogReady = await supabase
  .from('models')
  .select('id', { count: 'exact', head: true });

if (catalogReady.count > 0) {
  // Show comparison feature
}

No external service needed. Database IS your feature flag store.

5. Mobile-First, Always

Every UI component starts mobile-first, then scales up:

// Mobile: Stacked cards
// Desktop: Table
<div className="md:hidden">
  {/* Card layout */}
</div>
<div className="hidden md:block">
  <Table>...</Table>
</div>

60% of traffic is mobile. Design for it first, not as an afterthought.


The Numbers So Far

Phase 2 Stats:

  • Duration: 3 days (Jan 19-21)
  • Tasks completed: 10/10
  • Code added: ~3,200 lines across 24 files
  • Database tables used: 8 (products, functions, use_cases, models, providers, model_provider_pricing, parameter_support, model_trust_scores)
  • API endpoints created: 12 (CRUD + sync jobs)
  • UI pages created: 7 (dashboard, products, functions, use cases, catalog, detail, comparison)

Cumulative Progress:

  • Total phases complete: 3/6 (Phase 0, 0.5, 1, 2)
  • Total tasks complete: 33/72 (46%)
  • Lines of code: ~8,500
  • Waitlist signups: 150+ (and growing)

Phase 3 Target:

  • Start date: Jan 21
  • Target completion: Jan 28 (7 days)
  • Tasks: 15 (recommendation engine, opportunities, sanity check)
  • Key metric: Time to first opportunity viewed < 10 minutes

Join the Journey

Next post: Phase 3 progress update (Recommendation Engine + Sanity Check)

Previously:

Follow the build:


Let's Connect

Building something similar? Working with AI models? Have feedback on ModelOptix?

Drop a comment or DM me - I'd love to hear what you're working on.


Building in public, one phase at a time. Stop overpaying for AI.

Next milestone: Phase 3 complete (Recommendation Engine) - Target: Jan 28

Share this post