ML-180: remove backup download feature
Delete ArchiveController, its routes, the maintenance UI backup button, and the test file. Management scripts and Litestream supersede this functionality.
This commit is contained in:
+30
-8
@@ -1,14 +1,20 @@
|
||||
---
|
||||
id: ML-180
|
||||
title: Remove backup function from application
|
||||
status: To Do
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: "2026-05-12 04:57"
|
||||
updated_date: "2026-05-12 10:25"
|
||||
updated_date: "2026-05-15 06:11"
|
||||
labels:
|
||||
- api
|
||||
- ui
|
||||
dependencies: []
|
||||
modified_files:
|
||||
- lib/music_library_web/router.ex
|
||||
- lib/music_library_web/controllers/archive_controller.ex
|
||||
- lib/music_library_web/live/maintenance_live/index.ex
|
||||
- test/music_library_web/controllers/archive_controller_test.exs
|
||||
- docs/architecture.md
|
||||
---
|
||||
|
||||
## Description
|
||||
@@ -23,12 +29,12 @@ Management scripts and tools superseded this functionality. It can be removed fr
|
||||
|
||||
<!-- AC:BEGIN -->
|
||||
|
||||
- [ ] #1 The /backup and /api/v1/backup routes return 404
|
||||
- [ ] #2 The Maintenance page no longer shows a Backup button in the Database section
|
||||
- [ ] #3 `mix compile --warnings-as-errors` passes with no ArchiveController references
|
||||
- [ ] #4 `mix test` passes with no ArchiveControllerTest references
|
||||
- [ ] #5 The record format `:backup` type still works (record_component format labels still show "Backup" for backup-format records)
|
||||
- [ ] #6 `docs/architecture.md` no longer lists ArchiveController in the routes table
|
||||
- [x] #1 The /backup and /api/v1/backup routes return 404
|
||||
- [x] #2 The Maintenance page no longer shows a Backup button in the Database section
|
||||
- [x] #3 `mix compile --warnings-as-errors` passes with no ArchiveController references
|
||||
- [x] #4 `mix test` passes with no ArchiveControllerTest references
|
||||
- [x] #5 The record format `:backup` type still works (record_component format labels still show "Backup" for backup-format records)
|
||||
- [x] #6 `docs/architecture.md` no longer lists ArchiveController in the routes table
|
||||
<!-- AC:END -->
|
||||
|
||||
## Implementation Plan
|
||||
@@ -136,3 +142,19 @@ None required. No migrations, no environment variables, no service provisioning.
|
||||
- **`docs/architecture.md`**: Remove the `ArchiveController` row from the routes table. No other architecture docs need changes.
|
||||
- No changes to `docs/project-conventions.md`, `docs/production-infrastructure.md`, `docs/available-tasks.md`, or README needed.
|
||||
<!-- SECTION:PLAN:END -->
|
||||
|
||||
## Final Summary
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||
|
||||
Removed the in-app database backup download feature:
|
||||
|
||||
1. **Router** (`lib/music_library_web/router.ex`): Removed `get "/backup", ArchiveController, :backup` from both the `:logged_in` pipeline and the `:api` scope.
|
||||
2. **Controller** (`lib/music_library_web/controllers/archive_controller.ex`): Deleted — module only contained `backup/2` and a private `database_path/0` helper.
|
||||
3. **Maintenance UI** (`lib/music_library_web/live/maintenance_live/index.ex`): Removed the `<.button href={~p"/backup"}>` element from the Database section.
|
||||
4. **Tests** (`test/music_library_web/controllers/archive_controller_test.exs`): Deleted.
|
||||
5. **Docs** (`docs/architecture.md`): Removed the `ArchiveController` row from the controller routes table.
|
||||
|
||||
All 982 tests pass. No ArchiveController references remain. The `:backup` record format atom and `format_label(:backup)` are intentionally untouched (they represent a record format type, not the backup download feature).
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||
@@ -345,7 +345,6 @@ All authenticated routes live inside a single `live_session` with three `on_moun
|
||||
| `SessionController` | `/login`, `/sessions/create` | Login/logout |
|
||||
| `HealthController` | `/health` | Health check |
|
||||
| `LastFmController` | `/auth/last_fm/callback` | Last.fm OAuth |
|
||||
| `ArchiveController` | `/backup`, `/api/v1/backup` | Database backup download (API route requires token) |
|
||||
| `AssetController` | `/assets/:transform_payload`, `/public/assets/:transform_payload`, `/api/v1/assets/:transform_payload` | Serve images with transforms (public route for emails, API route requires token) |
|
||||
| `CollectionController` | `/api/v1/collection/*`, `POST /api/v1/collection/:record_id/scrobble` | JSON API for collection queries (search with `?q=`, returns 4 cover sizes), and scrobbling records from Presto |
|
||||
| `ErrorController` | `/api/v1/errors`, `/api/v1/errors/:id`, `/api/v1/errors/:id/mute`, `/api/v1/errors/:id/unmute`, `/api/v1/errors/:id/resolve`, `/api/v1/errors/:id/unresolve` | JSON API for production error queries and mutations (requires Bearer token); POST endpoints for mute/unmute/resolve/unresolve |
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
defmodule MusicLibraryWeb.ArchiveController do
|
||||
use MusicLibraryWeb, :controller
|
||||
|
||||
# The database path is configuration controlled, and not derived from any
|
||||
# user input, so we can safely skip the check.
|
||||
# sobelow_skip ["Traversal.SendDownload"]
|
||||
def backup(conn, _params) do
|
||||
MusicLibrary.Repo.vacuum()
|
||||
|
||||
database_path = database_path()
|
||||
current_time = DateTime.utc_now()
|
||||
file_name = "music_library_#{DateTime.to_unix(current_time)}.db"
|
||||
|
||||
send_download(conn, {:file, database_path},
|
||||
filename: file_name,
|
||||
content_type: "application/x-sqlite3"
|
||||
)
|
||||
end
|
||||
|
||||
defp database_path do
|
||||
Application.get_env(:music_library, MusicLibrary.Repo)[:database]
|
||||
end
|
||||
end
|
||||
@@ -153,9 +153,6 @@ defmodule MusicLibraryWeb.MaintenanceLive.Index do
|
||||
>
|
||||
{gettext("Optimize")}
|
||||
</.button>
|
||||
<.button href={~p"/backup"}>
|
||||
{gettext("Backup")}
|
||||
</.button>
|
||||
</.button_group>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -63,8 +63,6 @@ defmodule MusicLibraryWeb.Router do
|
||||
scope "/" do
|
||||
pipe_through :logged_in
|
||||
|
||||
get "/backup", ArchiveController, :backup
|
||||
|
||||
get "/assets/:transform_payload", AssetController, :show
|
||||
|
||||
live_session :default,
|
||||
@@ -138,7 +136,6 @@ defmodule MusicLibraryWeb.Router do
|
||||
post "/errors/:id/resolve", ErrorController, :resolve
|
||||
post "/errors/:id/unresolve", ErrorController, :unresolve
|
||||
get "/assets/:transform_payload", AssetController, :show
|
||||
get "/backup", ArchiveController, :backup
|
||||
end
|
||||
|
||||
if Application.compile_env(:music_library, :monitoring_routes) do
|
||||
|
||||
@@ -362,7 +362,6 @@ msgid "Album"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/record_components.ex
|
||||
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Backup"
|
||||
msgstr ""
|
||||
|
||||
@@ -362,7 +362,6 @@ msgid "Album"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/record_components.ex
|
||||
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Backup"
|
||||
msgstr ""
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
defmodule MusicLibraryWeb.ArchiveControllerTest do
|
||||
use MusicLibraryWeb.ConnCase
|
||||
|
||||
describe "GET /backup" do
|
||||
test "returns a sqlite database file", %{conn: conn} do
|
||||
conn = get(conn, "/backup")
|
||||
|
||||
assert response(conn, 200)
|
||||
assert get_resp_header(conn, "content-type") |> hd() =~ "application/x-sqlite3"
|
||||
|
||||
[content_disposition] = get_resp_header(conn, "content-disposition")
|
||||
assert content_disposition =~ "attachment"
|
||||
assert content_disposition =~ "music_library_"
|
||||
assert content_disposition =~ ".db"
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user