feat: alignment on media import event shape
This commit is contained in:
@@ -9,7 +9,7 @@ surface MediaControlSurface {
|
||||
facing _: MediaOperator
|
||||
|
||||
provides:
|
||||
ImportMediaRequested(project, source_file)
|
||||
ImportMediaRequested(source_path, project, metadata)
|
||||
UpdateMediaRequested(media, changes)
|
||||
DeleteMediaRequested(media)
|
||||
UpsertMediaTranslationRequested(media, language, title, alt, caption)
|
||||
@@ -121,22 +121,29 @@ invariant DateBasedMediaLayout {
|
||||
}
|
||||
|
||||
rule ImportMedia {
|
||||
when: ImportMediaRequested(project, source_file)
|
||||
let uuid_name = generate_uuid() + extension(source_file)
|
||||
when: ImportMediaRequested(source_path, project, metadata)
|
||||
-- metadata is optional import context: title, alt, caption, author,
|
||||
-- language, and tags may be supplied by the caller.
|
||||
let uuid_name = generate_uuid() + extension(source_path)
|
||||
let dest = format("media/{yyyy}/{mm}/{uuid_name}",
|
||||
yyyy: now.year, mm: now.month_padded)
|
||||
ensures: Media.created(
|
||||
project: project,
|
||||
filename: uuid_name,
|
||||
original_name: source_file.name,
|
||||
mime_type: detect_mime(source_file),
|
||||
size: source_file.size,
|
||||
width: detect_width(source_file),
|
||||
height: detect_height(source_file),
|
||||
original_name: basename(source_path),
|
||||
mime_type: detect_mime(source_path),
|
||||
size: file_size(source_path),
|
||||
width: detect_width(source_path),
|
||||
height: detect_height(source_path),
|
||||
title: metadata.title,
|
||||
alt: metadata.alt,
|
||||
caption: metadata.caption,
|
||||
author: metadata.author,
|
||||
language: metadata.language,
|
||||
file_path: dest,
|
||||
tags: {}
|
||||
tags: metadata.tags
|
||||
)
|
||||
ensures: FileCopied(source_file, dest)
|
||||
ensures: FileCopied(source_path, dest)
|
||||
ensures: SidecarWritten(media)
|
||||
ensures: ThumbnailsGenerated(media)
|
||||
ensures: SearchIndexUpdated(media)
|
||||
|
||||
@@ -14,7 +14,7 @@ surface MediaProcessingControlSurface {
|
||||
facing _: MediaProcessingOperator
|
||||
|
||||
provides:
|
||||
ImportMediaRequested(source_path, project)
|
||||
ImportMediaRequested(source_path, project, metadata)
|
||||
TagMediaRequested(media, tags)
|
||||
DeleteMediaRequested(media)
|
||||
ValidateMediaRequested(project)
|
||||
@@ -239,11 +239,13 @@ invariant MediaTranslationFileLayout {
|
||||
-- ============================================================================
|
||||
|
||||
rule ImportMedia {
|
||||
when: ImportMediaRequested(source_path, project)
|
||||
when: ImportMediaRequested(source_path, project, metadata)
|
||||
-- metadata is optional import context: title, alt, caption, author,
|
||||
-- language, and tags may be supplied by the caller.
|
||||
-- 1. Validate file type (must be supported image)
|
||||
-- 2. Generate UUID v4 filename
|
||||
-- 3. Copy to media/{YYYY}/{MM}/{uuid}.{ext}
|
||||
-- 4. Write sidecar {binary_path}.meta
|
||||
-- 4. Apply optional metadata and write sidecar {binary_path}.meta
|
||||
-- 5. Generate four thumbnail sizes
|
||||
-- 6. Index for search (FTS5)
|
||||
ensures: media/Media.created(
|
||||
@@ -253,6 +255,12 @@ rule ImportMedia {
|
||||
size: file_size(source_path),
|
||||
width: extract_width_from_header(source_path),
|
||||
height: extract_height_from_header(source_path),
|
||||
title: metadata.title,
|
||||
alt: metadata.alt,
|
||||
caption: metadata.caption,
|
||||
author: metadata.author,
|
||||
language: metadata.language,
|
||||
tags: metadata.tags,
|
||||
file_path: format("media/{yyyy}/{mm}/{uuid}.{ext}"),
|
||||
sidecar_path: format("media/{yyyy}/{mm}/{uuid}.{ext}.meta"),
|
||||
checksum: sha256(source_path)
|
||||
|
||||
Reference in New Issue
Block a user