Releases: javinizer/javinizer-go
Releases · javinizer/javinizer-go
Javinizer v0.3.4-alpha (Pre-release)
[v0.3.4-alpha] - 2026-05-02
Fixed
- Replace contentIDMatchesExpected with core series+number validation (contentIDCoreMatch) to reach 97.7% r18.dev match rate, ignoring suffix mismatches that caused 84% of old failures
- Remove generateAlternateContentIDs fallback which matched 0% of misses due to only trying 4 hardcoded maker codes out of 7,704
- Prevent ONED-025 false positive resolving to ONED-205 by validating core number match
Javinizer v0.3.3-alpha (Pre-release)
[v0.3.3-alpha] - 2026-05-02
Added
- Completeness scoring system with configurable essential/important/nice-to-have tiers and weighted percentage calculation
- CompletenessDial SVG component with tier-appropriate colors (red/yellow/green) and hover breakdown tooltip
- Completeness filter buttons on review page to filter movies by Incomplete/Partial/Complete
- Grid card selection mode with shift-click range selection, select all/deselect all, and bulk exclude/rescrape actions
- Review page grid view with poster and cover display modes (3-column layout for cover art)
- WebUI config section with
default_review_viewsetting (detail, grid-poster, grid-cover) and settings UI - Runes-based global background-job store (
$state) replacing local component state for cross-page persistence - BackgroundJobIndicator and ProgressModal moved to authenticated layout so they persist across page navigation
- BackgroundJobIndicator redesigned as theme-aware card (
bg-card) with status-tinted rings and lucide icons - All Go backend job statuses handled in indicator and modal (completed, failed, cancelled, organized, reverted, pending, running)
- Status-specific success messages in ProgressModal (scraping completed, organization complete, revert complete)
- Real-time job progress synchronization on /jobs page via WebSocket-derived
computeJobProgressutility - Auto-polling (5s interval) for running jobs on /jobs page, stopping when no jobs are running
liveProgressin ProgressModal derived from WebSocket data instead of REST API polling- Shared
$lib/utils/job-progress.tsutility withTERMINAL_STATUSES,isTerminalStatus(), andcomputeJobProgress() clearJobMessages()method on websocket store for evicting stale per-job data- WebSocket store deep-copy for
messagesByFileper-job records (store immutability) - Capped WebSocket
messagesarray at 200 entries to prevent unbounded growth - Playwright E2E test suite (98 tests) for review page: completeness dial, selection mode, bulk actions, view toggle, keyboard navigation, filter persistence, and edge cases
- Review state unit tests for completeness computation and view mode handling
- Completeness utility tests for tier scoring, edge cases, and custom weight validation
- Batch rescrape endpoint with scraper selection, NFO merge strategy presets, and progress indicator
- Batch exclude endpoint with per-movie and bulk exclusion support
- Movie edit PATCH endpoint for inline field editing on review page
Updatefield persisted onBatchJobandBatchJobSlimfor update mode tracking- Database migration
000008_jobs_update_column.sqlfor jobs update column - Comprehensive backend test coverage: batch rescrape (unit + integration), batch exclude integration, API handlers (actress, auth, genre, history, events, version, system, jobs), config validation/redact, NFO merger DMMID preservation, database helpers/race branches, WebSocket hub nil guards, fsutil move, httpclient builder, DMM scraper helpers, worker single_scrape branches
Changed
- Rename
metadata-onlyoperation mode tometadata-artworkacross codebase (Go types, organizer strategy, config, tests) - Derive version from git tags/commit hash instead of embedded
version.txtfile (removedversion.txt) - Review page view mode is now 3-state:
detail | grid-poster | grid-cover(legacygridmaps togrid-poster) - ProgressModal uses two separate
$effectblocks withuntrack()to avoidcancelRedirectcircular dependency - ProgressModal auto-redirect countdown now guarded by
hasNavigatedflag preventing duplicate navigation - ProgressModal
latestMessagederived frommessagesByFileinstead of cappedmessagesarray TERMINAL_STATUSESaligned with Go backend:completed,failed,cancelled,organized,reverted(removed non-existentdoneandskipped)createBatchJobPollingQueryusesisTerminalStatus()to stop polling for all terminal statuses- Homepage
activeJobCountuses sharedisTerminalStatusutility instead of inline Set - E2E test selectors updated from
/^grid$/ito/^poster$/ifor view mode toggle buttons
Fixed
- Scraped movies now always persisted to database regardless of custom scraper selection
- NFO actress merge preserves DMMIDs from scraped data when matching by JapaneseName or romanized name
- Omit
TranslationsinUpsertto prevent transaction rollback on orphaned rows - Frontend review page reads destination from job data instead of query param
- Actress search switched to server-side to prevent client-side performance issues
- svelte-check added to pre-commit hook to catch TypeScript errors early
- BackgroundJobIndicator auto-dismiss timer re-arms when user closes modal after terminal status (tracks
showModalas dependency) - Auto-dismiss timer callback guards against null
jobIdand verifies prop matches store's current jobId - ProgressModal dismisses job store state after successful
goto()navigation (handles rejection too) reopenModal()guards against nulljobIdto prevent inconsistent store stateMath.max(0, ...)for remaining files count whencompleted + failed > total_files(retry scenarios)- Windows path separators handled in browse page file display (
split(/[\\/]/)) - Unnecessary
Record<string, any>type assertion removed from browse page config access
Javinizer v0.3.2-alpha (Pre-release)
[v0.3.2-alpha] - 2026-05-01
Added
- API token authentication with bearer tokens (jv_ prefix, SHA-256 hash storage, one-time display)
- Token CRUD REST endpoints: POST/GET/DELETE /api/v1/tokens, POST /api/v1/tokens/:id/regenerate
requireTokenOrSessionmiddleware coexisting with existing session/cookie authjavinizer token create/revoke/listCLI subcommands with--jsonoutput- API Tokens section in web UI settings with create, revoke, and regenerate flows
- TokenDisplayModal with security warning, copy-to-clipboard, and one-time display pattern
- Rate limiting on token write endpoints (create, revoke, regenerate)
Fixed
- TokenService.Validate() now uses synchronous UpdateLastUsed matching middleware behavior
- Token CRUD endpoints moved to writeProtected group with IP rate limiting
Javinizer v0.3.1-alpha (Pre-release)
[v0.3.1-alpha] - 2026-04-30
Added
- Word replacement (uncensor) system with database-backed replacements and API endpoints
- Import/export API endpoints for genres, actresses, and word replacements
- Frontend types and API client methods for import/export
- Import/export UI to genres, words, and actresses pages
- CLI word command with list/add/remove/export/import subcommands
- Import/export subcommands to genre and actress CLI commands
- Playwright e2e test infrastructure
- E2e tests for import/export with fixtures
- E2e auth mode with rate limit bypass
- E2e tests for import/export across all three features
- Support both id and original query params for genre/word deletion endpoints
Fixed
- R18.dev scraper reliability — rental ID handling, direct URL fallback, alternate content IDs, nil guards, regex dedup
- DMM scraper hardening — priority scaling, cover extraction, proxy auth, JSON parsing, nil guards
- Replace remaining native confirm() with confirmDialog
- Hide Review & Organize button when no files completed successfully
- Address code review findings on import/export and Upsert paths
- TypeScript type errors in e2e tests
- SQLite lock detection — add string-based fallback for database is locked errors in retryOnLocked
- E2e runner port check to only match LISTEN state
- Export endpoints to use GET instead of POST
Changed
- Switch genre/word replacement deletion from original-key to ID-based (both id and original params supported)
- Gitignore Playwright test artifacts (test-results/, auth-state.json)
Javinizer v0.3.0-alpha (Pre-release)
[v0.3.0-alpha] - 2026-04-29
Added
- StandardModule base struct and BaseScraperConfig eliminating ~2,150 lines of module.go boilerplate across 14 scrapers
- ValidateCommonSettings shared validation function replacing 14 identical validation blocks
- NewScraperHTTPClient and InitScraperClient helpers replacing 14 per-scraper httpclient.go files
- BaseRepository[T, ID] generic struct with CRUD methods for 12 database repositories
- ResolveNFOPath/FindNFOFile shared helpers replacing triplicated NFO path discovery logic
- FormatActressName package-level function consolidating duplicated implementations
- core.ParsePagination helper replacing 4 duplicated limit/offset parsing implementations
- toHistoryRecord and paginateAndConvert helpers eliminating 4x copy-pasted conversion blocks
- Svelte-query QueryClientProvider with SSR-safe lazy client module
- Poster-from-url, exclude-movie, and save-edits mutations using createMutation
- Shared query helpers for config and scrapers with cache deduplication
- createBatchJobPollingQuery helper with refetchInterval for polling components
- Reactive actress list query with CRUD mutations and merge flow
- Dark mode with class-based toggle and styling across all pages
- Grid view for review page with ReviewGridCard and viewMode toggle
- Use-as-poster button for screenshots in review page
- Favicon for web frontend
- unknown_actress_mode config (skip by default, fallback for placeholder)
- Use-as-poster backend with poster generation, reset, and cache-busting
- Shift-click range selection for files and persistent recursive checkbox
- Translation warnings propagated to frontend UI
Fixed
- Recursive chown on /javinizer for Unraid compatibility — fixes pre-existing root-owned files from prior versions
- Convert javstash runtime from seconds to minutes
- JavLibrary search result parsing: handle current HTML format with videothumblist divs, multiline HTML, attribute-order independence
- JavLibrary double language segment in URL construction when legacy pattern returns /en/?v=...
- JavLibrary over-broad cover-screenshot filter that removed all screenshots
- FlareSolverr proxy bypass in direct mode — removed fallback that overrode empty proxyProfile
- URL encoding for query parameters in GetURL/ScrapeURL
- Missing template tags and YEAR/Translations data loss
- Template structure preservation during MaxPathLength truncation
- Truncated path names use ~ instead of ... with improved in-place preview path display
- Umask respected in file/directory permissions for Docker group-write support
- MGStage prefixed IDs (GANA-2850 → 200GANA-2850) and hyphenated ID format for search queries
- Actresses matching unknown_actress_text filtered from scraper results
- Stale actress/genre associations cleared when upserting with empty lists
- Global scraper priority merged as fallback when per-field overrides exclude sources
- Actress name keys normalized in aggregator and batch jobs cancelled when all movies excluded
- DMM-resolved ContentID propagated as fallback with diagnostic logging
- Operation_mode forwarded in organize request
- Organizer regression: copyOnly path, subtitle handling, truncation guards
- OOM issue #13: reduced memory in crop/placeholder/dimension reads, persist poster crop state
- Output preview refreshed when movie fields are edited on review page
- Genre replacement DELETE uses query param to handle special characters
- Local state used instead of direct onUpdate for Use as Poster
- Live R18.dev test skips on 403 instead of failing
- Direct proxy mode does not leak global proxy to FlareSolverr
- Inherit proxy mode passes global proxy to FlareSolverr
Changed
- All 14 scrapers migrated to shared infrastructure (StandardModule, BaseScraperConfig, shared HTTP client)
- All frontend pages migrated from manual fetch + $state patterns to TanStack svelte-query
- MoveToFolder/RenameFolderInPlace removed from OutputConfig, API contracts, and frontend
- Deprecated merge_strategy removed from NFOComparisonRequest API contracts and Swagger
- Deprecated MergeMovieMetadata() and ParseMergeStrategy() functions removed
- No-op validateNoLegacyProxyDirectFields() stub removed, rejectUnknownProxyFields() wired
- Stale artifacts deleted: coverage files, root binaries, orphaned testdata, stale docs
- Preview generation refactored to use OperationStrategy.Plan()
- 86 files changed, +3,795/-1,598 lines
Added
- Persist file browser sort preference across navigation within session
- Use '...' truncation marker with '~' fallback for trailing dots
- Auto-switch operation mode to 'Rename file only' when destination matches source path with empty folder/subfolder format
Fixed
- Prevent blank file on Windows when src==dst and harden preview/organizer edge cases
- Windows mixed slashes in preview and empty folder format creating unwanted subfolders
Added
- Add client-side pagination to FileBrowser
- Add pagination controls above file list in FileBrowser
Fixed
- Allow same-origin WebSocket and CORS when AllowedOrigins is configured
- Remove user directive from docker-compose to enable entrypoint privilege bootstrap
- Add Docker defaults for setup CIDRs and fix bind mount ownership
- Allow Docker bridge access to /auth/setup via configurable trusted CIDRs
- Resolve AP-288 404 from r18.dev by accepting blank dvd_id with validated content_id fallback
- Add TokyoHot short-prefix ID matching and search query resolution
Changed
- Add GitHub issue templates for bug reports, feature requests, and scraper issues
Javinizer v0.2.11-alpha (Pre-release)
[v0.2.11-alpha] - 2026-04-26
Added
- Persist file browser sort preference across navigation within session
- Use '...' truncation marker with '~' fallback for trailing dots
- Auto-switch operation mode to 'Rename file only' when destination matches source path with empty folder/subfolder format
Fixed
- Prevent blank file on Windows when src==dst and harden preview/organizer edge cases
- Windows mixed slashes in preview and empty folder format creating unwanted subfolders
Added
- Add client-side pagination to FileBrowser
- Add pagination controls above file list in FileBrowser
Fixed
- Allow same-origin WebSocket and CORS when AllowedOrigins is configured
- Remove user directive from docker-compose to enable entrypoint privilege bootstrap
- Add Docker defaults for setup CIDRs and fix bind mount ownership
- Allow Docker bridge access to /auth/setup via configurable trusted CIDRs
- Resolve AP-288 404 from r18.dev by accepting blank dvd_id with validated content_id fallback
- Add TokyoHot short-prefix ID matching and search query resolution
Changed
- Add GitHub issue templates for bug reports, feature requests, and scraper issues
Javinizer v0.2.10-alpha (Pre-release)
[v0.2.10-alpha] - 2026-04-25
Added
- Add client-side pagination to FileBrowser
- Add pagination controls above file list in FileBrowser
Fixed
- Allow same-origin WebSocket and CORS when AllowedOrigins is configured
- Remove user directive from docker-compose to enable entrypoint privilege bootstrap
- Add Docker defaults for setup CIDRs and fix bind mount ownership
- Allow Docker bridge access to /auth/setup via configurable trusted CIDRs
- Resolve AP-288 404 from r18.dev by accepting blank dvd_id with validated content_id fallback
- Add TokyoHot short-prefix ID matching and search query resolution
Changed
- Add GitHub issue templates for bug reports, feature requests, and scraper issues
Javinizer v0.2.9-alpha (Pre-release)
[v0.2.9-alpha] - 2026-04-22
Fixed
- Apply environment variable overrides (DEEPL_API_KEY, OPENAI_API_KEY, etc.) before config validation in
LoadOrCreate(), preventing "api_key is required" errors when keys are set via env vars but empty in config file - Persist per-field scraper priorities to config file and add scrollbar to priority modal
- Clean
web/distbeforegit checkoutto remove stale build artifacts - Update
with_embedded_web.shrestore_placeholder to usegit checkout - Add
ACTRESSsingular tag and fixACTORNAMEto resolve from actress data instead of movie title - Add
subfolder_pathto organize preview response and improve cross-platform compatibility - Add cross-device move fallback to file organizer
Changed
- Switch nightly releases to commit-hash tagging scheme
- Remove duplicated
web/placeholderdir, usegit checkoutin Makefile restore target
Javinizer v0.2.8-alpha (Pre-release)
[v0.2.8-alpha] - 2026-04-19
Added
- Windows CI test runner for path-specific bug detection
fsPath()helper ininternal/history/reverter.gothat normalizes paths for afero MemMapFs (forward-slash + drive letter stripping)filepath.ToSlash()normalization onWillMovepath comparisons in organizer strategies to prevent false positives on Windowsfilepath.ToSlash()normalization onisDescendant()path comparisons for cross-platform directory hierarchy checks- Windows volume root detection in
cleanupEmptyDirtermination conditions runtime.GOOS == "windows"skip guards for Unix-only tests (file permissions, shell scripts,/dev/null, concurrent file locking)
Fixed
- Windows path separator mismatches in organizer plan tests and batch preview tests (hardcoded
/vs\fromfilepath.Join) - Windows file handle locks preventing
t.TempDir()cleanup — addeddefer CloseLogger()anddefer db.Close()in test helpers - Windows
filepath.IsAbsreturning false for\dest\...paths (no drive letter) in multipart test - Windows tilde expansion failure in
validateNFOPath—filepath.Join("~", ...)produces~\...which doesn't match the~/prefix check - Windows double-slash in database error messages — normalized with
strings.ReplaceAll("//", "/")afterfilepath.ToSlash - Windows
WillMoveincorrectlytruewhen source/target paths differ only in separator style (production bug inorganizer.go,strategy_organize.go,strategy_inplace.go,strategy_inplace_norenamefolder.go) - Windows
isDescendant()failing to detect descendant paths due to separator mismatch - Windows
cleanupEmptyDirwalking past drive root — addedfilepath.VolumeNameroot detection - Windows concurrent config writer test timing out due to different file locking semantics
- Windows
fsPath()drive-letter check order — check beforefilepath.ToSlash()to avoid dead code - Windows afero MemMapFs path lookup failures in
ReadNFOSnapshot— usefsPath()to strip drive letter and normalize separators - Windows LogDir output using backslash separators — apply
filepath.ToSlashinoverrides.go
Added
FormatActressNameshared helper ininternal/models/movie.godeduplicatingActress.FullName()andActressInfo.FullName()implementationsScraperOptionandScraperChoicetypes moved frominternal/api/contractstointernal/models/with backward-compatible aliases, eliminating reverse dependency where all 14 scrapers imported the API layerJobRepositoryInterface.Upsert()method replacing read-then-writeFindByID→Create/Updatepattern with single atomic operationUpdateRequeststruct forPOST /api/v1/batch/{id}/updatewithforce_overwrite,preserve_nfo,preset,scalar_strategy,array_strategy,skip_nfo,skip_downloadfieldsskip_nfoandskip_downloadfields onOrganizeRequestforPOST /api/v1/batch/{id}/organize- Update options UI in review page header (force overwrite, preserve NFO, skip NFO, skip download toggles) with collapsible options panel
- Organize options UI in destination settings card (skip NFO, skip download toggles)
- Older-than-days cleanup picker on Jobs page with "Clean History" and "Clean Events" buttons and client-side validation
- Version check section in ServerSettingsSection: current/latest version display, "Update available" badge, "Check for Updates" button, error state handling
getVersionStatus()andcheckVersion()API client methodsVersionStatusResponseTypeScript interface with error field- Server-side validation rejecting
force_overwrite+preserve_nfoas mutually exclusive (returns 400) presetbinding validation (oneof=conservative gap-fill aggressive)- 1MB request body size cap on update endpoint via
io.LimitReader
Changed
- Javstash scraper
module.goproxy declaration changed from value typeconfig.ProxyConfigto pointer type*config.ProxyConfig, matching the pattern used by all other 13 scrapers AggregatorOptionsandAggregatorstruct fields changed from concrete*database.GenreReplacementRepository/*database.ActressAliasRepositoryto interface typesdatabase.GenreReplacementRepositoryInterface/database.ActressAliasRepositoryInterfaceprocessUpdateJobandprocessUpdateModenow accept*UpdateOptionsparameter for configurable update behaviorprocessOrganizeJobnow acceptsskipNFOandskipDownloadparametersupdateBatchJobhandler now parses optionalUpdateRequestbody (backward compatible with empty body), validates job existence/status before body parsing, and returns 400 for malformed JSONpersistToDatabaseusesUpsertinstead ofFindByID+Create/Update, eliminating persistence race condition- All 14 scraper module.go files updated to import
models.ScraperOption/models.ScraperChoiceinstead ofcontracts.ScraperOption/contracts.ScraperChoice - Downloader HTTP client creation deferred until actually needed —
skip_download=trueno longer triggers downloader setup, preventing proxy/registry errors on NFO-only updates preserve_nfonow usesPreserveExistingmerge strategy (notPreferNFO) to prevent blanking fields when existing NFO is incompletepreserve_nfotakes final precedence after preset resolution, preventing silent override- DisplayTitle templating runs for ALL update paths (including
force_overwrite), not just the NFO merge block - Preview
$effectreactive to skip toggles viavoidreferences; retry path persists last update options and skip flags - Force Overwrite and Preserve NFO made mutually exclusive in UI via reactive
$effects - Test databases switched from in-memory shared-cache SQLite to temp file-based SQLite with WAL mode, eliminating
database table is lockedflaky test failures under concurrency - Cross-platform path utility (
path.ts) withsplitPath,buildPathUp,buildBreadcrumbPath,isRootPathfunctions for Windows/Unix path handling - FileBrowser breadcrumb navigation, "go up" button, and path construction now use cross-platform path utility instead of Unix-only logic
- OperationRow truncated paths now show 40/60 head-tail split with click-to-expand/collapse
- 54 files changed, ~1,192 lines added, ~468 lines removed
Javinizer v0.2.5-alpha (Pre-release)
Full Changelog: v0.2.4-alpha...v0.2.5-alpha