202 lines
5.1 KiB
Markdown
202 lines
5.1 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
|
|
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.
|