Executive Summary Ecosystem Exam Preview Competency Framework ISO 17024 Roadmap | SolidSkills SolidContext

Contents

System Overview Laravel Module (CMS) Nuxt 4 Frontend MCP Server Data Pipeline Database Schema API Design MVP Pages Auth & Tiers RAG Pipeline Multi-Tenancy Usage-Based Billing Tech Stack Module Structure Nuxt Config Timeline

1. System Architecture Overview

SolidContext is a split-architecture system. Laravel handles content management and the web frontend. A dedicated Python (FastAPI) inference service handles all AI/LLM-facing requests — vector search, RAG queries, and embedding — because PHP is too slow for real-time inference workloads.

ComponentTechnologyRoleRepo
CMS + Doc Generation Laravel 12 Module Content ingestion from Library domain, doc generation pipeline, admin management, web frontend API (browse/list/read) platform-backend/Modules/SolidContext/
Inference API Python (FastAPI) + LlamaIndex Vector search, RAG retrieval, LLM answer synthesis, embedding. All MCP/AI tool requests hit this service. solidcontext-api/ (new repo)
Web Frontend Nuxt 4 (SSR) Public docs website — browse, search, read docs. SEO-indexed. Talks to Laravel for content, FastAPI for AI search. solidcontext/ (new repo)
MCP Server TypeScript npm package Connects AI tools (Claude Code, Cursor, Copilot) to the Inference API. Distributed via npx. solidcontext-mcp/ (new repo)
Why two backends? Laravel stays as the CMS because it has direct access to the Library domain models (Lesson, CourseVersion, Software, VideoTranscriptSegment), visibility logic, and the existing Algolia/Typesense indexes. No data duplication. FastAPI handles the performance-critical inference path because Python has the richest AI/ML ecosystem (LlamaIndex, embedding models, vector DB clients) and is orders of magnitude faster than PHP for streaming LLM responses and vector operations.

2. Laravel Module (CMS): Modules/SolidContext/

Content ingestion, doc generation, and web browsing API. Follows nwidart/laravel-modules v12 conventions. Does not serve AI/LLM requests — those go to the FastAPI inference service.

Module Registration

// Modules/SolidContext/module.json
{
    "name": "SolidContext",
    "alias": "solidcontext",
    "active": true,
    "providers": [
        "Modules\\SolidContext\\Providers\\SolidContextServiceProvider"
    ]
}

Models

SolidContextDoc — The core entity

Each doc is a generated, structured piece of documentation derived from Library content.

class SolidContextDoc extends Model
{
    use HasFactory, UsesUuid, SoftDeletes;

    protected $table = 'solid_context_docs';

    protected $fillable = [
        'software_id',
        'title',
        'slug',
        'content',
        'summary',
        'software_version',
        'tags',
        'difficulty',
        'token_count',
        'snippet_count',
        'tier',
        'source_type',
        'source_id',
        'published_at',
    ];

    protected function casts(): array
    {
        return [
            'tags' => 'array',
            'published_at' => 'datetime',
            'tier' => SolidContextTier::class,
            'difficulty' => SolidContextDifficulty::class,
        ];
    }

    public function software(): BelongsTo
    {
        return $this->belongsTo(SolidContextSoftware::class, 'software_id');
    }

    protected static function newFactory(): SolidContextDocFactory
    {
        return SolidContextDocFactory::new();
    }
}

SolidContextSoftware — Software catalog mirror

class SolidContextSoftware extends Model
{
    use HasFactory, UsesUuid;

    protected $table = 'solid_context_software';

    protected $fillable = [
        'library_software_id',
        'name',
        'slug',
        'description',
        'versions',
        'doc_count',
        'logo_url',
    ];

    protected function casts(): array
    {
        return [
            'versions' => 'array',
        ];
    }

    public function docs(): HasMany
    {
        return $this->hasMany(SolidContextDoc::class, 'software_id');
    }

    protected static function newFactory(): SolidContextSoftwareFactory
    {
        return SolidContextSoftwareFactory::new();
    }
}

Services

DocGenerationService

Transforms Library domain content into SolidContext docs. This is the heart of the system.

class DocGenerationService
{
    /**
     * Generate docs for a specific software.
     * Reads from Library domain models (Lesson, CourseVersion).
     * Applies visibility rules from LibraryAggregator.
     */
    public function generateForSoftware(Software $software): int
    {
        $docsGenerated = 0;

        $software->courseVersions()
            ->where(fn ($q) => $q
                ->whereHas('status', fn ($q) => $q->where('tag', 'published'))
                ->whereHas('privacy', fn ($q) => $q->where('tag', 'public'))
            )
            ->with(['sections.lessons'])
            ->chunkById(50, function ($versions) use (&$docsGenerated) {
                $versions->each(function (CourseVersion $version) use (&$docsGenerated) {
                    $version->sections->flatMap->lessons->each(
                        function (Lesson $lesson) use ($version, &$docsGenerated) {
                            $this->generateDocFromLesson($lesson, $version);
                            $docsGenerated++;
                        }
                    );
                });
            });

        return $docsGenerated;
    }

    /**
     * Transform a Lesson into a SolidContext doc.
     * Uses the lesson_script accessor (strips HTML, URL-decodes, unescapes).
     */
    private function generateDocFromLesson(Lesson $lesson, CourseVersion $version): SolidContextDoc
    {
        return SolidContextDoc::updateOrCreate(
            ['source_type' => 'lesson', 'source_id' => $lesson->uuid],
            [
                'title'     => $lesson->name,
                'slug'      => $lesson->slug,
                'content'   => $lesson->lesson_script,  // sanitized via accessor
                'summary'   => Str::words($lesson->lesson_script, 200),
                'tags'      => $lesson->tags,
                'tier'      => $this->determineTier($lesson, $version),
                // ... remaining fields
            ]
        );
    }
}

DocSearchService (Laravel — basic text search for web frontend)

Simple Eloquent search for the Nuxt 4 browsing experience. Not used by MCP or AI tools.

class DocSearchService
{
    public function search(
        string $query,
        ?string $softwareSlug = null,
        ?string $version = null,
        int $limit = 10,
    ): LengthAwarePaginator {
        return SolidContextDoc::query()
            ->whereNotNull('published_at')
            ->when($softwareSlug, fn ($q, $slug) =>
                $q->whereHas('software', fn ($q) => $q->where('slug', $slug))
            )
            ->when($version, fn ($q, $v) =>
                $q->where('software_version', $v)
            )
            ->where(fn ($q) =>
                $q->where('title', 'like', "%{$query}%")
                  ->orWhereJsonContains('tags', $query)
                  ->orWhere('content', 'like', "%{$query}%")
            )
            ->paginate($limit);
    }
}
Search Architecture Split The Laravel DocSearchService is a basic text search for the web frontend's browsing experience. All AI-powered semantic search (vector similarity, RAG retrieval) happens in the FastAPI inference service using LlamaIndex + pgvector/Pinecone. MCP tools and AI clients never touch Laravel directly.

Artisan Command

// php artisan solidcontext:generate-docs
// Regenerates all docs from Library content. Safe to re-run (uses updateOrCreate).
// Run on schedule (weekly) or manually after content publishes.

class GenerateDocsCommand extends Command
{
    protected $signature = 'solidcontext:generate-docs {--software= : Filter by software slug}';

    public function handle(DocGenerationService $service): int
    {
        $total = Software::query()
            ->isVisible()->isPublished()
            ->when($this->option('software'), fn ($q, $slug) =>
                $q->where('slug', $slug)
            )
            ->get()
            ->sum(function (Software $software) use ($service) {
                $count = $service->generateForSoftware($software);
                $this->info("Generated {$count} docs for {$software->name}");

                return $count;
            });

        $this->info("Total: {$total} docs generated.");

        return Command::SUCCESS;
    }
}

3. Data Pipeline

Content flows from the Library domain through a generation pipeline into SolidContext docs.

Source Data

SourceModelKey FieldsLocation
Lesson Transcripts Lesson lesson_script (via accessor: strips HTML, URL-decodes, unescapes entities), name, slug, duration, difficulty_level, tags via lessonTags() app/Library/Courses/Models/Lesson.php
Course Metadata CourseVersion name, description, version, language, sections hierarchy, lesson_tags (aggregated) app/Library/Courses/Models/CourseVersion.php
Software Catalog Software name, slug, description, visibility, status app/Library/Software/Models/Software.php
Transcript Segments VideoTranscriptSegment text, start/end timestamps, lesson context. Already chunked. Indexed in Typesense (not Algolia). app/Library/Models/VideoTranscriptSegment.php

Visibility Rules (What Gets Published)

The generation pipeline reuses the Library domain's existing visibility logic:

Tier Determination

ConditionTierContent Served
Course has FIRST_FIVE_UNLOCKED non-member access AND lesson is in first 5 Free Full content + summary
Introductory / fundamentals courses (first course in family) Free Full content + summary
All other published, public content Premium Summary only (free tier), full content (premium tier)

Pipeline Steps

  1. Query Library models — Filter by visibility rules, eager load sections + lessons + tags
  2. Extract content — Read lesson_script (auto-sanitized by Eloquent accessor), gather metadata
  3. Generate doc — Create/update SolidContextDoc with content, summary, tags, tier, token count
  4. Index for search — (MVP: no-op, uses LIKE queries. v2: push to Algolia solid_context index)
  5. Cache software counts — Update doc_count on SolidContextSoftware

4. Database Schema

-- Modules/SolidContext/database/migrations/

CREATE TABLE solid_context_software (
    id             BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    uuid           CHAR(36) UNIQUE NOT NULL,
    library_software_id  BIGINT UNSIGNED,     -- FK to software table
    name           VARCHAR(255) NOT NULL,
    slug           VARCHAR(255) UNIQUE NOT NULL,
    description    TEXT,
    versions       JSON,                         -- ["2024", "2025", "Evergreen"]
    doc_count      INT UNSIGNED DEFAULT 0,
    logo_url       VARCHAR(500),
    created_at     TIMESTAMP,
    updated_at     TIMESTAMP
);

CREATE TABLE solid_context_docs (
    id             BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    uuid           CHAR(36) UNIQUE NOT NULL,
    software_id    BIGINT UNSIGNED NOT NULL,      -- FK to solid_context_software
    title          VARCHAR(500) NOT NULL,
    slug           VARCHAR(500) NOT NULL,
    content        LONGTEXT,                       -- Full doc content (markdown)
    summary        TEXT,                            -- ~200 word summary (free tier)
    software_version VARCHAR(50),                  -- "2024", "Evergreen"
    tags           JSON,                            -- ["features", "sweep"]
    difficulty     VARCHAR(20),                     -- beginner, intermediate, advanced
    token_count    INT UNSIGNED DEFAULT 0,
    snippet_count  INT UNSIGNED DEFAULT 0,
    tier           VARCHAR(20) NOT NULL DEFAULT 'premium',  -- free, premium
    source_type    VARCHAR(50),                     -- lesson, course_version
    source_id      CHAR(36),                        -- UUID of source entity
    published_at   TIMESTAMP NULL,
    created_at     TIMESTAMP,
    updated_at     TIMESTAMP,
    deleted_at     TIMESTAMP NULL,

    INDEX idx_software_id (software_id),
    INDEX idx_slug (slug),
    INDEX idx_tier (tier),
    INDEX idx_software_version (software_version),
    INDEX idx_source (source_type, source_id),
    UNIQUE idx_software_slug (software_id, slug, software_version),
    FOREIGN KEY (software_id) REFERENCES solid_context_software(id)
);

5. API Design

Two separate API surfaces. Laravel serves the content management and web browsing endpoints. FastAPI serves the performance-critical inference endpoints that AI tools and MCP hit.

Laravel CMS API — /api/solidcontext/v1/

Content browsing, listing, and reading. Powers the Nuxt 4 frontend. Standard Laravel module routes.

MethodEndpointAuthDescription
GET /api/solidcontext/v1/software Public List all software with doc counts and versions
GET /api/solidcontext/v1/software/{slug} Public Software detail with version list
GET /api/solidcontext/v1/software/{slug}/docs Public List docs for a software (paginated). Returns summaries for premium docs.
GET /api/solidcontext/v1/docs/{uuid} Public Single doc. Free tier docs: full content. Premium docs: summary only.
GET /api/solidcontext/v1/docs/{uuid}/full API Key Full content for premium docs. Requires X-SolidContext-Key header.

FastAPI Inference API — inference.solidcontext.com/v1/

High-performance vector search and RAG retrieval. This is what MCP servers and AI tools call. Python + LlamaIndex.

MethodEndpointAuthDescription
POST /v1/query Free / API Key RAG query — vector search + LLM synthesis. Returns an answer with source citations. Tier determines content depth.
GET /v1/search Free / API Key Semantic vector search. Params: q, software, version, top_k. Returns ranked doc chunks.
GET /v1/resolve/{name} Public Fuzzy-resolve a software name to a SolidContext software object. Used by MCP resolve-software tool.
POST /v1/embed Enterprise Upload and embed private content for a tenant. Used by VARs to index their proprietary docs.
Why POST for /v1/query? RAG queries send a natural language prompt (potentially long) plus context parameters (tenant_id, conversation history). POST avoids URL length limits and allows structured request bodies. The response can also be streamed via SSE for real-time token delivery.

API Resources

// SolidContextDocResource — controls tier-based content visibility
class SolidContextDocResource extends JsonResource
{
    public function toArray($request): array
    {
        $isPremiumAuthorized = $this->isAuthorizedForFullContent($request);

        return [
            'uuid'             => $this->uuid,
            'title'            => $this->title,
            'slug'             => $this->slug,
            'software'         => SolidContextSoftwareResource::make($this->whenLoaded('software')),
            'software_version' => $this->software_version,
            'tags'             => $this->tags,
            'difficulty'       => $this->difficulty,
            'token_count'      => $this->token_count,
            'snippet_count'    => $this->snippet_count,
            'tier'             => $this->tier,
            'summary'          => $this->summary,
            'content'          => $this->when(
                $this->tier === SolidContextTier::Free || $isPremiumAuthorized,
                $this->content
            ),
            'published_at'     => $this->published_at,
        ];
    }
}

6. MVP Pages (Nuxt 4 Frontend)

RoutePageSSRDescription
/ pages/index.vue Yes Homepage — hero, search bar, software grid, featured docs
/software pages/software/index.vue Yes Full software catalog with doc counts
/software/:slug pages/software/[slug].vue Yes Software detail — version filter, doc listing, description
/software/:slug/:doc pages/software/[slug]/[doc].vue Yes Doc detail — full content, related docs, "powered by SolidProfessor" CTA
/search pages/search.vue No Search results with filters (software, version, tier, difficulty)
SSR Strategy All content pages are server-rendered for SEO — these docs should be Google-indexed so engineers find them organically. Search page is client-rendered (SPA) since it's interactive and doesn't need indexing. Follows the same pattern as /library/ app's routeRules.

7. Nuxt 4 Configuration

Following the /library/ app pattern exactly:

// solidcontext/nuxt.config.ts
import tailwindcss from '@tailwindcss/vite'

export default defineNuxtConfig({
  compatibilityDate: '2026-03-14',
  ssr: true,

  app: {
    head: {
      title: 'SolidContext — Engineering Docs for AI',
      link: [
        { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
        { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700&display=swap' },
      ],
    },
  },

  vite: {
    plugins: [tailwindcss()],
  },

  routeRules: {
    '/':                     { ssr: true },
    '/software':              { ssr: true },
    '/software/**':           { ssr: true },
    '/search':                { ssr: false },
  },

  runtimeConfig: {
    public: {
      cmsApiBase: process.env.NUXT_PUBLIC_CMS_API_BASE || 'http://localhost:8080/api/solidcontext/v1',
      inferenceBase: process.env.NUXT_PUBLIC_INFERENCE_BASE || 'http://localhost:8000/v1',
      spUrl: process.env.NUXT_PUBLIC_SP_URL || 'https://www.solidprofessor.com',
    },
  },

  devServer: { port: 3140 },
  typescript: { strict: true },
  modules: ['@pinia/nuxt'],
})

Composables

// composables/useSolidContextApi.ts
// Two API bases: Laravel for content browsing, FastAPI for AI search
export function useSolidContextApi() {
  const config = useRuntimeConfig()
  const cms = config.public.cmsApiBase       // Laravel: /api/solidcontext/v1
  const inference = config.public.inferenceBase // FastAPI: inference.solidcontext.com/v1

  return {
    // Content browsing (Laravel CMS API)
    listSoftware: () => useFetch(`${cms}/software`),
    getSoftware: (slug: string) => useFetch(`${cms}/software/${slug}`),
    listDocs: (slug: string, params?: Record<string, string>) =>
      useFetch(`${cms}/software/${slug}/docs`, { params }),
    getDoc: (uuid: string) => useFetch(`${cms}/docs/${uuid}`),

    // AI-powered search (FastAPI Inference API)
    search: (params: Record<string, string>) =>
      useFetch(`${inference}/search`, { params }),
    query: (prompt: string, software?: string) =>
      useFetch(`${inference}/query`, {
        method: 'POST',
        body: { prompt, software },
      }),
  }
}

8. MCP Server

TypeScript npm package using @modelcontextprotocol/sdk. All MCP tool calls hit the FastAPI Inference API (not Laravel). Two operating modes:

ModeData SourceWhen
API Mode (default) Queries the FastAPI inference service at runtime User has internet. Freshest data. Pro/Enterprise tiers require API key.
Bundled Mode Pre-built JSON data bundle shipped with npm package Offline use. Free tier only. Updated on npm publish.

MCP Tools

ToolInputOutputInference API Call
resolve-software { name: "solidworks" } Software object with slug, versions, doc count GET /v1/resolve/{name}
query-docs { softwareId, query, version? } RAG answer with source citations + ranked doc chunks POST /v1/query

Distribution

# Users install with a single line in their MCP config:
{
  "mcpServers": {
    "solidcontext": {
      "command": "npx",
      "args": ["-y", "@solidprofessorhub/solidcontext-mcp"],
      "env": {
        "SOLIDCONTEXT_API_KEY": "sc_..."   // optional, for premium tier
      }
    }
  }
}

9. Authentication & Tiers

API Key Model

SolidContext uses its own API key system, separate from Passport OAuth2. These are long-lived keys for MCP/programmatic access, not user sessions.

Free

$0

For individuals

Features
  • Public Repos
  • Access Control
  • OAuth 2.0
Current Plan

Enterprise

Custom

For enterprises

Pro Features
  • SOC-2 and GDPR
  • SSO (SAML / OIDC)
  • Self-Hosted

API Access by Tier

TierAuthContent AccessRate Limit
Free None required Public repos, doc metadata, summaries, free-tier doc content 60 req/min per IP
Pro X-SolidContext-Key header Everything in Free + private repos, full content for all docs, team collaboration Unlimited
Enterprise X-SolidContext-Key + SSO (SAML / OIDC) Everything in Pro + self-hosted deployment, SOC-2 and GDPR compliance Unlimited
Key Generation (Future) Pro and Enterprise API keys would be generated from a user's SolidProfessor account settings page. For MVP, all content can be served as free tier to validate the concept.

10. Core RAG Pipeline

SolidContext is a domain-specific Retrieval-Augmented Generation (RAG) system. The competitive advantage is the quality of answers derived from proprietary mechanical engineering content, not just a search wrapper.

Ingestion & Parsing

The ingestion pipeline processes internal SME documentation from the Library domain. Course materials (Markdown lesson scripts, video transcripts, CAD metadata) are extracted and cleaned through the existing Eloquent accessors and dedicated parsers.

SourceParserNotes
Lesson scripts Eloquent accessor (lesson_script) Already strips HTML, URL-decodes, unescapes entities
Video transcripts VideoTranscriptSegment Pre-chunked in Typesense with timestamps
Course metadata CourseVersion + relationships Name, description, version, section hierarchy
PDFs / CAD docs LlamaParse or Unstructured.io Future: parse supplemental materials and CAD metadata

Chunking & Embedding

Documents are broken into logical chunks (by paragraph, course module, or lesson) and converted into numerical vectors via an embedding model.

# solidcontext-api/app/pipeline/embed.py
# Runs in the FastAPI service — called by Laravel via internal API after doc generation

from llama_index.core import Document, VectorStoreIndex
from llama_index.core.node_parser import SentenceSplitter

async def embed_document(doc: SolidContextDoc, vector_store: VectorStore):
    splitter = SentenceSplitter(chunk_size=512, chunk_overlap=50)
    nodes = splitter.get_nodes_from_documents([
        Document(
            text=doc.content,
            metadata={
                "tenant_id": "solidprofessor",
                "software": doc.software_slug,
                "version": doc.software_version,
                "tier": doc.tier,
                "source_id": doc.uuid,
            },
        )
    ])

    await vector_store.async_add(nodes)

Vector Storage & Retrieval

Vectors are stored in a database optimized for similarity search. When a user asks a question, it's converted to a vector, the most relevant chunks are retrieved, and fed to an LLM to synthesize an answer.

OptionProsBest For
pgvector (via Supabase) Single database for auth, relational data, and vectors. No new infrastructure. MVP — simplest path to production
Pinecone Purpose-built for vector search. Managed, scales automatically. Native metadata filtering. Scale — when query volume justifies dedicated infra
Weaviate Open-source, self-hostable. Hybrid search (vector + keyword). GraphQL API. Enterprise — self-hosted deployments
Embedding Model Start with OpenAI's text-embedding-3-small for cost efficiency. Evaluate open-source alternatives like BGE-m3 for self-hosted Enterprise tier where data must not leave the customer's infrastructure.

11. Multi-Tenancy (Enterprise / VARs)

The Enterprise tier enables Value Added Resellers (VARs) to search SolidProfessor's foundational content plus their own private content, with strict data isolation between tenants.

Metadata Filtering Architecture

Instead of separate databases per tenant, every vector is tagged with a tenant_id. Query-time filtering enforces isolation. This runs in the FastAPI inference service, not Laravel.

# solidcontext-api/app/services/search.py
# Multi-tenant retrieval — filters at query time

class MultiTenantSearchService:
    def __init__(self, vector_store: VectorStore):
        self.vector_store = vector_store

    async def search(
        self,
        query: str,
        user: AuthenticatedUser,
        top_k: int = 10,
    ) -> list[DocChunk]:
        tenant_filter = self._resolve_tenants(user)

        return await self.vector_store.similarity_search(
            query=query,
            top_k=top_k,
            filter={"tenant_id": {"$in": tenant_filter}},
        )

    def _resolve_tenants(self, user: AuthenticatedUser) -> list[str]:
        match user.tier:
            case Tier.ENTERPRISE:
                return ["solidprofessor", user.tenant_id]
            case Tier.PRO:
                return ["solidprofessor"]
            case _:
                return ["solidprofessor"]

Tier Access Model

TierContent AccessData Isolation
Free Vectors tagged tenant_id: solidprofessor (public content only) Shared — read-only base content
Pro All SolidProfessor vectors (public + premium content) Shared — full SP content library
Enterprise tenant_id: solidprofessor OR tenant_id: {var_id} Isolated — VAR's private content never visible to other tenants
LLM Data Security The LLM provider must have a strict "zero data retention" policy. VAR content sent as context to the LLM must never be used to train public models. Enforce this via API contracts with providers (OpenAI Enterprise, Anthropic, or self-hosted models for Enterprise tier).

12. Usage-Based Billing

Pro and Enterprise tiers are billed based on actual consumption — token usage across search queries and generated answers.

Token Tracking

Every search query and RAG-generated answer consumes LLM tokens. An observability gateway sits between the application and the LLM provider to automatically log usage per user or API key.

ToolRoleKey Feature
Helicone LLM proxy / observability One-line integration, per-user token tracking, cost analytics, caching
Langfuse LLM observability / tracing Open-source, detailed trace visualization, prompt management, self-hostable

Billing Engine

Token usage data feeds into a metered billing platform. Monthly aggregation with configurable markup on base LLM costs.

# solidcontext-api/app/middleware/token_tracking.py
# FastAPI middleware — tracks token usage on every inference request

from fastapi import Request, Response
from starlette.middleware.base import BaseHTTPMiddleware

class TrackTokenUsage(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next) -> Response:
        response = await call_next(request)

        if token_usage := response.headers.get("X-Token-Usage"):
            await self.usage_store.record(
                api_key_id=request.state.api_key.id,
                tenant_id=request.state.api_key.tenant_id,
                tokens_used=int(token_usage),
                endpoint=request.url.path,
            )

        return response

Billing Integration

OptionTypeBest For
Stripe Metered Billing SaaS billing platform Already integrated in platform-backend via Laravel Cashier. Natural fit.
Lago Open-source billing engine Complex pricing models, self-hostable, granular usage events
Pricing Formula Monthly cost = (total tokens consumed x base LLM cost per token) x markup multiplier. The Pro tier includes a base allocation (e.g., 500K tokens/month). Overage is billed at the per-token rate. Enterprise tiers negotiate custom commitments.

13. Full Module Structure

Modules/SolidContext/ ├── module.json # name, alias, providers ├── composer.json ├── config/ │ └── solidcontext.php # API key settings, rate limits ├── database/ │ ├── factories/ │ │ ├── SolidContextDocFactory.php │ │ └── SolidContextSoftwareFactory.php │ └── migrations/ │ ├── create_solid_context_software_table.php │ └── create_solid_context_docs_table.php ├── routes/ │ └── api.php # /api/solidcontext/v1/* ├── src/ │ ├── Console/ │ │ └── GenerateDocsCommand.php # solidcontext:generate-docs │ ├── Enums/ │ │ ├── SolidContextTier.php # Free, Pro, Enterprise │ │ └── SolidContextDifficulty.php # Beginner, Intermediate, Advanced │ ├── Http/ │ │ ├── Controllers/ │ │ │ ├── SoftwareController.php # index, show │ │ │ ├── DocController.php # index, show, full │ │ │ ├── SearchController.php # __invoke │ │ │ └── ResolveController.php # __invoke (fuzzy match) │ │ ├── Middleware/ │ │ │ └── ValidateApiKey.php # Premium tier auth │ │ ├── Requests/ │ │ │ ├── SearchDocsRequest.php │ │ │ └── ListDocsRequest.php │ │ └── Resources/ │ │ ├── SolidContextDocResource.php │ │ └── SolidContextSoftwareResource.php │ ├── Models/ │ │ ├── SolidContextDoc.php │ │ └── SolidContextSoftware.php │ ├── Services/ │ │ ├── DocGenerationService.php # Transform Library → Docs │ │ ├── DocSearchService.php # Search across docs │ │ └── SoftwareResolverService.php # Fuzzy name matching │ └── Providers/ │ ├── SolidContextServiceProvider.php │ ├── RouteServiceProvider.php │ └── EventServiceProvider.php └── Tests/ ├── Feature/ │ ├── SoftwareEndpointTest.php │ ├── DocEndpointTest.php │ ├── SearchEndpointTest.php │ └── ResolveEndpointTest.php └── Unit/ ├── DocGenerationServiceTest.php └── SoftwareResolverServiceTest.php

14. Tech Stack Summary

CMS + Web Frontend

ComponentTechnologyVersion
CMS BackendLaravelv12
Module Systemnwidart/laravel-modulesv12
PHPPHP8.4
Web FrontendNuxt4.x
CSSTailwind CSSv4 (via @tailwindcss/vite)
State ManagementPiniav2

Inference API (AI/LLM-facing)

ComponentTechnologyVersion
Inference FrameworkFastAPI (Python)0.115+
PythonPython3.12+
MCP SDK@modelcontextprotocol/sdklatest
MCP RuntimeTypeScript + tsxlatest

RAG & AI Layer

ComponentTechnologyPurpose
OrchestrationLlamaIndexDomain-specific document structuring and advanced retrieval
EmbeddingsOpenAI text-embedding-3-smallConvert content chunks into vectors (cost-efficient)
Embeddings (self-hosted)BGE-m3Open-source alternative for Enterprise self-hosted deployments
Vector Store (MVP)pgvector via SupabaseAuth, relational data, and vectors in one database
Vector Store (Scale)PineconeManaged, auto-scaling, native metadata filtering for multi-tenancy
Document ParsingLlamaParse / Unstructured.ioExtract text from PDFs, CAD docs, supplemental materials
LLM ProviderOpenAI / Anthropic APIAnswer synthesis from retrieved context chunks

Observability & Billing

ComponentTechnologyPurpose
LLM ObservabilityHelicone or LangfuseToken tracking, cost analytics, per-user usage logging
BillingStripe Metered Billing (via Laravel Cashier)Usage-based invoicing, overage billing, subscription management
Billing (alt)LagoOpen-source, complex pricing models, self-hostable

Testing & Quality

ComponentTechnologyVersion
Testing (Backend)Pestv3
Testing (Frontend)Vitest + Vue Test Utilslatest
FormattingLaravel Pint + ESLintlatest

15. Estimated Timeline

PhaseScopeDuration
Phase 1: Laravel Module + RAG Pipeline Models, migrations, ingestion pipeline, chunking, embedding, pgvector setup, artisan command, API endpoints (free tier only) 2-3 weeks
Phase 2: Nuxt 4 Frontend 5 MVP pages, composables, basic Tailwind styling, SSR config 1-2 weeks
Phase 3: MCP Server TypeScript MCP server, 2 tools, API mode, npm publishing 1 week
Phase 4: Pro Tier + Billing API key auth, Stripe metered billing, Helicone/Langfuse integration, token tracking, rate limiting 1-2 weeks
Phase 5: Enterprise + Multi-Tenancy Tenant metadata filtering, VAR content upload pipeline, SSO (SAML/OIDC), self-hosted vector store option, SOC-2/GDPR compliance 2-3 weeks