From 00894f45266d2c67f108674cce5130752ff3dfd9 Mon Sep 17 00:00:00 2001 From: Iron_Felix Date: Sat, 6 Dec 2025 05:18:23 +0300 Subject: [PATCH] feat: ftime logic for usertitle is changed --- api/_build/openapi.yaml | 6 +++ api/api.gen.go | 6 ++- api/paths/users-id-titles-id.yaml | 3 ++ api/paths/users-id-titles.yaml | 3 ++ modules/backend/handlers/users.go | 12 +++++ modules/backend/queries.sql | 8 +-- modules/frontend/src/api/client.gen.ts | 2 +- modules/frontend/src/api/sdk.gen.ts | 7 ++- modules/frontend/src/api/types.gen.ts | 50 +++++++++++++++++++ .../src/pages/UsersPage/UsersPage.tsx | 0 sql/migrations/000001_init.up.sql | 15 +----- sql/queries.sql.go | 36 +++++++------ 12 files changed, 113 insertions(+), 35 deletions(-) create mode 100644 modules/frontend/src/pages/UsersPage/UsersPage.tsx diff --git a/api/_build/openapi.yaml b/api/_build/openapi.yaml index 9ed5b5f..ad0c9be 100644 --- a/api/_build/openapi.yaml +++ b/api/_build/openapi.yaml @@ -395,6 +395,9 @@ paths: rate: type: integer format: int32 + ftime: + type: string + format: date-time required: - title_id - status @@ -478,6 +481,9 @@ paths: rate: type: integer format: int32 + ftime: + type: string + format: date-time responses: '200': description: Title successfully updated diff --git a/api/api.gen.go b/api/api.gen.go index d93e925..04d10c0 100644 --- a/api/api.gen.go +++ b/api/api.gen.go @@ -262,7 +262,8 @@ type GetUserTitlesParams struct { // AddUserTitleJSONBody defines parameters for AddUserTitle. type AddUserTitleJSONBody struct { - Rate *int32 `json:"rate,omitempty"` + Ftime *time.Time `json:"ftime,omitempty"` + Rate *int32 `json:"rate,omitempty"` // Status User's title status Status UserTitleStatus `json:"status"` @@ -271,7 +272,8 @@ type AddUserTitleJSONBody struct { // UpdateUserTitleJSONBody defines parameters for UpdateUserTitle. type UpdateUserTitleJSONBody struct { - Rate *int32 `json:"rate,omitempty"` + Ftime *time.Time `json:"ftime,omitempty"` + Rate *int32 `json:"rate,omitempty"` // Status User's title status Status *UserTitleStatus `json:"status,omitempty"` diff --git a/api/paths/users-id-titles-id.yaml b/api/paths/users-id-titles-id.yaml index 1da2b81..20a174f 100644 --- a/api/paths/users-id-titles-id.yaml +++ b/api/paths/users-id-titles-id.yaml @@ -61,6 +61,9 @@ patch: rate: type: integer format: int32 + ftime: + type: string + format: date-time responses: '200': description: Title successfully updated diff --git a/api/paths/users-id-titles.yaml b/api/paths/users-id-titles.yaml index 75f5461..f1e5e95 100644 --- a/api/paths/users-id-titles.yaml +++ b/api/paths/users-id-titles.yaml @@ -122,6 +122,9 @@ post: rate: type: integer format: int32 + ftime: + type: string + format: date-time responses: '200': description: Title successfully added to user diff --git a/modules/backend/handlers/users.go b/modules/backend/handlers/users.go index 995d5af..eecd82f 100644 --- a/modules/backend/handlers/users.go +++ b/modules/backend/handlers/users.go @@ -69,6 +69,16 @@ func sqlDate2oapi(p_date pgtype.Timestamptz) *time.Time { return nil } +func oapiDate2sql(t *time.Time) pgtype.Timestamptz { + if t == nil { + return pgtype.Timestamptz{Valid: false} + } + return pgtype.Timestamptz{ + Time: *t, + Valid: true, + } +} + // func UserTitleStatus2Sqlc(s *[]oapi.UserTitleStatus) (*SqlcUserStatus, error) { // var sqlc_status SqlcUserStatus // if s == nil { @@ -365,6 +375,7 @@ func (s Server) AddUserTitle(ctx context.Context, request oapi.AddUserTitleReque TitleID: request.Body.TitleId, Status: *status, Rate: request.Body.Rate, + Ftime: oapiDate2sql(request.Body.Ftime), } user_title, err := s.db.InsertUserTitle(ctx, params) @@ -428,6 +439,7 @@ func (s Server) UpdateUserTitle(ctx context.Context, request oapi.UpdateUserTitl Rate: request.Body.Rate, UserID: request.UserId, TitleID: request.TitleId, + Ftime: oapiDate2sql(request.Body.Ftime), } user_title, err := s.db.UpdateUserTitle(ctx, params) diff --git a/modules/backend/queries.sql b/modules/backend/queries.sql index 03502c4..19971e5 100644 --- a/modules/backend/queries.sql +++ b/modules/backend/queries.sql @@ -400,13 +400,14 @@ FROM reviews WHERE review_id = sqlc.arg('review_id')::bigint; -- name: InsertUserTitle :one -INSERT INTO usertitles (user_id, title_id, status, rate, review_id) +INSERT INTO usertitles (user_id, title_id, status, rate, review_id, ctime) VALUES ( sqlc.arg('user_id')::bigint, sqlc.arg('title_id')::bigint, sqlc.arg('status')::usertitle_status_t, sqlc.narg('rate')::int, - sqlc.narg('review_id')::bigint + sqlc.narg('review_id')::bigint, + sqlc.narg('ftime')::timestamptz ) RETURNING user_id, title_id, status, rate, review_id, ctime; @@ -415,7 +416,8 @@ RETURNING user_id, title_id, status, rate, review_id, ctime; UPDATE usertitles SET status = COALESCE(sqlc.narg('status')::usertitle_status_t, status), - rate = COALESCE(sqlc.narg('rate')::int, rate) + rate = COALESCE(sqlc.narg('rate')::int, rate), + ctime = COALESCE(sqlc.narg('ftime')::timestamptz, ctime) WHERE user_id = sqlc.arg('user_id') AND title_id = sqlc.arg('title_id') diff --git a/modules/frontend/src/api/client.gen.ts b/modules/frontend/src/api/client.gen.ts index 2de06ac..952c663 100644 --- a/modules/frontend/src/api/client.gen.ts +++ b/modules/frontend/src/api/client.gen.ts @@ -13,4 +13,4 @@ import type { ClientOptions as ClientOptions2 } from './types.gen'; */ export type CreateClientConfig = (override?: Config) => Config & T>; -export const client = createClient(createConfig({ baseUrl: 'http://10.1.0.65:8081/api/v1' })); +export const client = createClient(createConfig({ baseUrl: '/api/v1' })); diff --git a/modules/frontend/src/api/sdk.gen.ts b/modules/frontend/src/api/sdk.gen.ts index 5359156..7d46120 100644 --- a/modules/frontend/src/api/sdk.gen.ts +++ b/modules/frontend/src/api/sdk.gen.ts @@ -2,7 +2,7 @@ import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; -import type { AddUserTitleData, AddUserTitleErrors, AddUserTitleResponses, DeleteUserTitleData, DeleteUserTitleErrors, DeleteUserTitleResponses, GetTitleData, GetTitleErrors, GetTitleResponses, GetTitlesData, GetTitlesErrors, GetTitlesResponses, GetUsersIdData, GetUsersIdErrors, GetUsersIdResponses, GetUserTitleData, GetUserTitleErrors, GetUserTitleResponses, GetUserTitlesData, GetUserTitlesErrors, GetUserTitlesResponses, UpdateUserData, UpdateUserErrors, UpdateUserResponses, UpdateUserTitleData, UpdateUserTitleErrors, UpdateUserTitleResponses } from './types.gen'; +import type { AddUserTitleData, AddUserTitleErrors, AddUserTitleResponses, DeleteUserTitleData, DeleteUserTitleErrors, DeleteUserTitleResponses, GetTitleData, GetTitleErrors, GetTitleResponses, GetTitlesData, GetTitlesErrors, GetTitlesResponses, GetUsersData, GetUsersErrors, GetUsersIdData, GetUsersIdErrors, GetUsersIdResponses, GetUsersResponses, GetUserTitleData, GetUserTitleErrors, GetUserTitleResponses, GetUserTitlesData, GetUserTitlesErrors, GetUserTitlesResponses, UpdateUserData, UpdateUserErrors, UpdateUserResponses, UpdateUserTitleData, UpdateUserTitleErrors, UpdateUserTitleResponses } from './types.gen'; export type Options = Options2 & { /** @@ -32,6 +32,11 @@ export const getTitles = (options?: Option */ export const getTitle = (options: Options) => (options.client ?? client).get({ url: '/titles/{title_id}', ...options }); +/** + * Search user by nickname or dispname (both in one param), response is always sorted by id + */ +export const getUsers = (options?: Options) => (options?.client ?? client).get({ url: '/users/', ...options }); + /** * Get user info */ diff --git a/modules/frontend/src/api/types.gen.ts b/modules/frontend/src/api/types.gen.ts index ce4db4b..d4526a7 100644 --- a/modules/frontend/src/api/types.gen.ts +++ b/modules/frontend/src/api/types.gen.ts @@ -60,6 +60,12 @@ export type Title = { title_names: { [key: string]: Array; }; + /** + * Localized description. Key = language (ISO 639-1), value = description. + */ + title_desc?: { + [key: string]: string; + }; studio?: Studio; tags: Tags; poster?: Image; @@ -231,6 +237,50 @@ export type GetTitleResponses = { export type GetTitleResponse = GetTitleResponses[keyof GetTitleResponses]; +export type GetUsersData = { + body?: never; + path?: never; + query?: { + word?: string; + limit?: number; + /** + * pass cursor naked + */ + cursor_id?: number; + }; + url: '/users/'; +}; + +export type GetUsersErrors = { + /** + * Request params are not correct + */ + 400: unknown; + /** + * Unknown server error + */ + 500: unknown; +}; + +export type GetUsersResponses = { + /** + * List of users with cursor + */ + 200: { + /** + * List of users + */ + data: Array; + cursor: number; + }; + /** + * No users found + */ + 204: void; +}; + +export type GetUsersResponse = GetUsersResponses[keyof GetUsersResponses]; + export type GetUsersIdData = { body?: never; path: { diff --git a/modules/frontend/src/pages/UsersPage/UsersPage.tsx b/modules/frontend/src/pages/UsersPage/UsersPage.tsx new file mode 100644 index 0000000..e69de29 diff --git a/sql/migrations/000001_init.up.sql b/sql/migrations/000001_init.up.sql index d6353d6..d57b807 100644 --- a/sql/migrations/000001_init.up.sql +++ b/sql/migrations/000001_init.up.sql @@ -170,17 +170,4 @@ EXECUTE FUNCTION update_title_rating(); CREATE TRIGGER trg_notify_new_signal AFTER INSERT ON signals FOR EACH ROW -EXECUTE FUNCTION notify_new_signal(); - -CREATE OR REPLACE FUNCTION set_ctime() -RETURNS TRIGGER AS $$ -BEGIN - NEW.ctime = now(); - RETURN NEW; -END; -$$ LANGUAGE plpgsql; - -CREATE TRIGGER set_ctime_on_update -BEFORE UPDATE ON usertitles -FOR EACH ROW -EXECUTE FUNCTION set_ctime(); \ No newline at end of file +EXECUTE FUNCTION notify_new_signal(); \ No newline at end of file diff --git a/sql/queries.sql.go b/sql/queries.sql.go index 0c17599..d253cc9 100644 --- a/sql/queries.sql.go +++ b/sql/queries.sql.go @@ -9,6 +9,8 @@ import ( "context" "encoding/json" "time" + + "github.com/jackc/pgx/v5/pgtype" ) const createImage = `-- name: CreateImage :one @@ -394,23 +396,25 @@ func (q *Queries) InsertTitleTags(ctx context.Context, arg InsertTitleTagsParams } const insertUserTitle = `-- name: InsertUserTitle :one -INSERT INTO usertitles (user_id, title_id, status, rate, review_id) +INSERT INTO usertitles (user_id, title_id, status, rate, review_id, ctime) VALUES ( $1::bigint, $2::bigint, $3::usertitle_status_t, $4::int, - $5::bigint + $5::bigint, + $6::timestamptz ) RETURNING user_id, title_id, status, rate, review_id, ctime ` type InsertUserTitleParams struct { - UserID int64 `json:"user_id"` - TitleID int64 `json:"title_id"` - Status UsertitleStatusT `json:"status"` - Rate *int32 `json:"rate"` - ReviewID *int64 `json:"review_id"` + UserID int64 `json:"user_id"` + TitleID int64 `json:"title_id"` + Status UsertitleStatusT `json:"status"` + Rate *int32 `json:"rate"` + ReviewID *int64 `json:"review_id"` + Ftime pgtype.Timestamptz `json:"ftime"` } func (q *Queries) InsertUserTitle(ctx context.Context, arg InsertUserTitleParams) (Usertitle, error) { @@ -420,6 +424,7 @@ func (q *Queries) InsertUserTitle(ctx context.Context, arg InsertUserTitleParams arg.Status, arg.Rate, arg.ReviewID, + arg.Ftime, ) var i Usertitle err := row.Scan( @@ -1017,18 +1022,20 @@ const updateUserTitle = `-- name: UpdateUserTitle :one UPDATE usertitles SET status = COALESCE($1::usertitle_status_t, status), - rate = COALESCE($2::int, rate) + rate = COALESCE($2::int, rate), + ctime = COALESCE($3::timestamptz, ctime) WHERE - user_id = $3 - AND title_id = $4 + user_id = $4 + AND title_id = $5 RETURNING user_id, title_id, status, rate, review_id, ctime ` type UpdateUserTitleParams struct { - Status *UsertitleStatusT `json:"status"` - Rate *int32 `json:"rate"` - UserID int64 `json:"user_id"` - TitleID int64 `json:"title_id"` + Status *UsertitleStatusT `json:"status"` + Rate *int32 `json:"rate"` + Ftime pgtype.Timestamptz `json:"ftime"` + UserID int64 `json:"user_id"` + TitleID int64 `json:"title_id"` } // Fails with sql.ErrNoRows if (user_id, title_id) not found @@ -1036,6 +1043,7 @@ func (q *Queries) UpdateUserTitle(ctx context.Context, arg UpdateUserTitleParams row := q.db.QueryRow(ctx, updateUserTitle, arg.Status, arg.Rate, + arg.Ftime, arg.UserID, arg.TitleID, )