Files

212 lines
5.9 KiB
Markdown

# 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
Spinning-wheel 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.
- Fetch Steam Store metadata for owned apps so tools, DLC, demos, and other non-game app types can be excluded before recommendation.
- 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.
- Apply hard eligibility filters before scoring.
- Apply preferred filters as weighting only, not as inclusion/exclusion rules.
- 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`
- `supports_singleplayer`
- `supports_multiplayer`
- `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 matching preferred single-player or multiplayer mode.
- 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.
- Hard exclusion only for explicit eligibility filters; review, mode, genre, and playtime preferences should not remove candidates by themselves.
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.
- Exclude non-game Steam app types before they enter the wheel.
- 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 eligibility filters that can remove games from the candidate pool.
- Add preferred filters for review signal, single-player/multiplayer, genre, and playtime weighting.
- Add true-random toggle behavior.
- Add spinning-wheel 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.