Files
bDS2/specs/metadata.allium
2026-04-23 10:42:27 +02:00

126 lines
4.0 KiB
Plaintext

-- allium: 1
-- bDS Project Metadata, Categories, Publishing Preferences
-- Scope: core (Wave 1)
-- Distilled from: src/main/engine/MetaEngine.ts, schema.ts
use "./project.allium" as project
surface MetadataControlSurface {
facing _: MetadataOperator
provides:
UpdateProjectMetadataRequested(project, changes)
AddCategoryRequested(project, name)
RemoveCategoryRequested(project, name)
UpdateCategorySettingsRequested(project, category, settings)
SetPublishingPreferencesRequested(project, prefs)
AppStarted(project)
}
surface PublishingPreferencesSurface {
context prefs: PublishingPreferences
exposes:
prefs.ssh_host when prefs.ssh_host != null
prefs.ssh_user when prefs.ssh_user != null
prefs.ssh_remote_path when prefs.ssh_remote_path != null
prefs.ssh_mode
}
value CategoryRenderSettings {
render_in_lists: Boolean
show_title: Boolean
post_template_slug: String?
list_template_slug: String?
}
entity ProjectMetadata {
project: project/Project
name: String
description: String?
public_url: String?
main_language: String? -- ISO 639-1
default_author: String?
max_posts_per_page: Integer -- 1..500, default 50
blogmark_category: String?
pico_theme: String? -- 12+ named Pico CSS themes
semantic_similarity_enabled: Boolean
blog_languages: Set<String> -- subset of supported languages
categories: Set<String> -- category names
category_settings: Set<CategoryRenderSettings>
}
entity PublishingPreferences {
ssh_host: String?
ssh_user: String?
ssh_remote_path: String?
ssh_mode: scp | rsync
}
invariant DefaultCategories {
-- New projects start with: article, picture, aside, page
-- These are defaults, not invariants — user can remove them
}
invariant MetadataPersistedAsFiles {
-- Four separate JSON files in meta/:
-- meta/project.json — name, description, publicUrl, mainLanguage, etc.
-- meta/categories.json — sorted category list
-- meta/category-meta.json — per-category render settings
-- meta/publishing.json — SSH connection details (non-secret)
-- All writes are atomic (temp file + rename)
}
config {
default_max_posts_per_page: Integer = 50
min_posts_per_page: Integer = 1
max_posts_per_page: Integer = 500
default_categories: Set<String> = {"article", "picture", "aside", "page"}
supported_pico_themes: Set<String> = {
"default", "amber", "blue", "cyan", "fuchsia", "green",
"grey", "indigo", "jade", "lime", "orange", "pink",
"pumpkin", "purple", "red", "sand", "slate", "violet",
"yellow", "zinc"
}
}
rule UpdateProjectMetadata {
when: UpdateProjectMetadataRequested(project, changes)
ensures: MetadataFieldsUpdated(project, changes)
ensures: ProjectJsonWritten(project)
}
rule AddCategory {
when: AddCategoryRequested(project, name)
requires: not (name in project.metadata.categories)
ensures: project.metadata.categories = project.metadata.categories + {name}
ensures: CategoriesJsonWritten(project)
}
rule RemoveCategory {
when: RemoveCategoryRequested(project, name)
ensures: project.metadata.categories = project.metadata.categories - {name}
ensures: CategorySettingsRemoved(project, name)
ensures: CategoriesJsonWritten(project)
ensures: CategoryMetaJsonWritten(project)
}
rule UpdateCategorySettings {
when: UpdateCategorySettingsRequested(project, category, settings)
ensures: CategorySettingsUpdated(project, category, settings)
ensures: CategoryMetaJsonWritten(project)
}
rule SetPublishingPreferences {
when: SetPublishingPreferencesRequested(project, prefs)
ensures: project.publishing_preferences = prefs
ensures: PublishingJsonWritten(project)
}
rule StartupSync {
when: AppStarted(project)
-- Loads metadata from filesystem, merges with DB,
-- creates defaults for new projects
ensures: ProjectMetadata.synced_from_filesystem(project)
}