Skip to content

Data Model

NeuralRepo uses Cloudflare D1 (SQLite) as its primary database. The schema is designed for single-user data isolation, efficient full-text search, and flexible idea relations.

erDiagram
users ||--o{ auth_accounts : "has"
users ||--o{ sessions : "has"
users ||--o{ api_keys : "has"
users ||--o{ magic_links : "has"
users ||--o{ ideas : "owns"
ideas ||--o{ idea_tags : "has"
ideas ||--o{ idea_links : "has"
ideas ||--o{ attachments : "has"
ideas ||--o{ idea_relations : "source"
ideas ||--o{ idea_relations : "target"
ideas ||--o{ duplicate_detections : "source"
ideas ||--o{ duplicate_detections : "target"
tags ||--o{ idea_tags : "has"
users ||--o{ oauth_authorization_codes : "has"
users ||--o{ oauth_refresh_tokens : "has"

The central user record. All data queries are scoped by user_id.

ColumnTypeDescription
idTEXT (UUID)Primary key
emailTEXTUnique email address
display_nameTEXTDisplay name
avatar_urlTEXTProfile avatar URL
planTEXTfree or pro
stripe_customer_idTEXTStripe customer reference
stripe_subscription_idTEXTStripe subscription reference
anthropic_api_key_encryptedTEXTEncrypted Anthropic API key (BYOK)
openai_api_key_encryptedTEXTEncrypted OpenAI API key (BYOK)
openrouter_api_key_encryptedTEXTEncrypted OpenRouter API key (BYOK)
github_sync_repoTEXTGitHub sync repository
github_sync_token_encryptedTEXTEncrypted GitHub sync token
settings_jsonTEXTUser settings (JSON string, default {})
created_atTEXTISO 8601 timestamp
updated_atTEXTISO 8601 timestamp

Links external OAuth providers to a user.

ColumnTypeDescription
idTEXTPrimary key
user_idTEXTFK to users
providerTEXTgithub, google, apple, email
provider_account_idTEXTExternal account ID
provider_emailTEXTEmail from the provider
created_atTEXTISO 8601 timestamp

Active user sessions. Tokens are SHA-256 hashed before storage.

ColumnTypeDescription
idTEXTPrimary key
user_idTEXTFK to users
token_hashTEXTSHA-256 hash of the session token
expires_atTEXT30-day expiry timestamp
created_atTEXTISO 8601 timestamp

API keys for programmatic access. Keys are hashed with SHA-256.

ColumnTypeDescription
idTEXTPrimary key
user_idTEXTFK to users
labelTEXTUser-assigned label
key_hashTEXTSHA-256 hash of the nrp_ prefixed key
scopesTEXTSpace-separated scope list (null for full access)
sourceTEXTKey source (default manual)
last_used_atTEXTTimestamp of most recent use
created_atTEXTISO 8601 timestamp

The core content table.

ColumnTypeDescription
idINTEGERAuto-increment primary key
user_idTEXTFK to users
titleTEXTIdea title (max 200 chars)
bodyTEXTMarkdown body
statusTEXTcaptured, exploring, building, shipped, shelved
sourceTEXTOrigin: web, cli, claude-mcp, siri, email, api, shortcut
source_urlTEXTOptional URL reference
source_summaryTEXTSummary from source
parent_idINTEGERSelf-referencing FK for parent idea
is_archivedINTEGERSoft delete flag (0 = active, 1 = archived)
vectorize_idTEXTCloudflare Vectorize embedding ID
created_atTEXTISO 8601 timestamp
updated_atTEXTISO 8601 timestamp

Unique tag definitions scoped by user.

ColumnTypeDescription
idINTEGERPrimary key
user_idTEXTFK to users
nameTEXTTag name (lowercase, unique per user)
colorTEXTOptional hex color (#rrggbb format)
created_atTEXTISO 8601 timestamp

Many-to-many join between ideas and tags.

ColumnTypeDescription
idea_idINTEGERFK to ideas
tag_idINTEGERFK to tags

Links attached to ideas.

ColumnTypeDescription
idINTEGERPrimary key
idea_idINTEGERFK to ideas
urlTEXTLink URL
titleTEXTOptional display title
link_typeTEXTurl, claude-chat, github-repo, github-issue, attachment
created_atTEXTISO 8601 timestamp

Typed directional links between ideas.

ColumnTypeDescription
idINTEGERPrimary key
source_idea_idINTEGERFK to ideas
target_idea_idINTEGERFK to ideas
relation_typeTEXTrelated, parent, blocks, inspires, duplicate, supersedes
user_idTEXTFK to users
scoreREALSimilarity score (null for manual relations)
noteTEXTOptional description
created_atTEXTISO 8601 timestamp

Records when the system detects similar ideas.

ColumnTypeDescription
idINTEGERPrimary key
idea_idINTEGERThe newer/suspected duplicate
duplicate_of_idINTEGERThe existing original idea
similarity_scoreREALCosine similarity (0.0 to 1.0)
statusTEXTpending, merged, dismissed
created_atTEXTISO 8601 timestamp

Files attached to ideas, stored in R2.

ColumnTypeDescription
idTEXTPrimary key
idea_idINTEGERFK to ideas
user_idTEXTFK to users
filenameTEXTOriginal filename
r2_keyTEXTR2 object key
content_typeTEXTMIME type
size_bytesINTEGERFile size
created_atTEXTISO 8601 timestamp

oauth_authorization_codes and oauth_refresh_tokens support the MCP OAuth flow. Authorization codes are short-lived (10 minutes). Refresh tokens expire after 90 days.

The ideas_fts table is an FTS5 virtual table that mirrors the title and body columns of the ideas table:

CREATE VIRTUAL TABLE ideas_fts USING fts5(title, body, content=ideas, content_rowid=id);

Sync triggers keep the FTS index up to date on insert, update, and delete operations. FTS5 is used for keyword search and is combined with vector search for hybrid results.

Key indexes for query performance:

TableIndexColumns
ideasidx_ideas_user_statususer_id, status
ideasidx_ideas_user_createduser_id, created_at
ideasidx_ideas_parentparent_id
idea_tagsidx_idea_tags_ideaidea_id
idea_tagsidx_idea_tags_tagtag_id
idea_relationsidx_relations_sourcesource_idea_id
idea_relationsidx_relations_targettarget_idea_id
idea_linksidx_idea_links_ideaidea_id
sessionsidx_sessions_tokentoken_hash
api_keysidx_api_keys_hashkey_hash

Ideas use a soft delete pattern. The is_archived column is 0 for active ideas and 1 for archived ideas.

All queries include a WHERE is_archived = 0 condition by default. This allows recovery of accidentally deleted ideas and preserves relation integrity.