=== Comic Collector Changelog ===

Complete release history for Comic Collector.

= 2.7.0 =
* WordPress.org compliance: the FAQ/Help Center (comic-collector-faq.html) now loads its PDF-export library (html2pdf.js) from a bundled local copy instead of a remote CDN — no external script is called
* WordPress.org compliance: the public collection shortcode is now registered as the uniquely-prefixed `[comcol_collection]` (was `[comic_collection]`)
* WordPress.org compliance: the Theme "Google Font" setting is now sanitized against a fixed allow-list of supported fonts (the value is used to build the Google Fonts URL), rejecting anything not on the list
* WordPress.org compliance: expanded External Services documentation — added the actual currency-rate endpoint (open.er-api.com), clearer Comic Vine terms/privacy links, and corrected the license-server description

= 2.6.9 =
* Removed the PGX grading lookup and all PGX references — the company is defunct and the service is offline (CGC and CBCS cert lookup are unaffected)
* On update, existing WooCommerce product → comic links are migrated automatically to the new prefixed meta key (no action needed)
* WordPress.org compliance: escaped all remaining echoed output across admin pages, the public collection shortcode, dashboard widgets, and Gutenberg/Elementor blocks (esc_attr/esc_url/wp_kses_post)
* WordPress.org compliance: renamed all generic `CC_`/`cc_` prefixed classes, hooks, the version constant, the pull-list shortcode, the comic product meta key, and admin page slugs to the unique `COMCOL_`/`comcol_`/`comic-collector-` prefix to avoid plugin conflicts
* WordPress.org compliance: documented the Comic Vine and Open Library external services with full terms-of-use and privacy-policy links, and corrected the grading-service legal links
* Security: added an explicit capability check to the Annotations moderation screen
* Security: fully anchored the extension settings-key validation regex so a crafted key suffix cannot slip arbitrary option names through
* Security: the annotation rate limiter now uses the Transients API instead of writing internal `_transient_*` options directly
* Fix: the public collection pagination links no longer double-escape their URLs
* Fix: the Comic Vine API key set in core Settings is now read correctly by every feature that uses it

= 2.6.8 =
* Fix: the PWA service worker (cc-sw.js) and web app manifest (cc-manifest.json) were unreachable on sites with trailing-slash permalinks — WordPress 301-redirected them to a trailing-slash URL, and browsers refuse to register a service worker served behind a redirect. Offline/PWA support now works on such sites

= 2.6.7 =
* New: eBay Marketplace setting (Settings → General) — choose your local eBay site (US, UK, Canada, Australia, Germany, France, Italy, Spain). All eBay buy/search/sell links across the plugin now open on your local site with the correct regional affiliate attribution
* Fix: price inputs now accept European number formats — "12,50" is read as 12.50 instead of 1250, and "1.234,56" as 1234.56. Applies everywhere prices are entered (purchase price, cover price, listing price, etc.)
* Fix: eBay affiliate tracking is now applied to all regional eBay domains (ebay.co.uk, ebay.de, …) — previously only ebay.com links were wrapped
* Note: estimated values continue to use US sold data (the reference market for comic pricing) converted to your display currency

= 2.6.6 =
* Pricing fix: cached PriceCharting product matches are now verified against the comic's title and issue on every lookup — a stale or wrong cached match can no longer price the wrong product (the cause of wildly wrong values like a $4 book showing $200+)
* Pricing fix: when a cached PriceCharting match fails or is rejected, the engine now falls back to a fresh search instead of silently losing its primary source
* Pricing fix: eBay comps for a standard-cover comic now exclude variant/incentive listings (1:25, virgin, foil, Cover B, etc.) — ratio variants listing at many multiples of the standard cover were poisoning values
* Pricing safeguard: weak data (active-listing asks with no PriceCharting/GoCollect/eBay-sold corroboration) can no longer move a comic's value by more than 50% — the existing value is kept and the comic is flagged for review with the proposed value stored in the audit trail
* Pricing fix: when two same-name series tie in match scoring (e.g. "Little Monsters" 2020 vs 2022), the product with actual market data now wins instead of whichever came first
* Currency: listing prices are now converted from USD to the WooCommerce store currency when the store isn't set to USD — previously a $25 comic on a £/€/¥ store was listed as £25/€25/¥25
* Currency: manually entered listing prices are treated as store-currency amounts (what the buyer should see) and converted to USD internally
* Currency: completed-order sale prices are converted from the store currency back to USD so sold-archive revenue and profit stay consistent with USD costs
* Pricing accuracy: graded comics are now valued at their ACTUAL slab grade. PriceCharting's per-grade price ladder (Ungraded through 10.0) is matched to the comic's grade with interpolation between grade anchors — previously every slab used the 8.0/8.5 price regardless of grade
* Pricing accuracy: GoCollect is now used for slabbed comics only — its graded fair-market values were previously applied to raw comics, ignoring the slab premium
* Pricing accuracy: eBay active-listing comps are now restricted to fixed-price US listings — in-progress auctions (current bid, not market price) no longer drag values down
* Pricing accuracy: sold-listing comps no longer discard repeated identical sale prices, and the lookback window now widens to 90 days instead of all-time when recent data is thin
* Pricing accuracy: a variant priced from its standard cover's data (no variant-specific match) is now flagged low-confidence instead of silently trusted
* Pricing: price confidence can now reach "high" when PriceCharting and an independent sold/FMV source agree within 25%
* Pricing reliability: eBay scraping now backs off for 12 hours after repeated HTTP failures instead of burning two requests per comic per refresh (manual refresh still retries)
* Pricing reliability: GoCollect calls are capped at 45/day to stay inside the free tier instead of failing mid-batch
* Pricing observability: per-source hit rates (7 days) now display on the dashboard Tools card, and cron price updates now store the same audit trail as manual refreshes
* New: price sample size (number of market data points behind each value) is stored per comic for liquidity-aware analytics
* Maintenance: price history table is now purged daily (raw source samples kept 30 days, value timeline kept 365 days)
* Manual price refresh no longer discards the cached PriceCharting product match — the divergence check evicts bad matches automatically

= 2.6.5 =
* Pricing accuracy: graded comics are now valued at their ACTUAL slab grade. PriceCharting's per-grade price ladder (Ungraded through 10.0) is matched to the comic's grade with interpolation between grade anchors — previously every slab used the 8.0/8.5 price regardless of grade
* Pricing accuracy: GoCollect is now used for slabbed comics only — its graded fair-market values were previously applied to raw comics, ignoring the slab premium
* Pricing accuracy: eBay active-listing comps are now restricted to fixed-price US listings — in-progress auctions (current bid, not market price) no longer drag values down
* Pricing accuracy: sold-listing comps no longer discard repeated identical sale prices, and the lookback window now widens to 90 days instead of all-time when recent data is thin
* Pricing accuracy: a variant priced from its standard cover's data (no variant-specific match) is now flagged low-confidence instead of silently trusted
* Pricing: price confidence can now reach "high" when PriceCharting and an independent sold/FMV source agree within 25%
* Pricing reliability: eBay scraping now backs off for 12 hours after repeated HTTP failures instead of burning two requests per comic per refresh (manual refresh still retries)
* Pricing reliability: GoCollect calls are capped at 45/day to stay inside the free tier instead of failing mid-batch
* Pricing observability: per-source hit rates (7 days) now display on the dashboard Tools card, and cron price updates now store the same audit trail as manual refreshes
* New: price sample size (number of market data points behind each value) is stored per comic for liquidity-aware analytics
* Maintenance: price history table is now purged daily (raw source samples kept 30 days, value timeline kept 365 days)
* Manual price refresh no longer discards the cached PriceCharting product match — the divergence check evicts bad matches automatically

= 2.6.4 =
* Dashboard: Publisher Breakdown now shows each publisher's logo (with a colored-initial fallback for unrecognized publishers)
* Dashboard: added shared cover-thumbnail styles used by Pro extension widgets (Pull List, Reading List, Offers, Print Run Estimator)

= 2.6.3 =
* Dashboard: new Recent Additions widget — a cover-art strip of the latest comics added to your collection (toggleable from Customize)
* Dashboard: Key Issues widget now shows cover thumbnails next to each issue
* Dashboard: added a Scan button to the header toolbar when the Inventory Scanner Pro extension is active

= 2.6.2 =
* Security: removed unused remote extension-installer code left over from the retired marketplace (PHP handler and all related admin JS)
* Security: added a capability check to the duplicate-comic AJAX lookup
* Security: hardened the PWA service worker endpoint with proper 404/500 handling
* Fixed the comcol_comic_sold action firing twice with inconsistent argument order on WooCommerce sales — listeners now always receive (comic_id, sale_price, order_id)
* Fixed duplicate sold-archive rows and double profit accounting when an order passed through both processing and completed statuses
* Fixed the database schema upgrade routine running on every admin page load
* Internationalization: wrapped all user-facing strings (admin notices, public collection page, offer and annotation forms, emails) for translation, and enabled JS translations via wp.i18n — the plugin is now fully translation-ready

= 2.6.1 =
* Removed forced "Powered by Comic Collector" from user-facing offer emails — only the site/store name is shown
* Added CSS-specific sanitization for theme settings (card shadow, border radius, font family) to prevent CSS injection
* Changed /extensions REST endpoint to require edit_posts capability instead of public access
* Fixed /search REST endpoint exposing estimated_value to unauthenticated users when public value display is disabled
* Added Twilio SMS service disclosure to External Services documentation
* Updated CGC entry to reference the actual API endpoint (api.aws.ccg-ops.com)

= 2.6.0 =
* Added automatic AI model fallback — if one provider returns a quota/rate-limit error (429), automatically retries with the next configured model
* Overhauled AI Insights system prompt to produce actionable, section-based insights instead of generic summaries
* AI Insights now surfaces sell opportunities, hidden gems, portfolio risk, grading candidates, and declining values
* Increased AI max tokens from 800 to 1200 to support richer structured output
* Hardened eBay affiliate tracking — centralized EPN campaign ID with obfuscation and integrity verification
* Removed plaintext affiliate IDs from all plugin source files
* All extensions now use centralized COMCOL_eBay methods for affiliate URL generation

= 2.5.9 =
* Updated AI model preferences to current free-tier-compatible models (gemini-2.0-flash, gpt-4o-mini)
* Added comcol_ai_model_preference filter hook for customizing AI model fallback order
* Centralized model preference into reusable get_model_preference() method

= 2.5.8 =
* Fixed all WordPress.org plugin check errors for escape output compliance
* Fixed unescaped output in Pull List admin tabs, AI settings, Pull List shortcode
* Fixed unescaped output in Elementor Comic Display, Stats, and Grid widgets
* Fixed SQL security scanner errors in Pull List query builder with phpcs annotations
* Restructured Elementor widget render methods for scanner compatibility

= 2.5.7 =
* Fixed WordPress.org plugin check security warnings in Activity Log query builder
* Updated "Tested up to" to WordPress 7.0

= 2.5.6 =
* Added filter hook for variant cover data so Pro can supplement from LOCG releases
* Changed "Pulled" status label to "Owned" across all admin and frontend displays
* Enlarged variant cover thumbnails from 32x48 to 40x60 with border styling
* Added dark mode border color for variant cover thumbnails
* Removed loading="lazy" from variant cover images inside expandable panels
* Removed duplicate description field from variant cover API requests

= 2.5.5 =
* Pull list variant covers display and label improvements

= 2.5.4 =
* Pull list enhancements and bug fixes

= 2.4.0 =
* Added Activity Log — tracks all collection changes (add, edit, delete, sell) with timestamps and details
* Added Activity Log admin page with filterable table, pagination, and clear old entries
* Added Activity Log retention setting in Settings > General
* Added WordPress admin dashboard widget showing collection stats, recent adds, and recent sales
* Added GoCollect CSV import — upload GoCollect exports with auto-detected column mapping
* Added Comic Vine JSON import — upload Comic Vine API response files with cover download support
* Expanded Import page with format auto-detection (XML/CSV/JSON) and per-format documentation
* Improved deduplication across all import formats (barcode, Comic Vine ID, title+issue+publisher)

= 2.3.0 =
* Added Dark Mode — enable separately for admin pages and public collection via Settings > General
* Added frontend dark mode for the public-facing collection shortcode
* Added duplicate detection warnings when adding comics that match existing entries
* Added eBay listing integration with "List on eBay" button for one-click pre-filled listings
* Added eBay affiliate tracking to support continued plugin development

= 2.2.0 =
* Added AI-powered comic identification from cover photos (requires WordPress 7.0+)
* Added AI smart search for natural-language wishlist queries
* Added AI collection insights and lot description generation
* Added AI settings section with usage tracking and rate limiting
* Fixed duplicate plugin folder creation on ZIP upload (upgrader_source_selection filter)
* Fixed "Type ERASE to confirm" input truncation in Danger Zone settings

= 2.1.2 =
* Major pricing accuracy overhaul
* Search queries now include volume and year for precise series disambiguation
* PriceCharting results validated against requested issue number to prevent cross-issue contamination
* Fixed cache key collisions that caused consecutive issues to share prices
* Lot/bundle listings filtered from eBay sold data for raw comics
* eBay searches narrowed to Comic Books category (259104) with negative keyword filtering
* Source weight rebalancing — PriceCharting and GoCollect weighted higher as trusted references
* Divergence filtering discards eBay outliers when they conflict with reference sources
* Recentered condition multiplier baseline from NM (9.4) to VF (8.0) to match eBay sold averages
* Raised scraping price floor from $1 to $3 to exclude junk listings

= 2.1.0 =
* Added multi-currency support with automatic exchange rate conversion
* Added Metron, GCD, and Open Library as additional data sources
* Added A-Z alphabet filter to public collection shortcode
* Added community annotations system
* Added custom fields support
* Improved API key management in settings
* Various bug fixes and performance improvements

= 2.0.0 =
* Major release with extension ecosystem support
* Added REST API (comcol/v1 namespace)
* Added Gutenberg blocks and Elementor widgets
* Added PWA support
* Added CSS variable theming
* Added onboarding wizard
* WooCommerce integration improvements

= 1.0.0 =
* Initial release
