Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
af71723
feat(filters): add 18 predefined query filters with global scope
davidp57 Feb 3, 2026
09159cb
added documentation
davidp57 Feb 3, 2026
59e98c9
chore(openspec): archive add-predefined-queries change
davidp57 Feb 3, 2026
7021c5b
chore: remove .github and openspec from version control
davidp57 Feb 8, 2026
079254e
Revert "feat: make LOCAL_GAMES_PATHS editable in Settings UI"
davidp57 Feb 8, 2026
9e59762
bug: corrected prefixing of columns in the SQL queries (and added a t…
davidp57 Feb 8, 2026
dee5123
bug: corrected unclosed SQL query (and added a test case)
davidp57 Feb 8, 2026
5ee9bbd
bug: removed unused imports
davidp57 Feb 8, 2026
862b96a
bugs:
davidp57 Feb 8, 2026
a2a501d
bug: pinned fastapi to >=0.89.0
davidp57 Feb 8, 2026
b2e8e2a
fix: reverted auto-refresh when selecting filters (and added an Apply…
davidp57 Feb 8, 2026
2dbb8ec
fix: reverted auto-refresh when selecting filters (and added an Apply…
davidp57 Feb 9, 2026
c8cea54
fix: updated filters.css to handle responsive design on mobile phones.
davidp57 Feb 9, 2026
79919ef
fix: updated query_filter_counts and removed dead .games-grid CSS rule
davidp57 Feb 9, 2026
c7b4bd2
fix: restore /random endpoint to single-game redirect with global fil…
davidp57 Feb 9, 2026
d736596
added Claude config to .gitignore
davidp57 Feb 9, 2026
78b4273
bug fix - missing CSS
davidp57 Feb 9, 2026
d2ef1b9
feat: implement labels system with priority and personal ratings
davidp57 Feb 9, 2026
e8b1fc2
feat: add priority and rating UI to bulk actions
davidp57 Feb 9, 2026
c1daa16
feat: add priority and rating badges on game cards
davidp57 Feb 9, 2026
9e92686
fix: update collections routes to use labels tables
davidp57 Feb 9, 2026
2e9fa42
feat: add manual playtime tag UI for bulk operations
davidp57 Feb 9, 2026
60ea75f
fix: correct parameter name for manual playtime tag endpoint
davidp57 Feb 9, 2026
bcecaf2
fix: migrate system labels to English and handle null tags
davidp57 Feb 9, 2026
5665dc1
fix: improve playtime dropdown positioning
davidp57 Feb 9, 2026
23d0fd5
feat: replace alert dialogs with toast notifications
davidp57 Feb 9, 2026
3eadc8b
feat: add Shift-click range selection for games
davidp57 Feb 9, 2026
2650028
feat: add quick actions on game detail page
davidp57 Feb 9, 2026
e3539b0
updated UI and backend for Gameplay tags
davidp57 Feb 10, 2026
1e83606
completed the user tags and edit feature; added tests and documentation
davidp57 Feb 10, 2026
af0a7f6
feat: merge MAIN into feat-global-filters and complete post-merge QA
davidp57 Feb 18, 2026
20d69d0
Merge branch 'feat-global-filters' into feat-multiple-edit-tags-and-a…
davidp57 Feb 18, 2026
509a29a
style: amΓ©liorer la visibilitΓ© des boutons d'Γ©dition sur game_detail
davidp57 Feb 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 0 additions & 52 deletions .github/workflows/docker-publish.yml

This file was deleted.

29 changes: 28 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
# Copilot documentation
.copilot-docs/

# OpenSpec workflow and GitHub configs
openspec/

# Docker
data/
.empty/
Expand Down Expand Up @@ -223,4 +226,28 @@ marimo/_lsp/
__marimo__/

# Streamlit
.streamlit/secrets.toml
.streamlit/secrets.toml

# Claude code
.claude/
.github/prompts/opsx-apply.prompt.md
.github/prompts/opsx-archive.prompt.md
.github/prompts/opsx-bulk-archive.prompt.md
.github/prompts/opsx-continue.prompt.md
.github/prompts/opsx-explore.prompt.md
.github/prompts/opsx-ff.prompt.md
.github/prompts/opsx-new.prompt.md
.github/prompts/opsx-onboard.prompt.md
.github/prompts/opsx-sync.prompt.md
.github/prompts/opsx-verify.prompt.md
.github/skills/openspec-apply-change/SKILL.md
.github/skills/openspec-archive-change/SKILL.md
.github/skills/openspec-bulk-archive-change/SKILL.md
.github/skills/openspec-continue-change/SKILL.md
.github/skills/openspec-explore/SKILL.md
.github/skills/openspec-ff-change/SKILL.md
.github/skills/openspec-new-change/SKILL.md
.github/skills/openspec-onboard/SKILL.md
.github/skills/openspec-sync-specs/SKILL.md
.github/skills/openspec-verify-change/SKILL.md
.github/copilot-instructions.md
141 changes: 130 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,137 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- **Editable local games paths in Settings UI (non-Docker)**: Users running Backlogia locally can now configure game folder paths directly from the Settings page without needing to edit environment variables or .env files
- **Docker deployment detection**: Automatically detects Docker environment and adapts UI accordingly

**From feat-multiple-edit-tags-and-actions branch:**
- **Comprehensive test coverage for labels system**: 62 new tests covering all metadata and bulk operations:
- API integration tests (32 tests): All priority, rating, manual tag, and bulk operation endpoints
- Database migration tests (12 tests): Collections→labels migration, metadata columns, CASCADE behavior
- Manual tag persistence tests (5 tests): Auto vs manual tag conflict resolution, non-Steam games
- Edge case tests (13 tests): Games with all metadata, system label deletion, NULL playtime handling, large library performance
- **Complete API documentation**: New `docs/api-metadata-endpoints.md` with request/response examples, curl commands, and error codes for all 13 metadata endpoints
- **Enhanced user documentation**:
- Quick Start guide with step-by-step workflows (auto-tagging, priorities, ratings, bulk actions, collections)
- FAQ section with 12 common questions (e.g., "Why aren't my Epic games auto-tagged?", "Do manual tags get overwritten?")
- Keyboard shortcuts documentation for multi-select mode (Shift-click range selection)
- **Developer contribution guide**: New `docs/contributing-labels-system.md` with:
- System architecture diagrams (database schema, auto column lifecycle)
- Tutorial for adding new system labels with code examples
- Tutorial for adding new metadata fields (completion_status example)
- Performance optimization techniques (batch processing, caching, indexing)
- Migration best practices (idempotency, testing, rollback procedures)

**From feat-global-filters branch (Merge MAIN β†’ feat-global-filters):**
- **Predefined query filters system**: 18 quick filters organized in 4 categories for better library organization:
- **Gameplay** (5 filters): Unplayed, Played, Started, Well-Played, Heavily-Played
- **Ratings** (7 filters): Highly-Rated, Well-Rated, Below-Average, Unrated, Hidden Gems, Critic Favorites, Community Favorites
- **Dates** (5 filters): Recently Added, Older Library, Recent Releases, Recently Updated, Classics
- **Content** (2 filters): NSFW, Safe
- **Global filter persistence**: 6 global filters (stores, genres, queries, excludeStreaming, noIgdb, protondbTier) persist across all pages via localStorage
- **Random page**: New `/random` endpoint with full page displaying configurable number of random games (default 12, max 50) with filter support
- **Reusable filter components**: Component-based architecture with `_filter_bar.html`, `filters.css`, and `filters.js` for consistent UX
- **2-tier caching system** for IGDB data:
- **Tier 1 (Memory)**: 15-minute cache for instant page loads (~0ms)
- **Tier 2 (Database)**: 24-hour persistent cache surviving restarts
- Hash-based invalidation on library changes
- Filter-specific caching (each filter combo gets own cache)
- **Advanced filter suite** (4 new filters):
- **Collection filter**: Show games from specific user collections
- **ProtonDB tier filter**: Hierarchical Steam Deck compatibility (Platinum > Gold > Silver > Bronze)
- **Exclude streaming**: Hide cloud gaming services (Xbox Cloud, GeForce NOW)
- **No IGDB data**: Show games missing IGDB metadata for curation
- **Xbox Game Pass integration**: Authentication via XSTS token, market/region selection, subscription plan configuration
- **CSS architecture refactoring**: Externalized 2000+ lines of inline CSS to shared files (`filters.css`, `shared-game-cards.css`, `discover-hero.css`)
- **Optional authentication system**: Password protection with bcrypt hashing and signed session tokens (opt-in via `ENABLE_AUTH`)
- **Docker environment detection**: Auto-detects Docker and disables LOCAL_GAMES_PATHS editing (use volume mounts instead)
- **Progressive Web App meta**: Theme color support for better mobile/PWA experience

**Combined features:**
- **Complete filter system**: 18 predefined queries + 4 advanced filters working in harmony
- **Performance optimizations**:
- Database indexes on frequently filtered columns (playtime_hours, total_rating, added_at, release_date, nsfw, last_modified)
- Discover page: 1 UNION ALL query for DB categories + parallel IGDB API fetching
- 2-tier caching: 99.95% faster on cached loads
- **Comprehensive test suite**: 120+ tests covering filters, caching, edge cases, performance, labels system
- **Complete documentation**: Filter system architecture, SQL reference, merge documentation, API reference

### Changed
- Settings UI now conditionally renders based on deployment mode:
- **Non-Docker**: Editable input field for `LOCAL_GAMES_PATHS` with database storage
- **Docker**: Read-only display with instructions for configuring via `.env` and `docker-compose.yml`
- Docker deployments prevent `LOCAL_GAMES_PATHS` from being saved through the UI (paths must be volume-mounted)
- Settings template updated with deployment-specific instructions and help text
- **Filter behavior**: Filters are always global for simpler UX (no toggle needed)
- **Filter application**: Auto-apply with 300ms debounce using event delegation
- **Global filter count**: Expanded from 3 to 6 global filters (stores, genres, queries, excludeStreaming, noIgdb, protondbTier)
- **Discover page architecture**: Immediate render + AJAX for IGDB sections (non-blocking)
- **Filter bar**: Extended with 4 advanced filter UI components
- **JavaScript buildUrl()**: Signature extended from 6 to 10 parameters for advanced filters
- **Custom dropdowns**: Replaced native select elements with styled dropdowns for dark theme
- **Settings UI**: Conditional rendering based on Docker/bare-metal deployment
- **CSS organization**: Inline styles moved to external cacheable files

### Fixed
- **Global filter persistence**: Advanced filters (excludeStreaming, noIgdb) now persist across pages
- **Filter synchronization**: Defensive dual-save strategy (buildUrl + saveCurrentFilters) ensures robust persistence
- **Navigation link interception**: Global filters automatically added to Library/Discover/Collections/Random links
- **Docker localStorage conflicts**: Browser cache requires Ctrl+F5 hard refresh after code changes
- **Column validation**: PRAGMA-based sort column detection prevents SQL errors on schema changes
- **Filter state persistence**: Event delegation for dynamically loaded filter checkboxes
- **Recently Updated filter**: Works for all stores (uses `last_modified` field)

### Technical Details
- Modified `web/routes/settings.py` to detect Docker environment using `/.dockerenv` file
- Added conditional rendering in `web/templates/settings.html` based on `is_docker` flag
- POST handler skips `LOCAL_GAMES_PATHS` database save in Docker mode
- Added `.copilot-docs/` to `.gitignore` for development documentation

**From feat-multiple-edit-tags-and-actions branch:**
- **New files**:
- `tests/test_api_metadata_endpoints.py`: API integration tests for metadata endpoints (32 tests)
- `tests/test_database_migrations.py`: Database migration tests (12 tests)
- `tests/test_edge_cases_labels.py`: Edge case tests for labels system (13 tests)
- `docs/api-metadata-endpoints.md`: Complete API reference with examples and error codes
- `docs/contributing-labels-system.md`: Developer guide for labels system contributions
- `web/routes/api_metadata.py`: REST API for game metadata (priority, rating, manual tags, bulk operations)
- **Modified files**:
- `tests/test_system_labels_auto_tagging.py`: Added 5 manual tag persistence tests
- `docs/system-labels-auto-tagging.md`: Added Quick Start guide, FAQ (12 questions), keyboard shortcuts
- `web/database.py`: Added labels tables migration, metadata columns
- **Database schema**:
- Migrated `collections` β†’ `labels` system with CASCADE delete
- Added `game_labels` junction table (game_id, label_id, added_at)
- Added `priority` and `personal_rating` columns to `games` table

**From feat-global-filters branch (Merge MAIN β†’ feat-global-filters):**
- **New files**:
- `web/utils/filters.py`: Filter definitions (PREDEFINED_QUERIES, QUERY_DISPLAY_NAMES, QUERY_CATEGORIES, QUERY_DESCRIPTIONS)
- `web/templates/_filter_bar.html`: Reusable filter bar component with 4 advanced filters
- `web/templates/random.html`: Random games page with grid layout
- `web/static/css/filters.css`: Filter bar styles (~500 lines)
- `web/static/css/shared-game-cards.css`: Game card components (~800 lines)
- `web/static/css/discover-hero.css`: Discover page hero section (~600 lines)
- `web/static/js/filters.js`: Global filter management with 6 global filters
- `tests/test_predefined_filters.py`: Unit tests (26)
- `tests/test_predefined_filters_integration.py`: Integration tests (26)
- `tests/test_empty_library.py`: Empty library tests (7)
- `tests/test_large_library_performance.py`: Performance tests (6)
- `tests/test_recently_updated_edge_case.py`: Edge case tests (4)
- `tests/test_advanced_filters.py`: Advanced filter tests (15)
- `tests/test_caching_system.py`: 2-tier cache tests (19)
- `requirements-dev.txt`: Development dependencies (pytest, pytest-cov, ruff)
- `.copilot-docs/filter-system.md`: Filter system architecture
- `.copilot-docs/filter-sql-reference.md`: SQL conditions reference
- `.copilot-docs/database-schema.md`: Database schema documentation
- `merge_MAIN_to_FEAT_GLOBAL_FILTERS.md`: Comprehensive merge documentation (temporary file, will be removed post-PR)
- **Modified files**:
- `web/routes/library.py`: Added 4 advanced filters + PRAGMA column validation + personal_rating/priority sorting
- `web/routes/discover.py`: 2-tier caching + modular architecture + filter integration
- `web/routes/collections.py`: Advanced filter support in collection detail page
- `web/routes/settings.py`: Xbox credentials + Docker detection
- `web/main.py`: Auth router import + DB table creation calls (labels, auth, cache)
- `web/database.py`: Added `popularity_cache` table + `ensure_predefined_query_indexes()`
- `web/templates/discover.html`: Removed 1800 lines inline CSS, external CSS links
- `web/templates/index.html`: Removed 300 lines inline CSS, external CSS links
- `web/templates/collection_detail.html`: CSS links + PWA theme-color meta tag
- `requirements.txt`: Removed pytest (moved to requirements-dev.txt), added bcrypt, itsdangerous
- **Database schema**:
- New table: `popularity_cache` (for Tier 2 caching)
- New indexes: On playtime_hours, total_rating, added_at, release_date, nsfw, last_modified
- New tables: `collections`, `collection_games` (for collection filtering)
- Migration: Collections β†’ labels system with metadata columns
- **API changes**:
- `buildUrl()` JavaScript function: 6 β†’ 10 parameters
- New endpoint: `/api/discover/igdb-sections` (AJAX IGDB section loading)
- New endpoints: 13 metadata API endpoints (priority, rating, manual tags, bulk operations)
- Extended parameters: All route handlers accept 6 global filter parameters
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,38 @@ All your games from every store, displayed in one place. Smart deduplication ens
- **Flexible sorting** β€” Sort by name, rating, playtime, or release date
- **Store indicators** β€” See at a glance which platforms you own each game on

### Smart Filters

Quickly find games that match your mood with predefined filters organized into categories:

- **Gameplay Filters** β€” Unplayed, Just Tried, Played, Well-Played, Heavily-Played
- **Rating Filters** β€” Highly-Rated (90+), Well-Rated (75+), Below-Average (<75), Unrated, Hidden Gems, Critic Favorites, Community Favorites
- **Date Filters** β€” Recently Added (30 days), Older Library (180+ days), Recent Releases (90 days), Recently Updated, Classics (pre-2000)
- **Content Filters** β€” NSFW, Safe

**Features:**
- **Result count badges** β€” See how many games match each filter before applying it
- **Global Filters Mode** β€” Enable "Apply filters globally" to keep your selected filters active across all pages (Library, Discover, Collections, Random)
- **Keyboard navigation** β€” Use arrow keys to navigate filters, Esc to close dropdowns, Enter/Space to toggle filters
- **Accessibility** β€” Full ARIA label support and screen reader compatibility

### Automatic Gameplay Tagging (Steam)

Steam games are automatically tagged with gameplay labels based on your playtime. Every time you sync your Steam library, Backlogia evaluates each game's playtime and assigns the appropriate label:

| Label | Playtime |
|-------|----------|
| **Never Launched** | 0 hours |
| **Just Tried** | < 2 hours |
| **Played** | 2 - 10 hours |
| **Well Played** | 10 - 50 hours |
| **Heavily Played** | 50+ hours |

- Labels update automatically on each Steam sync β€” no manual action required
- Labels are visible on game detail pages and power the Gameplay filters above
- Steam-only: other stores don't provide reliable playtime data, but you can assign labels manually
- See [System Labels documentation](docs/system-labels-auto-tagging.md) for technical details

### Rich Game Details

Every game is enriched with metadata from IGDB (Internet Game Database), giving you consistent information across all stores.
Expand All @@ -69,7 +101,7 @@ Find your next game to play with curated discovery sections based on your actual
- **Highly rated** β€” Games scoring 90+ ratings
- **Hidden gems** β€” Quality games that deserve more attention
- **Most played** β€” Your games ranked by playtime
- **Random pick** β€” Can't decide? Let Backlogia choose for you
- **Random pick** β€” Can't decide? Let Backlogia surprise you with one game. Works with global filters to respect your preferences

### Custom Collections

Expand Down
Loading
Loading