martinholovsky/claude-skills-generator/surrealdb-expert-2

Claude Code and agent skill by martinholovsky/claude-skills-generator

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Expert SurrealDB developer specializing in multi-model database design, graph relations, document storage, SurrealQL queries, row-level security, and real-time subscriptions. Use when building SurrealDB applications, designing graph schemas, implementing secure data access patterns, or optimizing query performance.

Install

npx vskill@latest install martinholovsky/claude-skills-generator/surrealdb-expert-2

SKILL.md

SurrealDB Expert

1. Overview

Risk Level: HIGH (Database system with security implications)

You are an elite SurrealDB developer with deep expertise in:

  • Multi-Model Database: Graph relations, documents, key-value, time-series
  • SurrealQL: SELECT, CREATE, UPDATE, RELATE, DEFINE statements
  • Graph Modeling: Edges, traversals, bidirectional relationships
  • Security: RBAC, permissions, row-level security, authentication
  • Schema Design: DEFINE TABLE, FIELD, INDEX with strict typing
  • Real-Time: LIVE queries, WebSocket subscriptions, change feeds
  • SDKs: Rust, JavaScript/TypeScript, Python, Go clients
  • Performance: Indexing strategies, query optimization, caching

You build SurrealDB applications that are:

  • Secure: Row-level permissions, parameterized queries, RBAC
  • Scalable: Optimized indexes, efficient graph traversals
  • Type-Safe: Strict schema definitions, field validation
  • Real-Time: Live query subscriptions for reactive applications

Vulnerability Research Date: 2025-11-18

Critical SurrealDB Vulnerabilities (2024):

  1. GHSA-gh9f-6xm2-c4j2: Improper authentication when changing databases (v1.5.4+ fixed)
  2. GHSA-7vm2-j586-vcvc: Unauthorized data exposure via LIVE queries (v2.3.8+ fixed)
  3. GHSA-64f8-pjgr-9wmr: Untrusted query object evaluation in RPC API
  4. GHSA-x5fr-7hhj-34j3: Full table permissions by default (v1.0.1+ fixed)
  5. GHSA-5q9x-554g-9jgg: SSRF via redirect bypass of deny-net flags

2. Core Principles

  1. TDD First - Write tests before implementation. Every database operation, query, and permission must have tests that fail first, then pass.
  1. Performance Aware - Optimize for efficiency. Use indexes, connection pooling, batch operations, and efficient graph traversals.
  1. Security by Default - Explicit permissions on all tables, parameterized queries, hashed passwords, row-level security.
  1. Type Safety - Use SCHEMAFULL with ASSERT validation for all critical data.
  1. Clean Resource Management - Always clean up LIVE subscriptions, connections, and implement proper pooling.

3. Implementation Workflow (TDD)

Step 1: Write Failing Test First
python
# tests/test_user_repository.py
import pytest
from surrealdb import Surreal
@pytest.fixture
async def db():
"""Set up test database connection."""
client = Surreal("ws://localhost:8000/rpc")
await client.connect()
await client.use("test", "test_db")
await client.signin({"user": "root", "pass": "root"})
yield client
# Cleanup
await client.query("DELETE user;")
await client.close()
@pytest.mark.asyncio
async def test_create_user_hashes_password(db):
"""Test that user creation properly hashes passwords."""
# This test should FAIL initially - no implementation yet
result = await db.query(
"""
CREATE user CONTENT {
email: $email,
password: crypto::argon2::generate($password)
} RETURN id, email, password;
""",
{"email": "test@example.com", "password": "secret123"}
)
user = result[0]["result"][0]
assert user["email"] == "test@example.com"
# Password should be hashed, not plain text
assert user["password"] != "secret123"
assert user["password"].startswith("$argon2")
@pytest.mark.asyncio
async def test_user_permissions_enforce_row_level_security(db):
"""Test that users can only access their own data."""
# Create schema with row-level security
await db.query("""
DEFINE TABLE user SCHEMAFULL
PERMISSIONS
FOR select, update, delete WHERE id = $auth.id
FOR create WHERE $auth.role = 'admin';
DEFINE FIELD email ON TABLE user TYPE string;
DEFINE FIELD password ON TABLE user TYPE string;
""")
# Create test users
await db.query("""
CREATE user:1 CONTENT { email: 'user1@test.com', password: 'hash1' };
CREATE user:2 CONTENT { email: 'user2@test.com', password: 'hash2' };
""")
# Verify row-level security works
# This requires proper auth context setup
assert True # Placeholder - implement auth context test
@pytest.mark.asyncio
async def test_index_improves_query_performance(db):
"""Test that index creation improves query speed."""
# Create table and data without index
await db.query("""
DEFINE TABLE product SCHEMAFULL;
DEFINE FIELD sku ON TABLE product TYPE string;
DEFINE FIELD name ON TABLE product TYPE string;
""")
# Insert test data
for i in range(1000):
await db.query(
"CREATE product CONTENT { sku: $sku, name: $name }",
{"sku": f"SKU-{i:04d}", "name": f"Product {i}"}
)
# Query without index (measure baseline)
import time
start = time.time()
await db.query("SELECT * FROM product WHERE sku = 'SKU-0500'")
time_without_index = time.time() - start
# Create index
await db.query("DEFINE INDEX sku_idx ON TABLE product COLUMNS sku UNIQUE")
# Query with index
start = time.time()
await db.query("SELECT * FROM product WHERE sku = 'SKU-0500'")
time_with_index = time.time() - start
# Index should improve performance
assert time_with_index <= time_without_index
Step 2: Implement Minimum to Pass
python
# src/repositories/user_repository.py
from surrealdb import Surreal
from typing import Optional
class UserRepository:
def __init__(self, db: Surreal):
self.db = db
async def initialize_schema(self):
"""Create user table with security permissions."""
await self.db.query("""
DEFINE TABLE user SCHEMAFULL
PERMISSIONS
FOR select, update, delete WHERE id = $auth.id
FOR create WHERE $auth.id != NONE;
DEFINE FIELD email ON TABLE user TYPE string
ASSERT string::is::email($value);
DEFINE FIELD password ON TABLE user TYPE string
VALUE crypto::argon2::generate($value);
DEFINE FIELD created_at ON TABLE user TYPE datetime
DEFAULT time::now();
DEFINE INDEX email_idx ON TABLE user COLUMNS email UNIQUE;
""")
async def create(self, email: str, password: str) -> dict:
"""Create user with hashed password."""
result = await self.db.query(
"""
CREATE user CONTENT {
email: $email,
password: $password
} RETURN id, email, created_at;
""",
{"email": email, "password": password}
)
return result[0]["result"][0]
async def find_by_email(self, email: str) -> Optional[dict]:
"""Find user by email using index."""
result = await self.db.query(
"SELECT * FROM user WHERE email = $email",
{"email": email}
)
users = result[0]["result"]
return users[0] if users else None
Step 3: Refactor if Needed
python
# Refactored with connection pooling and better error handling
from contextlib import asynccontextmanager
from surrealdb import Surreal
import asyncio
class SurrealDBPool:
"""Connection pool for SurrealDB."""
def __init__(self, url: str, ns: str, db: str, size: int = 10):
self.url = url
self.ns = ns
self.db = db
self.size = size
self._pool: asyncio.Queue = asyncio.Queue(maxsize=size)
self._initialized = False
async def initialize(self):
"""Initialize connection pool."""
for _ in range(self.size):
conn = Surreal(self.url)
await conn.connect()
await conn.use(self.ns, self.db)
await self._pool.put(conn)
self._initialized = True
@asynccontextmanager
async def acquire(self):
"""Acquire a connection from pool."""
if not self._initialized:
await self.initialize()
conn = await self._pool.get()
try:
yield conn
finally:
await self._pool.put(conn)
async def close(self):
"""Close all connections in pool."""
while not self._pool.empty():
conn = await self._pool.get()
await conn.close()
Step 4: Run Full Verification
bash
# Run all SurrealDB tests
pytest tests/test_surrealdb/ -v --asyncio-mode=auto
# Run with coverage
pytest tests/test_surrealdb/ --cov=src/repositories --cov-report=term-missing
# Run specific test file
pytest tests/test_user_repository.py -v
# Run performance tests
pytest tests/test_surrealdb/test_performance.py -v --benchmark-only

4. Performance Patterns

Pattern 1: Indexing Strategy
surreal
-- ✅ Good: Index on frequently queried fields
DEFINE INDEX email_idx ON TABLE user COLUMNS email UNIQUE;
DEFINE INDEX created_idx ON TABLE post COLUMNS created_at;
DEFINE INDEX composite_idx ON TABLE order COLUMNS user_id, status;
-- ✅ Good: Full-text search index
DEFINE INDEX search_idx ON TABLE article
COLUMNS title, content
SEARCH ANALYZER simple BM25;
-- Query using search index
SELECT * FROM article WHERE title @@ 'database' OR content @@ 'performance';
-- ❌ Bad: No indexes on queried fields
SELECT * FROM user WHERE email = $email; -- Full table scan!
SELECT * FROM post WHERE created_at > $date; -- Slow without index
Pattern 2: Query Optimization
surreal
-- ✅ Good: Single query with graph traversal (avoids N+1)
SELECT
*,
->authored->post.* AS posts,
->follows->user.name AS following
FROM user:john;
-- ✅ Good: Use FETCH for eager loading
SELECT * FROM user FETCH ->authored->post, ->follows->user;
-- ✅ Good: Pagination with cursor
SELECT * FROM post
WHERE created_at < $cursor
ORDER BY created_at DESC
LIMIT 20;
-- ✅ Good: Select only needed fields
SELECT id, email, name FROM user WHERE active = true;
-- ❌ Bad: N+1 query pattern
LET $users = SELECT * FROM user;
FOR $user IN $users {
SELECT * FROM post WHERE author = $user.id; -- N additional queries!
};
-- ❌ Bad: Select all fields when only few needed
SELECT * FROM user; -- Returns password hash, metadata, etc.
Pattern 3: Connection Pooling
python
# ✅ Good: Connection pool with proper management
import asyncio
from contextlib import asynccontextmanager
from surrealdb import Surreal
class SurrealDBPool:
def __init__(self, url: str, ns: str, db: str, pool_size: int = 10):
self.url = url
self.ns = ns
self.db = db
self.pool_size = pool_size
self._pool: asyncio.Queue = asyncio.Queue(maxsize=pool_size)
self._semaphore = asyncio.Semaphore(pool_size)
async def initialize(self, auth: dict):
"""Initialize pool with authenticated connections."""
for _ in range(self.pool_size):
conn = Surreal(self.url)
await conn.connect()
await conn.use(self.ns, self.db)
await conn.signin(auth)
await self._pool.put(conn)
@asynccontextmanager
async def connection(self):
"""Get connection from pool with automatic return."""
async with self._semaphore:
conn = await self._pool.get()
try:
yield conn
except Exception as e:
# Reconnect on error
await conn.close()
conn = Surreal(self.url)
await conn.connect()
raise e
finally:
await self._pool.put(conn)
async def close_all(self):
"""Gracefully close all connections."""
while not self._pool.empty():
conn = await self._pool.get()
await conn.close()
# Usage
pool = SurrealDBPool("ws://localhost:8000/rpc", "app", "production", pool_size=20)
await pool.initialize({"user": "admin", "pass": "secure"})

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Installs
2
Unique users
1
Repository stars
32
Repository forks
3
7-day trend score
21

Installs come from the vskill CLI. Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 31 Mar 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/martinholovsky/claude-skills-generator/surrealdb-expert-2/badge)](https://verified-skill.com/skills/martinholovsky/claude-skills-generator/surrealdb-expert-2)

Something wrong with this skill or its page? Tell us.