chore: brought RuDS up to bDS2 alignment, as that is the new baseline we want to hit

This commit is contained in:
2026-07-18 10:16:30 +02:00
parent 7880e37c34
commit a594b99e90
50 changed files with 3140 additions and 449 deletions

View File

@@ -1,11 +1,31 @@
-- allium: 1
-- bDS SQLite Database Schema
-- bDS Persistence Data Contract
-- Scope: core (Wave 1 — exact compatibility contract)
-- Distilled from: ../bDS/src/main/database/schema.ts
-- Distilled from: ../bDS2/src/main/database/schema.ts
--
-- This document specifies the exact SQLite schema that the Rust
-- implementation must be able to read and write. It is the ground truth
-- for database compatibility.
-- This document specifies the persisted data model the rewrite must be able
-- to read and write. It is the ground truth for storage compatibility.
enum PostStatus {
draft
published
archived
}
enum PostTranslationStatus {
draft
published
}
enum TemplateStatus {
draft
published
}
enum ScriptStatus {
draft
published
}
-- ============================================================================
-- CORE ENTITIES
@@ -29,7 +49,7 @@ entity Post {
slug: String -- URL-friendly identifier
excerpt: String? -- Optional summary
content: String? -- Draft body (null when published)
status: draft | published | archived
status: PostStatus
author: String? -- Author name
created_at: Timestamp
updated_at: Timestamp
@@ -58,7 +78,7 @@ entity PostTranslation {
title: String
excerpt: String?
content: String? -- Draft body (null when published)
status: draft | published
status: PostTranslationStatus
created_at: Timestamp
updated_at: Timestamp
published_at: Timestamp?
@@ -119,7 +139,7 @@ entity Template {
enabled: Boolean
version: Integer -- Incremented on each update
file_path: String -- templates/{slug}.liquid
status: draft | published
status: TemplateStatus
content: String? -- Draft body (null when published)
created_at: Timestamp
updated_at: Timestamp
@@ -131,11 +151,11 @@ entity Script {
slug: String -- URL-safe identifier
title: String
kind: macro | utility | transform
entrypoint: String -- Default: "render" for macros
entrypoint: String -- Default: "render" for macros, "main" otherwise
enabled: Boolean
version: Integer -- Incremented on each update
file_path: String -- scripts/{slug}.lua
status: draft | published
file_path: String -- scripts/{slug}.{extension}
status: ScriptStatus
content: String? -- Draft body (null when published)
created_at: Timestamp
updated_at: Timestamp
@@ -184,8 +204,7 @@ entity GeneratedFileHash {
-- ============================================================================
entity PostSearchIndex {
-- SQLite FTS5 virtual table, not a real entity
-- Created via: CREATE VIRTUAL TABLE posts_fts USING fts5(...)
-- Full-text search index projection, not a user-authored entity
-- Indexed fields: title, excerpt, content, tags, categories
-- Plus all translation titles, excerpts, and content
post: Post
@@ -193,8 +212,7 @@ entity PostSearchIndex {
}
entity MediaSearchIndex {
-- SQLite FTS5 virtual table
-- Created via: CREATE VIRTUAL TABLE media_fts USING fts5(...)
-- Full-text search index projection
-- Indexed fields: title, alt, caption, original_name, tags
-- Plus all translation titles, alts, and captions
media: Media
@@ -221,16 +239,18 @@ entity ChatMessage {
content: String?
tool_call_id: String? -- For tool responses
tool_calls: String? -- JSON array of tool calls
cache_read_tokens: Integer?
cache_write_tokens: Integer?
created_at: Timestamp
}
entity AiProvider {
-- Provider catalog, populated from upstream model registry.
-- Read-only in Rust core; TypeScript app manages inserts.
-- Managed by the application and treated as read-only during normal use.
id: String -- PRIMARY KEY
name: String
env: String? -- Environment variable for API key
npm: String? -- NPM package reference (legacy)
package_ref: String? -- Legacy package reference
api: String? -- Base API URL
doc: String? -- Documentation URL
updated_at: Timestamp
@@ -261,7 +281,6 @@ entity AiModel {
max_output_tokens: Integer
interleaved: String? -- interleaved capability descriptor
status: String? -- active | deprecated | preview
provider_npm: String? -- provider-specific NPM reference (legacy)
updated_at: Timestamp
}
@@ -270,7 +289,7 @@ entity AiModelModality {
provider: AiProvider
model_id: String
direction: String -- "input" | "output"
modality: String -- "text" | "image" | "audio" | "video"
modality: String -- "text" | "image" | "audio" | "file" | "tool"
}
entity AiCatalogMeta {
@@ -287,7 +306,7 @@ entity EmbeddingKey {
post_id: String
project_id: String
content_hash: String -- SHA-256 of title+content
vector: String -- Base64-encoded Float32Array bytes (1536 bytes for 384-dim)
vector: String -- Encoded vector payload (1536 bytes for 384-dim)
}
entity DismissedDuplicatePair {
@@ -327,6 +346,305 @@ entity DbNotification {
created_at: Timestamp
}
surface ProjectRecordSurface {
context project: Project
exposes:
project.id
project.name
project.slug
project.description when project.description != null
project.data_path when project.data_path != null
project.created_at
project.updated_at
project.is_active
}
surface PostTranslationRecordSurface {
context translation: PostTranslation
exposes:
translation.id
translation.project_id
translation.translation_for
translation.language
translation.title
translation.excerpt when translation.excerpt != null
translation.content when translation.content != null
translation.status
translation.created_at
translation.updated_at
translation.published_at when translation.published_at != null
translation.file_path
translation.checksum when translation.checksum != null
}
surface MediaTranslationRecordSurface {
context translation: MediaTranslation
exposes:
translation.id
translation.project_id
translation.translation_for
translation.language
translation.title when translation.title != null
translation.alt when translation.alt != null
translation.caption when translation.caption != null
translation.created_at
translation.updated_at
}
surface TagRecordSurface {
context tag: Tag
exposes:
tag.id
tag.project_id
tag.name
tag.color when tag.color != null
tag.post_template_slug when tag.post_template_slug != null
tag.created_at
tag.updated_at
}
surface TemplateRecordSurface {
context template: Template
exposes:
template.id
template.project_id
template.slug
template.title
template.kind
template.enabled
template.version
template.file_path
template.status
template.content when template.content != null
template.created_at
template.updated_at
}
surface ScriptRecordSurface {
context script: Script
exposes:
script.id
script.project_id
script.slug
script.title
script.kind
script.entrypoint
script.enabled
script.version
script.file_path
script.status
script.content when script.content != null
script.created_at
script.updated_at
}
surface PostLinkRecordSurface {
context link: PostLink
exposes:
link.id
link.source_post_id
link.target_post_id
link.link_text when link.link_text != null
link.created_at
}
surface PostMediaLinkRecordSurface {
context link: PostMediaLink
exposes:
link.id
link.project_id
link.post_id
link.media_id
link.sort_order
link.created_at
}
surface SettingRecordSurface {
context setting: Setting
exposes:
setting.key
setting.value
setting.updated_at
}
surface GeneratedFileHashRecordSurface {
context record: GeneratedFileHash
exposes:
record.project_id
record.relative_path
record.content_hash
record.updated_at
}
surface PostSearchIndexRecordSurface {
context record: PostSearchIndex
exposes:
record.post
record.stemmed_content
}
surface MediaSearchIndexRecordSurface {
context record: MediaSearchIndex
exposes:
record.media
record.stemmed_content
}
surface ChatConversationRecordSurface {
context conversation: ChatConversation
exposes:
conversation.id
conversation.title
conversation.model when conversation.model != null
conversation.copilot_session_id when conversation.copilot_session_id != null
conversation.created_at
conversation.updated_at
}
surface ChatMessageRecordSurface {
context message: ChatMessage
exposes:
message.id
message.conversation_id
message.role
message.content when message.content != null
message.tool_call_id when message.tool_call_id != null
message.tool_calls when message.tool_calls != null
message.cache_read_tokens when message.cache_read_tokens != null
message.cache_write_tokens when message.cache_write_tokens != null
message.created_at
}
surface AiModelRecordSurface {
context model: AiModel
exposes:
model.provider
model.model_id
model.name
model.family when model.family != null
model.attachment
model.reasoning
model.tool_call
model.structured_output
model.temperature
model.knowledge when model.knowledge != null
model.release_date when model.release_date != null
model.last_updated_date when model.last_updated_date != null
model.open_weights
model.input_price when model.input_price != null
model.output_price when model.output_price != null
model.cache_read_price when model.cache_read_price != null
model.cache_write_price when model.cache_write_price != null
model.context_window
model.max_input_tokens
model.max_output_tokens
model.interleaved when model.interleaved != null
model.status when model.status != null
model.updated_at
}
surface AiModelModalityRecordSurface {
context modality: AiModelModality
exposes:
modality.provider
modality.model_id
modality.direction
modality.modality
}
surface AiCatalogMetaRecordSurface {
context meta: AiCatalogMeta
exposes:
meta.key
meta.value
}
surface EmbeddingKeyRecordSurface {
context key: EmbeddingKey
exposes:
key.label
key.post_id
key.project_id
key.content_hash
key.vector
}
surface DismissedDuplicatePairRecordSurface {
context pair: DismissedDuplicatePair
exposes:
pair.id
pair.project_id
pair.post_id_a
pair.post_id_b
pair.dismissed_at
}
surface ImportDefinitionRecordSurface {
context definition: ImportDefinition
exposes:
definition.id
definition.project_id
definition.name
definition.wxr_file_path when definition.wxr_file_path != null
definition.uploads_folder_path when definition.uploads_folder_path != null
definition.last_analysis_result when definition.last_analysis_result != null
definition.created_at
definition.updated_at
}
surface DbNotificationRecordSurface {
context notification: DbNotification
exposes:
notification.id
notification.entity_type
notification.entity_id
notification.action
notification.from_cli
notification.seen_at when notification.seen_at != null
notification.created_at
}
surface Fts5PostSchemaSurface {
context schema: Fts5PostSchema
exposes:
schema.fields
schema.stemmer_languages
}
surface Fts5MediaSchemaSurface {
context schema: Fts5MediaSchema
exposes:
schema.fields
schema.stemmer_languages
}
surface MigrationVersionSurface {
context _: MigrationVersion
}
-- ============================================================================
-- SCHEMA CONSTRAINTS AND INDEXES
-- ============================================================================