Sprinter Docs

Seed Data

Seeding entity types, demo data, and agents -- what each script creates, how to run them, and environment requirements.

Seed Data

The Sprinter Platform provides seed scripts for bootstrapping entity types, demo data, and agent records. These scripts live in the scripts/ directory and use the Supabase admin client to bypass RLS.

Available seed scripts

ScriptCommandPurpose
seed-entity-types.mjspnpm seed:typesCreates entity type definitions with schemas, field configs, and extraction instructions
seed-demo-data.mjspnpm seed:demoCreates sample entities across all entity types
seed-agents.mjspnpm seed:agentsCreates DB records for system agents using the repo's configured primary agent identity

Running seeds

All seed scripts require two environment variables:

# Set in .env.local
NEXT_PUBLIC_SUPABASE_URL=https://mhfzqccnyqxyteedsrdi.supabase.co
SUPABASE_SECRET_KEY=eyJ...  # or SUPABASE_SERVICE_ROLE_KEY

The scripts use --env-file=.env.local to load these automatically:

# Seed entity types (run first)
pnpm seed:types

# Seed demo data (requires entity types to exist)
pnpm seed:demo

# Seed agent DB records (run after entity types)
pnpm seed:agents
  1. pnpm seed:types -- entity types must exist before entities can be created
  2. pnpm seed:agents -- agents should exist before demo data references them
  3. pnpm seed:demo -- demo entities reference entity types and may trigger extraction

What each seed creates

seed-entity-types

Creates entity type definitions in the entity_types table. Each type includes:

  • Slug and name -- unique identifier and display name
  • JSON schema -- field definitions with types, enums, and required fields
  • Config -- UI settings (icon, color, card fields), scoring criteria, and field extraction configuration
  • Field configs -- per-field extraction instructions, dependencies, sources, consensus settings, and cascade configuration

Example entity types created for Amble (the AI consulting product):

  • opportunity -- AI automation opportunities with status pipeline, ROI fields, scoring criteria
  • company -- companies with industry, size, revenue fields
  • contact -- people with role, email, phone fields
  • technology -- technology solutions with maturity, cost, adoption fields
  • meeting -- meeting records with date, attendees, action items
  • Additional types as defined in the script

Each entity type gets a UUID generated via crypto.randomUUID() since the entity_types.id column has no default.

The script uses upsert logic -- it is safe to run multiple times. Existing types are updated rather than duplicated.

seed-demo-data

Creates sample entities in the default tenant (00000000-0000-0000-0000-000000000000). The demo data includes:

  • Opportunities across multiple categories (operations, sales, marketing, product)
  • Companies with industry and size classifications
  • Relations between entities (opportunities linked to companies, contacts linked to companies)
  • Realistic field values for testing extraction, scoring, and visualization

The script generates UUIDs for each entity and creates them in the entities table with the appropriate entity_type_id and tenant_id.

seed-agents

Creates database records for system agents. This is useful because:

  • The agents table uses UUID IDs for foreign key references (e.g., chat_participants)
  • System agents need stable database rows for queries, heartbeat runs, and multi-participant messaging
  • The primary assistant identity comes from product.config.ts, so forks can change branding and the default slug in one place

The script creates records for the default agents:

  • Primary assistant -- general intelligence assistant with entity graph tools (product.config.ts, configured defaultAgentSlug)
  • Analyst -- scoring and ROI analysis specialist
  • Researcher -- web search and research specialist

The script is idempotent -- it checks for existing agents by slug and only inserts those not already present. The runtime also backfills missing system agents on first resolution so upgraded installs are not blocked if this seed has not been run yet.

Additional seed scripts

The scripts/ directory contains additional specialized scripts:

ScriptPurpose
seed-agent-goals-tasks.mjsCreates agent-goal and agent-task entities for workflow testing
seed-department-command-centers.mjsCreates department entities with workspace views
seed-source-entity-type.mjsCreates the source and source-item entity types for content ingestion
provision-tenant.mjsCreates a new tenant with initial configuration
seed-rock-hill-v2.mjsSeeds data for the Rock Hill Capital demo tenant
setup-workspace-architect-agent.mjsCreates a workspace architect agent with view management tools

These are not exposed as pnpm scripts and are run directly:

node --env-file=.env.local scripts/seed-agent-goals-tasks.mjs

Creating custom seeds

When forking the platform for a new product, create new seed scripts in scripts/:

import { createClient } from "@supabase/supabase-js";
import { randomUUID } from "crypto";

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL,
  process.env.SUPABASE_SECRET_KEY ?? process.env.SUPABASE_SERVICE_ROLE_KEY,
);

const DEFAULT_TENANT_ID = "00000000-0000-0000-0000-000000000000";

// Entity types must generate their own IDs
const entityTypes = [
  {
    id: randomUUID(),
    slug: "my-type",
    name: "My Type",
    json_schema: {
      type: "object",
      properties: {
        description: { type: "string" },
        status: { type: "string", enum: ["draft", "active", "closed"] },
      },
      required: ["description"],
    },
    config: {
      ui: { icon: "file-text", cardFields: ["status"] },
    },
  },
];

for (const type of entityTypes) {
  const { error } = await supabase
    .from("entity_types")
    .upsert(type, { onConflict: "slug" });

  if (error) {
    console.error(`Failed to seed ${type.slug}:`, error.message);
  } else {
    console.log(`Seeded entity type: ${type.slug}`);
  }
}

Add a corresponding npm script in package.json:

{
  "scripts": {
    "seed:custom": "node --env-file=.env.local scripts/seed-custom-types.mjs"
  }
}

Troubleshooting

"relation does not exist" error: Run pnpm db:reset (local) or pnpm db:push (remote) to ensure all migrations are applied before seeding.

Duplicate key errors: The seed scripts use upsert where possible, but some scripts may fail on re-run if they use plain insert. Check the script for idempotency guarantees.

Missing environment variables: Ensure .env.local has both NEXT_PUBLIC_SUPABASE_URL and SUPABASE_SECRET_KEY (or SUPABASE_SERVICE_ROLE_KEY). The scripts need the service role key to bypass RLS.

On this page