Compare commits
2 commits
3ebc954718
...
aa6ccbefed
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa6ccbefed | ||
|
|
0e72172291 |
52 changed files with 5079 additions and 80 deletions
|
|
@ -33,11 +33,12 @@ const mockedApiClient = apiClient as {
|
||||||
get: ReturnType<typeof vi.fn>;
|
get: ReturnType<typeof vi.fn>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// v1.0.8 B6 — login / logout / resendVerificationEmail /
|
// v1.0.8 (post-tag, queue+auth annotation session) — full authService
|
||||||
// checkUsernameAvailability migrated to orval. Tests still mock
|
// migration to orval. Tests still mock `apiClient.post/get` for legacy
|
||||||
// `apiClient.post/get` for legacy ergonomics; the orval module's
|
// ergonomics; the orval module's functions are stubbed to delegate
|
||||||
// functions are stubbed to delegate back to those mocks so existing
|
// back to those mocks so existing
|
||||||
// `toHaveBeenCalledWith('/auth/...', ...)` assertions keep working.
|
// `toHaveBeenCalledWith('/auth/...', ...)` assertions keep working,
|
||||||
|
// modulo the wire-shape renames documented in authService.ts.
|
||||||
vi.mock('@/services/generated/auth/auth', () => ({
|
vi.mock('@/services/generated/auth/auth', () => ({
|
||||||
postAuthLogin: vi.fn(async (body: unknown) =>
|
postAuthLogin: vi.fn(async (body: unknown) =>
|
||||||
mockedApiClient.post('/auth/login', body).then((r: { data?: unknown }) => r?.data),
|
mockedApiClient.post('/auth/login', body).then((r: { data?: unknown }) => r?.data),
|
||||||
|
|
@ -45,6 +46,31 @@ vi.mock('@/services/generated/auth/auth', () => ({
|
||||||
postAuthLogout: vi.fn(async () =>
|
postAuthLogout: vi.fn(async () =>
|
||||||
mockedApiClient.post('/auth/logout').then((r: { data?: unknown }) => r?.data),
|
mockedApiClient.post('/auth/logout').then((r: { data?: unknown }) => r?.data),
|
||||||
),
|
),
|
||||||
|
postAuthRegister: vi.fn(async (body: unknown) =>
|
||||||
|
mockedApiClient
|
||||||
|
.post('/auth/register', body)
|
||||||
|
.then((r: { data?: unknown }) => r?.data),
|
||||||
|
),
|
||||||
|
postAuthRefresh: vi.fn(async (body: unknown) =>
|
||||||
|
mockedApiClient
|
||||||
|
.post('/auth/refresh', body)
|
||||||
|
.then((r: { data?: unknown }) => r?.data),
|
||||||
|
),
|
||||||
|
postAuthPasswordResetRequest: vi.fn(async (body: unknown) =>
|
||||||
|
mockedApiClient
|
||||||
|
.post('/auth/password/reset-request', body)
|
||||||
|
.then((r: { data?: unknown }) => r?.data),
|
||||||
|
),
|
||||||
|
postAuthPasswordReset: vi.fn(async (body: unknown) =>
|
||||||
|
mockedApiClient
|
||||||
|
.post('/auth/password/reset', body)
|
||||||
|
.then((r: { data?: unknown }) => r?.data),
|
||||||
|
),
|
||||||
|
postAuthVerifyEmail: vi.fn(async (params: { token: string }) =>
|
||||||
|
mockedApiClient
|
||||||
|
.post(`/auth/verify-email?token=${params.token}`)
|
||||||
|
.then((r: { data?: unknown }) => r?.data),
|
||||||
|
),
|
||||||
postAuthResendVerification: vi.fn(async (body: unknown) =>
|
postAuthResendVerification: vi.fn(async (body: unknown) =>
|
||||||
mockedApiClient
|
mockedApiClient
|
||||||
.post('/auth/resend-verification', body)
|
.post('/auth/resend-verification', body)
|
||||||
|
|
@ -150,10 +176,14 @@ describe('authService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toEqual(mockResponse);
|
expect(result).toEqual(mockResponse);
|
||||||
|
// Note: frontend RegisterFormData uses `password_confirm`; the
|
||||||
|
// service maps this to `password_confirmation` (backend DTO field
|
||||||
|
// name from register_request.go:8) before sending. This assertion
|
||||||
|
// checks the WIRE shape, not the form-data shape.
|
||||||
expect(mockedApiClient.post).toHaveBeenCalledWith('/auth/register', {
|
expect(mockedApiClient.post).toHaveBeenCalledWith('/auth/register', {
|
||||||
email: 'newuser@example.com',
|
email: 'newuser@example.com',
|
||||||
password: 'password123',
|
password: 'password123',
|
||||||
password_confirm: 'password123',
|
password_confirmation: 'password123',
|
||||||
username: 'newuser',
|
username: 'newuser',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -220,8 +250,10 @@ describe('authService', () => {
|
||||||
const result = await refreshToken('refresh-token-123');
|
const result = await refreshToken('refresh-token-123');
|
||||||
|
|
||||||
expect(result).toEqual(mockResponse);
|
expect(result).toEqual(mockResponse);
|
||||||
|
// Wire shape: backend DTO uses snake_case `refresh_token`,
|
||||||
|
// not the camelCase `refreshToken` passed as the JS arg.
|
||||||
expect(mockedApiClient.post).toHaveBeenCalledWith('/auth/refresh', {
|
expect(mockedApiClient.post).toHaveBeenCalledWith('/auth/refresh', {
|
||||||
refreshToken: 'refresh-token-123',
|
refresh_token: 'refresh-token-123',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -281,11 +313,16 @@ describe('authService', () => {
|
||||||
confirmPassword: 'newpassword123',
|
confirmPassword: 'newpassword123',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Wire shape: backend DTO field is `new_password` (cf. handlers/
|
||||||
|
// password_reset_handler.go:ResetPasswordRequest); the frontend
|
||||||
|
// form-data type uses `password`. confirmPassword is dropped —
|
||||||
|
// backend only validates that the new password meets the strength
|
||||||
|
// policy, the equality check happens client-side in the form.
|
||||||
expect(mockedApiClient.post).toHaveBeenCalledWith(
|
expect(mockedApiClient.post).toHaveBeenCalledWith(
|
||||||
'/auth/password/reset',
|
'/auth/password/reset',
|
||||||
{
|
{
|
||||||
token: 'reset-token-123',
|
token: 'reset-token-123',
|
||||||
password: 'newpassword123',
|
new_password: 'newpassword123',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -311,11 +348,14 @@ describe('authService', () => {
|
||||||
|
|
||||||
describe('verifyEmail', () => {
|
describe('verifyEmail', () => {
|
||||||
it('should successfully verify email', async () => {
|
it('should successfully verify email', async () => {
|
||||||
mockedApiClient.get.mockResolvedValue({ data: {} });
|
// Verb shift: was GET, backend route is POST (auth.go:VerifyEmail
|
||||||
|
// / routes_auth.go:107). Token still passed as query param per
|
||||||
|
// the swaggo annotation.
|
||||||
|
mockedApiClient.post.mockResolvedValue({ data: {} });
|
||||||
|
|
||||||
await verifyEmail('verification-token-123');
|
await verifyEmail('verification-token-123');
|
||||||
|
|
||||||
expect(mockedApiClient.get).toHaveBeenCalledWith(
|
expect(mockedApiClient.post).toHaveBeenCalledWith(
|
||||||
'/auth/verify-email?token=verification-token-123',
|
'/auth/verify-email?token=verification-token-123',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -327,7 +367,7 @@ describe('authService', () => {
|
||||||
data: { error: 'Invalid or expired token' },
|
data: { error: 'Invalid or expired token' },
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
mockedApiClient.get.mockRejectedValue(mockError);
|
mockedApiClient.post.mockRejectedValue(mockError);
|
||||||
|
|
||||||
await expect(verifyEmail('invalid-token')).rejects.toThrow();
|
await expect(verifyEmail('invalid-token')).rejects.toThrow();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,38 @@
|
||||||
/**
|
/**
|
||||||
* Auth service — orval-backed (partial v1.0.8 B6).
|
* Auth service — orval-backed (full migration post-v1.0.8 B6/B6.bis).
|
||||||
*
|
*
|
||||||
* Migrated to orval generated client:
|
* All 9 functions now route through the orval-generated client in
|
||||||
* login, logout, resendVerificationEmail, checkUsernameAvailability.
|
* services/generated/auth/auth.ts. Backend DTOs are the source of truth
|
||||||
|
* for the wire shape; this service maps from the frontend form-data
|
||||||
|
* type names (camelCase / French-named) to the snake_case JSON field
|
||||||
|
* names the Go DTOs expect.
|
||||||
*
|
*
|
||||||
* Still on raw apiClient (deferred v1.0.9 — backend annotation gaps or
|
* Wire-shape mappings worth knowing (drifts that pre-existed):
|
||||||
* field-name drift would risk breaking auth):
|
* - register: `password_confirm` (frontend) → `password_confirmation`
|
||||||
* - register → backend DTO says `password_confirmation` while the
|
* (backend `register_request.go:8`)
|
||||||
* frontend currently sends `password_confirm`
|
* - refreshToken: `refreshToken` (frontend arg) → `refresh_token` (DTO)
|
||||||
* (register_request.go:8). Renaming via orval would
|
* - resetPassword: `password` (frontend `ResetPasswordFormData`) →
|
||||||
* change wire shape; needs explicit verification on
|
* `new_password` (backend `ResetPasswordRequest`)
|
||||||
* prod first.
|
* - verifyEmail: verb shift GET → POST (token still passed as
|
||||||
* - refreshToken → same pattern, backend expects `refresh_token` but
|
* `?token=` query param; this matches the route
|
||||||
* current frontend sends `refreshToken`.
|
* registered at `routes_auth.go:107` and the swaggo
|
||||||
* - requestPasswordReset / resetPassword → endpoints not yet annotated
|
* annotation on `auth.go:VerifyEmail`).
|
||||||
* in swaggo (no /auth/password/* in openapi.yaml).
|
*
|
||||||
* - verifyEmail → frontend uses GET /auth/verify-email?token= but
|
* The previous code sending `password_confirm` / `refreshToken` /
|
||||||
* orval-generated spec says POST. Verb drift + the
|
* `password` was likely silently broken or fell through a backend
|
||||||
* query→header migration parked in FUNCTIONAL_AUDIT
|
* tolerance path — the new shape is what the swaggo-emitted
|
||||||
* §4#7 should land together in v1.0.9.
|
* `openapi.yaml` declares, and what `c.ShouldBindJSON` of the
|
||||||
|
* corresponding DTOs actually requires.
|
||||||
*/
|
*/
|
||||||
import { apiClient } from '@/services/api/client';
|
|
||||||
import {
|
import {
|
||||||
postAuthLogin,
|
postAuthLogin,
|
||||||
postAuthLogout,
|
postAuthLogout,
|
||||||
|
postAuthRefresh,
|
||||||
|
postAuthRegister,
|
||||||
postAuthResendVerification,
|
postAuthResendVerification,
|
||||||
|
postAuthPasswordReset,
|
||||||
|
postAuthPasswordResetRequest,
|
||||||
|
postAuthVerifyEmail,
|
||||||
getAuthCheckUsername,
|
getAuthCheckUsername,
|
||||||
} from '@/services/generated/auth/auth';
|
} from '@/services/generated/auth/auth';
|
||||||
import { handleApiServiceError } from '@/utils/serviceErrorHandler';
|
import { handleApiServiceError } from '@/utils/serviceErrorHandler';
|
||||||
|
|
@ -84,13 +92,13 @@ export async function login(data: LoginFormData): Promise<AuthResponse> {
|
||||||
// INT-API-003: Standardized error handling using handleApiServiceError
|
// INT-API-003: Standardized error handling using handleApiServiceError
|
||||||
export async function register(data: RegisterFormData): Promise<AuthResponse> {
|
export async function register(data: RegisterFormData): Promise<AuthResponse> {
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.post<AuthResponse>('/auth/register', {
|
const response = await postAuthRegister({
|
||||||
email: data.email,
|
email: data.email,
|
||||||
password: data.password,
|
password: data.password,
|
||||||
password_confirm: data.password_confirm, // Envoyer la confirmation du mot de passe
|
password_confirmation: data.password_confirm,
|
||||||
username: data.username,
|
username: data.username,
|
||||||
});
|
});
|
||||||
return response.data;
|
return response as unknown as AuthResponse;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleApiServiceError(error, {
|
handleApiServiceError(error, {
|
||||||
context: 'auth',
|
context: 'auth',
|
||||||
|
|
@ -128,10 +136,8 @@ export async function refreshToken(
|
||||||
refreshToken: string,
|
refreshToken: string,
|
||||||
): Promise<AuthResponse> {
|
): Promise<AuthResponse> {
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.post<AuthResponse>('/auth/refresh', {
|
const response = await postAuthRefresh({ refresh_token: refreshToken });
|
||||||
refreshToken,
|
return response as unknown as AuthResponse;
|
||||||
});
|
|
||||||
return response.data;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleApiServiceError(error, { context: 'auth' });
|
handleApiServiceError(error, { context: 'auth' });
|
||||||
}
|
}
|
||||||
|
|
@ -147,7 +153,7 @@ export async function requestPasswordReset(
|
||||||
data: ForgotPasswordFormData,
|
data: ForgotPasswordFormData,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await apiClient.post('/auth/password/reset-request', data);
|
await postAuthPasswordResetRequest({ email: data.email });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleApiServiceError(error, { context: 'auth' });
|
handleApiServiceError(error, { context: 'auth' });
|
||||||
}
|
}
|
||||||
|
|
@ -163,9 +169,9 @@ export async function resetPassword(
|
||||||
data: ResetPasswordFormData,
|
data: ResetPasswordFormData,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await apiClient.post('/auth/password/reset', {
|
await postAuthPasswordReset({
|
||||||
token: data.token,
|
token: data.token,
|
||||||
password: data.password,
|
new_password: data.password,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleApiServiceError(error, { context: 'auth' });
|
handleApiServiceError(error, { context: 'auth' });
|
||||||
|
|
@ -178,9 +184,12 @@ export async function resetPassword(
|
||||||
* @throws ApiError en cas d'erreur
|
* @throws ApiError en cas d'erreur
|
||||||
*/
|
*/
|
||||||
// INT-API-003: Standardized error handling using handleApiServiceError
|
// INT-API-003: Standardized error handling using handleApiServiceError
|
||||||
|
// Note: backend route is POST (`auth.go:VerifyEmail` /
|
||||||
|
// `routes_auth.go:107`), token still passed as `?token=` query param.
|
||||||
|
// orval handles both — we only adjust the verb client-side.
|
||||||
export async function verifyEmail(token: string): Promise<void> {
|
export async function verifyEmail(token: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await apiClient.get(`/auth/verify-email?token=${token}`);
|
await postAuthVerifyEmail({ token });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleApiServiceError(error, { context: 'auth' });
|
handleApiServiceError(error, { context: 'auth' });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,28 @@
|
||||||
/**
|
/**
|
||||||
* Queue API Service
|
* Queue API Service — orval-backed (v1.0.8 post-tag, queue annotation session).
|
||||||
* v0.102: Persistent user playback queue — sync with backend
|
* v0.102: persistent user playback queue + collaborative session sharing
|
||||||
|
* (v0.203 Lot D1).
|
||||||
|
*
|
||||||
|
* Public surface (queueApi object) preserved verbatim — useQueueSync,
|
||||||
|
* PlayerQueue, and any other consumer keeps importing
|
||||||
|
* `queueApi.{getQueue, addToQueue, ...}` without change. The body of
|
||||||
|
* each method now delegates to the orval-generated functions in
|
||||||
|
* services/generated/queue/queue.ts (annotated swaggo backend landed
|
||||||
|
* concurrently).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { apiClient } from './client';
|
import {
|
||||||
|
getQueue as orvalGetQueue,
|
||||||
|
putQueue as orvalUpdateQueue,
|
||||||
|
postQueueItems as orvalAddItem,
|
||||||
|
deleteQueueItemsId as orvalRemoveItem,
|
||||||
|
deleteQueue as orvalClearQueue,
|
||||||
|
postQueueSession as orvalCreateSession,
|
||||||
|
getQueueSessionToken as orvalGetSession,
|
||||||
|
deleteQueueSessionToken as orvalDeleteSession,
|
||||||
|
postQueueSessionTokenItems as orvalAddToSession,
|
||||||
|
deleteQueueSessionTokenItemsId as orvalRemoveFromSession,
|
||||||
|
} from '@/services/generated/queue/queue';
|
||||||
import type { Track } from '@/features/player/types';
|
import type { Track } from '@/features/player/types';
|
||||||
|
|
||||||
export interface QueueItemResponse {
|
export interface QueueItemResponse {
|
||||||
|
|
@ -39,6 +58,18 @@ export interface QueueResponse {
|
||||||
items: QueueItemResponse[];
|
items: QueueItemResponse[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Backend wraps each response in an APIResponse envelope:
|
||||||
|
// { success: true, data: { queue: ..., items: ... } }
|
||||||
|
// orval's mutator unwraps the Axios layer (`response.data`), so what
|
||||||
|
// we get here is the envelope itself. Strip the `data` key when present.
|
||||||
|
const unwrapPayload = <T>(raw: unknown): T => {
|
||||||
|
const env = raw as { data?: unknown } | undefined;
|
||||||
|
if (env && typeof env === 'object' && 'data' in env && env.data !== undefined) {
|
||||||
|
return env.data as T;
|
||||||
|
}
|
||||||
|
return raw as T;
|
||||||
|
};
|
||||||
|
|
||||||
function mapQueueItemToTrack(item: QueueItemResponse): Track | null {
|
function mapQueueItemToTrack(item: QueueItemResponse): Track | null {
|
||||||
const t = item.track;
|
const t = item.track;
|
||||||
if (!t) return null;
|
if (!t) return null;
|
||||||
|
|
@ -61,8 +92,8 @@ export const queueApi = {
|
||||||
tracks: Track[];
|
tracks: Track[];
|
||||||
queueItemIds: string[];
|
queueItemIds: string[];
|
||||||
}> {
|
}> {
|
||||||
const response = await apiClient.get<QueueResponse>('/queue');
|
const response = await orvalGetQueue();
|
||||||
const data = response.data as unknown as QueueResponse;
|
const data = unwrapPayload<QueueResponse>(response);
|
||||||
const items = (data?.items ?? []).sort((a, b) => a.position - b.position);
|
const items = (data?.items ?? []).sort((a, b) => a.position - b.position);
|
||||||
const tracks = items
|
const tracks = items
|
||||||
.map(mapQueueItemToTrack)
|
.map(mapQueueItemToTrack)
|
||||||
|
|
@ -84,34 +115,48 @@ export const queueApi = {
|
||||||
volume?: number;
|
volume?: number;
|
||||||
item_order?: string[];
|
item_order?: string[];
|
||||||
}): Promise<QueueResponse> {
|
}): Promise<QueueResponse> {
|
||||||
const response = await apiClient.put<QueueResponse>('/queue', payload);
|
const response = await orvalUpdateQueue(
|
||||||
return response.data as unknown as QueueResponse;
|
payload as Parameters<typeof orvalUpdateQueue>[0],
|
||||||
|
);
|
||||||
|
return unwrapPayload<QueueResponse>(response);
|
||||||
},
|
},
|
||||||
|
|
||||||
async addToQueue(trackId: string): Promise<QueueItemResponse> {
|
async addToQueue(trackId: string): Promise<QueueItemResponse> {
|
||||||
const response = await apiClient.post<{ item: QueueItemResponse }>(
|
const response = await orvalAddItem(
|
||||||
'/queue/items',
|
{ track_id: trackId } as unknown as Parameters<typeof orvalAddItem>[0],
|
||||||
{ track_id: trackId },
|
|
||||||
);
|
);
|
||||||
return (response.data as unknown as { item: QueueItemResponse }).item;
|
const payload = unwrapPayload<{ item: QueueItemResponse } | QueueItemResponse>(
|
||||||
|
response,
|
||||||
|
);
|
||||||
|
if (payload && typeof payload === 'object' && 'item' in payload && payload.item) {
|
||||||
|
return payload.item as QueueItemResponse;
|
||||||
|
}
|
||||||
|
return payload as QueueItemResponse;
|
||||||
},
|
},
|
||||||
|
|
||||||
async removeFromQueue(itemId: string): Promise<void> {
|
async removeFromQueue(itemId: string): Promise<void> {
|
||||||
await apiClient.delete(`/queue/items/${itemId}`);
|
await orvalRemoveItem(itemId);
|
||||||
},
|
},
|
||||||
|
|
||||||
async clearQueue(): Promise<void> {
|
async clearQueue(): Promise<void> {
|
||||||
await apiClient.delete('/queue');
|
await orvalClearQueue();
|
||||||
},
|
},
|
||||||
|
|
||||||
// v0.203 Lot D1: Collaborative queue sessions
|
// v0.203 Lot D1: Collaborative queue sessions
|
||||||
async createQueueSession(): Promise<{ session: { id: string; share_token: string }; share_url: string }> {
|
async createQueueSession(): Promise<{
|
||||||
const response = await apiClient.post<{ session: { id: string; share_token: string }; share_url?: string }>(
|
session: { id: string; share_token: string };
|
||||||
'/queue/session',
|
share_url: string;
|
||||||
);
|
}> {
|
||||||
const data = response.data as unknown as { session: { id: string; share_token: string }; share_url?: string };
|
const response = await orvalCreateSession();
|
||||||
|
const data = unwrapPayload<{
|
||||||
|
session: { id: string; share_token: string };
|
||||||
|
share_url?: string;
|
||||||
|
}>(response);
|
||||||
const shareUrl =
|
const shareUrl =
|
||||||
data.share_url ?? (typeof window !== 'undefined' ? `${window.location.origin}/?session=${data.session.share_token}` : '');
|
data.share_url ??
|
||||||
|
(typeof window !== 'undefined'
|
||||||
|
? `${window.location.origin}/?session=${data.session.share_token}`
|
||||||
|
: '');
|
||||||
return { session: data.session, share_url: shareUrl };
|
return { session: data.session, share_url: shareUrl };
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -120,36 +165,33 @@ export const queueApi = {
|
||||||
items: Array<{
|
items: Array<{
|
||||||
id: string;
|
id: string;
|
||||||
position: number;
|
position: number;
|
||||||
track?: { id: string; title?: string; artist?: string; duration?: number; cover_art_path?: string; genre?: string; like_count?: number };
|
track?: {
|
||||||
|
id: string;
|
||||||
|
title?: string;
|
||||||
|
artist?: string;
|
||||||
|
duration?: number;
|
||||||
|
cover_art_path?: string;
|
||||||
|
genre?: string;
|
||||||
|
like_count?: number;
|
||||||
|
};
|
||||||
}>;
|
}>;
|
||||||
}> {
|
}> {
|
||||||
const response = await apiClient.get<{
|
const response = await orvalGetSession(token);
|
||||||
session: unknown;
|
return unwrapPayload(response);
|
||||||
items: Array<{
|
|
||||||
id: string;
|
|
||||||
position: number;
|
|
||||||
track?: { id: string; title?: string; artist?: string; duration?: number; cover_art_path?: string; genre?: string; like_count?: number };
|
|
||||||
}>;
|
|
||||||
}>(`/queue/session/${token}`);
|
|
||||||
return response.data as unknown as {
|
|
||||||
session: unknown;
|
|
||||||
items: Array<{
|
|
||||||
id: string;
|
|
||||||
position: number;
|
|
||||||
track?: { id: string; title?: string; artist?: string; duration?: number; cover_art_path?: string; genre?: string; like_count?: number };
|
|
||||||
}>;
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async deleteQueueSession(token: string): Promise<void> {
|
async deleteQueueSession(token: string): Promise<void> {
|
||||||
await apiClient.delete(`/queue/session/${token}`);
|
await orvalDeleteSession(token);
|
||||||
},
|
},
|
||||||
|
|
||||||
async addToSessionQueue(token: string, trackId: string): Promise<void> {
|
async addToSessionQueue(token: string, trackId: string): Promise<void> {
|
||||||
await apiClient.post(`/queue/session/${token}/items`, { track_id: trackId });
|
await orvalAddToSession(
|
||||||
|
token,
|
||||||
|
{ track_id: trackId } as unknown as Parameters<typeof orvalAddToSession>[1],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
async removeFromSessionQueue(token: string, itemId: string): Promise<void> {
|
async removeFromSessionQueue(token: string, itemId: string): Promise<void> {
|
||||||
await apiClient.delete(`/queue/session/${token}/items/${itemId}`);
|
await orvalRemoveFromSession(token, itemId);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,16 @@ import type {
|
||||||
GetAuthMe200,
|
GetAuthMe200,
|
||||||
InternalHandlersAPIResponse,
|
InternalHandlersAPIResponse,
|
||||||
InternalHandlersDisableTwoFactorRequest,
|
InternalHandlersDisableTwoFactorRequest,
|
||||||
|
InternalHandlersRequestPasswordResetRequest,
|
||||||
|
InternalHandlersResetPasswordRequest,
|
||||||
InternalHandlersStreamTokenResponse,
|
InternalHandlersStreamTokenResponse,
|
||||||
InternalHandlersVerifyTwoFactorRequest,
|
InternalHandlersVerifyTwoFactorRequest,
|
||||||
PostAuth2faDisable200,
|
PostAuth2faDisable200,
|
||||||
PostAuth2faSetup200,
|
PostAuth2faSetup200,
|
||||||
PostAuth2faVerify200,
|
PostAuth2faVerify200,
|
||||||
PostAuthLogoutBody,
|
PostAuthLogoutBody,
|
||||||
|
PostAuthPasswordReset200,
|
||||||
|
PostAuthPasswordResetRequest200,
|
||||||
PostAuthVerifyEmailParams,
|
PostAuthVerifyEmailParams,
|
||||||
VezaBackendApiInternalDtoLoginRequest,
|
VezaBackendApiInternalDtoLoginRequest,
|
||||||
VezaBackendApiInternalDtoLoginResponse,
|
VezaBackendApiInternalDtoLoginResponse,
|
||||||
|
|
@ -926,6 +930,196 @@ export function useGetAuthMe<TData = Awaited<ReturnType<typeof getAuthMe>>, TErr
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Completes a password reset using a valid token previously emailed to the user. Invalidates all the user's existing sessions on success.
|
||||||
|
* @summary Reset password with token
|
||||||
|
*/
|
||||||
|
export type postAuthPasswordResetResponse200 = {
|
||||||
|
data: PostAuthPasswordReset200
|
||||||
|
status: 200
|
||||||
|
}
|
||||||
|
|
||||||
|
export type postAuthPasswordResetResponse400 = {
|
||||||
|
data: InternalHandlersAPIResponse
|
||||||
|
status: 400
|
||||||
|
}
|
||||||
|
|
||||||
|
export type postAuthPasswordResetResponse500 = {
|
||||||
|
data: InternalHandlersAPIResponse
|
||||||
|
status: 500
|
||||||
|
}
|
||||||
|
|
||||||
|
export type postAuthPasswordResetResponseSuccess = (postAuthPasswordResetResponse200) & {
|
||||||
|
headers: Headers;
|
||||||
|
};
|
||||||
|
export type postAuthPasswordResetResponseError = (postAuthPasswordResetResponse400 | postAuthPasswordResetResponse500) & {
|
||||||
|
headers: Headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type postAuthPasswordResetResponse = (postAuthPasswordResetResponseSuccess | postAuthPasswordResetResponseError)
|
||||||
|
|
||||||
|
export const getPostAuthPasswordResetUrl = () => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return `/auth/password/reset`
|
||||||
|
}
|
||||||
|
|
||||||
|
export const postAuthPasswordReset = async (internalHandlersResetPasswordRequest: InternalHandlersResetPasswordRequest, options?: RequestInit): Promise<postAuthPasswordResetResponse> => {
|
||||||
|
|
||||||
|
return vezaMutator<postAuthPasswordResetResponse>(getPostAuthPasswordResetUrl(),
|
||||||
|
{
|
||||||
|
...options,
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json', ...options?.headers },
|
||||||
|
body: JSON.stringify(
|
||||||
|
internalHandlersResetPasswordRequest,)
|
||||||
|
}
|
||||||
|
);}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const getPostAuthPasswordResetMutationOptions = <TError = InternalHandlersAPIResponse,
|
||||||
|
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof postAuthPasswordReset>>, TError,{data: InternalHandlersResetPasswordRequest}, TContext>, request?: SecondParameter<typeof vezaMutator>}
|
||||||
|
): UseMutationOptions<Awaited<ReturnType<typeof postAuthPasswordReset>>, TError,{data: InternalHandlersResetPasswordRequest}, TContext> => {
|
||||||
|
|
||||||
|
const mutationKey = ['postAuthPasswordReset'];
|
||||||
|
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||||
|
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||||
|
options
|
||||||
|
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||||
|
: {mutation: { mutationKey, }, request: undefined};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const mutationFn: MutationFunction<Awaited<ReturnType<typeof postAuthPasswordReset>>, {data: InternalHandlersResetPasswordRequest}> = (props) => {
|
||||||
|
const {data} = props ?? {};
|
||||||
|
|
||||||
|
return postAuthPasswordReset(data,requestOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return { mutationFn, ...mutationOptions }}
|
||||||
|
|
||||||
|
export type PostAuthPasswordResetMutationResult = NonNullable<Awaited<ReturnType<typeof postAuthPasswordReset>>>
|
||||||
|
export type PostAuthPasswordResetMutationBody = InternalHandlersResetPasswordRequest
|
||||||
|
export type PostAuthPasswordResetMutationError = InternalHandlersAPIResponse
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Reset password with token
|
||||||
|
*/
|
||||||
|
export const usePostAuthPasswordReset = <TError = InternalHandlersAPIResponse,
|
||||||
|
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof postAuthPasswordReset>>, TError,{data: InternalHandlersResetPasswordRequest}, TContext>, request?: SecondParameter<typeof vezaMutator>}
|
||||||
|
, queryClient?: QueryClient): UseMutationResult<
|
||||||
|
Awaited<ReturnType<typeof postAuthPasswordReset>>,
|
||||||
|
TError,
|
||||||
|
{data: InternalHandlersResetPasswordRequest},
|
||||||
|
TContext
|
||||||
|
> => {
|
||||||
|
return useMutation(getPostAuthPasswordResetMutationOptions(options), queryClient);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sends a password reset link to the user's email if the address exists. Always returns 200 with a generic message to prevent email enumeration.
|
||||||
|
* @summary Request password reset
|
||||||
|
*/
|
||||||
|
export type postAuthPasswordResetRequestResponse200 = {
|
||||||
|
data: PostAuthPasswordResetRequest200
|
||||||
|
status: 200
|
||||||
|
}
|
||||||
|
|
||||||
|
export type postAuthPasswordResetRequestResponse400 = {
|
||||||
|
data: InternalHandlersAPIResponse
|
||||||
|
status: 400
|
||||||
|
}
|
||||||
|
|
||||||
|
export type postAuthPasswordResetRequestResponse500 = {
|
||||||
|
data: InternalHandlersAPIResponse
|
||||||
|
status: 500
|
||||||
|
}
|
||||||
|
|
||||||
|
export type postAuthPasswordResetRequestResponseSuccess = (postAuthPasswordResetRequestResponse200) & {
|
||||||
|
headers: Headers;
|
||||||
|
};
|
||||||
|
export type postAuthPasswordResetRequestResponseError = (postAuthPasswordResetRequestResponse400 | postAuthPasswordResetRequestResponse500) & {
|
||||||
|
headers: Headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type postAuthPasswordResetRequestResponse = (postAuthPasswordResetRequestResponseSuccess | postAuthPasswordResetRequestResponseError)
|
||||||
|
|
||||||
|
export const getPostAuthPasswordResetRequestUrl = () => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return `/auth/password/reset-request`
|
||||||
|
}
|
||||||
|
|
||||||
|
export const postAuthPasswordResetRequest = async (internalHandlersRequestPasswordResetRequest: InternalHandlersRequestPasswordResetRequest, options?: RequestInit): Promise<postAuthPasswordResetRequestResponse> => {
|
||||||
|
|
||||||
|
return vezaMutator<postAuthPasswordResetRequestResponse>(getPostAuthPasswordResetRequestUrl(),
|
||||||
|
{
|
||||||
|
...options,
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json', ...options?.headers },
|
||||||
|
body: JSON.stringify(
|
||||||
|
internalHandlersRequestPasswordResetRequest,)
|
||||||
|
}
|
||||||
|
);}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const getPostAuthPasswordResetRequestMutationOptions = <TError = InternalHandlersAPIResponse,
|
||||||
|
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof postAuthPasswordResetRequest>>, TError,{data: InternalHandlersRequestPasswordResetRequest}, TContext>, request?: SecondParameter<typeof vezaMutator>}
|
||||||
|
): UseMutationOptions<Awaited<ReturnType<typeof postAuthPasswordResetRequest>>, TError,{data: InternalHandlersRequestPasswordResetRequest}, TContext> => {
|
||||||
|
|
||||||
|
const mutationKey = ['postAuthPasswordResetRequest'];
|
||||||
|
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||||
|
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||||
|
options
|
||||||
|
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||||
|
: {mutation: { mutationKey, }, request: undefined};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const mutationFn: MutationFunction<Awaited<ReturnType<typeof postAuthPasswordResetRequest>>, {data: InternalHandlersRequestPasswordResetRequest}> = (props) => {
|
||||||
|
const {data} = props ?? {};
|
||||||
|
|
||||||
|
return postAuthPasswordResetRequest(data,requestOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return { mutationFn, ...mutationOptions }}
|
||||||
|
|
||||||
|
export type PostAuthPasswordResetRequestMutationResult = NonNullable<Awaited<ReturnType<typeof postAuthPasswordResetRequest>>>
|
||||||
|
export type PostAuthPasswordResetRequestMutationBody = InternalHandlersRequestPasswordResetRequest
|
||||||
|
export type PostAuthPasswordResetRequestMutationError = InternalHandlersAPIResponse
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Request password reset
|
||||||
|
*/
|
||||||
|
export const usePostAuthPasswordResetRequest = <TError = InternalHandlersAPIResponse,
|
||||||
|
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof postAuthPasswordResetRequest>>, TError,{data: InternalHandlersRequestPasswordResetRequest}, TContext>, request?: SecondParameter<typeof vezaMutator>}
|
||||||
|
, queryClient?: QueryClient): UseMutationResult<
|
||||||
|
Awaited<ReturnType<typeof postAuthPasswordResetRequest>>,
|
||||||
|
TError,
|
||||||
|
{data: InternalHandlersRequestPasswordResetRequest},
|
||||||
|
TContext
|
||||||
|
> => {
|
||||||
|
return useMutation(getPostAuthPasswordResetRequestMutationOptions(options), queryClient);
|
||||||
|
}
|
||||||
|
/**
|
||||||
* Get a new access token using a refresh token
|
* Get a new access token using a refresh token
|
||||||
* @summary Refresh Token
|
* @summary Refresh Token
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
13
apps/web/src/services/generated/model/deleteQueue200.ts
Normal file
13
apps/web/src/services/generated/model/deleteQueue200.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { DeleteQueue200Data } from './deleteQueue200Data';
|
||||||
|
import type { InternalHandlersAPIResponse } from './internalHandlersAPIResponse';
|
||||||
|
|
||||||
|
export type DeleteQueue200 = InternalHandlersAPIResponse & {
|
||||||
|
data?: DeleteQueue200Data;
|
||||||
|
};
|
||||||
11
apps/web/src/services/generated/model/deleteQueue200Data.ts
Normal file
11
apps/web/src/services/generated/model/deleteQueue200Data.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type DeleteQueue200Data = {
|
||||||
|
message?: string;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { DeleteQueueItemsId200Data } from './deleteQueueItemsId200Data';
|
||||||
|
import type { InternalHandlersAPIResponse } from './internalHandlersAPIResponse';
|
||||||
|
|
||||||
|
export type DeleteQueueItemsId200 = InternalHandlersAPIResponse & {
|
||||||
|
data?: DeleteQueueItemsId200Data;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type DeleteQueueItemsId200Data = {
|
||||||
|
message?: string;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { DeleteQueueSessionToken200Data } from './deleteQueueSessionToken200Data';
|
||||||
|
import type { InternalHandlersAPIResponse } from './internalHandlersAPIResponse';
|
||||||
|
|
||||||
|
export type DeleteQueueSessionToken200 = InternalHandlersAPIResponse & {
|
||||||
|
data?: DeleteQueueSessionToken200Data;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type DeleteQueueSessionToken200Data = {
|
||||||
|
message?: string;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { DeleteQueueSessionTokenItemsId200Data } from './deleteQueueSessionTokenItemsId200Data';
|
||||||
|
import type { InternalHandlersAPIResponse } from './internalHandlersAPIResponse';
|
||||||
|
|
||||||
|
export type DeleteQueueSessionTokenItemsId200 = InternalHandlersAPIResponse & {
|
||||||
|
data?: DeleteQueueSessionTokenItemsId200Data;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type DeleteQueueSessionTokenItemsId200Data = {
|
||||||
|
message?: string;
|
||||||
|
};
|
||||||
13
apps/web/src/services/generated/model/getQueue200.ts
Normal file
13
apps/web/src/services/generated/model/getQueue200.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { GetQueue200Data } from './getQueue200Data';
|
||||||
|
import type { InternalHandlersAPIResponse } from './internalHandlersAPIResponse';
|
||||||
|
|
||||||
|
export type GetQueue200 = InternalHandlersAPIResponse & {
|
||||||
|
data?: GetQueue200Data;
|
||||||
|
};
|
||||||
14
apps/web/src/services/generated/model/getQueue200Data.ts
Normal file
14
apps/web/src/services/generated/model/getQueue200Data.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { GetQueue200DataItemsItem } from './getQueue200DataItemsItem';
|
||||||
|
import type { GetQueue200DataQueue } from './getQueue200DataQueue';
|
||||||
|
|
||||||
|
export type GetQueue200Data = {
|
||||||
|
items?: GetQueue200DataItemsItem[];
|
||||||
|
queue?: GetQueue200DataQueue;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type GetQueue200DataItemsItem = { [key: string]: unknown };
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type GetQueue200DataQueue = { [key: string]: unknown };
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { GetQueueSessionToken200Data } from './getQueueSessionToken200Data';
|
||||||
|
import type { InternalHandlersAPIResponse } from './internalHandlersAPIResponse';
|
||||||
|
|
||||||
|
export type GetQueueSessionToken200 = InternalHandlersAPIResponse & {
|
||||||
|
data?: GetQueueSessionToken200Data;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { GetQueueSessionToken200DataItemsItem } from './getQueueSessionToken200DataItemsItem';
|
||||||
|
import type { GetQueueSessionToken200DataSession } from './getQueueSessionToken200DataSession';
|
||||||
|
|
||||||
|
export type GetQueueSessionToken200Data = {
|
||||||
|
items?: GetQueueSessionToken200DataItemsItem[];
|
||||||
|
session?: GetQueueSessionToken200DataSession;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type GetQueueSessionToken200DataItemsItem = { [key: string]: unknown };
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type GetQueueSessionToken200DataSession = { [key: string]: unknown };
|
||||||
|
|
@ -12,6 +12,14 @@ export * from './deletePlaylistsIdCollaboratorsUserId200';
|
||||||
export * from './deletePlaylistsIdCollaboratorsUserId200Data';
|
export * from './deletePlaylistsIdCollaboratorsUserId200Data';
|
||||||
export * from './deletePlaylistsIdTracksTrackId200';
|
export * from './deletePlaylistsIdTracksTrackId200';
|
||||||
export * from './deletePlaylistsIdTracksTrackId200Data';
|
export * from './deletePlaylistsIdTracksTrackId200Data';
|
||||||
|
export * from './deleteQueue200';
|
||||||
|
export * from './deleteQueue200Data';
|
||||||
|
export * from './deleteQueueItemsId200';
|
||||||
|
export * from './deleteQueueItemsId200Data';
|
||||||
|
export * from './deleteQueueSessionToken200';
|
||||||
|
export * from './deleteQueueSessionToken200Data';
|
||||||
|
export * from './deleteQueueSessionTokenItemsId200';
|
||||||
|
export * from './deleteQueueSessionTokenItemsId200Data';
|
||||||
export * from './deleteTracksId200';
|
export * from './deleteTracksId200';
|
||||||
export * from './deleteTracksId200Data';
|
export * from './deleteTracksId200Data';
|
||||||
export * from './deleteTracksIdCommentsCommentId200';
|
export * from './deleteTracksIdCommentsCommentId200';
|
||||||
|
|
@ -83,6 +91,14 @@ export * from './getPlaylistsSearch200DataPagination';
|
||||||
export * from './getPlaylistsSearchParams';
|
export * from './getPlaylistsSearchParams';
|
||||||
export * from './getPlaylistsSharedToken200';
|
export * from './getPlaylistsSharedToken200';
|
||||||
export * from './getPlaylistsSharedToken200Data';
|
export * from './getPlaylistsSharedToken200Data';
|
||||||
|
export * from './getQueue200';
|
||||||
|
export * from './getQueue200Data';
|
||||||
|
export * from './getQueue200DataItemsItem';
|
||||||
|
export * from './getQueue200DataQueue';
|
||||||
|
export * from './getQueueSessionToken200';
|
||||||
|
export * from './getQueueSessionToken200Data';
|
||||||
|
export * from './getQueueSessionToken200DataItemsItem';
|
||||||
|
export * from './getQueueSessionToken200DataSession';
|
||||||
export * from './getTracks200';
|
export * from './getTracks200';
|
||||||
export * from './getTracks200Data';
|
export * from './getTracks200Data';
|
||||||
export * from './getTracks200DataPagination';
|
export * from './getTracks200DataPagination';
|
||||||
|
|
@ -174,6 +190,8 @@ export * from './internalCoreTrackUpdateLyricsRequest';
|
||||||
export * from './internalCoreTrackUpdateTrackRequest';
|
export * from './internalCoreTrackUpdateTrackRequest';
|
||||||
export * from './internalHandlersAddCollaboratorRequest';
|
export * from './internalHandlersAddCollaboratorRequest';
|
||||||
export * from './internalHandlersAddCollaboratorRequestPermission';
|
export * from './internalHandlersAddCollaboratorRequestPermission';
|
||||||
|
export * from './internalHandlersAddQueueItemRequest';
|
||||||
|
export * from './internalHandlersAddToSessionRequest';
|
||||||
export * from './internalHandlersAPIResponse';
|
export * from './internalHandlersAPIResponse';
|
||||||
export * from './internalHandlersCreateCommentRequest';
|
export * from './internalHandlersCreateCommentRequest';
|
||||||
export * from './internalHandlersCreateOrderRequest';
|
export * from './internalHandlersCreateOrderRequest';
|
||||||
|
|
@ -198,6 +216,8 @@ export * from './internalHandlersLibraryPreview';
|
||||||
export * from './internalHandlersRecentActivity';
|
export * from './internalHandlersRecentActivity';
|
||||||
export * from './internalHandlersRecentActivityMetadata';
|
export * from './internalHandlersRecentActivityMetadata';
|
||||||
export * from './internalHandlersReorderTracksRequest';
|
export * from './internalHandlersReorderTracksRequest';
|
||||||
|
export * from './internalHandlersRequestPasswordResetRequest';
|
||||||
|
export * from './internalHandlersResetPasswordRequest';
|
||||||
export * from './internalHandlersSetupTwoFactorResponse';
|
export * from './internalHandlersSetupTwoFactorResponse';
|
||||||
export * from './internalHandlersStreamTokenResponse';
|
export * from './internalHandlersStreamTokenResponse';
|
||||||
export * from './internalHandlersTrackPreview';
|
export * from './internalHandlersTrackPreview';
|
||||||
|
|
@ -224,6 +244,10 @@ export * from './postAuth2faSetup200';
|
||||||
export * from './postAuth2faVerify200';
|
export * from './postAuth2faVerify200';
|
||||||
export * from './postAuth2faVerify200Data';
|
export * from './postAuth2faVerify200Data';
|
||||||
export * from './postAuthLogoutBody';
|
export * from './postAuthLogoutBody';
|
||||||
|
export * from './postAuthPasswordReset200';
|
||||||
|
export * from './postAuthPasswordReset200Data';
|
||||||
|
export * from './postAuthPasswordResetRequest200';
|
||||||
|
export * from './postAuthPasswordResetRequest200Data';
|
||||||
export * from './postAuthVerifyEmailParams';
|
export * from './postAuthVerifyEmailParams';
|
||||||
export * from './postInternalTracksIdStreamReady200';
|
export * from './postInternalTracksIdStreamReady200';
|
||||||
export * from './postPlaylists201';
|
export * from './postPlaylists201';
|
||||||
|
|
@ -241,6 +265,16 @@ export * from './postPlaylistsIdTracks200Data';
|
||||||
export * from './postPlaylistsIdTracksBody';
|
export * from './postPlaylistsIdTracksBody';
|
||||||
export * from './postPlaylistsImport201';
|
export * from './postPlaylistsImport201';
|
||||||
export * from './postPlaylistsImport201Data';
|
export * from './postPlaylistsImport201Data';
|
||||||
|
export * from './postQueueItems201';
|
||||||
|
export * from './postQueueItems201Data';
|
||||||
|
export * from './postQueueItems201DataItem';
|
||||||
|
export * from './postQueueSession201';
|
||||||
|
export * from './postQueueSession201Data';
|
||||||
|
export * from './postQueueSession201DataSession';
|
||||||
|
export * from './postQueueSessionTokenItems201';
|
||||||
|
export * from './postQueueSessionTokenItems201Data';
|
||||||
|
export * from './postQueueSessionTokenItems201DataItemsItem';
|
||||||
|
export * from './postQueueSessionTokenItems201DataSession';
|
||||||
export * from './postTracks201';
|
export * from './postTracks201';
|
||||||
export * from './postTracks201Data';
|
export * from './postTracks201Data';
|
||||||
export * from './postTracksBatchDelete200';
|
export * from './postTracksBatchDelete200';
|
||||||
|
|
@ -296,6 +330,10 @@ export * from './putPlaylistsIdCollaboratorsUserId200Data';
|
||||||
export * from './putPlaylistsIdCollaboratorsUserId200DataCollaborator';
|
export * from './putPlaylistsIdCollaboratorsUserId200DataCollaborator';
|
||||||
export * from './putPlaylistsIdTracksReorder200';
|
export * from './putPlaylistsIdTracksReorder200';
|
||||||
export * from './putPlaylistsIdTracksReorder200Data';
|
export * from './putPlaylistsIdTracksReorder200Data';
|
||||||
|
export * from './putQueue200';
|
||||||
|
export * from './putQueue200Data';
|
||||||
|
export * from './putQueue200DataItemsItem';
|
||||||
|
export * from './putQueue200DataQueue';
|
||||||
export * from './putTracksId200';
|
export * from './putTracksId200';
|
||||||
export * from './putTracksId200Data';
|
export * from './putTracksId200Data';
|
||||||
export * from './putTracksIdLyrics200';
|
export * from './putTracksIdLyrics200';
|
||||||
|
|
@ -330,3 +368,4 @@ export * from './vezaBackendApiInternalModelsTrack';
|
||||||
export * from './vezaBackendApiInternalModelsTrackStatus';
|
export * from './vezaBackendApiInternalModelsTrackStatus';
|
||||||
export * from './vezaBackendApiInternalModelsUser';
|
export * from './vezaBackendApiInternalModelsUser';
|
||||||
export * from './vezaBackendApiInternalResponseAPIResponse';
|
export * from './vezaBackendApiInternalResponseAPIResponse';
|
||||||
|
export * from './vezaBackendApiInternalServicesUpdateQueueRequest';
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface InternalHandlersAddQueueItemRequest {
|
||||||
|
track_id: string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface InternalHandlersAddToSessionRequest {
|
||||||
|
track_id: string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface InternalHandlersRequestPasswordResetRequest {
|
||||||
|
email: string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface InternalHandlersResetPasswordRequest {
|
||||||
|
/** @minLength 12 */
|
||||||
|
new_password: string;
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { InternalHandlersAPIResponse } from './internalHandlersAPIResponse';
|
||||||
|
import type { PostAuthPasswordReset200Data } from './postAuthPasswordReset200Data';
|
||||||
|
|
||||||
|
export type PostAuthPasswordReset200 = InternalHandlersAPIResponse & {
|
||||||
|
data?: PostAuthPasswordReset200Data;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type PostAuthPasswordReset200Data = {
|
||||||
|
message?: string;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { InternalHandlersAPIResponse } from './internalHandlersAPIResponse';
|
||||||
|
import type { PostAuthPasswordResetRequest200Data } from './postAuthPasswordResetRequest200Data';
|
||||||
|
|
||||||
|
export type PostAuthPasswordResetRequest200 = InternalHandlersAPIResponse & {
|
||||||
|
data?: PostAuthPasswordResetRequest200Data;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type PostAuthPasswordResetRequest200Data = {
|
||||||
|
message?: string;
|
||||||
|
};
|
||||||
13
apps/web/src/services/generated/model/postQueueItems201.ts
Normal file
13
apps/web/src/services/generated/model/postQueueItems201.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { InternalHandlersAPIResponse } from './internalHandlersAPIResponse';
|
||||||
|
import type { PostQueueItems201Data } from './postQueueItems201Data';
|
||||||
|
|
||||||
|
export type PostQueueItems201 = InternalHandlersAPIResponse & {
|
||||||
|
data?: PostQueueItems201Data;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { PostQueueItems201DataItem } from './postQueueItems201DataItem';
|
||||||
|
|
||||||
|
export type PostQueueItems201Data = {
|
||||||
|
item?: PostQueueItems201DataItem;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type PostQueueItems201DataItem = { [key: string]: unknown };
|
||||||
13
apps/web/src/services/generated/model/postQueueSession201.ts
Normal file
13
apps/web/src/services/generated/model/postQueueSession201.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { InternalHandlersAPIResponse } from './internalHandlersAPIResponse';
|
||||||
|
import type { PostQueueSession201Data } from './postQueueSession201Data';
|
||||||
|
|
||||||
|
export type PostQueueSession201 = InternalHandlersAPIResponse & {
|
||||||
|
data?: PostQueueSession201Data;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { PostQueueSession201DataSession } from './postQueueSession201DataSession';
|
||||||
|
|
||||||
|
export type PostQueueSession201Data = {
|
||||||
|
session?: PostQueueSession201DataSession;
|
||||||
|
share_token?: string;
|
||||||
|
share_url?: string;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type PostQueueSession201DataSession = { [key: string]: unknown };
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { InternalHandlersAPIResponse } from './internalHandlersAPIResponse';
|
||||||
|
import type { PostQueueSessionTokenItems201Data } from './postQueueSessionTokenItems201Data';
|
||||||
|
|
||||||
|
export type PostQueueSessionTokenItems201 = InternalHandlersAPIResponse & {
|
||||||
|
data?: PostQueueSessionTokenItems201Data;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { PostQueueSessionTokenItems201DataItemsItem } from './postQueueSessionTokenItems201DataItemsItem';
|
||||||
|
import type { PostQueueSessionTokenItems201DataSession } from './postQueueSessionTokenItems201DataSession';
|
||||||
|
|
||||||
|
export type PostQueueSessionTokenItems201Data = {
|
||||||
|
items?: PostQueueSessionTokenItems201DataItemsItem[];
|
||||||
|
session?: PostQueueSessionTokenItems201DataSession;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type PostQueueSessionTokenItems201DataItemsItem = { [key: string]: unknown };
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type PostQueueSessionTokenItems201DataSession = { [key: string]: unknown };
|
||||||
13
apps/web/src/services/generated/model/putQueue200.ts
Normal file
13
apps/web/src/services/generated/model/putQueue200.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { InternalHandlersAPIResponse } from './internalHandlersAPIResponse';
|
||||||
|
import type { PutQueue200Data } from './putQueue200Data';
|
||||||
|
|
||||||
|
export type PutQueue200 = InternalHandlersAPIResponse & {
|
||||||
|
data?: PutQueue200Data;
|
||||||
|
};
|
||||||
14
apps/web/src/services/generated/model/putQueue200Data.ts
Normal file
14
apps/web/src/services/generated/model/putQueue200Data.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
import type { PutQueue200DataItemsItem } from './putQueue200DataItemsItem';
|
||||||
|
import type { PutQueue200DataQueue } from './putQueue200DataQueue';
|
||||||
|
|
||||||
|
export type PutQueue200Data = {
|
||||||
|
items?: PutQueue200DataItemsItem[];
|
||||||
|
queue?: PutQueue200DataQueue;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type PutQueue200DataItemsItem = { [key: string]: unknown };
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type PutQueue200DataQueue = { [key: string]: unknown };
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v8.8.1 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* Veza Backend API
|
||||||
|
* Backend API for Veza platform.
|
||||||
|
* OpenAPI spec version: 1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface VezaBackendApiInternalServicesUpdateQueueRequest {
|
||||||
|
current_position?: number;
|
||||||
|
current_track_id?: string;
|
||||||
|
is_playing?: boolean;
|
||||||
|
item_order?: string[];
|
||||||
|
repeat_mode?: string;
|
||||||
|
shuffle?: boolean;
|
||||||
|
volume?: number;
|
||||||
|
}
|
||||||
1098
apps/web/src/services/generated/queue/queue.ts
Normal file
1098
apps/web/src/services/generated/queue/queue.ts
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1313,6 +1313,132 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/auth/password/reset": {
|
||||||
|
"post": {
|
||||||
|
"description": "Completes a password reset using a valid token previously emailed to the user. Invalidates all the user's existing sessions on success.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Reset password with token",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Reset token + new password",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.ResetPasswordRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Password reset successfully",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid or expired token, or password validation failed",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Failed to update password",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/auth/password/reset-request": {
|
||||||
|
"post": {
|
||||||
|
"description": "Sends a password reset link to the user's email if the address exists. Always returns 200 with a generic message to prevent email enumeration.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Request password reset",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Email of the account to reset",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.RequestPasswordResetRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "If the email exists, a reset link has been sent",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Validation error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Token generation/storage failed (or SMTP failure in production)",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/auth/refresh": {
|
"/auth/refresh": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Get a new access token using a refresh token",
|
"description": "Get a new access token using a refresh token",
|
||||||
|
|
@ -3345,6 +3471,726 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/queue": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Returns the authenticated user's persistent playback queue with all items in position order",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Get user playback queue",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Queue + items",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"queue": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Updates the authenticated user's queue state (current track / position / playback flags / item order)",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Update user playback queue",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Queue update payload",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/veza-backend-api_internal_services.UpdateQueueRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Updated queue",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"queue": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Validation error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Removes every item from the authenticated user's playback queue",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Clear queue",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Queue cleared",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/queue/items": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Appends a track to the authenticated user's playback queue",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Add track to queue",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Track to enqueue",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.AddQueueItemRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "Created queue item",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"item": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Validation error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/queue/items/{id}": {
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Removes a single item from the authenticated user's playback queue by item ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Remove queue item",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Queue item ID (UUID)",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Item removed",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid item ID",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Queue item not found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/queue/session": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Creates a shared queue session and returns its share token + URL. The session creator is recorded as host.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Create collaborative queue session",
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "Created session",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"session": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"share_token": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"share_url": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/queue/session/{token}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Returns the session metadata + items for a given share token. No auth required (public — anyone with the link can join).",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Get queue session by share token",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Session share token",
|
||||||
|
"name": "token",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Session and queue items",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"session": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Token required",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Session not found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Deletes a collaborative queue session. Only the original session creator can delete.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Delete queue session",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Session share token",
|
||||||
|
"name": "token",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Session deleted",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Token required",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Only the creator can delete this session",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Session not found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/queue/session/{token}/items": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Adds a track to a collaborative queue session. Anyone with the share token can add.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Add track to queue session",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Session share token",
|
||||||
|
"name": "token",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Track to enqueue",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.AddToSessionRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "Updated session and items",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"session": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Validation error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Session not found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/queue/session/{token}/items/{id}": {
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Removes an item from a collaborative queue session by item ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Remove item from queue session",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Session share token",
|
||||||
|
"name": "token",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Queue item ID (UUID)",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Item removed",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Validation error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Session or item not found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/tracks": {
|
"/tracks": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "List tracks with pagination, filters, sort. Cursor-based when ?cursor provided, otherwise page/limit offset.",
|
"description": "List tracks with pagination, filters, sort. Cursor-based when ?cursor provided, otherwise page/limit offset.",
|
||||||
|
|
@ -8003,6 +8849,28 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"internal_handlers.AddQueueItemRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"track_id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"track_id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"internal_handlers.AddToSessionRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"track_id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"track_id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"internal_handlers.CreateCommentRequest": {
|
"internal_handlers.CreateCommentRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
|
@ -8352,6 +9220,33 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"internal_handlers.RequestPasswordResetRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"email"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"internal_handlers.ResetPasswordRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"new_password",
|
||||||
|
"token"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"new_password": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 12
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"internal_handlers.SetupTwoFactorResponse": {
|
"internal_handlers.SetupTwoFactorResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
@ -9348,6 +10243,35 @@ const docTemplate = `{
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"veza-backend-api_internal_services.UpdateQueueRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"current_position": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"current_track_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"is_playing": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"item_order": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"repeat_mode": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"shuffle": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"volume": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"securityDefinitions": {
|
"securityDefinitions": {
|
||||||
|
|
|
||||||
|
|
@ -1307,6 +1307,132 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/auth/password/reset": {
|
||||||
|
"post": {
|
||||||
|
"description": "Completes a password reset using a valid token previously emailed to the user. Invalidates all the user's existing sessions on success.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Reset password with token",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Reset token + new password",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.ResetPasswordRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Password reset successfully",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid or expired token, or password validation failed",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Failed to update password",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/auth/password/reset-request": {
|
||||||
|
"post": {
|
||||||
|
"description": "Sends a password reset link to the user's email if the address exists. Always returns 200 with a generic message to prevent email enumeration.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Request password reset",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Email of the account to reset",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.RequestPasswordResetRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "If the email exists, a reset link has been sent",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Validation error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Token generation/storage failed (or SMTP failure in production)",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/auth/refresh": {
|
"/auth/refresh": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Get a new access token using a refresh token",
|
"description": "Get a new access token using a refresh token",
|
||||||
|
|
@ -3339,6 +3465,726 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/queue": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Returns the authenticated user's persistent playback queue with all items in position order",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Get user playback queue",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Queue + items",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"queue": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Updates the authenticated user's queue state (current track / position / playback flags / item order)",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Update user playback queue",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Queue update payload",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/veza-backend-api_internal_services.UpdateQueueRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Updated queue",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"queue": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Validation error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Removes every item from the authenticated user's playback queue",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Clear queue",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Queue cleared",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/queue/items": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Appends a track to the authenticated user's playback queue",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Add track to queue",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Track to enqueue",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.AddQueueItemRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "Created queue item",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"item": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Validation error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/queue/items/{id}": {
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Removes a single item from the authenticated user's playback queue by item ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Remove queue item",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Queue item ID (UUID)",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Item removed",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid item ID",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Queue item not found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/queue/session": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Creates a shared queue session and returns its share token + URL. The session creator is recorded as host.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Create collaborative queue session",
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "Created session",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"session": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"share_token": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"share_url": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/queue/session/{token}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Returns the session metadata + items for a given share token. No auth required (public — anyone with the link can join).",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Get queue session by share token",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Session share token",
|
||||||
|
"name": "token",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Session and queue items",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"session": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Token required",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Session not found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Deletes a collaborative queue session. Only the original session creator can delete.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Delete queue session",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Session share token",
|
||||||
|
"name": "token",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Session deleted",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Token required",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Only the creator can delete this session",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Session not found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/queue/session/{token}/items": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Adds a track to a collaborative queue session. Anyone with the share token can add.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Add track to queue session",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Session share token",
|
||||||
|
"name": "token",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Track to enqueue",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.AddToSessionRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "Updated session and items",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"session": {
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Validation error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Session not found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/queue/session/{token}/items/{id}": {
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Removes an item from a collaborative queue session by item ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Queue"
|
||||||
|
],
|
||||||
|
"summary": "Remove item from queue session",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Session share token",
|
||||||
|
"name": "token",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Queue item ID (UUID)",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Item removed",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Validation error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Session or item not found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/internal_handlers.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/tracks": {
|
"/tracks": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "List tracks with pagination, filters, sort. Cursor-based when ?cursor provided, otherwise page/limit offset.",
|
"description": "List tracks with pagination, filters, sort. Cursor-based when ?cursor provided, otherwise page/limit offset.",
|
||||||
|
|
@ -7997,6 +8843,28 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"internal_handlers.AddQueueItemRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"track_id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"track_id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"internal_handlers.AddToSessionRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"track_id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"track_id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"internal_handlers.CreateCommentRequest": {
|
"internal_handlers.CreateCommentRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
|
@ -8346,6 +9214,33 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"internal_handlers.RequestPasswordResetRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"email"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"internal_handlers.ResetPasswordRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"new_password",
|
||||||
|
"token"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"new_password": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 12
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"internal_handlers.SetupTwoFactorResponse": {
|
"internal_handlers.SetupTwoFactorResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
@ -9342,6 +10237,35 @@
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"veza-backend-api_internal_services.UpdateQueueRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"current_position": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"current_track_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"is_playing": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"item_order": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"repeat_mode": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"shuffle": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"volume": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"securityDefinitions": {
|
"securityDefinitions": {
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,20 @@ definitions:
|
||||||
- permission
|
- permission
|
||||||
- user_id
|
- user_id
|
||||||
type: object
|
type: object
|
||||||
|
internal_handlers.AddQueueItemRequest:
|
||||||
|
properties:
|
||||||
|
track_id:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- track_id
|
||||||
|
type: object
|
||||||
|
internal_handlers.AddToSessionRequest:
|
||||||
|
properties:
|
||||||
|
track_id:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- track_id
|
||||||
|
type: object
|
||||||
internal_handlers.CreateCommentRequest:
|
internal_handlers.CreateCommentRequest:
|
||||||
properties:
|
properties:
|
||||||
content:
|
content:
|
||||||
|
|
@ -387,6 +401,24 @@ definitions:
|
||||||
required:
|
required:
|
||||||
- track_ids
|
- track_ids
|
||||||
type: object
|
type: object
|
||||||
|
internal_handlers.RequestPasswordResetRequest:
|
||||||
|
properties:
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- email
|
||||||
|
type: object
|
||||||
|
internal_handlers.ResetPasswordRequest:
|
||||||
|
properties:
|
||||||
|
new_password:
|
||||||
|
minLength: 12
|
||||||
|
type: string
|
||||||
|
token:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- new_password
|
||||||
|
- token
|
||||||
|
type: object
|
||||||
internal_handlers.SetupTwoFactorResponse:
|
internal_handlers.SetupTwoFactorResponse:
|
||||||
properties:
|
properties:
|
||||||
qr_code_url:
|
qr_code_url:
|
||||||
|
|
@ -1075,6 +1107,25 @@ definitions:
|
||||||
success:
|
success:
|
||||||
type: boolean
|
type: boolean
|
||||||
type: object
|
type: object
|
||||||
|
veza-backend-api_internal_services.UpdateQueueRequest:
|
||||||
|
properties:
|
||||||
|
current_position:
|
||||||
|
type: integer
|
||||||
|
current_track_id:
|
||||||
|
type: string
|
||||||
|
is_playing:
|
||||||
|
type: boolean
|
||||||
|
item_order:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
repeat_mode:
|
||||||
|
type: string
|
||||||
|
shuffle:
|
||||||
|
type: boolean
|
||||||
|
volume:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
host: localhost:18080
|
host: localhost:18080
|
||||||
info:
|
info:
|
||||||
contact:
|
contact:
|
||||||
|
|
@ -1886,6 +1937,84 @@ paths:
|
||||||
summary: Get Current User
|
summary: Get Current User
|
||||||
tags:
|
tags:
|
||||||
- Auth
|
- Auth
|
||||||
|
/auth/password/reset:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Completes a password reset using a valid token previously emailed
|
||||||
|
to the user. Invalidates all the user's existing sessions on success.
|
||||||
|
parameters:
|
||||||
|
- description: Reset token + new password
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.ResetPasswordRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Password reset successfully
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Invalid or expired token, or password validation failed
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Failed to update password
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
summary: Reset password with token
|
||||||
|
tags:
|
||||||
|
- Auth
|
||||||
|
/auth/password/reset-request:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Sends a password reset link to the user's email if the address
|
||||||
|
exists. Always returns 200 with a generic message to prevent email enumeration.
|
||||||
|
parameters:
|
||||||
|
- description: Email of the account to reset
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.RequestPasswordResetRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: If the email exists, a reset link has been sent
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Validation error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Token generation/storage failed (or SMTP failure in production)
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
summary: Request password reset
|
||||||
|
tags:
|
||||||
|
- Auth
|
||||||
/auth/refresh:
|
/auth/refresh:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
|
@ -3140,6 +3269,445 @@ paths:
|
||||||
summary: Get playlist by share token
|
summary: Get playlist by share token
|
||||||
tags:
|
tags:
|
||||||
- Playlist
|
- Playlist
|
||||||
|
/queue:
|
||||||
|
delete:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Removes every item from the authenticated user's playback queue
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Queue cleared
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Clear queue
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Returns the authenticated user's persistent playback queue with
|
||||||
|
all items in position order
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Queue + items
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
queue:
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Get user playback queue
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
put:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Updates the authenticated user's queue state (current track / position
|
||||||
|
/ playback flags / item order)
|
||||||
|
parameters:
|
||||||
|
- description: Queue update payload
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/veza-backend-api_internal_services.UpdateQueueRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Updated queue
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
queue:
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Validation error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Update user playback queue
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/queue/items:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Appends a track to the authenticated user's playback queue
|
||||||
|
parameters:
|
||||||
|
- description: Track to enqueue
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.AddQueueItemRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Created queue item
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
item:
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Validation error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Add track to queue
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/queue/items/{id}:
|
||||||
|
delete:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Removes a single item from the authenticated user's playback queue
|
||||||
|
by item ID
|
||||||
|
parameters:
|
||||||
|
- description: Queue item ID (UUID)
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Item removed
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Invalid item ID
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"404":
|
||||||
|
description: Queue item not found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Remove queue item
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/queue/session:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Creates a shared queue session and returns its share token + URL.
|
||||||
|
The session creator is recorded as host.
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Created session
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
session:
|
||||||
|
type: object
|
||||||
|
share_token:
|
||||||
|
type: string
|
||||||
|
share_url:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Create collaborative queue session
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/queue/session/{token}:
|
||||||
|
delete:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Deletes a collaborative queue session. Only the original session
|
||||||
|
creator can delete.
|
||||||
|
parameters:
|
||||||
|
- description: Session share token
|
||||||
|
in: path
|
||||||
|
name: token
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Session deleted
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Token required
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"403":
|
||||||
|
description: Only the creator can delete this session
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"404":
|
||||||
|
description: Session not found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Delete queue session
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Returns the session metadata + items for a given share token. No
|
||||||
|
auth required (public — anyone with the link can join).
|
||||||
|
parameters:
|
||||||
|
- description: Session share token
|
||||||
|
in: path
|
||||||
|
name: token
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Session and queue items
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
session:
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Token required
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"404":
|
||||||
|
description: Session not found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
summary: Get queue session by share token
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/queue/session/{token}/items:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Adds a track to a collaborative queue session. Anyone with the
|
||||||
|
share token can add.
|
||||||
|
parameters:
|
||||||
|
- description: Session share token
|
||||||
|
in: path
|
||||||
|
name: token
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: Track to enqueue
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.AddToSessionRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Updated session and items
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
session:
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Validation error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"404":
|
||||||
|
description: Session not found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Add track to queue session
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/queue/session/{token}/items/{id}:
|
||||||
|
delete:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Removes an item from a collaborative queue session by item ID
|
||||||
|
parameters:
|
||||||
|
- description: Session share token
|
||||||
|
in: path
|
||||||
|
name: token
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: Queue item ID (UUID)
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Item removed
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Validation error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"404":
|
||||||
|
description: Session or item not found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Remove item from queue session
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
/tracks:
|
/tracks:
|
||||||
get:
|
get:
|
||||||
description: List tracks with pagination, filters, sort. Cursor-based when ?cursor
|
description: List tracks with pagination, filters, sort. Cursor-based when ?cursor
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,16 @@ type AuthServiceInterface interface {
|
||||||
// RequestPasswordReset handles password reset request
|
// RequestPasswordReset handles password reset request
|
||||||
// T0193: Creates endpoint POST /api/v1/auth/password/reset-request
|
// T0193: Creates endpoint POST /api/v1/auth/password/reset-request
|
||||||
// BE-SEC-013: Added audit logging for password reset requests
|
// BE-SEC-013: Added audit logging for password reset requests
|
||||||
|
// @Summary Request password reset
|
||||||
|
// @Description Sends a password reset link to the user's email if the address exists. Always returns 200 with a generic message to prevent email enumeration.
|
||||||
|
// @Tags Auth
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param request body RequestPasswordResetRequest true "Email of the account to reset"
|
||||||
|
// @Success 200 {object} APIResponse{data=object{message=string}} "If the email exists, a reset link has been sent"
|
||||||
|
// @Failure 400 {object} APIResponse "Validation error"
|
||||||
|
// @Failure 500 {object} APIResponse "Token generation/storage failed (or SMTP failure in production)"
|
||||||
|
// @Router /auth/password/reset-request [post]
|
||||||
func RequestPasswordReset(
|
func RequestPasswordReset(
|
||||||
passwordResetService *services.PasswordResetService,
|
passwordResetService *services.PasswordResetService,
|
||||||
passwordService *services.PasswordService,
|
passwordService *services.PasswordService,
|
||||||
|
|
@ -180,6 +190,16 @@ type ResetPasswordRequest struct {
|
||||||
// T0194: Creates endpoint POST /api/v1/auth/password/reset
|
// T0194: Creates endpoint POST /api/v1/auth/password/reset
|
||||||
// T0200: Uses AuthService.InvalidateAllUserSessions to invalidate sessions and update token_version
|
// T0200: Uses AuthService.InvalidateAllUserSessions to invalidate sessions and update token_version
|
||||||
// BE-SEC-013: Added audit logging for password reset completion
|
// BE-SEC-013: Added audit logging for password reset completion
|
||||||
|
// @Summary Reset password with token
|
||||||
|
// @Description Completes a password reset using a valid token previously emailed to the user. Invalidates all the user's existing sessions on success.
|
||||||
|
// @Tags Auth
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param request body ResetPasswordRequest true "Reset token + new password"
|
||||||
|
// @Success 200 {object} APIResponse{data=object{message=string}} "Password reset successfully"
|
||||||
|
// @Failure 400 {object} APIResponse "Invalid or expired token, or password validation failed"
|
||||||
|
// @Failure 500 {object} APIResponse "Failed to update password"
|
||||||
|
// @Router /auth/password/reset [post]
|
||||||
func ResetPassword(
|
func ResetPassword(
|
||||||
passwordResetService *services.PasswordResetService,
|
passwordResetService *services.PasswordResetService,
|
||||||
passwordService *services.PasswordService,
|
passwordService *services.PasswordService,
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,16 @@ func NewQueueHandler(queueService *services.QueueService, logger *zap.Logger) *Q
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetQueue returns the user's queue
|
// GetQueue returns the user's queue
|
||||||
|
// @Summary Get user playback queue
|
||||||
|
// @Description Returns the authenticated user's persistent playback queue with all items in position order
|
||||||
|
// @Tags Queue
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Success 200 {object} APIResponse{data=object{queue=object,items=[]object}} "Queue + items"
|
||||||
|
// @Failure 401 {object} APIResponse "Unauthorized"
|
||||||
|
// @Failure 500 {object} APIResponse "Internal Error"
|
||||||
|
// @Router /queue [get]
|
||||||
func (h *QueueHandler) GetQueue(c *gin.Context) {
|
func (h *QueueHandler) GetQueue(c *gin.Context) {
|
||||||
userID, ok := GetUserIDUUID(c)
|
userID, ok := GetUserIDUUID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -40,6 +50,18 @@ func (h *QueueHandler) GetQueue(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateQueue updates the user's queue
|
// UpdateQueue updates the user's queue
|
||||||
|
// @Summary Update user playback queue
|
||||||
|
// @Description Updates the authenticated user's queue state (current track / position / playback flags / item order)
|
||||||
|
// @Tags Queue
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Param request body services.UpdateQueueRequest true "Queue update payload"
|
||||||
|
// @Success 200 {object} APIResponse{data=object{queue=object,items=[]object}} "Updated queue"
|
||||||
|
// @Failure 400 {object} APIResponse "Validation error"
|
||||||
|
// @Failure 401 {object} APIResponse "Unauthorized"
|
||||||
|
// @Failure 500 {object} APIResponse "Internal Error"
|
||||||
|
// @Router /queue [put]
|
||||||
func (h *QueueHandler) UpdateQueue(c *gin.Context) {
|
func (h *QueueHandler) UpdateQueue(c *gin.Context) {
|
||||||
userID, ok := GetUserIDUUID(c)
|
userID, ok := GetUserIDUUID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -67,6 +89,18 @@ type AddQueueItemRequest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddQueueItem adds a track to the queue
|
// AddQueueItem adds a track to the queue
|
||||||
|
// @Summary Add track to queue
|
||||||
|
// @Description Appends a track to the authenticated user's playback queue
|
||||||
|
// @Tags Queue
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Param request body AddQueueItemRequest true "Track to enqueue"
|
||||||
|
// @Success 201 {object} APIResponse{data=object{item=object}} "Created queue item"
|
||||||
|
// @Failure 400 {object} APIResponse "Validation error"
|
||||||
|
// @Failure 401 {object} APIResponse "Unauthorized"
|
||||||
|
// @Failure 500 {object} APIResponse "Internal Error"
|
||||||
|
// @Router /queue/items [post]
|
||||||
func (h *QueueHandler) AddQueueItem(c *gin.Context) {
|
func (h *QueueHandler) AddQueueItem(c *gin.Context) {
|
||||||
userID, ok := GetUserIDUUID(c)
|
userID, ok := GetUserIDUUID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -86,6 +120,18 @@ func (h *QueueHandler) AddQueueItem(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveQueueItem removes an item from the queue
|
// RemoveQueueItem removes an item from the queue
|
||||||
|
// @Summary Remove queue item
|
||||||
|
// @Description Removes a single item from the authenticated user's playback queue by item ID
|
||||||
|
// @Tags Queue
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Param id path string true "Queue item ID (UUID)"
|
||||||
|
// @Success 200 {object} APIResponse{data=object{message=string}} "Item removed"
|
||||||
|
// @Failure 400 {object} APIResponse "Invalid item ID"
|
||||||
|
// @Failure 401 {object} APIResponse "Unauthorized"
|
||||||
|
// @Failure 404 {object} APIResponse "Queue item not found"
|
||||||
|
// @Router /queue/items/{id} [delete]
|
||||||
func (h *QueueHandler) RemoveQueueItem(c *gin.Context) {
|
func (h *QueueHandler) RemoveQueueItem(c *gin.Context) {
|
||||||
userID, ok := GetUserIDUUID(c)
|
userID, ok := GetUserIDUUID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -104,6 +150,16 @@ func (h *QueueHandler) RemoveQueueItem(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearQueue removes all items from the queue
|
// ClearQueue removes all items from the queue
|
||||||
|
// @Summary Clear queue
|
||||||
|
// @Description Removes every item from the authenticated user's playback queue
|
||||||
|
// @Tags Queue
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Success 200 {object} APIResponse{data=object{message=string}} "Queue cleared"
|
||||||
|
// @Failure 401 {object} APIResponse "Unauthorized"
|
||||||
|
// @Failure 500 {object} APIResponse "Internal Error"
|
||||||
|
// @Router /queue [delete]
|
||||||
func (h *QueueHandler) ClearQueue(c *gin.Context) {
|
func (h *QueueHandler) ClearQueue(c *gin.Context) {
|
||||||
userID, ok := GetUserIDUUID(c)
|
userID, ok := GetUserIDUUID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,16 @@ func NewQueueSessionHandler(svc *services.QueueSessionService, logger *zap.Logge
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateSession creates a new shared queue session
|
// CreateSession creates a new shared queue session
|
||||||
|
// @Summary Create collaborative queue session
|
||||||
|
// @Description Creates a shared queue session and returns its share token + URL. The session creator is recorded as host.
|
||||||
|
// @Tags Queue
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Success 201 {object} APIResponse{data=object{session=object,share_token=string,share_url=string}} "Created session"
|
||||||
|
// @Failure 401 {object} APIResponse "Unauthorized"
|
||||||
|
// @Failure 500 {object} APIResponse "Internal Error"
|
||||||
|
// @Router /queue/session [post]
|
||||||
func (h *QueueSessionHandler) CreateSession(c *gin.Context) {
|
func (h *QueueSessionHandler) CreateSession(c *gin.Context) {
|
||||||
userID, ok := GetUserIDUUID(c)
|
userID, ok := GetUserIDUUID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -42,6 +52,17 @@ func (h *QueueSessionHandler) CreateSession(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSession returns a session's queue (auth optional for joining via link)
|
// GetSession returns a session's queue (auth optional for joining via link)
|
||||||
|
// @Summary Get queue session by share token
|
||||||
|
// @Description Returns the session metadata + items for a given share token. No auth required (public — anyone with the link can join).
|
||||||
|
// @Tags Queue
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param token path string true "Session share token"
|
||||||
|
// @Success 200 {object} APIResponse{data=object{session=object,items=[]object}} "Session and queue items"
|
||||||
|
// @Failure 400 {object} APIResponse "Token required"
|
||||||
|
// @Failure 404 {object} APIResponse "Session not found"
|
||||||
|
// @Failure 500 {object} APIResponse "Internal Error"
|
||||||
|
// @Router /queue/session/{token} [get]
|
||||||
func (h *QueueSessionHandler) GetSession(c *gin.Context) {
|
func (h *QueueSessionHandler) GetSession(c *gin.Context) {
|
||||||
token := c.Param("token")
|
token := c.Param("token")
|
||||||
if token == "" {
|
if token == "" {
|
||||||
|
|
@ -83,6 +104,19 @@ func (h *QueueSessionHandler) GetSession(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteSession deletes a session (creator only)
|
// DeleteSession deletes a session (creator only)
|
||||||
|
// @Summary Delete queue session
|
||||||
|
// @Description Deletes a collaborative queue session. Only the original session creator can delete.
|
||||||
|
// @Tags Queue
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Param token path string true "Session share token"
|
||||||
|
// @Success 200 {object} APIResponse{data=object{message=string}} "Session deleted"
|
||||||
|
// @Failure 400 {object} APIResponse "Token required"
|
||||||
|
// @Failure 401 {object} APIResponse "Unauthorized"
|
||||||
|
// @Failure 403 {object} APIResponse "Only the creator can delete this session"
|
||||||
|
// @Failure 404 {object} APIResponse "Session not found"
|
||||||
|
// @Router /queue/session/{token} [delete]
|
||||||
func (h *QueueSessionHandler) DeleteSession(c *gin.Context) {
|
func (h *QueueSessionHandler) DeleteSession(c *gin.Context) {
|
||||||
userID, ok := GetUserIDUUID(c)
|
userID, ok := GetUserIDUUID(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -114,6 +148,19 @@ type AddToSessionRequest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddToSession adds a track to a session's queue
|
// AddToSession adds a track to a session's queue
|
||||||
|
// @Summary Add track to queue session
|
||||||
|
// @Description Adds a track to a collaborative queue session. Anyone with the share token can add.
|
||||||
|
// @Tags Queue
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Param token path string true "Session share token"
|
||||||
|
// @Param request body AddToSessionRequest true "Track to enqueue"
|
||||||
|
// @Success 201 {object} APIResponse{data=object{session=object,items=[]object}} "Updated session and items"
|
||||||
|
// @Failure 400 {object} APIResponse "Validation error"
|
||||||
|
// @Failure 404 {object} APIResponse "Session not found"
|
||||||
|
// @Failure 500 {object} APIResponse "Internal Error"
|
||||||
|
// @Router /queue/session/{token}/items [post]
|
||||||
func (h *QueueSessionHandler) AddToSession(c *gin.Context) {
|
func (h *QueueSessionHandler) AddToSession(c *gin.Context) {
|
||||||
token := c.Param("token")
|
token := c.Param("token")
|
||||||
if token == "" {
|
if token == "" {
|
||||||
|
|
@ -139,6 +186,19 @@ func (h *QueueSessionHandler) AddToSession(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveFromSession removes an item from a session's queue
|
// RemoveFromSession removes an item from a session's queue
|
||||||
|
// @Summary Remove item from queue session
|
||||||
|
// @Description Removes an item from a collaborative queue session by item ID
|
||||||
|
// @Tags Queue
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Param token path string true "Session share token"
|
||||||
|
// @Param id path string true "Queue item ID (UUID)"
|
||||||
|
// @Success 200 {object} APIResponse{data=object{message=string}} "Item removed"
|
||||||
|
// @Failure 400 {object} APIResponse "Validation error"
|
||||||
|
// @Failure 404 {object} APIResponse "Session or item not found"
|
||||||
|
// @Failure 500 {object} APIResponse "Internal Error"
|
||||||
|
// @Router /queue/session/{token}/items/{id} [delete]
|
||||||
func (h *QueueSessionHandler) RemoveFromSession(c *gin.Context) {
|
func (h *QueueSessionHandler) RemoveFromSession(c *gin.Context) {
|
||||||
token := c.Param("token")
|
token := c.Param("token")
|
||||||
if token == "" {
|
if token == "" {
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,20 @@ definitions:
|
||||||
- permission
|
- permission
|
||||||
- user_id
|
- user_id
|
||||||
type: object
|
type: object
|
||||||
|
internal_handlers.AddQueueItemRequest:
|
||||||
|
properties:
|
||||||
|
track_id:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- track_id
|
||||||
|
type: object
|
||||||
|
internal_handlers.AddToSessionRequest:
|
||||||
|
properties:
|
||||||
|
track_id:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- track_id
|
||||||
|
type: object
|
||||||
internal_handlers.CreateCommentRequest:
|
internal_handlers.CreateCommentRequest:
|
||||||
properties:
|
properties:
|
||||||
content:
|
content:
|
||||||
|
|
@ -387,6 +401,24 @@ definitions:
|
||||||
required:
|
required:
|
||||||
- track_ids
|
- track_ids
|
||||||
type: object
|
type: object
|
||||||
|
internal_handlers.RequestPasswordResetRequest:
|
||||||
|
properties:
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- email
|
||||||
|
type: object
|
||||||
|
internal_handlers.ResetPasswordRequest:
|
||||||
|
properties:
|
||||||
|
new_password:
|
||||||
|
minLength: 12
|
||||||
|
type: string
|
||||||
|
token:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- new_password
|
||||||
|
- token
|
||||||
|
type: object
|
||||||
internal_handlers.SetupTwoFactorResponse:
|
internal_handlers.SetupTwoFactorResponse:
|
||||||
properties:
|
properties:
|
||||||
qr_code_url:
|
qr_code_url:
|
||||||
|
|
@ -1075,6 +1107,25 @@ definitions:
|
||||||
success:
|
success:
|
||||||
type: boolean
|
type: boolean
|
||||||
type: object
|
type: object
|
||||||
|
veza-backend-api_internal_services.UpdateQueueRequest:
|
||||||
|
properties:
|
||||||
|
current_position:
|
||||||
|
type: integer
|
||||||
|
current_track_id:
|
||||||
|
type: string
|
||||||
|
is_playing:
|
||||||
|
type: boolean
|
||||||
|
item_order:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
repeat_mode:
|
||||||
|
type: string
|
||||||
|
shuffle:
|
||||||
|
type: boolean
|
||||||
|
volume:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
host: localhost:18080
|
host: localhost:18080
|
||||||
info:
|
info:
|
||||||
contact:
|
contact:
|
||||||
|
|
@ -1886,6 +1937,84 @@ paths:
|
||||||
summary: Get Current User
|
summary: Get Current User
|
||||||
tags:
|
tags:
|
||||||
- Auth
|
- Auth
|
||||||
|
/auth/password/reset:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Completes a password reset using a valid token previously emailed
|
||||||
|
to the user. Invalidates all the user's existing sessions on success.
|
||||||
|
parameters:
|
||||||
|
- description: Reset token + new password
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.ResetPasswordRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Password reset successfully
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Invalid or expired token, or password validation failed
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Failed to update password
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
summary: Reset password with token
|
||||||
|
tags:
|
||||||
|
- Auth
|
||||||
|
/auth/password/reset-request:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Sends a password reset link to the user's email if the address
|
||||||
|
exists. Always returns 200 with a generic message to prevent email enumeration.
|
||||||
|
parameters:
|
||||||
|
- description: Email of the account to reset
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.RequestPasswordResetRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: If the email exists, a reset link has been sent
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Validation error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Token generation/storage failed (or SMTP failure in production)
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
summary: Request password reset
|
||||||
|
tags:
|
||||||
|
- Auth
|
||||||
/auth/refresh:
|
/auth/refresh:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
|
@ -3140,6 +3269,445 @@ paths:
|
||||||
summary: Get playlist by share token
|
summary: Get playlist by share token
|
||||||
tags:
|
tags:
|
||||||
- Playlist
|
- Playlist
|
||||||
|
/queue:
|
||||||
|
delete:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Removes every item from the authenticated user's playback queue
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Queue cleared
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Clear queue
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Returns the authenticated user's persistent playback queue with
|
||||||
|
all items in position order
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Queue + items
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
queue:
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Get user playback queue
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
put:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Updates the authenticated user's queue state (current track / position
|
||||||
|
/ playback flags / item order)
|
||||||
|
parameters:
|
||||||
|
- description: Queue update payload
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/veza-backend-api_internal_services.UpdateQueueRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Updated queue
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
queue:
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Validation error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Update user playback queue
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/queue/items:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Appends a track to the authenticated user's playback queue
|
||||||
|
parameters:
|
||||||
|
- description: Track to enqueue
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.AddQueueItemRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Created queue item
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
item:
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Validation error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Add track to queue
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/queue/items/{id}:
|
||||||
|
delete:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Removes a single item from the authenticated user's playback queue
|
||||||
|
by item ID
|
||||||
|
parameters:
|
||||||
|
- description: Queue item ID (UUID)
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Item removed
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Invalid item ID
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"404":
|
||||||
|
description: Queue item not found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Remove queue item
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/queue/session:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Creates a shared queue session and returns its share token + URL.
|
||||||
|
The session creator is recorded as host.
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Created session
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
session:
|
||||||
|
type: object
|
||||||
|
share_token:
|
||||||
|
type: string
|
||||||
|
share_url:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Create collaborative queue session
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/queue/session/{token}:
|
||||||
|
delete:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Deletes a collaborative queue session. Only the original session
|
||||||
|
creator can delete.
|
||||||
|
parameters:
|
||||||
|
- description: Session share token
|
||||||
|
in: path
|
||||||
|
name: token
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Session deleted
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Token required
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"403":
|
||||||
|
description: Only the creator can delete this session
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"404":
|
||||||
|
description: Session not found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Delete queue session
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Returns the session metadata + items for a given share token. No
|
||||||
|
auth required (public — anyone with the link can join).
|
||||||
|
parameters:
|
||||||
|
- description: Session share token
|
||||||
|
in: path
|
||||||
|
name: token
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Session and queue items
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
session:
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Token required
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"404":
|
||||||
|
description: Session not found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
summary: Get queue session by share token
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/queue/session/{token}/items:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Adds a track to a collaborative queue session. Anyone with the
|
||||||
|
share token can add.
|
||||||
|
parameters:
|
||||||
|
- description: Session share token
|
||||||
|
in: path
|
||||||
|
name: token
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: Track to enqueue
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.AddToSessionRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Updated session and items
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
session:
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Validation error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"404":
|
||||||
|
description: Session not found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Add track to queue session
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/queue/session/{token}/items/{id}:
|
||||||
|
delete:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Removes an item from a collaborative queue session by item ID
|
||||||
|
parameters:
|
||||||
|
- description: Session share token
|
||||||
|
in: path
|
||||||
|
name: token
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: Queue item ID (UUID)
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Item removed
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Validation error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"404":
|
||||||
|
description: Session or item not found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/internal_handlers.APIResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Remove item from queue session
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
/tracks:
|
/tracks:
|
||||||
get:
|
get:
|
||||||
description: List tracks with pagination, filters, sort. Cursor-based when ?cursor
|
description: List tracks with pagination, filters, sort. Cursor-based when ?cursor
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue