refactor: convert to bun workspaces monorepo

- Move web app into apps/web/
- Create packages/shared/ with shared types
- Create plugins/decky-vault/ scaffold
- Root package.json manages workspaces only
This commit is contained in:
2026-06-28 05:20:28 +08:00
parent c4bede20d4
commit cd72b7a948
345 changed files with 488 additions and 126 deletions
-112
View File
@@ -1,112 +0,0 @@
---
title: "Anti-Cheat Tracking, Steam Reviews & Playability Indicators"
date: "2026-04-30"
version: "2026.0.95"
summary: "Major update adding anti-cheat tracking, Steam reviews integration, playability indicators, games list revamp, community suggestions, and more."
---
# Hello everyone!
Starting with somewhat every major release, we'll be making this quick changelog like updates page to track whats new and whats changed. Feel free to check for whats new as I'm always trying to improve the site and experience a lot more!
For now here are some of the recent updates if you have some time to read over them.
And if there are any issues/problems, feel free to visit the [contact page](https://deckyvault.xyz/contact) to submit a report or leave a review!
> Adrian Bonpin
## Added
### Anti-Cheat Tracking
- Per-game anti-cheat status display on game details page
- Anti-cheat badges on games list and search results
- Anti-cheat filter in games list
- Anti-cheat awareness step in benchmark submission wizard
- Anti-cheat is game-level property (not per-device)
### Steam Reviews Integration
- Steam review score badge in game details hero section
- Steam review score display on games list cards
- Steam review score display on search results
- Steam review score and sentiment stored on game records
- Steam review fetching integrated into game sync flow
- Embedded Steam review snippets on game details page
- Steam review score filter in games list (min %)
- Steam review score sort option in games list
### Playability Indicators
- Auto-calculated playability status (Plays Great / Playable / Needs Tweaks / Unplayable)
- Per-device playability with aggregate game-level status
- Manual override capability for admins/contributors
- Color-coded playability badges across all game views
- "Plays Great" quick-filter in games list
- Auto-recalculates on benchmark submission and Steam sync
### Games List Revamp
- FPS range filter (min/max)
- FSR support filter
- Proton/Native runtime filter
- Anti-cheat status filter
- Playability status filter
- Steam review score minimum filter
- Free-to-play filter
- Multiplayer filter
- New sort options: Best Performance, Most Popular, Release Date, Steam Reviews
- Saved/bookmarked filter presets
### Community Suggestions
- "Suggest Edit" button on game details page (non-Steam games only)
- Community suggestion submission for editable fields
- Moderation queue for pending suggestions
- Approve/reject workflow with review notes
- Discord webhook notifications for new suggestions
### Manage Dashboard
- Overview dashboard replacing simple redirect
- Total games, benchmarks, and users stats cards
- Pending reports and suggestions counters
- 30-day activity metrics
- Top contributors leaderboard
- Playability distribution chart
- Steam sync health overview
### Benchmark Peer Review
- Enhanced report system for flagging incorrect presets
- Report status tracking (open/reviewed/dismissed)
- Verified badge on peer-reviewed benchmarks
### Preset Detail Modal
- Added load times (SSD/SD) display
- Added battery life estimate display
- Added custom system indicator
## Changed
- Sync All now processes games in parallel (5 concurrent) instead of one-by-one
- Removed 100-game limit for Sync All (now syncs all Steam games)
- Sync Selected now uses bulk endpoint for faster processing
- Manage page now shows dashboard by default instead of redirecting to users
- Games list now supports 12 filter dimensions and 7 sort options
- Game details page now shows anti-cheat, playability, and Steam reviews prominently
- "Suggest Edit" only appears for non-Steam games (manual, GOG, Epic sources)
- Anti-cheat step in wizard now shows game-level status, not per-device
- Steam sync now sets `syncStatus: "error"` on failure (was missing before)
- Steam sync now handles HTTP 429 rate limiting with Retry-After support
- Steam sync now rejects non-game types (DLC, soundtracks, demos)
## Fixed
- Steam reviews now display correctly (fixed pagination issue with Steam API cursor)
- Steam reviews component now handles missing/error data gracefully
- Anti-cheat badge no longer shows for games without anti-cheat
- Playability calculation only considers anti-cheat if game actually uses it
- API routes registered correctly (removed duplicate `/api` prefix)
- Dashboard and saved-filters routes now accessible
- Sync logic extracted duplicated retry/backoff code into reusable helper
## Technical
- Added `steamReviewScore`, `steamReviewSentiment`, `steamReviewCount` to games table
- Added `playabilityStatus`, `playabilityOverride`, `playabilityCalculatedAt` to games and gamePlatformSupport tables
- Created `community_suggestions` table for moderation workflow
- Created `saved_filters` table for user filter presets
- Added playability auto-calculation engine with `recalculatePlayability()` export
- Added Steam reviews caching API
- Added admin dashboard stats API
- Extracted `recordSyncFailure()` helper for consistent sync error handling
-22
View File
@@ -1,22 +0,0 @@
---
title: "Updates Page & Markdown Content Pipeline"
date: "2026-05-01"
version: "2026.0.96"
summary: "New updates page with version release notes, markdown-based content pipeline with auto-extracted chapter navigation and reading progress bar."
---
# Hello everyone!
This release brings a brand new way to track what's changing on the site. We've added an updates page where you can find release notes for every version, complete with chapter navigation and a reading progress bar to help you get through longer posts.
As always, if you run into any issues, feel free to visit the [contact page](https://deckyvault.xyz/contact) to submit a report!
> Adrian Bonpin
## Added
### Updates Page
- Updates page listing all version release notes
- Update viewer with auto-extracted chapter navigation and reading progress bar
- Markdown-based content pipeline (gray-matter + remark/rehype)
- First update post converted from existing changelog
-42
View File
@@ -1,42 +0,0 @@
---
title: "PWA Support, Gamepad Navigation & Sitemap Reliability"
date: "2026-05-06"
version: "2026.0.97"
summary: "PWA with offline caching, gamepad navigation hook, sitemap reliability fixes, multi-genre filtering, and shareable filter URLs."
---
# Hello everyone!
This release is a big one for reliability and quality-of-life. We've added PWA support so you can install DeckyVault on your device and use it offline, gamepad navigation for controller users, and a bunch of fixes around sitemap generation and filtering that should make the experience a lot more consistent.
As always, if you run into any issues, feel free to visit the [contact page](https://deckyvault.xyz/contact) to submit a report!
> Adrian Bonpin
## Fixed
- Sitemap.xml used ISR caching (`revalidate = 3600`) which poisoned the cache with empty responses on DB hiccups; switched to `force-dynamic` for per-request fresh generation
- DB errors during sitemap generation were silently caught and returned as empty arrays (no games indexed); errors now propagate to observability with structured logging
- Games with NULL `syncStatus` were excluded from sitemap due to SQL `<> 'failed'` returning NULL (not TRUE) for NULL values
- Multi-genre selection in games filter panel only applied the first selected genre; now supports comma-separated OR-matching
- FPS range filter included results from non-active devices; now scoped to the selected device filter when present
## Added
- PWA service worker with offline caching for game pages and images (stale-while-revalidate for HTML, cache-first for Steam CDN images)
- Offline fallback page (`offline.html`) when navigating without network
- Gamepad navigation hook (D-pad/left stick focus, A/B/X/Y buttons, context-aware actions)
- Structured logging for sitemap generation metrics (games, devices, timestamps) via `console.info` JSON
- Filter state synchronized to URL query parameters for shareable/bookmarkable filtered views
- WCAG 2.1 AA touch targets (44×44px) on all games page filter controls
## Changed
- Web manifest icons now declare explicit 192px (maskable) and 512px (any) sizes
- Viewport meta tag added with `viewport-fit=cover` and `user-scalable=no` for installed PWA feel
- Apple mobile web app meta tags added for iOS home screen support
- Loading a saved filter now auto-collapses the filter panel for visual feedback
- Sitemap generation flattened into a single function in `app/sitemap.ts` (removed delegation to `lib/sitemap/`)
## Technical
- Removed `lib/sitemap/fetch-dynamic-entries.ts`, `lib/sitemap/build-static-entries.ts`, `lib/sitemap/validate-image-url.ts`
- Removed `app/api/revalidate-sitemap/` route (no longer needed with `force-dynamic`)
- Added `@serwist/next`, `@serwist/precaching`, `@serwist/sw`, `@serwist/strategies`, `@serwist/expiration`, `@serwist/routing`, and `serwist` dependencies
- Build script updated to use `--webpack` flag for `@serwist/next` compatibility
@@ -1,18 +0,0 @@
---
title: "Submit Bug Fix & Game Card Layout Fix"
date: "2026-05-09"
version: "2026.0.97.1"
summary: "Fixed submit wizard crash when creating new game versions and game card height issue in grid views."
---
# Hello everyone!
A quick patch release to fix two issues that were affecting the submit flow and the games list layout.
As always, if you run into any issues, feel free to visit the [contact page](https://deckyvault.xyz/contact) to submit a report!
> Adrian Bonpin
## Fixed
- Submit wizard crashed with `can't access property "id", (intermediate value).data is undefined` when creating a new game version — the frontend expected a `{ data: { id } }` wrapper but the API returns the created version object directly
- Game Card height in grid views was extending beyond actual content, causing inconsistent row alignment
-29
View File
@@ -1,29 +0,0 @@
---
title: "R2 Storage, Profile Photos, Dashboard, and UX Overhaul"
date: "2026-05-09"
version: "2026.0.98"
summary: "Cloudflare R2 storage with daily cleanup cron, profile photo uploads, public data dashboard, game details UX improvements, advanced search filters, and static sitemaps."
---
### Added
- **Cloudflare R2 Storage**: Full R2 integration for file uploads with storage tracking, orphan detection, and daily cleanup cron
- **Profile Photos**: Upload, customize, and delete custom profile photos (stored in R2)
- **Daily Cron System**: Modular `/api/cron/daily` endpoint with task registry for storage cleanup, sitemap regeneration, and future tasks
- **Public Dashboard**: New `/dashboard` page with trending games, best new releases, and most tested/reported visualizations
- **Advanced Search Filters**: Full filter panel on search page (device, FPS range, FSR, Proton/Native, anti-cheat, playability) with saved filter presets
- **Admin Sitemap Regeneration**: `POST /api/sitemap/regenerate` for on-demand sitemap updates
### Changed
- **Game Details Page**: Restructured layout — metadata now inline with hero section, system requirements expanded by default, improved controller navigation and mobile responsiveness
- **Static Sitemaps**: Replaced dynamic per-request sitemap generation with build-time static XML files for zero-latency serving
- **Search Page**: Added collapsible filter panel with save/load filter presets
### Technical
- Added `storage_objects` database table for R2 object tracking
- Added `@aws-sdk/client-s3` R2 integration (S3-compatible API)
- Added `CRON_SECRET`, `R2_ACCOUNT_ID`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `R2_BUCKET_NAME`, `R2_PUBLIC_URL` environment variables
- Deprecated `S3_*` environment variables (replaced by `R2_*`)
- Removed dynamic sitemap generation in favor of `npm run build:sitemap`
-27
View File
@@ -1,27 +0,0 @@
---
title: "Screenshots, Power Tracking, YouTube Links & Quality of Life"
date: "2026-05-09"
version: "2026.0.99"
summary: "Screenshot attachments for benchmarks, energy/power usage tracking with auto-computed battery estimates, YouTube video linking, community auto-pinning, mobile game cover hero, and responsive filter panel."
---
### Visual Evidence for Benchmarks
You can now attach up to 2 screenshots when submitting a benchmark — show your in-game settings, FPS overlay, or any relevant visual proof. Screenshots are compressed for storage but retain full clarity for review.
### Power Usage & Battery Life
Track the TDP (thermal design power) you set on your device while benchmarking. DeckyVault now auto-computes estimated battery life based on your TDP and the device's watt-hour capacity. Performance cards show a quick-look bar with ⚡ TDP, 🔋 Wh, and ⏱ estimated hours. A new Battery Life vs TDP chart visualizes the relationship across devices.
### YouTube Video Linking
Link a YouTube video to any benchmark entry to show gameplay footage alongside your settings. Videos display as privacy-enhanced embeds in the preset detail modal.
### Community Auto-Pinning
Entries that receive 10 or more votes with at least 80% approval are automatically pinned, surfacing the best community presets.
### Mobile Improvements
- **Game cover hero:** On mobile, the game cover image now serves as a full-bleed background with a gradient overlay, making better use of screen real estate.
- **Filter drawer:** The games list filter panel is now a slide-out drawer on narrow screens, preventing overflow and improving touch accessibility.
-32
View File
@@ -1,32 +0,0 @@
---
title: "Screenshot Uploads in Wizard, Performance Badges, and Smarter Battery Estimates"
date: "2026-05-10"
version: "2026.0.100"
summary: "Attach screenshots directly in the submit wizard, see performance badges on game cards, and get auto-computed battery estimates in the Review step."
---
### Screenshot Uploads in the Submit Wizard
You can now attach up to 2 screenshots directly in the Review step of the benchmark submission wizard — no more post-submit interstitial. Screenshots are gated on having at least one game setting configured, ensuring your evidence is meaningful.
### Performance Badges on Game Cards
Browse the games list and instantly spot standout titles:
- **⚡ RAW PERFORMER** — games that hit 60+ FPS without upscaling or frame generation
- **⚠ POOR PERFORMANCE** — games struggling below 30 FPS
- **Best FPS** — the highest average FPS recorded for the game
- **🔋 Battery estimate** — for handheld devices, see estimated playtime in hours
### Smarter Battery Estimates
The manual "Estimated Battery" field has been removed. Battery life is now always computed automatically from your device's watt-hour capacity and the TDP you set during benchmarking. You'll see this estimate in:
- The submit wizard's Review step
- Game cards (for handheld entries)
- Preset detail modals
### Preset Detail Modal Improvements
Preset modals now show richer context:
- **Game version** and **build ID** for the benchmarked entry
- **Anti-cheat** name and status at the game + hardware level
- **Verification date** alongside the verified badge
-31
View File
@@ -1,31 +0,0 @@
---
title: "Landing Page, SteamDB Version Sync, and Security Hardening"
date: "2026-05-14"
version: "2026.0.101"
summary: "Discover trending games on the new landing page, auto-fetch latest game versions from SteamDB, and enjoy improved API security."
---
### New Landing Page
The homepage now showcases what's happening in the DeckyVault community:
- **Recently Added Benchmarks** — games with the newest benchmark submissions
- **Trending This Week** — games with the most benchmarks, comments, and upvotes in the last 7 days
- **Most Tested Games** — the most benchmarked games across all devices
Each section shows compact game cards with cover art, **playability badges** (with readable status labels), **performance tags** (Raw Performer / Poor Performance), and average FPS. Click any card to jump straight to the game's detail page.
### SteamDB Version Auto-Fetch
When submitting a benchmark, the wizard now automatically checks SteamDB for the latest game version and build ID. If found, it appears as a recommended option at the top of the version selector — no more guessing which version you're on.
This feature is best-effort and can be disabled via the `STEAMDB_SCRAPING_ENABLED` environment variable.
### API Security Hardening
We've tightened up the API with several layers of protection:
- **Tiered rate limiting** — different limits for authentication, reads, writes, and public forms
- **Comment anti-spam** — duplicate detection, size limits, and hourly caps
- **Submission validation** — FPS must be within realistic bounds, settings payloads have size caps
- **Content sanitization** — comment content is cleaned server-side before storage
-28
View File
@@ -1,28 +0,0 @@
---
title: "Moderator Role, Performance Tag Fix, and Steam Sale Section"
date: "2026-05-16"
version: "2026.0.102"
summary: "New moderator role for community management, handheld-scoped performance tags for more accurate badges, Steam sale discovery on the landing page, and submit wizard fixes."
---
### New Moderator Role
A new **moderator** role sits between contributor and admin, giving trusted community members the ability to:
- Verify benchmarks, handle reports, and review community suggestions
- Moderate comments and remove problematic entries
- Access the manage panel with role-appropriate navigation
Admins retain full control over user management, storage, and hardware creation. Existing contributors keep their permissions unchanged.
### Handheld-Scoped Performance Tags
Performance badges (Raw Performer, Poor Performance, best FPS) are now calculated using **Steam Deck data only** — console performance no longer masks handheld reality. A game running at 90 FPS on Steam Machine but 25 FPS on Steam Deck will correctly show as "Poor Performance" rather than displaying both badges confusingly.
### Steam Sale Discovery
The landing page now features an **On Sale & Performing Well** section showing discounted Steam games from the DeckyVault database. Each card displays the discount percentage, sale price, performance badges, and Steam review score — helping you spot great deals on games that actually run well.
### Submit Wizard Improvements
- **Drag-and-drop** in the settings editor and screenshot uploader no longer triggers accidental text selection
- **Editing entries with screenshots** now shows your existing screenshots in the Review step — remove individual ones or add new ones before re-submitting
-23
View File
@@ -1,23 +0,0 @@
---
title: "ProtonDB Redirects, Smart Sharing & Clean URLs"
date: "2026-05-20"
version: "2026.2.0"
summary: "Fast redirects for ProtonDB users, clean game slugs for non-Steam game sharing, and share URLs now use human-readable identifiers instead of UUIDs."
---
### ProtonDB URL Compatibility
You can now replace `protondb.com` with `deckyvault.xyz` in any ProtonDB URL to land on the matching DeckyVault game page. Visiting `deckyvault.xyz/app/730` automatically redirects you to the Counter-Strike 2 benchmarks page. This works for any Steam App ID in the DeckyVault database.
### Smart Share URLs
The share button on benchmark presets now produces clean, readable URLs:
- **Steam games:** `deckyvault.xyz/game/730?preset=...` (numeric Steam App ID)
- **Non-Steam games:** `deckyvault.xyz/game/the-witcher-3-wild-hunt?preset=...` (title-based slug)
No more long UUID strings when you share a benchmark with friends. Existing UUID links continue to work — this is purely additive.
### Non-Steam Game Slugs
All non-Steam games (manual entries, GOG, Epic Games Store) now receive auto-generated URL-friendly slugs based on their title. Slugs are unique, deduplicated automatically, and remain stable even if the game title is later edited.
-22
View File
@@ -1,22 +0,0 @@
---
title: "SEO Improvements — Better Titles, Rich Results & Performance Hints"
date: "2026-05-25"
version: "2026.2.1"
summary: "Fixed duplicate page titles across the site, added structured data (breadcrumbs, ratings, organization) for rich search results, improved meta descriptions, and added preconnect hints for faster image loading."
---
### Page Title Cleanup
The `/games` and `/devices` pages no longer show the brand name twice in search results. Titles now read `"Games | DeckyVault"` and `"Devices | DeckyVault"` instead of the old `"Games — DeckyVault | DeckyVault"`. The `/compare` and `/profile` pages also have unique titles now instead of reusing the homepage title.
### Rich Search Results
Game detail pages now include **BreadcrumbList** and **AggregateRating** structured data, enabling breadcrumb trails and star ratings in Google search results. The homepage includes **Organization** schema for brand visibility.
### Better Meta Descriptions
Game page descriptions no longer cut off mid-sentence — the new smart truncation respects word boundaries for cleaner search result snippets.
### Faster Image Loading
Preconnect hints for Steam, SteamGridDB, Discord, Google, and Cloudflare R2 CDNs reduce connection setup time when loading game cover images.
-20
View File
@@ -1,20 +0,0 @@
---
title: "Domain Restriction & Branded Placeholder — Sign-Up Protection"
date: "2026-05-27"
version: "2026.2.2"
summary: "Blocked sign-ups using @deckyvault.xyz email addresses in production and updated all auth form email placeholders to use the DeckyVault domain."
---
### Domain Protection for Sign-Ups
New accounts can no longer be created with `@deckyvault.xyz` email addresses in production. This prevents unauthorized use of the DeckyVault brand domain — the domain owner is the only one who should be creating accounts with those addresses.
The restriction applies to all sign-up methods: email/password, one-time code (OTP), and social login via Google or Discord.
**What's NOT affected:**
- Existing `@deckyvault.xyz` accounts continue to work normally — login, password reset, and OTP sign-in are all functional
- Development builds still allow `@deckyvault.xyz` sign-ups for testing
### Branded Placeholder Text
All email input fields across web and mobile now show `you@deckyvault.xyz` as the default placeholder, replacing the generic `you@example.com`. This appears in the sign-up, login, and forgot password forms.