go test -json implicitly sets testing.Verbose()=true, so the old guard
always printed manga lists through the script. Switched to an env var
(SOURCETEST_VERBOSE=1) set by the script only when -v is passed.
- Guard isCloudflareChallenge with directStatus >= 400 to prevent
overriding status to 0 when no direct request was made
- When FS returns challenge page without a prior direct status,
return an error instead of silently passing HTTP 0
- Restore default FS session ID to 'goyomi' — without a session,
each request spawns a new Chrome, causing timeouts under load
- Add Message field to FlareSolverrResponse for better error reporting
- Document FLARESOLVERR_SESSION env var: shared session = fast after
1st request, but serializes. Set empty for parallel (resource-heavy).
- guya: align JSON structs with current API (seriesListEntry, seriesDetail),
use Cover/Author/Artist fields, fix chapter date parsing via release_date
- iken: update DTO fields to match API (postTitle, featuredImage, etc.),
add JSON-vs-HTML detection, map seriesStatus to source.Status constants
- kemono: set Accept: text/css header for DDOS-Guard bypass
- madtheme: use .book-detailed-item selector, fix pagination detection,
use 'updated_at' sort for latest updates
- mangahub: check cookie jar in addition to Set-Cookie headers, add
retry-once logic for API key expiry (matching Kotlin interceptor)
When -v is passed, test-sources.sh passes it through to go test -v.
sourcetest.Run uses testing.Verbose() to print the full manga list
from GetPopularManga and GetLatestUpdates, showing title + URL.
The domain aquareader.net now redirects to aquareader.org.
Direct access to aquareader.net hits a JS-based tracking intermediary (mks98.com)
via FlareSolverr, while aquareader.org works reliably.
- Fix GraphQL x param: was "POPULAR"/"LATEST", must be per-site source ID
(e.g. "m01"); order type moved to separate mod param
- Add mhub_access cookie acquisition (x-mhub-access header required on all
API calls); cached 10 min, retried with ?reloadKey=1 on failure
- Fix image URLs: construct as imgx.mghcdn.com/{p}{image} from pages JSON
- Fix thumbnail URLs: add thumb.mghcdn.com/ CDN prefix
- Fix hasNext: use len(rows)==30 instead of non-existent count field
- Fix chapter URL format: /{slug}/chapter-{num} matching Kotlin
- Fix page URL parsing to match new chapter URL format
- Add artist and alternativeTitle fields to manga details
- Fix status parsing: "ongoing"/"completed" string values
- Switch from parameterized GQL variables to direct string interpolation
- Add MangaSource field to Config; update all 11 wrapper sources with
their correct per-site source IDs
Based on Kotlin reference verification:
- madtheme, mangabox, mangacatalog, mangahub → flare
Also updated phase4-standalone.md with project requirement for
checking HTTP client type when porting sources from Kotlin
- Remove global ProxyEnabled() logic from httpclient
- Each source now explicitly chooses client at import time:
- flare client: for JS-rendering/cloudflare sources
- normal httpclient: for REST API sources
- Updated 29 base sources based on Kotlin reference (network.cloudflareClient)
- Add FLARESOLVERR_LOG_LEVEL and FLARESOLVERR_PROXY to .env.example
- Change default port to 3300 in dev.env
- Make compose-dev.yml use ADDR env var for host port
- Enable FLARESOLVERR_PROXY by default in dev.env for testing
- Add config table for storing FlareSolverr proxy setting
- Add HTTP endpoints to get/set proxy status (GET/POST /api/config/flaresolverr)
- Refactor httpclient to support proxy mode (requests go through FlareSolverr)
- Add verbose logging for debugging
- Add POST support to FlareSolverr client
Usage:
GET /api/config/flaresolverr - returns {flaresolverr_proxy: bool}
POST /api/config/flaresolverr - body: {enabled: true/false}
- .env.example documents all env vars with defaults (postgres creds, DATABASE_URL, TTLs, pool sizes)
- compose.yml reads postgres credentials and app config from .env via env_file
- .gitignore: track .env.example, ignore .env
- PostgreSQL schema: sources, manga, chapters, pages, source_meta with indexes
- golang-migrate runner with embedded SQL via go:embed (pgx5:// scheme)
- sqlc-generated type-safe queries for all tables (pgx/v5 native)
- Config package with all env vars including TTL durations
- Wire DB init and config into cmd/server/main.go