diff --git a/backend/docs/docs.go b/backend/docs/docs.go index e7746e6..1219ede 100644 --- a/backend/docs/docs.go +++ b/backend/docs/docs.go @@ -394,14 +394,14 @@ const docTemplate = `{ } }, "delete": { - "description": "Delete a row from ` + "`" + `current` + "`" + ` by ID.", + "description": "Delete a row from ` + "`" + `current_archive` + "`" + ` by ID.", "produces": [ "application/json" ], "tags": [ "shows" ], - "summary": "Delete show", + "summary": "Delete archived show", "parameters": [ { "type": "integer", diff --git a/backend/docs/swagger.json b/backend/docs/swagger.json index 4cd1ca7..e562319 100644 --- a/backend/docs/swagger.json +++ b/backend/docs/swagger.json @@ -392,14 +392,14 @@ } }, "delete": { - "description": "Delete a row from `current` by ID.", + "description": "Delete a row from `current_archive` by ID.", "produces": [ "application/json" ], "tags": [ "shows" ], - "summary": "Delete show", + "summary": "Delete archived show", "parameters": [ { "type": "integer", diff --git a/backend/docs/swagger.yaml b/backend/docs/swagger.yaml index 92e7b28..c26e634 100644 --- a/backend/docs/swagger.yaml +++ b/backend/docs/swagger.yaml @@ -409,7 +409,7 @@ paths: - auth /api/v1/shows: delete: - description: Delete a row from `current` by ID. + description: Delete a row from `current_archive` by ID. parameters: - description: Show ID format: int64 @@ -434,7 +434,7 @@ paths: description: delete failed schema: $ref: '#/definitions/httpapi.HTTPError' - summary: Delete show + summary: Delete archived show tags: - shows get: diff --git a/backend/internal/http/handlers.go b/backend/internal/http/handlers.go index a5ddb51..ff8b5ba 100644 --- a/backend/internal/http/handlers.go +++ b/backend/internal/http/handlers.go @@ -270,8 +270,8 @@ func listShowsHandler(svc episode.UseCases) gin.HandlerFunc { } // deleteShowHandler godoc -// @Summary Delete show -// @Description Delete a row from `current` by ID. +// @Summary Delete archived show +// @Description Delete a row from `current_archive` by ID. // @Tags shows // @Produce json // @Param id query int64 true "Show ID" diff --git a/backend/internal/repo/episode_repo.go b/backend/internal/repo/episode_repo.go index 57d0bda..cb41e3c 100644 --- a/backend/internal/repo/episode_repo.go +++ b/backend/internal/repo/episode_repo.go @@ -290,7 +290,7 @@ func (r *pgxEpisodeRepo) MoveToArchive(ctx context.Context, ids []int64) (episod } func (r *pgxEpisodeRepo) Delete(ctx context.Context, id int64) error { - cmdTag, err := r.pool.Exec(ctx, `DELETE FROM current WHERE id = $1`, id) + cmdTag, err := r.pool.Exec(ctx, `DELETE FROM current_archive WHERE id = $1`, id) if err != nil { return err } diff --git a/backend/internal/repo/episode_repo_test.go b/backend/internal/repo/episode_repo_test.go index d6c05cf..ad5b943 100644 --- a/backend/internal/repo/episode_repo_test.go +++ b/backend/internal/repo/episode_repo_test.go @@ -19,7 +19,7 @@ func TestPGXEpisodeRepo_Delete(t *testing.T) { t.Run("not found", func(t *testing.T) { fp := &fakePool{ execFn: func(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error) { - if sql != `DELETE FROM current WHERE id = $1` { + if sql != `DELETE FROM current_archive WHERE id = $1` { t.Fatalf("unexpected sql: %s", sql) } return pgconn.NewCommandTag("DELETE 0"), nil @@ -32,9 +32,13 @@ func TestPGXEpisodeRepo_Delete(t *testing.T) { }) t.Run("ok", func(t *testing.T) { - var gotID int64 + var ( + gotSQL string + gotID int64 + ) fp := &fakePool{ execFn: func(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error) { + gotSQL = sql gotID = args[0].(int64) return pgconn.NewCommandTag("DELETE 1"), nil }, @@ -43,6 +47,9 @@ func TestPGXEpisodeRepo_Delete(t *testing.T) { if err := repo.Delete(context.Background(), 22); err != nil { t.Fatalf("unexpected err: %v", err) } + if gotSQL != `DELETE FROM current_archive WHERE id = $1` { + t.Fatalf("expected archive delete sql, got %s", gotSQL) + } if gotID != 22 { t.Fatalf("expected id 22, got %d", gotID) } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ee81d80..27e376f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,7 +11,8 @@ "firebase": "^12.6.0", "react": "^19.1.1", "react-dom": "^19.1.1", - "react-router-dom": "^7.9.5" + "react-router-dom": "^7.9.5", + "react-snowfall": "^2.4.0" }, "devDependencies": { "@eslint/js": "^9.36.0", @@ -4215,6 +4216,12 @@ "react": "^19.1.1" } }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, "node_modules/react-refresh": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", @@ -4263,6 +4270,19 @@ "react-dom": ">=18" } }, + "node_modules/react-snowfall": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-snowfall/-/react-snowfall-2.4.0.tgz", + "integrity": "sha512-KAPMiGnxt11PEgC2pTVrTQsvk5jt1kLUtG+ZamiKLphTZ7GiYT1Aa5kX6jp4jKWq1kqJHchnGT9CDm4g86A5Gg==", + "license": "MIT", + "dependencies": { + "react-fast-compare": "^3.2.2" + }, + "peerDependencies": { + "react": "^16.8 || 17.x || 18.x || 19.x", + "react-dom": "^16.8 || 17.x || 18.x || 19.x" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index b4e1f4c..46d8442 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,7 +15,8 @@ "firebase": "^12.6.0", "react": "^19.1.1", "react-dom": "^19.1.1", - "react-router-dom": "^7.9.5" + "react-router-dom": "^7.9.5", + "react-snowfall": "^2.4.0" }, "devDependencies": { "@eslint/js": "^9.36.0", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index e29ce7d..198a80d 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -9,6 +9,7 @@ import DebugOverlay from "./components/DebugOverlay"; import AuthStatus from "./components/AuthStatus"; import { useAuth } from "./auth/AuthProvider"; import "./index.css"; +import Snowfall from "react-snowfall"; const TIME_SYNC_OFF_THRESHOLD = 100; @@ -29,6 +30,10 @@ export default function App() { return (