feat: more fields for titles and refactored schemas

This commit is contained in:
Iron_Felix 2025-11-16 01:47:11 +03:00
parent 4949a3c25f
commit e18f4a44c3
2 changed files with 101 additions and 41 deletions

View file

@ -34,6 +34,21 @@ const (
// ReleaseSeason Title release season // ReleaseSeason Title release season
type ReleaseSeason string type ReleaseSeason string
// Studio defines model for Studio.
type Studio struct {
Description *string `json:"description,omitempty"`
Id *int64 `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
PosterId *int64 `json:"poster_id,omitempty"`
PosterPath *string `json:"poster_path,omitempty"`
}
// Tag A localized tag: keys are language codes (ISO 639-1), values are tag names
type Tag map[string]string
// Tags Array of localized tags
type Tags = []Tag
// Title defines model for Title. // Title defines model for Title.
type Title struct { type Title struct {
EpisodesAired *int32 `json:"episodes_aired,omitempty"` EpisodesAired *int32 `json:"episodes_aired,omitempty"`
@ -41,7 +56,7 @@ type Title struct {
EpisodesLen *map[string]float64 `json:"episodes_len,omitempty"` EpisodesLen *map[string]float64 `json:"episodes_len,omitempty"`
// Id Unique title ID (primary key) // Id Unique title ID (primary key)
Id *int64 `json:"id,omitempty"` Id int64 `json:"id"`
PosterId *int64 `json:"poster_id,omitempty"` PosterId *int64 `json:"poster_id,omitempty"`
Rating *float64 `json:"rating,omitempty"` Rating *float64 `json:"rating,omitempty"`
RatingCount *int32 `json:"rating_count,omitempty"` RatingCount *int32 `json:"rating_count,omitempty"`
@ -49,11 +64,13 @@ type Title struct {
// ReleaseSeason Title release season // ReleaseSeason Title release season
ReleaseSeason *ReleaseSeason `json:"release_season,omitempty"` ReleaseSeason *ReleaseSeason `json:"release_season,omitempty"`
ReleaseYear *int32 `json:"release_year,omitempty"` ReleaseYear *int32 `json:"release_year,omitempty"`
StudioId *int64 `json:"studio_id,omitempty"` Studio *Studio `json:"studio,omitempty"`
StudioName *string `json:"studio_name,omitempty"`
// Tags Array of localized tags
Tags Tags `json:"tags"`
// TitleNames Localized titles. Key = language (ISO 639-1), value = list of names // TitleNames Localized titles. Key = language (ISO 639-1), value = list of names
TitleNames *map[string][]string `json:"title_names,omitempty"` TitleNames map[string][]string `json:"title_names"`
// TitleStatus Title status // TitleStatus Title status
TitleStatus *TitleStatus `json:"title_status,omitempty"` TitleStatus *TitleStatus `json:"title_status,omitempty"`
@ -201,20 +218,20 @@ func (a *Title) UnmarshalJSON(b []byte) error {
delete(object, "release_year") delete(object, "release_year")
} }
if raw, found := object["studio_id"]; found { if raw, found := object["studio"]; found {
err = json.Unmarshal(raw, &a.StudioId) err = json.Unmarshal(raw, &a.Studio)
if err != nil { if err != nil {
return fmt.Errorf("error reading 'studio_id': %w", err) return fmt.Errorf("error reading 'studio': %w", err)
} }
delete(object, "studio_id") delete(object, "studio")
} }
if raw, found := object["studio_name"]; found { if raw, found := object["tags"]; found {
err = json.Unmarshal(raw, &a.StudioName) err = json.Unmarshal(raw, &a.Tags)
if err != nil { if err != nil {
return fmt.Errorf("error reading 'studio_name': %w", err) return fmt.Errorf("error reading 'tags': %w", err)
} }
delete(object, "studio_name") delete(object, "tags")
} }
if raw, found := object["title_names"]; found { if raw, found := object["title_names"]; found {
@ -273,11 +290,9 @@ func (a Title) MarshalJSON() ([]byte, error) {
} }
} }
if a.Id != nil { object["id"], err = json.Marshal(a.Id)
object["id"], err = json.Marshal(a.Id) if err != nil {
if err != nil { return nil, fmt.Errorf("error marshaling 'id': %w", err)
return nil, fmt.Errorf("error marshaling 'id': %w", err)
}
} }
if a.PosterId != nil { if a.PosterId != nil {
@ -315,25 +330,21 @@ func (a Title) MarshalJSON() ([]byte, error) {
} }
} }
if a.StudioId != nil { if a.Studio != nil {
object["studio_id"], err = json.Marshal(a.StudioId) object["studio"], err = json.Marshal(a.Studio)
if err != nil { if err != nil {
return nil, fmt.Errorf("error marshaling 'studio_id': %w", err) return nil, fmt.Errorf("error marshaling 'studio': %w", err)
} }
} }
if a.StudioName != nil { object["tags"], err = json.Marshal(a.Tags)
object["studio_name"], err = json.Marshal(a.StudioName) if err != nil {
if err != nil { return nil, fmt.Errorf("error marshaling 'tags': %w", err)
return nil, fmt.Errorf("error marshaling 'studio_name': %w", err)
}
} }
if a.TitleNames != nil { object["title_names"], err = json.Marshal(a.TitleNames)
object["title_names"], err = json.Marshal(a.TitleNames) if err != nil {
if err != nil { return nil, fmt.Errorf("error marshaling 'title_names': %w", err)
return nil, fmt.Errorf("error marshaling 'title_names': %w", err)
}
} }
if a.TitleStatus != nil { if a.TitleStatus != nil {

View file

@ -2,8 +2,10 @@ openapi: 3.1.1
info: info:
title: Titles, Users, Reviews, Tags, and Media API title: Titles, Users, Reviews, Tags, and Media API
version: 1.0.0 version: 1.0.0
servers: servers:
- url: /api/v1 - url: /api/v1
paths: paths:
/title: /title:
get: get:
@ -63,6 +65,7 @@ paths:
description: Request params are not correct description: Request params are not correct
'500': '500':
description: Unknown server error description: Unknown server error
# /title/{title_id}: # /title/{title_id}:
# get: # get:
# summary: Get title description # summary: Get title description
@ -569,6 +572,7 @@ components:
- finished - finished
- ongoing - ongoing
- planned - planned
ReleaseSeason: ReleaseSeason:
type: string type: string
description: Title release season description: Title release season
@ -577,6 +581,7 @@ components:
- spring - spring
- summer - summer
- fall - fall
UserTitleStatus: UserTitleStatus:
type: string type: string
description: User's title status description: User's title status
@ -585,8 +590,57 @@ components:
- planned - planned
- dropped - dropped
- in-progress - in-progress
Review:
type: object
additionalProperties: true
Tag:
type: object
description: "A localized tag: keys are language codes (ISO 639-1), values are tag names"
additionalProperties:
type: string
example:
en: "Shojo"
ru: "Сёдзё"
ja: "少女"
Tags:
type: array
description: "Array of localized tags"
items:
$ref: '#/components/schemas/Tag'
example:
- en: "Shojo"
ru: "Сёдзё"
ja: "少女"
- en: "Shounen"
ru: "Сёнен"
ja: "少年"
Studio:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
poster_id:
type: integer
format: int64
poster_path:
type: string
description:
type: string
Title: Title:
type: object type: object
required:
- id
- title_names
- tags
properties: properties:
id: id:
type: integer type: integer
@ -607,11 +661,10 @@ components:
en: ["Attack on Titan", "AoT"] en: ["Attack on Titan", "AoT"]
ru: ["Атака титанов", "Титаны"] ru: ["Атака титанов", "Титаны"]
ja: ["進撃の巨人"] ja: ["進撃の巨人"]
studio_id: studio:
type: integer $ref: '#/components/schemas/Studio'
format: int64 tags:
studio_name: $ref: '#/components/schemas/Tags'
type: string
poster_id: poster_id:
type: integer type: integer
format: int64 format: int64
@ -640,6 +693,7 @@ components:
type: number type: number
format: double format: double
additionalProperties: true additionalProperties: true
User: User:
type: object type: object
properties: properties:
@ -683,12 +737,7 @@ components:
- user_id - user_id
- nickname - nickname
# - creation_date # - creation_date
UserTitle: UserTitle:
type: object type: object
additionalProperties: true additionalProperties: true
Review:
type: object
additionalProperties: true
Tag:
type: object
additionalProperties: true