zurri / SYSTEM_FLOW.md
nexusbert's picture
initial commit
b5e5eac

Zurri System Flow

Complete System Architecture Flow

🎯 Overview

Zurri is an agents-only marketplace where creators list fully packaged AI agents, and users subscribe/purchase to chat with them via a standardized protocol.


πŸ“Š Complete User Journeys

1️⃣ Creator Journey: List an Agent

Creator Registers/Logs In
    ↓
POST /api/auth/register or /api/auth/login
    ↓
Receives JWT Token
    ↓
Creates Agent Listing
    POST /api/agents
    {
      name, description, endpoint, price,
      isSubscription, subscriptionDuration,
      promptTemplate, metadata, imageUrl
    }
    ↓
System Uploads Metadata to IPFS (Pinata)
    - Stores: name, description, endpoint, price, creatorId, metadata
    - Returns IPFS hash (CID)
    ↓
Agent Saved to Database
    - Status: PENDING
    - IPFS hash stored
    - Creator ID linked
    ↓
Admin Reviews Listing
    GET /api/agents/admin/pending (admin only)
    ↓
Admin Approves/Rejects
    PATCH /api/agents/:id/approve
    PATCH /api/agents/:id/reject
    ↓
Agent Status β†’ APPROVED
    ↓
Agent Appears in Marketplace
    GET /api/agents (public)

2️⃣ User Journey: Discover & Subscribe

User Registers/Logs In
    ↓
POST /api/auth/register or /api/auth/login
    ↓
Receives JWT Token
    ↓
Browse Marketplace
    GET /api/agents
    Query params: page, limit, search, sortBy
    ↓
View Agent Details
    GET /api/agents/:id
    (Endpoint hidden unless creator/admin)
    ↓
Subscribe to Agent
    POST /api/subscriptions/agent/:agentId
    Authorization: Bearer <token>
    ↓
System Creates Subscription
    - Checks if agent is APPROVED
    - Checks for existing active subscription
    - Calculates expiry date
      β€’ Subscription: currentDate + duration (days)
      β€’ One-time: 2099-12-31 (lifetime)
    - Generates payment reference
    ↓
Returns Payment Info
    {
      subscription: {...},
      payment: {
        reference: "sub_xxx_1234567890",
        amount: 100.00,
        currency: "NGN"
      }
    }
    ↓
User Completes Payment via Paystack
    (External payment flow)
    ↓
Paystack Webhook
    POST /api/subscriptions/webhook/paystack
    - Verifies signature (HMAC SHA512)
    - Checks event type: 'charge.success'
    - Finds subscription by payment reference
    ↓
Subscription Activated
    - isPaymentVerified: true
    - status: ACTIVE
    ↓
User Can Now Chat with Agent

3️⃣ User Journey: Chat with Agent

User Has Active Subscription
    ↓
Send Message to Agent
    POST /api/chat/:agentId/message
    Authorization: Bearer <token>
    Body: {
      message: "Hello!",
      conversationId?: "conv_123",  // Optional
      metadata?: {...}
    }
    ↓
System Validates Request
    - Verifies JWT token (optional auth)
    - Checks agent exists and is APPROVED
    - Verifies subscription access:
      β€’ Check active subscription
      β€’ Check expiry date
      β€’ Verify payment status
    ↓
Chat Protocol Service Processes
    - Validates message length (max 10000 chars)
    - Generates conversationId if missing
    - Builds payload:
      {
        message,
        conversationId,
        metadata: { agentId, timestamp, ...userMetadata },
        systemPrompt: agent.promptTemplate (if exists)
      }
    ↓
Forwards to Agent Endpoint
    POST <agent.endpoint>
    - Uses axios with timeout (default 30s)
    - Includes custom headers from agent.metadata.headers
    ↓
Agent Processes & Responds
    Returns: {
      response: "Agent's reply",
      conversationId: "conv_123",
      metadata?: {...}
    }
    ↓
System Saves Conversation
    - Saves user message to ChatMessage table
    - Saves agent response to ChatMessage table
    - Updates agent.usageCount++
    ↓
Returns Response to User
    {
      response: "Agent's reply",
      conversationId: "conv_123",
      metadata: {...}
    }

4️⃣ User Journey: View Chat History

User Requests History
    GET /api/chat/:agentId/history
    Authorization: Bearer <token>
    Query params: conversationId?, limit=50
    ↓
System Validates
    - Verifies authentication (required)
    - Checks agent exists and is APPROVED
    ↓
Retrieves Messages
    - Queries ChatMessage table
    - Filters by agentId, userId
    - Optionally filters by conversationId
    - Orders by createdAt ASC
    - Limits to 50 messages (or specified)
    ↓
Returns Conversation History
    {
      messages: [
        {
          id, agentId, userId,
          role: "user" | "assistant" | "system",
          content, metadata, createdAt
        },
        ...
      ]
    }

πŸ”„ Complete Data Flow Diagrams

Agent Creation Flow

Creator Input
    ↓
[Validation] β†’ Required fields check
    ↓
[IPFS Upload] β†’ Pinata SDK
    ↓
    β”œβ”€ Success β†’ CID stored
    └─ Failure β†’ Continue without IPFS hash
    ↓
[Database] β†’ Agent entity created
    - Status: PENDING
    - IPFS hash: CID (if available)
    ↓
Admin Moderation Queue

Subscription & Payment Flow

User Request
    ↓
[Validation] β†’ Agent approved? User has subscription?
    ↓
[Database] β†’ Create Subscription record
    - Status: ACTIVE (pending verification)
    - isPaymentVerified: false
    ↓
[Payment] β†’ Generate reference
    ↓
Paystack Payment Flow (External)
    ↓
[Webhook] β†’ Paystack POST /api/subscriptions/webhook/paystack
    ↓
[Security] β†’ Verify HMAC signature
    ↓
[Update] β†’ Set isPaymentVerified: true

Chat Communication Flow

User Message
    ↓
[Auth Check] β†’ JWT validation (optional)
    ↓
[Access Check] β†’ Subscription verification
    ↓
[Protocol Service] β†’ Build standardized payload
    ↓
[HTTP Request] β†’ POST to agent.endpoint
    ↓
[Agent Processing] β†’ (External agent service)
    ↓
[Response] β†’ Agent returns structured response
    ↓
[Persistence] β†’ Save both messages to DB
    ↓
[Analytics] β†’ Update usage count
    ↓
[Response] β†’ Return to user

πŸ—„οΈ Database Relationships

User (1) ──< Creates >── (*) Agent
User (1) ──< Subscribes >── (*) Agent (via Subscription)
User (1) ──< Sends >── (*) ChatMessage
Agent (1) ──< Receives >── (*) ChatMessage
User (1) ──< Has >── (*) ApiKey

πŸ” Security Flow

Authentication

Request with Authorization header
    ↓
Extract Bearer token
    ↓
Verify JWT signature
    ↓
Extract user info (id, email, isAdmin)
    ↓
Attach to req.user
    ↓
Continue to route handler

Authorization Checks

  • Public Routes: No auth required

    • GET /api/agents (list)
    • GET /api/agents/:id (details, endpoint hidden)
  • Authenticated Routes: JWT required

    • POST /api/agents (create)
    • POST /api/chat/:id/message (subscription check)
    • GET /api/chat/:id/history (auth required)
  • Admin Routes: JWT + isAdmin check

    • PATCH /api/agents/:id/approve
    • GET /api/agents/admin/pending

Subscription Access Control

Chat Request
    ↓
Check subscription exists
    ↓
Check status === ACTIVE
    ↓
Check isPaymentVerified === true
    ↓
Check expiresAt > now
    ↓
Access granted βœ…

πŸ“‘ API Endpoint Summary

Authentication

  • POST /api/auth/register - Register user
  • POST /api/auth/login - Login
  • GET /api/auth/me - Get current user

Agents

  • GET /api/agents - List approved agents (public)
  • GET /api/agents/:id - Get agent details (public)
  • POST /api/agents - Create agent (creator)
  • PUT /api/agents/:id - Update agent (creator)
  • DELETE /api/agents/:id - Delete agent (creator)
  • GET /api/agents/my/list - Get my agents (creator)
  • PATCH /api/agents/:id/approve - Approve (admin)
  • PATCH /api/agents/:id/reject - Reject (admin)
  • GET /api/agents/admin/pending - Pending list (admin)

Chat

  • POST /api/chat/:id/message - Send message (subscription required)
  • GET /api/chat/:id/history - Get history (authenticated)

Subscriptions

  • POST /api/subscriptions/agent/:agentId - Create subscription
  • GET /api/subscriptions/my - Get my subscriptions
  • PATCH /api/subscriptions/:id/cancel - Cancel subscription
  • POST /api/subscriptions/webhook/paystack - Payment webhook

πŸ”„ State Machine

Agent Status

PENDING β†’ (admin approves) β†’ APPROVED
PENDING β†’ (admin rejects) β†’ REJECTED
APPROVED β†’ (admin suspends) β†’ SUSPENDED

Subscription Status

ACTIVE β†’ (expires) β†’ EXPIRED
ACTIVE β†’ (user cancels) β†’ CANCELLED

πŸ’Ύ IPFS Integration

Metadata Structure:
{
  name: string
  description: string
  endpoint: string (hidden from public)
  price: number
  creatorId: string
  metadata?: Record<string, any>
}

Upload Flow:
Creator creates agent
    ↓
Metadata object created
    ↓
Convert to JSON string
    ↓
Create File object
    ↓
Upload via Pinata SDK: upload.public.file()
    ↓
Receive CID (IPFS hash)
    ↓
Store CID in agent.ipfsHash
    ↓
Retrieval: GET https://gateway.mypinata.cloud/ipfs/{CID}

πŸš€ System Startup Flow

npm run dev
    ↓
Load .env variables
    ↓
Initialize TypeORM DataSource
    ↓
Connect to PostgreSQL
    ↓
Sync entities (dev mode)
    ↓
Initialize Express app
    ↓
Register middleware:
    - Helmet (security)
    - CORS
    - Body parser
    - Rate limiter
    ↓
Register routes:
    - /api/auth
    - /api/agents
    - /api/chat
    - /api/subscriptions
    ↓
Start HTTP server
    ↓
Ready to accept requests

πŸ“ˆ Key Features

  1. Agent Listing: Creators submit, admins moderate
  2. IPFS Transparency: Metadata stored on IPFS for verification
  3. Subscription Model: Flexible pricing (subscription or one-time)
  4. Chat Protocol: Standardized agent communication
  5. Conversation History: Persistent message storage
  6. Payment Integration: Paystack webhook verification
  7. Access Control: Subscription-based agent access
  8. Security: JWT auth, rate limiting, endpoint protection

πŸ”§ Configuration Requirements

Environment Variables

DATABASE_URL=postgres://...
PINATA_JWT=your_jwt_token
GATEWAY_URL=plum-historic-starfish-867.mypinata.cloud
JWT_SECRET=your_secret
PAYSTACK_SECRET=your_paystack_secret
PORT=3000
AGENT_CHAT_TIMEOUT=30000
MAX_MESSAGE_LENGTH=10000

This flow ensures secure, scalable agent marketplace operations with proper access control, payment verification, and standardized communication protocols.