nyxcore-systems
7 min read

From Protocol to Production: Launching the IPCHA API Service

A deep dive into building and deploying a complex protocol (IPCHA) as a fully rentable API service, covering FastAPI, Next.js, Prisma, and key lessons from the trenches of a rapid development cycle.

FastAPINext.jsTypeScriptPrismaDockerAPI DevelopmentBackendFrontendDeploymentLessons Learned

It’s 12:15 UTC, and I've just pushed the final commit, watched the CI pipelines glow green, and seen PR #133 merge into main. The feeling of a major feature fully deployed, tested, and documented is always exhilarating. Today, we're celebrating the launch of the IPCHA Protocol API Service—a monumental effort that transformed a complex protocol into a rentable, robust, and user-friendly offering.

This post will walk you through the journey: from the core protocol implementation to building a full-fledged API, dashboard, and CLI integration, all while sharing the critical lessons learned along the way.

The Mission: IPCHA to the World

Our primary goal was ambitious: take the newly developed IPCHA (Inter-Protocol Claim Hashing and Arbitration) protocol, implement its 15 distinct modules, and expose it as a scalable, rentable API service. This wasn't just about functionality; it was about productization—complete with authentication, rate limiting, metering, a customer dashboard, and even Bring Your Own Key (BYOK) integration.

The journey encompassed:

  • IPCHA Protocol Implementation: The core logic, written in Python.
  • FastAPI Sidecar: The high-performance API layer.
  • REST Proxy & Middleware: The public-facing gateway with robust access control.
  • Prisma & PostgreSQL: For data persistence, tokens, and usage logs.
  • Next.js Dashboard: A rich UI for customers and administrators.
  • ShellAI CLI API: Extending functionality to command-line users.
  • End-to-End Testing & Documentation: Ensuring reliability and usability.

And as of today, it's all live on main.

From Python Modules to a Public-Facing API

The foundation of this service is the IPCHA protocol itself. Over the past sessions, we meticulously crafted 15 Python modules across ipcha/, src/arbitration/, benchmarks/, sdrl_claims/, and scripts/. With 78 unit tests ensuring its internal integrity, the core protocol was solid, committed as b34b44f.

But a protocol isn't a product until it's accessible. This is where the API layer came in.

The FastAPI Powerhouse

We opted for a FastAPI sidecar (ipcha/api.py, ipcha/Dockerfile) to serve the Python-based IPCHA logic. This provided 10 high-performance endpoints, seamlessly integrated into our Docker Compose setup. It’s fast, robust, and leverages Python's strengths.

Data Persistence and Security

For managing API tokens, usage logs, and job states, we designed a Prisma schema with IpchaApiToken, IpchaUsageLog, and IpchaJob models. Crucially, we implemented Row-Level Security (RLS) policies in prisma/rls.sql to ensure data isolation between tenants.

A dedicated token service (src/server/services/ipcha-token-service.ts) was built to issue secure nyx_ip_ tokens, hashed with SHA-256 for integrity.

The Next.js & TypeScript Ecosystem

Our frontend and API gateway were built on Next.js and TypeScript, providing a unified developer experience.

  • Sidecar Client: A robust callIpcha() function (src/server/services/ipcha-client.ts) handles communication with the FastAPI sidecar.
  • REST Middleware: This is the heart of our rentable service. In src/app/api/v1/ipcha/middleware.ts, we implemented:
    • Authentication: Verifying API tokens.
    • Rate Limiting: Preventing abuse.
    • Daily Quota Management: Enforcing usage limits.
    • Metering: Tracking API calls for billing.
  • REST Proxy: The public-facing API (src/app/api/v1/ipcha/_proxy.ts and 11 route files) routes all sync and async requests to the sidecar, applying the middleware policies.
  • Bring Your Own Key (BYOK): A critical enterprise feature, our validate/route.ts resolves tenant API keys by decrypting apiKey.encryptedKey and passes it securely via an X-LLM-Api-Key header.
  • tRPC Router: For internal and dashboard communication, a dedicated ipcha.ts tRPC router provides both customer and admin access.
  • Dashboard: Located at src/app/(dashboard)/dashboard/ipcha/, our new dashboard features 8 tab components, offering customers full visibility into their IPCHA usage, tokens, and job status.
  • ShellAI CLI API: To extend the reach, we integrated 8 new endpoints, 3 services, and 20 tests into our existing CLI API (src/app/api/v1/cli/), allowing command-line access to IPCHA functionalities.

Quality and Deployment

A project of this scale demands rigorous testing. With 78 Python unit tests for the core protocol and 20 tests for the CLI API, we had strong foundational coverage. The final step was end-to-end validation. Our integration test report (docs/reports/2026-03-15-ipcha-api-integration-test.md) proudly shows 14/14 tests passing, covering everything from scoring and sanitization to arbitration, routing, evaluation, and access control, with full data flow traces documented.

The culmination of this effort was PR #133, merging feat/cli-api into main at 2026-03-15 11:50 UTC, after all CI checks (Unit Tests, Lint & Typecheck, E2E Tests) passed flawlessly.

Lessons Learned: Navigating the Hurdles

No complex project is without its challenges. Here are some of the key "pain points" we encountered and how we overcame them, hopefully saving you some headaches!

1. Prisma's Stricter JSON Types

  • The Problem: We initially tried to use Record<string, unknown> for a Prisma Json field, expecting flexibility. However, Prisma's InputJsonValue is much stricter, leading to TS2322 type errors.
  • The Workaround: For compatibility, we found that JSON.parse(JSON.stringify(body)) effectively converts arbitrary objects into a structure that Prisma's InputJsonValue can accept, ensuring type safety without sacrificing too much flexibility.

2. Next.js fetch() Caching Gotchas

  • The Problem: When calling our FastAPI sidecar from Next.js, we noticed stale data in the playground. Next.js 14, by default, caches fetch() results, which is great for static content but problematic for dynamic API calls.
  • The Workaround: The fix was simple but crucial: adding cache: "no-store" to our callIpcha() function in ipcha-client.ts. This explicitly tells Next.js not to cache the fetch results, ensuring fresh data on every request.

3. Dockerignore's Broad Strokes

  • The Problem: Our .dockerignore file was set to exclude all tests/ directories for a leaner production image. However, we needed tests/evaluation/ for specific runtime checks.
  • The Workaround: We added an exception: !tests/evaluation to the .dockerignore file. This allows specific subdirectories to be included while maintaining the general exclusion rule. A good reminder to be precise with ignore files!

4. PostgreSQL Type Casting in Prisma Raw Queries

  • The Problem: When executing raw SQL queries via Prisma's $queryRaw, we encountered operator does not exist: uuid = text errors. Prisma was passing ctx.tenantId as a string, but our PostgreSQL column expected a uuid type.
  • The Workaround: Explicit type casting in the SQL query itself saved the day: ${ctx.tenantId}::uuid. This tells PostgreSQL to treat the incoming string as a UUID, resolving the type mismatch.

5. tRPC Union Return Types from .catch()

  • The Problem: In our systemHealth tRPC router, we tried to return a default object using .catch(() => ({ total: 0 })) for error handling. This created a union return type that TypeScript couldn't easily narrow, making field access (.total) problematic without verbose checks.
  • The Workaround: We extracted a const defaultMetrics = { ... } object and explicitly typed the callIpcha result as callIpcha<typeof defaultMetrics>. Then, we handled the .then(r => r.total) separately. This maintains type safety and avoids the union type complexity.

The Road Ahead

With the IPCHA API service now live on main—our production environment (root@46.225.232.35) is humming, all four containers running smoothly, and the first nyx_ip_ tokens generated—our immediate focus shifts to refinement and expansion.

Here’s what’s next on the roadmap:

  1. Docker Compose Environment Variables: Move from inline environment variables to env_file: .env.production for the ipcha service in docker-compose.yml for cleaner management.
  2. Idempotent RLS Policies: Update our RLS SQL to be idempotent (DROP POLICY IF EXISTS ... ; CREATE POLICY ...) to prevent errors on re-application.
  3. OpenAPI Documentation: Leverage FastAPI's auto-generated Swagger/OpenAPI docs (available at /docs) to provide comprehensive API documentation.
  4. Workflow Engine Integration: Wire IPCHA scoring directly into the nyxCore workflow engine as a new step type, unlocking powerful new automation possibilities.
  5. Usage Dashboard Charts: Enhance the customer dashboard with 30-day trend charts for usage, moving beyond just recent calls.
  6. External API Documentation & Pricing: Prepare public-facing API documentation and a pricing page for external customers.
  7. Branch Cleanup: Delete the feat/cli-api branch, as it's now fully merged into main.

This project has been a testament to what a focused team can achieve, turning a complex protocol into a fully functional, rentable service in record time. The lessons learned will undoubtedly serve us well on future endeavors. Onward!