Unify API route parameters, return IResult everywhere, merge picture upload DTOs and centralize validation limits

Guid and long route constraints, id/trackId parameter names, Update*Request without the New prefix,
sentence-case operation summaries, shared security scheme id and a single Limits class.
This commit is contained in:
2026-09-24 12:36:48 +02:00
parent 405df082cc
commit fcf3093ad8
38 changed files with 740 additions and 829 deletions
+471 -557
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -40,8 +40,8 @@ export async function addAlbumToPlaylistAction({ request, params, locals, fetch
}
const api = createApiClient({ fetch, accessToken });
const { data: tracks, error: tracksErr } = await api.GET('/albums/{albumId}/tracks', {
params: { path: { albumId }, query: { pageNumber: 1, pageSize: ALBUM_TRACKS_PAGE_SIZE } }
const { data: tracks, error: tracksErr } = await api.GET('/albums/{id}/tracks', {
params: { path: { id: albumId }, query: { pageNumber: 1, pageSize: ALBUM_TRACKS_PAGE_SIZE } }
});
if (tracksErr || !tracks) {
@@ -18,9 +18,9 @@ export const load: PageServerLoad = async ({ params, locals, url, fetch, parent
const [albumRes, tracksRes, libraryRes] = await Promise.all([
api.GET('/albums/{id}', { params: { path: { id: params.id } } }),
api.GET('/albums/{albumId}/tracks', {
api.GET('/albums/{id}/tracks', {
params: {
path: { albumId: params.id },
path: { id: params.id },
query: { pageNumber: 1, pageSize: ALBUM_TRACKS_PAGE_SIZE }
}
}),
@@ -71,8 +71,8 @@ export const actions: Actions = {
if (!trackId) return fail(400, { message: 'Falta la canción.' });
const api = createApiClient({ fetch, accessToken });
const result = await api.DELETE('/albums/{albumId}/tracks/{trackId}', {
params: { path: { albumId: params.id, trackId } }
const result = await api.DELETE('/albums/{id}/tracks/{trackId}', {
params: { path: { id: params.id, trackId } }
});
const failure = unwrapOrFail(result, 'No se pudo quitar la canción.');
if (failure) return failure;
@@ -102,13 +102,13 @@ export const actions: Actions = {
newPictureIntentId = uploaded.intentId;
}
const result = await api.PUT('/albums/{albumId}', {
params: { path: { albumId: params.id } },
const result = await api.PUT('/albums/{id}', {
params: { path: { id: params.id } },
body: {
newTitle: parsed.body.title,
newDescription: parsed.body.description,
newReleaseYear: parsed.body.releaseYear,
newPictureIntentId
title: parsed.body.title,
description: parsed.body.description,
releaseYear: parsed.body.releaseYear,
pictureIntentId: newPictureIntentId
}
});
const failure = unwrapOrFail(result, 'No se pudo actualizar el álbum.');
@@ -121,8 +121,8 @@ export const actions: Actions = {
if (typeof accessToken !== 'string') return accessToken;
const api = createApiClient({ fetch, accessToken });
const result = await api.DELETE('/albums/{albumId}', {
params: { path: { albumId: params.id } }
const result = await api.DELETE('/albums/{id}', {
params: { path: { id: params.id } }
});
const failure = unwrapOrFail(result, 'No se pudo eliminar el álbum.');
if (failure) return failure;
@@ -28,8 +28,8 @@ export const actions: Actions = {
if (!trackId) return fail(400, { message: 'Falta la canción.' });
const api = createApiClient({ fetch, accessToken });
const result = await api.DELETE('/tracks/{trackId}', {
params: { path: { trackId } }
const result = await api.DELETE('/tracks/{id}', {
params: { path: { id: trackId } }
});
const failure = unwrapOrFail(result, 'No se pudo borrar la canción.');
if (failure) return failure;
@@ -26,8 +26,8 @@ export const load: PageServerLoad = async ({ locals, url, fetch }) => {
fetchAllPages(
async (pageNumber, pageSize) =>
(
await api.GET('/playlists/{playlistId}/tracks', {
params: { path: { playlistId: playlist.id }, query: { pageNumber, pageSize } }
await api.GET('/playlists/{id}/tracks', {
params: { path: { id: playlist.id }, query: { pageNumber, pageSize } }
})
).data,
PLAYLIST_TRACKS_LIMIT
@@ -23,8 +23,8 @@ export const load: PageServerLoad = async ({ params, locals, url, fetch, parent
fetchAllPages(
async (pageNumber, pageSize) =>
(
await api.GET('/playlists/{playlistId}/tracks', {
params: { path: { playlistId: params.id }, query: { pageNumber, pageSize } }
await api.GET('/playlists/{id}/tracks', {
params: { path: { id: params.id }, query: { pageNumber, pageSize } }
})
).data,
PLAYLIST_TRACKS_LIMIT
@@ -44,8 +44,8 @@ export const actions: Actions = {
if (!trackId) return fail(400, { message: 'Falta la canción.' });
const api = createApiClient({ fetch, accessToken });
const result = await api.DELETE('/playlists/{playlistId}/tracks/{trackId}', {
params: { path: { playlistId: params.id, trackId } }
const result = await api.DELETE('/playlists/{id}/tracks/{trackId}', {
params: { path: { id: params.id, trackId } }
});
const failure = unwrapOrFail(result, 'No se pudo quitar la canción.');
if (failure) return failure;
@@ -78,9 +78,14 @@ export const actions: Actions = {
newPictureIntentId = result.intentId;
}
const result = await api.PUT('/playlists/{playlistId}', {
params: { path: { playlistId: params.id } },
body: { newName: name, newDescription: description, newPictureIntentId, newVisibility }
const result = await api.PUT('/playlists/{id}', {
params: { path: { id: params.id } },
body: {
name,
description,
pictureIntentId: newPictureIntentId,
visibility: newVisibility
}
});
const failure = unwrapOrFail(result, 'No se pudo actualizar la playlist.');
if (failure) return failure;
@@ -92,8 +97,8 @@ export const actions: Actions = {
if (typeof accessToken !== 'string') return accessToken;
const api = createApiClient({ fetch, accessToken });
const result = await api.DELETE('/playlists/{playlistId}', {
params: { path: { playlistId: params.id } }
const result = await api.DELETE('/playlists/{id}', {
params: { path: { id: params.id } }
});
const failure = unwrapOrFail(result, 'No se pudo eliminar la playlist.');
if (failure) return failure;
@@ -25,8 +25,8 @@ export const load: PageServerLoad = async ({ params, locals, url, fetch, parent
const tracksByPlaylist = await Promise.all(
playlistItems.map((playlist) =>
api
.GET('/playlists/{playlistId}/tracks', {
params: { path: { playlistId: playlist.id }, query: { pageNumber: 1, pageSize: 1 } }
.GET('/playlists/{id}/tracks', {
params: { path: { id: playlist.id }, query: { pageNumber: 1, pageSize: 1 } }
})
.then((res) => Number(res.data?.totalItemCount ?? 0))
)
+2 -2
View File
@@ -45,9 +45,9 @@ export const load: PageServerLoad = async ({ locals, url, fetch }) => {
const spotlightPlaylist = playlistItems[0] ?? null;
const spotlightTracksPromise = spotlightPlaylist
? api
.GET('/playlists/{playlistId}/tracks', {
.GET('/playlists/{id}/tracks', {
params: {
path: { playlistId: spotlightPlaylist.id },
path: { id: spotlightPlaylist.id },
query: { pageNumber: 1, pageSize: HOME_SPOTLIGHT_TRACKS_LIMIT }
}
})
@@ -5,9 +5,9 @@ import { ALBUM_TRACKS_PAGE_SIZE } from '$lib/config';
export const GET: RequestHandler = async ({ params, locals, fetch }) => {
const api = createApiClient({ fetch, accessToken: locals.accessToken ?? undefined });
const result = await api.GET('/albums/{albumId}/tracks', {
const result = await api.GET('/albums/{id}/tracks', {
params: {
path: { albumId: params.id },
path: { id: params.id },
query: { pageNumber: 1, pageSize: ALBUM_TRACKS_PAGE_SIZE }
}
});