From b811d9356090aa9e3a8e4cae9621050a65db48b4 Mon Sep 17 00:00:00 2001 From: boris Date: Wed, 15 Jul 2026 22:48:36 +0100 Subject: [PATCH] initial commit --- AGENTS.md | 58 ++++++++++ CODE_OF_CONDUCT.md | 21 ++++ CONTRIBUTING.md | 51 +++++++++ README.md | 35 ++++++ SECURITY.md | 49 ++++++++ docs/architecture-decisions.md | 83 ++++++++++++++ docs/data-and-integrations.md | 79 +++++++++++++ docs/feature-roadmap.md | 75 ++++++++++++ docs/implementation-plan.md | 127 +++++++++++++++++++++ docs/open-questions.md | 104 +++++++++++++++++ docs/product-brief.md | 69 +++++++++++ docs/technical-plan.md | 201 +++++++++++++++++++++++++++++++++ 12 files changed, 952 insertions(+) create mode 100644 AGENTS.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 README.md create mode 100644 SECURITY.md create mode 100644 docs/architecture-decisions.md create mode 100644 docs/data-and-integrations.md create mode 100644 docs/feature-roadmap.md create mode 100644 docs/implementation-plan.md create mode 100644 docs/open-questions.md create mode 100644 docs/product-brief.md create mode 100644 docs/technical-plan.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..f5f6c1e --- /dev/null +++ b/AGENTS.md @@ -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. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..aa327d8 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -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. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..d176cd0 --- /dev/null +++ b/CONTRIBUTING.md @@ -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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b4448cc --- /dev/null +++ b/README.md @@ -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. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..ce1d629 --- /dev/null +++ b/SECURITY.md @@ -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. diff --git a/docs/architecture-decisions.md b/docs/architecture-decisions.md new file mode 100644 index 0000000..a8e8188 --- /dev/null +++ b/docs/architecture-decisions.md @@ -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. diff --git a/docs/data-and-integrations.md b/docs/data-and-integrations.md new file mode 100644 index 0000000..46c44e5 --- /dev/null +++ b/docs/data-and-integrations.md @@ -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. diff --git a/docs/feature-roadmap.md b/docs/feature-roadmap.md new file mode 100644 index 0000000..cff76d9 --- /dev/null +++ b/docs/feature-roadmap.md @@ -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. diff --git a/docs/implementation-plan.md b/docs/implementation-plan.md new file mode 100644 index 0000000..e2f4996 --- /dev/null +++ b/docs/implementation-plan.md @@ -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. diff --git a/docs/open-questions.md b/docs/open-questions.md new file mode 100644 index 0000000..50e60d5 --- /dev/null +++ b/docs/open-questions.md @@ -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. diff --git a/docs/product-brief.md b/docs/product-brief.md new file mode 100644 index 0000000..4119154 --- /dev/null +++ b/docs/product-brief.md @@ -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. diff --git a/docs/technical-plan.md b/docs/technical-plan.md new file mode 100644 index 0000000..ef8532d --- /dev/null +++ b/docs/technical-plan.md @@ -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.