Files
movies-diary/spa/src/lib/api/diary.ts
Gabriel Kaszewski 29cc68b07c
Some checks failed
CI / Check / Test (push) Failing after 27m0s
feat: add WatchMedium field, general review editing, configurable deploy
- WatchMedium enum (cinema/streaming/tv/physical_media/download/media_server/other)
- PATCH /api/v1/reviews/:id partial update (rating, comment, watched_at, watch_medium)
- edit_review use case w/ ownership + remote review guard, best-effort AP Update broadcast
- SPA: icon picker, edit sheet (long-press mobile / pencil desktop), watch medium badge
- shared ReviewFormFields, EditableContextMenu, parse_watched_at/format_watched_at
- deploy.sh parameterized (--features, --tag), CORS allows PATCH
- CONTEXT.md glossary, ADR-0001 general review editing
2026-07-10 00:01:14 +02:00

85 lines
2.7 KiB
TypeScript

import { z } from "zod"
import type { DiaryEntryDto, Paginated } from "./common"
import { diaryEntryDtoSchema, movieDtoSchema, paginatedSchema, reviewDtoSchema } from "./common"
import { del, get, patch, post } from "./client"
export const diaryQueryParamsSchema = z.object({
limit: z.number().optional(),
offset: z.number().optional(),
sort_by: z.string().optional(),
movie_id: z.string().uuid().optional(),
})
export type DiaryQueryParams = z.infer<typeof diaryQueryParamsSchema>
export const diaryResponseSchema = paginatedSchema(diaryEntryDtoSchema)
export type DiaryResponse = Paginated<DiaryEntryDto>
export const logReviewRequestSchema = z.object({
external_metadata_id: z.string().optional(),
manual_title: z.string().optional(),
manual_release_year: z.number().optional(),
manual_director: z.string().optional(),
rating: z.number(),
comment: z.string().optional(),
watched_at: z.string(),
watch_medium: z.string().optional(),
})
export type LogReviewRequest = z.infer<typeof logReviewRequestSchema>
export const editReviewRequestSchema = z.object({
rating: z.number().optional(),
comment: z.string().nullable().optional(),
watched_at: z.string().optional(),
watch_medium: z.string().nullable().optional(),
})
export type EditReviewRequest = z.infer<typeof editReviewRequestSchema>
export const feedEntryDtoSchema = z.object({
movie: movieDtoSchema,
review: reviewDtoSchema,
user_id: z.string().uuid(),
user_display_name: z.string(),
is_federated: z.boolean(),
actor_url: z.string().optional(),
})
export type FeedEntryDto = z.infer<typeof feedEntryDtoSchema>
export const activityFeedQueryParamsSchema = z.object({
limit: z.number().optional(),
offset: z.number().optional(),
sort_by: z.string().optional(),
})
export type ActivityFeedQueryParams = z.infer<typeof activityFeedQueryParamsSchema>
export const activityFeedResponseSchema = paginatedSchema(feedEntryDtoSchema)
export type ActivityFeedResponse = Paginated<FeedEntryDto>
export const exportQueryParamsSchema = z.object({
format: z.string().optional(),
})
export type ExportQueryParams = z.infer<typeof exportQueryParamsSchema>
export function getDiary(params?: DiaryQueryParams) {
return get<DiaryResponse>("/diary", params)
}
export function logReview(data: LogReviewRequest) {
return post("/reviews", data)
}
export function editReview(id: string, data: EditReviewRequest) {
return patch(`/reviews/${id}`, data)
}
export function deleteReview(id: string) {
return del(`/reviews/${id}`)
}
export function getActivityFeed(params?: ActivityFeedQueryParams) {
return get<ActivityFeedResponse>("/activity-feed", params)
}
export function exportDiary(params?: ExportQueryParams) {
return get<Blob>("/diary/export", params)
}