From ff89d78ab47631c04dae3e3fef60c230956701a4 Mon Sep 17 00:00:00 2001 From: Chili Palmer Date: Thu, 28 May 2026 21:15:58 +0200 Subject: [PATCH] fix: A1-3 publish_post deletes old file when post path changes --- SPECGAPS.md | 2 +- lib/bds/posts.ex | 4 ++++ test/bds/posts_test.exs | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/SPECGAPS.md b/SPECGAPS.md index 4cbddce..f504b5e 100644 --- a/SPECGAPS.md +++ b/SPECGAPS.md @@ -12,7 +12,7 @@ Gap categories: **SC** = spec correct, fix code | **CS** = code correct, update |---|---|---|---|---| | A1-1 | ~~No `archived→draft` or `archived→published` transition~~ | post.allium:121-122 | `unarchive_post/1` implemented, `publish_post` already handled archived→published | **Resolved:** `unarchive_post/1` in posts.ex restores content from disk, UI wired via quick actions, 4 tests added | | A1-2 | ~~`DeletePost` must delete translations + translation files~~ | post.allium:209-212 | `delete_post/1` now fetches translations before cascade-delete and removes their files from disk | **Resolved:** translation file cleanup added to `delete_post/1` in posts.ex, test added | -| A1-3 | Publish must delete old file when path changes | engine_side_effects.allium:73-74 | `publish_post` does not delete old file | Fix code: add old file deletion on path change | +| A1-3 | ~~Publish must delete old file when path changes~~ | engine_side_effects.allium:73-74 | `publish_post` now deletes old file when `file_path` changes | **Resolved:** old file deletion added to `publish_post/1` in posts.ex, test added | | A1-4 | `doNotTranslate: false` written to frontmatter despite "only when true" | frontmatter.allium:398 | `lib/bds/frontmatter.ex:38-39` writes false | Fix code: omit `doNotTranslate` when false | | A1-5 | Auto-save after 3000ms idle | editor_post.allium:183-188 | No auto-save timer | Fix code: implement auto-save on idle + unmount + tab switch | | A1-6 | On-demand rendering in preview server | preview.allium:53-93 | Server serves static pre-generated files | Fix code: implement on-demand template rendering for post/archive/language routes | diff --git a/lib/bds/posts.ex b/lib/bds/posts.ex index e33c15d..d840374 100644 --- a/lib/bds/posts.ex +++ b/lib/bds/posts.ex @@ -171,6 +171,10 @@ defmodule BDS.Posts do serialize_post_file(%{post | updated_at: updated_at, content: body}, published_at) ) + if post.file_path != "" and post.file_path != relative_path do + delete_post_file(post) + end + post |> Post.changeset(%{ status: :published, diff --git a/test/bds/posts_test.exs b/test/bds/posts_test.exs index 86e4f10..b918b0b 100644 --- a/test/bds/posts_test.exs +++ b/test/bds/posts_test.exs @@ -188,6 +188,39 @@ defmodule BDS.PostsTest do refute File.exists?(full_path <> ".tmp") end + test "publish_post deletes old file when file path changes", %{ + project: project, + temp_dir: temp_dir + } do + assert {:ok, post} = + BDS.Posts.create_post(%{ + project_id: project.id, + title: "Moving Post", + content: "Body" + }) + + assert {:ok, published} = BDS.Posts.publish_post(post.id) + new_path = Path.join(temp_dir, published.file_path) + assert File.exists?(new_path) + + old_relative = "posts/1999/01/moving-post.md" + old_full = Path.join(temp_dir, old_relative) + File.mkdir_p!(Path.dirname(old_full)) + File.write!(old_full, "stale content") + + import Ecto.Query + BDS.Repo.update_all( + from(p in BDS.Posts.Post, where: p.id == ^published.id), + set: [file_path: old_relative, content: "edited body"] + ) + + assert {:ok, republished} = BDS.Posts.publish_post(published.id) + assert republished.file_path == published.file_path + + assert File.exists?(Path.join(temp_dir, republished.file_path)) + refute File.exists?(old_full) + end + test "delete_post removes the database row and published markdown file when present" do temp_dir = Path.join(System.tmp_dir!(), "bds-post-delete-#{System.unique_integer([:positive])}")