refactor(utils): one PgTextString for the four pgtype.Text unwrappers

handlers textToString, router textToString, router getText, and utils
normText were four copies of the same NULL-to-empty unwrap (99 call
sites). One exported utils.PgTextString replaces them all; the private
normText (comparison normalizer) stays but is now the odd one out.

Harness fix found on the way: setupTestServer built a full wiring
literal for route registration and then RETURNED a second, sparser
literal that never copied AnnotationService — setup.AnnotationService
was always nil on the struct every test receives. Nobody noticed until
cross_library_move_test became the first caller (it previously used
the now-retired plain CreateMediaHighlight query); it now exercises
the real SaveHighlight path through the wired service.
This commit is contained in:
John O'Keefe committed 2026-10-17 16:36:58 -04:00
1 parent 00305ffc7b
commit 188ae076ab
15 files changed
+140 -139

No files matched your search

+39 -39
View File
@@ -815,44 +815,44 @@ func (mh *MediaHandler) ListMediaItems(c *echo.Context) error {
"id": uuid.UUID(item.ID.Bytes).String(),
"library_id": uuid.UUID(item.LibraryID.Bytes).String(),
"title": item.Title,
"author": textToString(item.Author),
"isbn": textToString(item.Isbn),
"description": textToString(item.Description),
"author": utils.PgTextString(item.Author),
"isbn": utils.PgTextString(item.Isbn),
"description": utils.PgTextString(item.Description),
"file_path": utils.ResolveMediaURL(item.LibraryID, pgtype.Text{String: item.FilePath, Valid: item.FilePath != ""}),
"file_size": item.FileSize,
"mime_type": textToString(item.MimeType),
"mime_type": utils.PgTextString(item.MimeType),
"cover_image_path": utils.ResolveMediaURL(item.LibraryID, item.CoverImagePath),
"series": textToString(item.Series),
"series": utils.PgTextString(item.Series),
"series_number": item.SeriesNumber,
"tags": item.Tags,
"asin": textToString(item.Asin),
"asin": utils.PgTextString(item.Asin),
"date_published": item.DatePublished.Time.Format("2006-01-02"),
"publisher": textToString(item.Publisher),
"publisher": utils.PgTextString(item.Publisher),
"contributors": item.Contributors,
"language": textToString(item.Language),
"edition": textToString(item.Edition),
"language": utils.PgTextString(item.Language),
"edition": utils.PgTextString(item.Edition),
"page_count": item.PageCount,
"genre": textToString(item.Genre),
"genre": utils.PgTextString(item.Genre),
"created_at": item.CreatedAt.Time.Format("2006-01-02T15:04:05Z07:00"),
"updated_at": item.UpdatedAt.Time.Format("2006-01-02T15:04:05Z07:00"),
"format_group": item.FormatGroup, // already string
// NEW: Reading direction fields
"manga_type": textToString(item.MangaType),
"reading_direction": textToString(item.ReadingDirection),
"manga_type": utils.PgTextString(item.MangaType),
"reading_direction": utils.PgTextString(item.ReadingDirection),
// NEW: Universal metadata fields
"series_count": item.SeriesCount,
"volume": item.Volume,
"imprint": textToString(item.Imprint),
"age_rating": textToString(item.AgeRating),
"web_url": textToString(item.WebUrl),
"metadata_notes": textToString(item.MetadataNotes),
"imprint": utils.PgTextString(item.Imprint),
"age_rating": utils.PgTextString(item.AgeRating),
"web_url": utils.PgTextString(item.WebUrl),
"metadata_notes": utils.PgTextString(item.MetadataNotes),
"community_rating": numericToFloat(item.CommunityRating),
// NEW: Comic-specific fields
"story_arc": textToString(item.StoryArc),
"story_arc": utils.PgTextString(item.StoryArc),
"is_black_and_white": item.IsBlackAndWhite,
"alternate_info": jsonBytesToMap(item.AlternateInfo),
"scan_information": textToString(item.ScanInformation),
"summary": textToString(item.Summary),
"scan_information": utils.PgTextString(item.ScanInformation),
"summary": utils.PgTextString(item.Summary),
}
}
return c.JSON(http.StatusOK, map[string]interface{}{"data": resolvedItems})
@@ -887,47 +887,47 @@ func (mh *MediaHandler) GetMediaItem(c *echo.Context) error {
"id": uuid.UUID(item.ID.Bytes).String(),
"library_id": uuid.UUID(item.LibraryID.Bytes).String(),
"title": item.Title,
"author": textToString(item.Author),
"isbn": textToString(item.Isbn),
"description": textToString(item.Description),
"author": utils.PgTextString(item.Author),
"isbn": utils.PgTextString(item.Isbn),
"description": utils.PgTextString(item.Description),
"file_path": utils.ResolveMediaURL(item.LibraryID, pgtype.Text{String: item.FilePath, Valid: item.FilePath != ""}),
"file_size": item.FileSize,
"mime_type": textToString(item.MimeType),
"mime_type": utils.PgTextString(item.MimeType),
"cover_image_path": utils.ResolveMediaURL(item.LibraryID, item.CoverImagePath),
"series": textToString(item.Series),
"series": utils.PgTextString(item.Series),
"series_number": item.SeriesNumber,
"tags": item.Tags,
"asin": textToString(item.Asin),
"asin": utils.PgTextString(item.Asin),
"date_published": item.DatePublished.Time.Format("2006-01-02"),
"publisher": textToString(item.Publisher),
"publisher": utils.PgTextString(item.Publisher),
"contributors": item.Contributors,
"language": textToString(item.Language),
"edition": textToString(item.Edition),
"language": utils.PgTextString(item.Language),
"edition": utils.PgTextString(item.Edition),
"page_count": item.PageCount,
"genre": textToString(item.Genre),
"genre": utils.PgTextString(item.Genre),
"created_at": item.CreatedAt.Time.Format("2006-01-02T15:04:05Z07:00"),
"updated_at": item.UpdatedAt.Time.Format("2006-01-02T15:04:05Z07:00"),
"format_group": item.FormatGroup,
"format_mimetype": textToString(item.FormatMimetype),
"format_mimetype": utils.PgTextString(item.FormatMimetype),
"narrators": item.Narrators,
"abridged": item.Abridged,
// NEW: Reading direction fields
"manga_type": textToString(item.MangaType),
"reading_direction": textToString(item.ReadingDirection),
"manga_type": utils.PgTextString(item.MangaType),
"reading_direction": utils.PgTextString(item.ReadingDirection),
// NEW: Universal metadata fields
"series_count": item.SeriesCount,
"volume": item.Volume,
"imprint": textToString(item.Imprint),
"age_rating": textToString(item.AgeRating),
"web_url": textToString(item.WebUrl),
"metadata_notes": textToString(item.MetadataNotes),
"imprint": utils.PgTextString(item.Imprint),
"age_rating": utils.PgTextString(item.AgeRating),
"web_url": utils.PgTextString(item.WebUrl),
"metadata_notes": utils.PgTextString(item.MetadataNotes),
"community_rating": numericToFloat(item.CommunityRating),
// NEW: Comic-specific fields
"story_arc": textToString(item.StoryArc),
"story_arc": utils.PgTextString(item.StoryArc),
"is_black_and_white": item.IsBlackAndWhite,
"alternate_info": jsonBytesToMap(item.AlternateInfo),
"scan_information": textToString(item.ScanInformation),
"summary": textToString(item.Summary),
"scan_information": utils.PgTextString(item.ScanInformation),
"summary": utils.PgTextString(item.Summary),
"library_type_name": textPtrToString(item.LibraryTypeName),
})
}