initial commit
This commit is contained in:
commit
b811d93560
12 files changed
+952
No files matched your search
@@ -0,0 +1,58 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## Project Mission
|
||||||
|
|
||||||
|
Build Steam Backlog Helper, a small cross-platform Tauri desktop app that helps Steam users with large backlogs pick a game to play now.
|
||||||
|
|
||||||
|
The MVP is a picker, not a full library manager.
|
||||||
|
|
||||||
|
## Naming
|
||||||
|
|
||||||
|
- Official app name: Steam Backlog Helper.
|
||||||
|
- Repository name: `steam-backlog-helper`.
|
||||||
|
- Package ID: `com.boris.backloghelper`.
|
||||||
|
- Internal slug: `backlog-helper`.
|
||||||
|
- Avoid putting `steam` in package IDs, bundle IDs, database names, or internal crate/package names unless an external integration specifically requires it.
|
||||||
|
|
||||||
|
## Confirmed Stack
|
||||||
|
|
||||||
|
- Tauri
|
||||||
|
- Rust
|
||||||
|
- Svelte/SvelteKit
|
||||||
|
- TypeScript
|
||||||
|
- SQLite
|
||||||
|
|
||||||
|
## Product Constraints
|
||||||
|
|
||||||
|
- Support Windows 10+, macOS 26+, and Linux AppImage.
|
||||||
|
- Keep all user data local.
|
||||||
|
- Use user-provided API keys.
|
||||||
|
- Include free-to-play games.
|
||||||
|
- Exclude demos, tools, soundtracks, and DLC from recommendations by default.
|
||||||
|
- Do not build private-profile fallback import for the MVP.
|
||||||
|
- Do not build import/export, recommendation history, accepted/rejected tracking, mood tagging, installed-game detection, or manual metadata editing for the MVP.
|
||||||
|
|
||||||
|
## Development Rules
|
||||||
|
|
||||||
|
- Prefer small, direct changes over broad refactors.
|
||||||
|
- Keep recommendation logic testable outside UI components.
|
||||||
|
- Add tests for featureful scoring, parsing, persistence, and integration code.
|
||||||
|
- Do not chase coverage on empty scaffolding.
|
||||||
|
- Use strict TypeScript.
|
||||||
|
- Keep Rust commands narrow and typed.
|
||||||
|
- Never commit real Steam, HowLongToBeat, or other provider API keys.
|
||||||
|
- Do not log secrets.
|
||||||
|
- Make setup and recommendation flows keyboard accessible.
|
||||||
|
|
||||||
|
## Documentation Rules
|
||||||
|
|
||||||
|
- Update `docs/implementation-plan.md` when milestone scope changes.
|
||||||
|
- Update `docs/architecture-decisions.md` when a meaningful technical decision changes.
|
||||||
|
- Update `SECURITY.md` when credential handling changes.
|
||||||
|
|
||||||
|
## Release Assumptions
|
||||||
|
|
||||||
|
- Gitea is the primary forge.
|
||||||
|
- Gitea runners should handle x86 builds where practical.
|
||||||
|
- arm64 builds may be produced locally.
|
||||||
|
- GitHub publication may happen later, so avoid Gitea-only assumptions in application code.
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Code Of Conduct
|
||||||
|
|
||||||
|
## Standard
|
||||||
|
|
||||||
|
This project should be welcoming, practical, and focused on building useful software.
|
||||||
|
|
||||||
|
Contributors are expected to:
|
||||||
|
|
||||||
|
- Communicate respectfully.
|
||||||
|
- Keep feedback specific and actionable.
|
||||||
|
- Avoid harassment, abuse, or discriminatory language.
|
||||||
|
- Respect user privacy and security.
|
||||||
|
- Keep discussions focused on the project.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
The repository owner may remove issues, pull requests, comments, or access when behavior is harmful to the project or its contributors.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This applies to project spaces including the repository, issue tracker, code review, release discussions, and related chat channels.
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
Steam Backlog Helper is personal-use first but should be shaped for an eventual open-source release.
|
||||||
|
|
||||||
|
## Before Starting
|
||||||
|
|
||||||
|
Read:
|
||||||
|
|
||||||
|
- `README.md`
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/implementation-plan.md`
|
||||||
|
- `docs/architecture-decisions.md`
|
||||||
|
- `SECURITY.md`
|
||||||
|
|
||||||
|
## Scope Discipline
|
||||||
|
|
||||||
|
The MVP is a recommendation picker. Avoid adding full backlog-management features until the picker is working.
|
||||||
|
|
||||||
|
Out of scope for MVP:
|
||||||
|
|
||||||
|
- Import/export.
|
||||||
|
- Recommendation history.
|
||||||
|
- Accepted/rejected tracking.
|
||||||
|
- Mood tagging.
|
||||||
|
- Installed-game detection.
|
||||||
|
- Manual metadata editing.
|
||||||
|
- Private-profile fallback import.
|
||||||
|
|
||||||
|
## Code Standards
|
||||||
|
|
||||||
|
- Use strict TypeScript.
|
||||||
|
- Keep recommendation logic independent of UI where practical.
|
||||||
|
- Keep Rust command payloads typed and explicit.
|
||||||
|
- Add tests for featureful logic.
|
||||||
|
- Preserve keyboard accessibility for setup and picker flows.
|
||||||
|
- Do not commit real API keys or personal library data.
|
||||||
|
|
||||||
|
## Commit And Branch Guidance
|
||||||
|
|
||||||
|
The repository owner will initialize Git. Once Git is initialized, prefer small branches focused on one feature or fix.
|
||||||
|
|
||||||
|
Suggested commit style:
|
||||||
|
|
||||||
|
- `docs: update implementation plan`
|
||||||
|
- `feat: import steam library`
|
||||||
|
- `fix: redact api keys in logs`
|
||||||
|
- `test: cover recommendation scoring`
|
||||||
|
|
||||||
|
## Release Guidance
|
||||||
|
|
||||||
|
Gitea is the primary release target. CI should be designed for Gitea runners first, with a possible future GitHub mirror.
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# Steam Backlog Helper
|
||||||
|
|
||||||
|
Steam Backlog Helper is a planned cross-platform desktop application that helps Steam users pick a game from a large backlog.
|
||||||
|
|
||||||
|
The first version is picker-first: it asks a short set of questions, scores the user's Steam library, and presents a dynamic shortlist with a slot-machine style reveal. It is designed for personal use first, with an open-source release path.
|
||||||
|
|
||||||
|
## Naming
|
||||||
|
|
||||||
|
- Official app name: Steam Backlog Helper
|
||||||
|
- Repository name: steam-backlog-helper
|
||||||
|
- Package ID: `com.boris.backloghelper`
|
||||||
|
- Internal slug: `backlog-helper`
|
||||||
|
|
||||||
|
## Product Direction
|
||||||
|
|
||||||
|
- Target users: Steam users with large libraries and many unplayed or lightly played games.
|
||||||
|
- Desktop framework: Tauri.
|
||||||
|
- Frontend: Svelte/SvelteKit with TypeScript.
|
||||||
|
- Storage: local SQLite.
|
||||||
|
- Platforms: Windows 10+, macOS 26+, and Linux AppImage.
|
||||||
|
- Distribution: personal Gitea releases, with possible GitHub publication later.
|
||||||
|
|
||||||
|
## Planning Documents
|
||||||
|
|
||||||
|
- [Product Brief](docs/product-brief.md)
|
||||||
|
- [Implementation Plan](docs/implementation-plan.md)
|
||||||
|
- [Feature Roadmap](docs/feature-roadmap.md)
|
||||||
|
- [Technical Plan](docs/technical-plan.md)
|
||||||
|
- [Data and Integrations](docs/data-and-integrations.md)
|
||||||
|
- [Architecture Decisions](docs/architecture-decisions.md)
|
||||||
|
- [Open Questions](docs/open-questions.md)
|
||||||
|
|
||||||
|
## Current Status
|
||||||
|
|
||||||
|
This repository currently contains planning documentation only. The next step is to scaffold the Tauri + SvelteKit application.
|
||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
The project has not shipped a stable release yet. Until the first release, security fixes apply to the main development branch.
|
||||||
|
|
||||||
|
## Reporting A Vulnerability
|
||||||
|
|
||||||
|
For now, report vulnerabilities privately to the repository owner through the same channel used to access the private Gitea project.
|
||||||
|
|
||||||
|
Do not open a public issue for:
|
||||||
|
|
||||||
|
- Credential leaks.
|
||||||
|
- API key storage flaws.
|
||||||
|
- Local data exposure.
|
||||||
|
- Remote code execution.
|
||||||
|
- Dependency compromise.
|
||||||
|
|
||||||
|
## Secret Handling
|
||||||
|
|
||||||
|
- Never commit real API keys.
|
||||||
|
- Never include real API keys in tests, fixtures, screenshots, logs, or documentation examples.
|
||||||
|
- Prefer OS credential storage for Steam and third-party provider keys.
|
||||||
|
- If local plaintext storage is temporarily used during early development, it must be clearly marked as temporary and replaced before release.
|
||||||
|
- Logs must redact API keys and tokens.
|
||||||
|
|
||||||
|
## Local Data
|
||||||
|
|
||||||
|
The MVP stores user data locally. Treat the following as sensitive:
|
||||||
|
|
||||||
|
- Steam API keys.
|
||||||
|
- Third-party metadata API keys.
|
||||||
|
- Steam profile identifiers.
|
||||||
|
- Imported library data.
|
||||||
|
- Recommendation inputs.
|
||||||
|
|
||||||
|
The MVP should not collect telemetry.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Prefer maintained packages with clear licenses.
|
||||||
|
- Validate the terms and maintenance state of any HowLongToBeat-compatible integration before making it core behavior.
|
||||||
|
- Avoid scraping or unofficial APIs unless their legal and maintenance risks are documented and accepted.
|
||||||
|
|
||||||
|
## Release Security
|
||||||
|
|
||||||
|
- Attempt self-signing for desktop artifacts where practical.
|
||||||
|
- Keep release artifacts reproducible enough that a maintainer can rebuild them.
|
||||||
|
- Do not publish artifacts that contain development credentials or local test data.
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
# Architecture Decisions
|
||||||
|
|
||||||
|
## ADR-001: Use Tauri For Desktop Shell
|
||||||
|
|
||||||
|
Status: Accepted.
|
||||||
|
|
||||||
|
Decision: Use Tauri instead of Electron for the desktop shell.
|
||||||
|
|
||||||
|
Reasoning:
|
||||||
|
|
||||||
|
- Small app size is a priority.
|
||||||
|
- Tauri supports Windows, macOS, and Linux.
|
||||||
|
- Rust is acceptable for native app services.
|
||||||
|
|
||||||
|
Consequence:
|
||||||
|
|
||||||
|
- Desktop integration and backend commands will be implemented in Rust.
|
||||||
|
- The project should avoid Node-only runtime assumptions outside the frontend build.
|
||||||
|
|
||||||
|
## ADR-002: Use Svelte/SvelteKit For Frontend
|
||||||
|
|
||||||
|
Status: Accepted.
|
||||||
|
|
||||||
|
Decision: Use Svelte/SvelteKit with TypeScript.
|
||||||
|
|
||||||
|
Reasoning:
|
||||||
|
|
||||||
|
- Svelte/SvelteKit is the preferred frontend framework.
|
||||||
|
- The app UI is interaction-heavy but not content-heavy.
|
||||||
|
|
||||||
|
Consequence:
|
||||||
|
|
||||||
|
- Frontend code should use strict TypeScript.
|
||||||
|
- Shared recommendation types should be kept consistent with Rust command payloads.
|
||||||
|
|
||||||
|
## ADR-003: Keep Data Local
|
||||||
|
|
||||||
|
Status: Accepted.
|
||||||
|
|
||||||
|
Decision: Store app data locally in SQLite.
|
||||||
|
|
||||||
|
Reasoning:
|
||||||
|
|
||||||
|
- The MVP is personal-use first.
|
||||||
|
- Cloud accounts and sync are out of scope.
|
||||||
|
- Local storage reduces privacy and operational complexity.
|
||||||
|
|
||||||
|
Consequence:
|
||||||
|
|
||||||
|
- No hosted app backend is planned for the MVP.
|
||||||
|
- Import/export is deferred until after the MVP.
|
||||||
|
|
||||||
|
## ADR-004: Use User-Provided API Keys
|
||||||
|
|
||||||
|
Status: Accepted.
|
||||||
|
|
||||||
|
Decision: Guide users to provide their own Steam Web API key and any required third-party metadata keys.
|
||||||
|
|
||||||
|
Reasoning:
|
||||||
|
|
||||||
|
- A hosted proxy is out of scope.
|
||||||
|
- The app is local-first.
|
||||||
|
|
||||||
|
Consequence:
|
||||||
|
|
||||||
|
- Credential storage must be treated as security-sensitive.
|
||||||
|
- Development fixtures must never contain real keys.
|
||||||
|
|
||||||
|
## ADR-005: Build A Picker Before A Library Manager
|
||||||
|
|
||||||
|
Status: Accepted.
|
||||||
|
|
||||||
|
Decision: The first screen and MVP workflow should be the recommendation picker, not a dense library-management UI.
|
||||||
|
|
||||||
|
Reasoning:
|
||||||
|
|
||||||
|
- The core problem is deciding what to play now.
|
||||||
|
- Full backlog management adds scope that is not required for the first usable version.
|
||||||
|
|
||||||
|
Consequence:
|
||||||
|
|
||||||
|
- Statuses, notes, pinning, import/export, and recommendation history are deferred.
|
||||||
|
- UI work should focus on the setup and picker flows.
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
# Data And Integrations
|
||||||
|
|
||||||
|
## Steam Web API
|
||||||
|
|
||||||
|
The MVP should use the Steam Web API for reliable owned-game import. Users should be guided through supplying their own Steam Web API key.
|
||||||
|
|
||||||
|
Relevant Steam API areas:
|
||||||
|
|
||||||
|
- Resolve vanity URL to Steam ID.
|
||||||
|
- Fetch owned games.
|
||||||
|
- Fetch player summaries.
|
||||||
|
- Fetch recently played games, if useful.
|
||||||
|
|
||||||
|
Known limitation: Steam library data may not be available when the user's profile or game details are private. Private-profile fallback import is out of scope for the MVP.
|
||||||
|
|
||||||
|
## SteamDB Consideration
|
||||||
|
|
||||||
|
SteamDB can be investigated as an alternative metadata source only after confirming availability, terms, and suitability. It should not be assumed as a replacement for the Steam Web API until that validation is complete.
|
||||||
|
|
||||||
|
## Steam Store Metadata
|
||||||
|
|
||||||
|
Steam store endpoints may be useful for metadata such as:
|
||||||
|
|
||||||
|
- Header images
|
||||||
|
- Genres
|
||||||
|
- Categories
|
||||||
|
- Short descriptions
|
||||||
|
- Release date
|
||||||
|
|
||||||
|
These endpoints should be cached locally and refreshed conservatively.
|
||||||
|
|
||||||
|
## Completion Time Data
|
||||||
|
|
||||||
|
Estimated game length is required for the MVP recommendation flow.
|
||||||
|
|
||||||
|
Preferred direction:
|
||||||
|
|
||||||
|
- Use a HowLongToBeat-compatible API or library after validating terms, maintenance status, and package quality.
|
||||||
|
- Cache estimates locally with source and confidence fields.
|
||||||
|
- Do not allow manual metadata editing in the MVP.
|
||||||
|
|
||||||
|
The project should avoid depending on an unofficial or license-unclear source without documenting the risk.
|
||||||
|
|
||||||
|
## Local Storage
|
||||||
|
|
||||||
|
Use SQLite for durable local data.
|
||||||
|
|
||||||
|
The app should support:
|
||||||
|
|
||||||
|
- Local-only operation after import.
|
||||||
|
- Metadata caching.
|
||||||
|
- Local settings.
|
||||||
|
- Resetting cached metadata.
|
||||||
|
|
||||||
|
Manual data import/export is out of scope for the MVP.
|
||||||
|
|
||||||
|
## Privacy
|
||||||
|
|
||||||
|
Default privacy posture:
|
||||||
|
|
||||||
|
- Store user data locally.
|
||||||
|
- Do not create a hosted account for MVP.
|
||||||
|
- Do not transmit the user's library to third-party services beyond the configured metadata providers required for the recommendation flow.
|
||||||
|
- Document which Steam API calls are made.
|
||||||
|
- Do not collect telemetry in the MVP.
|
||||||
|
|
||||||
|
## API Key Handling
|
||||||
|
|
||||||
|
The MVP should use user-provided API keys where required.
|
||||||
|
|
||||||
|
Credentials should not be stored as plain text if the platform provides a practical secure storage option.
|
||||||
|
|
||||||
|
Preferred order:
|
||||||
|
|
||||||
|
- Use OS-provided credential storage through a Tauri-compatible plugin or Rust crate.
|
||||||
|
- Fall back to a clearly documented local settings file only during early development.
|
||||||
|
- Never commit real API keys.
|
||||||
|
|
||||||
|
No hosted proxy service is planned for the MVP.
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
# Feature Roadmap
|
||||||
|
|
||||||
|
## MVP
|
||||||
|
|
||||||
|
The MVP should prove that the app can ingest a Steam library, enrich it with useful metadata, and produce a short "play this now" recommendation list.
|
||||||
|
|
||||||
|
### Library Setup
|
||||||
|
|
||||||
|
- Accept a Steam ID, vanity URL, or profile URL.
|
||||||
|
- Guide the user through providing a Steam Web API key.
|
||||||
|
- Fetch owned games for API-accessible libraries.
|
||||||
|
- Show clear guidance when profile or game-library privacy blocks access.
|
||||||
|
- Cache library data locally.
|
||||||
|
- Allow manual refresh.
|
||||||
|
- Do not support private-profile fallback imports in the MVP.
|
||||||
|
|
||||||
|
### Recommendation Setup
|
||||||
|
|
||||||
|
- Ask short questions before each recommendation run:
|
||||||
|
- Available play time.
|
||||||
|
- Optional genre preference.
|
||||||
|
- Completion intent, such as unplayed, already started, or either.
|
||||||
|
- Review-score tolerance.
|
||||||
|
- True-random toggle.
|
||||||
|
- Keep mood tagging out of scope for the MVP.
|
||||||
|
- Include all library games regardless of installed state.
|
||||||
|
- Exclude demos, tools, soundtracks, and DLC by default.
|
||||||
|
- Include free-to-play games.
|
||||||
|
|
||||||
|
### Recommendation Flow
|
||||||
|
|
||||||
|
- Present a dynamic shortlist rather than a single mandatory answer.
|
||||||
|
- Use a slot-machine style reveal for the primary recommendation.
|
||||||
|
- Explain why each game was chosen.
|
||||||
|
- Support opening a selected game through a Steam launch link.
|
||||||
|
- Keep recommendation history, accepted/rejected tracking, and local notes out of scope for the MVP.
|
||||||
|
|
||||||
|
### Metadata
|
||||||
|
|
||||||
|
- Fetch Steam metadata, including images, genres, categories, and review data where available.
|
||||||
|
- Fetch estimated time-to-beat data through a HowLongToBeat-compatible API or provider.
|
||||||
|
- Cache third-party metadata locally.
|
||||||
|
- Do not allow manual metadata editing in the MVP.
|
||||||
|
|
||||||
|
## Version 1
|
||||||
|
|
||||||
|
- Add a fuller library browsing view.
|
||||||
|
- Add user statuses such as completed, dropped, ignored, and pinned.
|
||||||
|
- Add recommendation history.
|
||||||
|
- Add accepted/rejected recommendation tracking.
|
||||||
|
- Add import/export of local app data.
|
||||||
|
- Add weighted recommendation settings.
|
||||||
|
- Add installed-game detection if practical across target platforms.
|
||||||
|
- Add self-signed build outputs where possible.
|
||||||
|
- Add release automation from Gitea.
|
||||||
|
|
||||||
|
## Later Ideas
|
||||||
|
|
||||||
|
- Achievement-aware recommendations.
|
||||||
|
- Local AI-assisted recommendation summaries.
|
||||||
|
- Multi-store support for GOG, Epic, itch.io, or manually added games.
|
||||||
|
- Optional cloud sync.
|
||||||
|
- Game session history.
|
||||||
|
- Purchase restraint mode that highlights owned alternatives before buying similar games.
|
||||||
|
- Public website or project page if the app moves beyond personal Gitea releases.
|
||||||
|
|
||||||
|
## MVP Acceptance Checklist
|
||||||
|
|
||||||
|
- The app can be built for Windows 10+, macOS 26+, and Linux AppImage.
|
||||||
|
- A user can populate their library through Steam Web API access.
|
||||||
|
- A user can request a recommendation in under 30 seconds after initial setup.
|
||||||
|
- Recommendations are deterministic enough to debug but varied enough to feel useful.
|
||||||
|
- The true-random toggle bypasses scoring.
|
||||||
|
- The selected game can be opened through a Steam app ID launch link.
|
||||||
|
- Keyboard users can complete the setup and recommendation flow.
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
# Implementation Plan
|
||||||
|
|
||||||
|
## Milestone 0: Repository Foundation
|
||||||
|
|
||||||
|
Goal: make the project ready for implementation.
|
||||||
|
|
||||||
|
Deliverables:
|
||||||
|
|
||||||
|
- Planning docs aligned with confirmed product decisions.
|
||||||
|
- `AGENTS.md` for coding-agent and contributor workflow.
|
||||||
|
- `SECURITY.md` for vulnerability handling and secret-management expectations.
|
||||||
|
- `CONTRIBUTING.md` for local development and contribution standards.
|
||||||
|
- `CODE_OF_CONDUCT.md` for open-source readiness.
|
||||||
|
- `.gitignore` suited for Tauri, SvelteKit, Rust, Node, and build artifacts.
|
||||||
|
|
||||||
|
Exit criteria:
|
||||||
|
|
||||||
|
- The repository explains what is in scope for the MVP.
|
||||||
|
- A new contributor can understand the intended stack and project rules.
|
||||||
|
|
||||||
|
## Milestone 1: Application Skeleton
|
||||||
|
|
||||||
|
Goal: create the first runnable desktop application.
|
||||||
|
|
||||||
|
Deliverables:
|
||||||
|
|
||||||
|
- Tauri app scaffold using `Steam Backlog Helper` as the display name and `com.boris.backloghelper` as the package ID.
|
||||||
|
- Svelte/SvelteKit frontend with TypeScript.
|
||||||
|
- Basic app shell with setup, picker, and settings routes or views.
|
||||||
|
- Lint, format, typecheck, and test commands.
|
||||||
|
- Initial SQLite migration system.
|
||||||
|
|
||||||
|
Exit criteria:
|
||||||
|
|
||||||
|
- The app runs locally in development mode.
|
||||||
|
- The app can open a desktop window.
|
||||||
|
- CI can run linting and typechecks.
|
||||||
|
|
||||||
|
## Milestone 2: Steam Setup And Library Import
|
||||||
|
|
||||||
|
Goal: import a user's Steam library through supported API access.
|
||||||
|
|
||||||
|
Deliverables:
|
||||||
|
|
||||||
|
- Steam profile input supporting Steam ID, vanity URL, or profile URL.
|
||||||
|
- User-provided Steam Web API key setup.
|
||||||
|
- Owned-games fetch.
|
||||||
|
- Library cache in SQLite.
|
||||||
|
- Clear failure states for invalid keys, private profiles, rate limits, and network failures.
|
||||||
|
|
||||||
|
Exit criteria:
|
||||||
|
|
||||||
|
- A public/API-accessible Steam library can be imported and refreshed.
|
||||||
|
- Imported games persist after app restart.
|
||||||
|
- No real API keys are logged or committed.
|
||||||
|
|
||||||
|
## Milestone 3: Metadata Enrichment
|
||||||
|
|
||||||
|
Goal: make recommendations useful beyond raw ownership and playtime.
|
||||||
|
|
||||||
|
Deliverables:
|
||||||
|
|
||||||
|
- Steam Store metadata lookup for images, genres, categories, and release data.
|
||||||
|
- Public review-score signal where available.
|
||||||
|
- HowLongToBeat-compatible completion-time integration after validation.
|
||||||
|
- Metadata cache with freshness timestamps.
|
||||||
|
- Default filtering for demos, tools, soundtracks, and DLC.
|
||||||
|
|
||||||
|
Exit criteria:
|
||||||
|
|
||||||
|
- Recommendation candidates include playtime, image, genre/category, review, and completion-time data where available.
|
||||||
|
- Metadata lookup failures degrade gracefully.
|
||||||
|
|
||||||
|
## Milestone 4: Recommendation Engine
|
||||||
|
|
||||||
|
Goal: produce explainable, useful recommendations.
|
||||||
|
|
||||||
|
Deliverables:
|
||||||
|
|
||||||
|
- Short-question recommendation flow.
|
||||||
|
- Weighted scoring using available time, optional genre, completion preference, review score, and playtime.
|
||||||
|
- True-random toggle that bypasses weighted scoring.
|
||||||
|
- Dynamic shortlist output.
|
||||||
|
- Human-readable recommendation explanations.
|
||||||
|
- Unit tests for scoring behavior.
|
||||||
|
|
||||||
|
Exit criteria:
|
||||||
|
|
||||||
|
- Recommendation behavior is deterministic under seeded test data.
|
||||||
|
- True-random mode is separate from weighted recommendations.
|
||||||
|
- Edge cases such as empty candidate sets have clear UI states.
|
||||||
|
|
||||||
|
## Milestone 5: Picker Experience
|
||||||
|
|
||||||
|
Goal: make the primary workflow feel focused and polished.
|
||||||
|
|
||||||
|
Deliverables:
|
||||||
|
|
||||||
|
- Recommendation-first home screen.
|
||||||
|
- Slot-machine style reveal for the primary recommendation.
|
||||||
|
- Keyboard-accessible controls.
|
||||||
|
- Steam app ID launch links.
|
||||||
|
- Responsive desktop layout for common window sizes.
|
||||||
|
|
||||||
|
Exit criteria:
|
||||||
|
|
||||||
|
- A keyboard-only user can complete setup and run a recommendation.
|
||||||
|
- The chosen game can be opened in Steam.
|
||||||
|
- The picker remains usable without a full library-management screen.
|
||||||
|
|
||||||
|
## Milestone 6: Packaging And Releases
|
||||||
|
|
||||||
|
Goal: produce installable desktop artifacts.
|
||||||
|
|
||||||
|
Deliverables:
|
||||||
|
|
||||||
|
- Windows 10+ build.
|
||||||
|
- macOS 26+ build, with self-signing where practical.
|
||||||
|
- Linux AppImage build.
|
||||||
|
- Gitea runner workflows for x86 builds.
|
||||||
|
- Local arm64 build instructions.
|
||||||
|
- Release artifact checklist.
|
||||||
|
|
||||||
|
Exit criteria:
|
||||||
|
|
||||||
|
- Release artifacts can be generated from the repository.
|
||||||
|
- The release process is documented for personal Gitea.
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
# Answered Product Questions
|
||||||
|
|
||||||
|
This file preserves the planning answers that shaped the current implementation plan. It is not an active blocker list.
|
||||||
|
|
||||||
|
## Product Scope
|
||||||
|
|
||||||
|
1. Who is the first target user: you personally, power users with large libraries, or a general Steam audience?
|
||||||
|
Target users are Steam users with large libraries and many unplayed or lightly played games.
|
||||||
|
2. Should the first version optimize for "pick something right now" or for long-term backlog management?
|
||||||
|
The first version should optimize for picking something to play right now.
|
||||||
|
3. Should the app recommend exactly one game, a ranked shortlist, or both?
|
||||||
|
It should produce a short-term dynamic list, with one primary recommendation.
|
||||||
|
4. Should recommendations feel mostly practical, playful, or a mix of both?
|
||||||
|
Recommendations should depend on short questions the user answers.
|
||||||
|
5. Should the app include a pure random mode even when it ignores scoring?
|
||||||
|
Yes. The app should include a true-random toggle.
|
||||||
|
|
||||||
|
## Platforms
|
||||||
|
|
||||||
|
1. Which operating systems must be supported first: macOS, Windows, Linux, or all three from day one?
|
||||||
|
All three from day one.
|
||||||
|
2. Are there specific minimum OS versions to support?
|
||||||
|
Windows 10+, macOS 26+, and Linux AppImage.
|
||||||
|
3. Do you care more about small app size or faster development?
|
||||||
|
Small app size.
|
||||||
|
|
||||||
|
## Steam Access
|
||||||
|
|
||||||
|
1. Are you comfortable requiring users to provide a Steam Web API key during the MVP?
|
||||||
|
Yes. Users should be guided to supply a Steam Web API key. SteamDB may be investigated only after validating availability and terms.
|
||||||
|
2. Should the app support private profiles through manual import or local Steam files if API access fails?
|
||||||
|
No. This is out of scope for the MVP.
|
||||||
|
3. Should the app launch games directly through Steam, or only help users choose?
|
||||||
|
The app should support Steam app ID launch links.
|
||||||
|
|
||||||
|
## Recommendation Inputs
|
||||||
|
|
||||||
|
1. What should matter most when picking a game: available time, genre, mood, completion progress, review score, randomness, or something else?
|
||||||
|
Available time, optional genre, completion progress, review score, and randomness should all be inputs.
|
||||||
|
2. Should the user be able to define moods such as "relaxing", "story-heavy", "challenging", "mindless", or "social"?
|
||||||
|
Out of scope for now.
|
||||||
|
3. Should the app avoid games the user has not installed?
|
||||||
|
No.
|
||||||
|
4. Should installed status be detected automatically if feasible?
|
||||||
|
Installed status is out of scope. Include all library games regardless of installed state.
|
||||||
|
5. Should free-to-play games, demos, tools, soundtracks, and DLC be excluded by default?
|
||||||
|
Free-to-play games should be included. Demos, tools, soundtracks, and DLC should be excluded.
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
|
||||||
|
1. Is estimated time-to-beat required for MVP?
|
||||||
|
Yes. Use a HowLongToBeat-compatible API or provider after validation.
|
||||||
|
2. Are third-party metadata providers acceptable?
|
||||||
|
Yes, if they are open or require a key.
|
||||||
|
3. Should users be able to manually edit genres, tags, and time estimates?
|
||||||
|
No. Metadata should come from reliable sources.
|
||||||
|
4. Should the app use public Steam review data as a recommendation signal?
|
||||||
|
Yes.
|
||||||
|
|
||||||
|
## User Data
|
||||||
|
|
||||||
|
1. Should all data remain local for the first version?
|
||||||
|
Yes. All data should stay local.
|
||||||
|
2. Do you want import/export in the MVP?
|
||||||
|
No. Import/export is out of scope.
|
||||||
|
3. Should recommendation history be kept?
|
||||||
|
No. Recommendation history is out of scope for now.
|
||||||
|
4. Should the app track whether the user accepted or rejected a recommendation?
|
||||||
|
No. Accepted/rejected tracking is out of scope for now.
|
||||||
|
|
||||||
|
## Interface
|
||||||
|
|
||||||
|
1. Do you prefer a dense library-management interface or a more guided picker interface?
|
||||||
|
Use a guided picker interface. Dense library management is out of scope.
|
||||||
|
2. Should the first screen be the recommendation flow or the full library?
|
||||||
|
The first screen should be recommendations.
|
||||||
|
3. Should there be a visual picker mode such as a wheel, cards, or slot-machine style animation?
|
||||||
|
Use a slot-machine style animation.
|
||||||
|
4. Should keyboard navigation be a priority?
|
||||||
|
Yes. The app should be accessible via keyboard.
|
||||||
|
|
||||||
|
## Technical Preferences
|
||||||
|
|
||||||
|
1. Do you prefer Tauri, Electron, or another desktop framework?
|
||||||
|
Tauri is preferred over Electron. Flutter is also acceptable if needed.
|
||||||
|
2. Are you comfortable with Rust in the project if using Tauri?
|
||||||
|
Yes.
|
||||||
|
3. Do you have a preferred frontend framework?
|
||||||
|
Svelte/SvelteKit.
|
||||||
|
4. Should the project prioritize automated tests from the beginning?
|
||||||
|
Prioritize code coverage on actual featureful code.
|
||||||
|
5. Should this repo be initialized with Git as part of the setup?
|
||||||
|
No. The owner will initialize Git.
|
||||||
|
|
||||||
|
## Distribution
|
||||||
|
|
||||||
|
1. Is this intended for personal use, open-source release, or commercial distribution?
|
||||||
|
Personal use, designed for open source.
|
||||||
|
2. Should app signing and auto-update be planned early?
|
||||||
|
Try to self-sign binaries where practical. Auto-update should use Git releases.
|
||||||
|
3. Do you want CI builds for each platform?
|
||||||
|
Yes. Use Gitea and Gitea runners first, with possible GitHub publication later. Build arm64 locally and x86 on runners.
|
||||||
|
4. Should the app have a public website or just release artifacts?
|
||||||
|
The app will be managed through personal Gitea.
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
# Product Brief
|
||||||
|
|
||||||
|
## Name
|
||||||
|
|
||||||
|
The official app name is Steam Backlog Helper.
|
||||||
|
|
||||||
|
Use neutral technical identifiers where possible:
|
||||||
|
|
||||||
|
- Repository name: `steam-backlog-helper`
|
||||||
|
- Package ID: `com.boris.backloghelper`
|
||||||
|
- Internal slug: `backlog-helper`
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Build a cross-platform desktop app that helps a Steam user pick a game from a large backlog.
|
||||||
|
|
||||||
|
The app should reduce decision fatigue by combining Steam library data, public metadata, completion-time estimates, review signals, and a short set of user answers.
|
||||||
|
|
||||||
|
## Target User
|
||||||
|
|
||||||
|
The initial user is a Steam user with a large library and many unplayed or lightly played games.
|
||||||
|
|
||||||
|
Secondary users may include:
|
||||||
|
|
||||||
|
- Players trying to finish owned games before buying more.
|
||||||
|
- Players who want recommendations based on time available.
|
||||||
|
- Players who want to rediscover forgotten purchases.
|
||||||
|
- Players who want a randomizer with more context than pure chance.
|
||||||
|
|
||||||
|
## Core Problem
|
||||||
|
|
||||||
|
Steam libraries often contain many owned, unplayed, partially played, or forgotten games. Steam itself exposes library and playtime data, but it does not provide a focused workflow for choosing what to play next based on the user's current situation.
|
||||||
|
|
||||||
|
## Product Principles
|
||||||
|
|
||||||
|
- Fast decision-making over exhaustive catalog management.
|
||||||
|
- Recommendations should be explainable.
|
||||||
|
- The user should answer only a short set of questions before receiving useful options.
|
||||||
|
- True random should remain available as a toggle.
|
||||||
|
- Local-first storage is required for the first version.
|
||||||
|
- Small app size matters more than fastest possible development.
|
||||||
|
- The app should support Steam launch links for selected games.
|
||||||
|
|
||||||
|
## Initial Success Criteria
|
||||||
|
|
||||||
|
- The user can enter a Steam profile and Steam Web API key during setup.
|
||||||
|
- The app imports owned Steam games for public or API-accessible libraries.
|
||||||
|
- The app excludes demos, tools, soundtracks, and DLC by default while keeping free-to-play games.
|
||||||
|
- The app asks short recommendation questions covering time available, genre preference, completion preference, review-score tolerance, and randomness.
|
||||||
|
- The app presents a short dynamic list of games to play now.
|
||||||
|
- The app includes a slot-machine style picker animation.
|
||||||
|
- The app can open selected games through Steam app ID launch links.
|
||||||
|
- The app runs on macOS, Windows, and Linux.
|
||||||
|
|
||||||
|
## Non-Goals For The First Version
|
||||||
|
|
||||||
|
- Replacing Steam as a launcher.
|
||||||
|
- Full library management.
|
||||||
|
- Manual metadata editing.
|
||||||
|
- Private-profile fallback imports.
|
||||||
|
- Installed-game detection.
|
||||||
|
- Recommendation history.
|
||||||
|
- Import/export.
|
||||||
|
- Mood tagging.
|
||||||
|
- Social recommendations.
|
||||||
|
- Multiplayer matchmaking.
|
||||||
|
- Full achievement tracking dashboards.
|
||||||
|
- Cloud account infrastructure.
|
||||||
|
- Mobile app support.
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
# Technical Plan
|
||||||
|
|
||||||
|
## Project Identifiers
|
||||||
|
|
||||||
|
- Official app name: Steam Backlog Helper
|
||||||
|
- Repository name: `steam-backlog-helper`
|
||||||
|
- Package ID: `com.boris.backloghelper`
|
||||||
|
- Internal slug: `backlog-helper`
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
|
||||||
|
The project will use:
|
||||||
|
|
||||||
|
- Desktop shell: Tauri
|
||||||
|
- Frontend: Svelte/SvelteKit with TypeScript
|
||||||
|
- Styling: scoped Svelte styles or a small shared CSS layer
|
||||||
|
- Local database: SQLite
|
||||||
|
- Backend/runtime language: Rust through Tauri commands
|
||||||
|
|
||||||
|
Tauri is preferred because small app size matters. Flutter remains a possible fallback only if Tauri becomes a poor fit during implementation.
|
||||||
|
|
||||||
|
## Proposed Architecture
|
||||||
|
|
||||||
|
```text
|
||||||
|
Desktop App
|
||||||
|
Frontend UI
|
||||||
|
Setup flow
|
||||||
|
Recommendation flow
|
||||||
|
Slot-machine picker
|
||||||
|
Settings for API keys and refresh
|
||||||
|
App Service Layer
|
||||||
|
Steam import
|
||||||
|
Metadata enrichment
|
||||||
|
Recommendation engine
|
||||||
|
Local persistence
|
||||||
|
Local SQLite Database
|
||||||
|
Games
|
||||||
|
Game length estimates
|
||||||
|
Metadata cache
|
||||||
|
Settings
|
||||||
|
Credential references
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Modules
|
||||||
|
|
||||||
|
### Steam Integration
|
||||||
|
|
||||||
|
Responsibilities:
|
||||||
|
|
||||||
|
- Resolve Steam profile inputs.
|
||||||
|
- Fetch owned games.
|
||||||
|
- Guide the user through Steam Web API key setup.
|
||||||
|
- Handle API errors and private profile failures.
|
||||||
|
- Normalize Steam app IDs and playtime.
|
||||||
|
- Refresh cached data.
|
||||||
|
- Create Steam launch URLs for selected app IDs.
|
||||||
|
|
||||||
|
### Metadata Service
|
||||||
|
|
||||||
|
Responsibilities:
|
||||||
|
|
||||||
|
- Attach display images.
|
||||||
|
- Attach genres and tags where available.
|
||||||
|
- Attach public Steam review data where available.
|
||||||
|
- Attach estimated time-to-beat through a HowLongToBeat-compatible provider.
|
||||||
|
- Track metadata freshness.
|
||||||
|
- Exclude demos, tools, soundtracks, and DLC from recommendations by default.
|
||||||
|
|
||||||
|
### Recommendation Engine
|
||||||
|
|
||||||
|
Responsibilities:
|
||||||
|
|
||||||
|
- Score candidate games based on the short questionnaire.
|
||||||
|
- Explain the score in human-readable terms.
|
||||||
|
- Support a true-random mode that bypasses weighted scoring.
|
||||||
|
- Return a ranked dynamic shortlist and one primary recommendation.
|
||||||
|
- Keep mood tagging, history, and accepted/rejected tracking out of the MVP.
|
||||||
|
|
||||||
|
### Local Persistence
|
||||||
|
|
||||||
|
Responsibilities:
|
||||||
|
|
||||||
|
- Store library cache.
|
||||||
|
- Store metadata cache.
|
||||||
|
- Store app settings.
|
||||||
|
- Store encrypted or OS-protected API credentials if practical.
|
||||||
|
- Avoid import/export until a later release.
|
||||||
|
|
||||||
|
## Data Model Draft
|
||||||
|
|
||||||
|
### games
|
||||||
|
|
||||||
|
- `steam_app_id`
|
||||||
|
- `name`
|
||||||
|
- `playtime_minutes`
|
||||||
|
- `last_played_at`
|
||||||
|
- `image_url`
|
||||||
|
- `genres`
|
||||||
|
- `tags`
|
||||||
|
- `review_score`
|
||||||
|
- `is_free_to_play`
|
||||||
|
- `is_excluded_type`
|
||||||
|
- `metadata_updated_at`
|
||||||
|
|
||||||
|
### game_lengths
|
||||||
|
|
||||||
|
- `steam_app_id`
|
||||||
|
- `main_minutes`
|
||||||
|
- `main_extra_minutes`
|
||||||
|
- `completionist_minutes`
|
||||||
|
- `source`
|
||||||
|
- `confidence`
|
||||||
|
- `updated_at`
|
||||||
|
|
||||||
|
### app_settings
|
||||||
|
|
||||||
|
- `key`
|
||||||
|
- `value_json`
|
||||||
|
|
||||||
|
### credentials
|
||||||
|
|
||||||
|
- `key`
|
||||||
|
- `storage_ref`
|
||||||
|
- `updated_at`
|
||||||
|
|
||||||
|
## Recommendation Strategy Draft
|
||||||
|
|
||||||
|
Start with a transparent weighted scoring system rather than machine learning.
|
||||||
|
|
||||||
|
Example scoring inputs:
|
||||||
|
|
||||||
|
- Positive weight for matching selected genre or tag.
|
||||||
|
- Positive weight for fitting available session time.
|
||||||
|
- Positive weight for partially played games in "finish something" mode.
|
||||||
|
- Positive weight for unplayed games in "try something new" mode.
|
||||||
|
- Positive weight for meeting the user's review-score preference.
|
||||||
|
- Negative weight for extremely long games in short-session mode.
|
||||||
|
- Hard exclusion for demos, tools, soundtracks, and DLC.
|
||||||
|
|
||||||
|
The UI should show concise explanations such as:
|
||||||
|
|
||||||
|
- "Picked because it is unplayed, highly tagged as puzzle, and fits a short session."
|
||||||
|
- "Picked because you already started it and have less than five hours estimated remaining."
|
||||||
|
|
||||||
|
## Implementation Phases
|
||||||
|
|
||||||
|
### Phase 0: Repository Foundation
|
||||||
|
|
||||||
|
- Add project documentation.
|
||||||
|
- Add `AGENTS.md`, `SECURITY.md`, and contribution guidance.
|
||||||
|
- Initialize Git when the owner is ready.
|
||||||
|
|
||||||
|
### Phase 1: Project Skeleton
|
||||||
|
|
||||||
|
- Initialize the desktop app.
|
||||||
|
- Add linting, formatting, and test scripts.
|
||||||
|
- Create the setup and picker shell.
|
||||||
|
- Add local database migrations.
|
||||||
|
|
||||||
|
### Phase 2: Steam Library Import
|
||||||
|
|
||||||
|
- Implement Steam profile input.
|
||||||
|
- Implement Steam Web API key settings.
|
||||||
|
- Fetch and cache owned games.
|
||||||
|
- Normalize games for recommendation use.
|
||||||
|
- Add refresh handling and error states.
|
||||||
|
|
||||||
|
### Phase 3: Metadata Enrichment
|
||||||
|
|
||||||
|
- Fetch Steam Store metadata.
|
||||||
|
- Fetch public review signals where available.
|
||||||
|
- Integrate a HowLongToBeat-compatible source after validating terms and package health.
|
||||||
|
- Cache metadata locally with refresh timestamps.
|
||||||
|
|
||||||
|
### Phase 4: Recommendations
|
||||||
|
|
||||||
|
- Implement the short-question flow.
|
||||||
|
- Add scoring and explanations.
|
||||||
|
- Add true-random toggle behavior.
|
||||||
|
- Add slot-machine reveal.
|
||||||
|
- Add Steam launch links.
|
||||||
|
|
||||||
|
### Phase 5: Packaging
|
||||||
|
|
||||||
|
- Configure Windows, macOS, and Linux AppImage builds.
|
||||||
|
- Add Gitea runner workflows.
|
||||||
|
- Keep arm64 builds local.
|
||||||
|
- Allow x86 builds on runners.
|
||||||
|
- Add app icons and metadata.
|
||||||
|
- Attempt self-signing where practical.
|
||||||
|
- Prepare release artifacts for personal Gitea releases.
|
||||||
|
|
||||||
|
## Development Standards
|
||||||
|
|
||||||
|
- TypeScript should be strict.
|
||||||
|
- User data should be stored locally by default.
|
||||||
|
- API failures should have clear recovery paths.
|
||||||
|
- Recommendation logic should be unit tested.
|
||||||
|
- Data migrations should be repeatable and versioned.
|
||||||
|
- Featureful code should have useful coverage; do not chase coverage for empty scaffolding.
|
||||||
|
- Keyboard accessibility is required for the setup and recommendation flow.
|
||||||
Reference in new issue
Block a user