fix: more work on metadata-diff
This commit is contained in:
@@ -88,7 +88,6 @@ config {
|
||||
|
||||
value PostFrontmatter {
|
||||
-- File path: posts/{YYYY}/{MM}/{slug}.md
|
||||
-- For translations: posts/{YYYY}/{MM}/{slug}.{language}.md
|
||||
id: String -- UUID v4
|
||||
title: String
|
||||
slug: String
|
||||
@@ -105,6 +104,29 @@ value PostFrontmatter {
|
||||
categories: List<String> -- Always written, even if empty
|
||||
}
|
||||
|
||||
value TranslationFrontmatter {
|
||||
-- File path: posts/{YYYY}/{MM}/{slug}.{language}.md
|
||||
-- Translation files only store language-specific metadata.
|
||||
-- Shared publication state and timestamps are inherited from the
|
||||
-- canonical post file and are not duplicated here.
|
||||
id: String -- UUID v4
|
||||
translation_for: String -- Canonical post UUID
|
||||
language: String -- ISO 639-1 language code
|
||||
title: String -- Translated title
|
||||
excerpt: String? -- Only written when the translated excerpt differs
|
||||
}
|
||||
|
||||
surface TranslationFrontmatterSurface {
|
||||
context frontmatter: TranslationFrontmatter
|
||||
|
||||
exposes:
|
||||
frontmatter.id
|
||||
frontmatter.translation_for
|
||||
frontmatter.language
|
||||
frontmatter.title
|
||||
frontmatter.excerpt when frontmatter.excerpt != null
|
||||
}
|
||||
|
||||
invariant PostFileLayout {
|
||||
-- Posts are stored in date-based directory structure
|
||||
-- YYYY and MM derived from created_at (zero-padded)
|
||||
@@ -125,6 +147,13 @@ invariant PostTranslationFileLayout {
|
||||
lang: t.language)
|
||||
}
|
||||
|
||||
invariant TranslationFilesInheritCanonicalMetadata {
|
||||
-- Missing status and timestamp fields in translation files are expected.
|
||||
-- Rebuild and metadata diff must resolve those values from the canonical post.
|
||||
for t in PostTranslations where file_path != "":
|
||||
parse_frontmatter(read_file(t.file_path)) = translation_frontmatter_fields(t)
|
||||
}
|
||||
|
||||
rule WritePostFile {
|
||||
when: PublishPostRequested(post)
|
||||
ensures: FileWritten(
|
||||
|
||||
@@ -46,6 +46,20 @@ rule RunMetadataDiff {
|
||||
if diffs.count > 0:
|
||||
ensures: DiffReport.created(entity_type: "post", entity_id: post.id, differences: diffs)
|
||||
|
||||
-- Translation files only carry language-specific metadata. Shared status and
|
||||
-- timestamp fields come from the canonical post and must not be reported as
|
||||
-- missing when they are absent from the translation file.
|
||||
for translation in project.post_translations:
|
||||
let translation_file_data = parse_post_file(translation.file_path)
|
||||
let translation_diffs = compare_translation_specific_fields(translation, translation_file_data)
|
||||
if translation_diffs.count > 0:
|
||||
ensures:
|
||||
DiffReport.created(
|
||||
entity_type: "post_translation",
|
||||
entity_id: translation.id,
|
||||
differences: translation_diffs
|
||||
)
|
||||
|
||||
-- Detect orphan files (on disk but not in DB)
|
||||
for file in scan_directory(project.effective_data_dir + "/posts", "*.md"):
|
||||
let matching = Posts where file_path = file
|
||||
|
||||
@@ -64,6 +64,15 @@ entity PostTranslation {
|
||||
}
|
||||
}
|
||||
|
||||
invariant TranslationFilesStoreOnlyLanguageSpecificMetadata {
|
||||
-- Translation markdown files persist only fields that differ by language.
|
||||
-- Shared metadata such as publication status and timestamps belongs to the
|
||||
-- canonical post file and is inherited from the canonical post when
|
||||
-- rebuilding or diffing translation files.
|
||||
for t in PostTranslations where file_path != "":
|
||||
translation_file(t).omits_shared_metadata = true
|
||||
}
|
||||
|
||||
surface PostTranslationSurface {
|
||||
context translation: PostTranslation
|
||||
|
||||
|
||||
Reference in New Issue
Block a user