Data Model

EpsimoAI uses PostgreSQL (RDS) with the pgvector extension for both relational data and vector embeddings. The schema supports multi-tenant isolation via user → project → resource ownership.

Entity-Relationship Diagram

erDiagram users ||--o{ projects : owns projects ||--o{ assistants : contains projects ||--o{ threads : contains threads }o--o| assistants : "used with" assistants ||--o{ assistant_token_price : "priced by" users { text user_id PK text email UK text password_hash text provider "Epsimo | Google" boolean email_verified int thread_counter int max_thread_counter timestamp created_at } projects { text project_id PK text user_id FK text name text description } assistants { text assistant_id PK text project_id FK text name jsonb config boolean public timestamp updated_at } threads { text thread_id PK text project_id FK text assistant_id FK "nullable" text name jsonb metadata timestamp updated_at } assistant_token_price { text agent_type PK int price "default 1" } checkpoints { text thread_id FK text thread_ts jsonb state "LangGraph checkpoint" }

Table Descriptions

users

Stores registered accounts. Each user has a usage counter (thread_counter) and a cap (max_thread_counter) that limits how many runs they can execute.

Column Type Description
user_id text (PK) UUID identifier
email text (unique) Login email
password_hash text bcrypt hash (null for OAuth users)
provider text Epsimo (email/password) or Google (OAuth)
email_verified boolean Whether email has been verified
thread_counter int Current usage count
max_thread_counter int Usage cap (increased via Stripe purchase)
created_at timestamp Account creation time

projects

Logical workspace that groups assistants and threads. Every user gets a default main project on first login.

Column Type Description
project_id text (PK) UUID identifier
user_id text (FK → users) Owner
name text Project name (e.g. "main")
description text Optional description

assistants

AI assistant configurations. Each assistant defines which LLM, tools, and system prompt to use.

Column Type Description
assistant_id text (PK) UUID identifier
project_id text (FK → projects) Owning project
name text Display name
config jsonb Full configuration (LLM type, tools, system message, agent type)
public boolean If true, accessible without project ownership
updated_at timestamp Last modification time

The config JSONB contains a configurable key with fields like: - type==agent/agent_type — agent type (e.g. chatbot, tools, retrieval) - type==agent/llm_type — LLM model name - type==agent/system_message — system prompt - type==agent/tools — array of enabled tool identifiers

threads

Conversation containers. A thread holds the message history and is linked to a project and optionally an assistant.

Column Type Description
thread_id text (PK) UUID identifier
project_id text (FK → projects) Owning project
assistant_id text (FK → assistants, nullable) Associated assistant
name text Thread title (auto-generated or user-set)
metadata jsonb Optional metadata
updated_at timestamp Last activity time

assistant_token_price

Maps agent types to their token cost multiplier. Used when incrementing thread_counter.

Column Type Description
agent_type text (PK) Agent type identifier
price int Cost multiplier (default 1)

checkpoints (LangGraph)

Stores LangGraph execution state for resumable conversations. Managed by the LangGraph PostgreSQL checkpoint saver.

Column Type Description
thread_id text Thread reference
thread_ts text Checkpoint timestamp
state jsonb Serialized graph state (messages, tool results)

Relationships

Vector Store (pgvector)

Document embeddings for RAG (retrieval-augmented generation) are stored using the pgvector extension in the same PostgreSQL instance. The langchain_pgvector collection stores: - Document chunks (text content) - Embedding vectors (OpenAI text-embedding-ada-002) - Metadata (source file, assistant_id, thread_id)