These commits are when the Protocol Buffers files have changed: (only the last 100 relevant commits are shown)
| Commit: | b5b9c21 | |
|---|---|---|
| Author: | John Beresford | |
chore(client-next): clean-up sidebar
| Commit: | c4c6d19 | |
|---|---|---|
| Author: | John Beresford | |
chore(ui-next): init emulator details page
| Commit: | 42a93cb | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | GitHub | |
chore: standardize emulator service (#568)
| Commit: | d52d66f | |
|---|---|---|
| Author: | John Beresford | |
chore: stub emulator service
| Commit: | cc1b505 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | GitHub | |
feat(emulators): complete EmulatorService RPC surface, clean up proto messages (#567) `emulator_service.proto` had two unimplemented TODO sections (`DefaultEmulatorProfiles`, `LocalEmulatorConfigs`) and was missing all singular request messages for its existing RPCs. This completes the service definition following the `LibraryService` pattern. ## Removed (unused messages) - Leftover plural batch-style variants: `CreateEmulatorsRequest/Response`, `UpdateEmulatorsRequest/Response`, `DeleteEmulatorsRequest/Response`, and the equivalent emulator profile counterparts - Stale multi-record DefaultEmulatorProfiles messages (`GetDefaultEmulatorProfilesRequest/Response`, etc.) - Stale LocalEmulatorConfig batch messages - Unused EmulatorPlatforms request/response messages ## Added (missing request messages for existing RPCs) - `GetEmulatorRequest`, `CreateEmulatorRequest`, `UpdateEmulatorRequest`, `DeleteEmulatorRequest` - `GetEmulatorProfileRequest`, `CreateEmulatorProfileRequest`, `UpdateEmulatorProfileRequest`, `DeleteEmulatorProfileRequest` ## Added (TODO: DefaultEmulatorProfiles) Five RPCs + messages: `GetDefaultEmulatorProfile`, `ListDefaultEmulatorProfiles`, `CreateDefaultEmulatorProfile`, `UpdateDefaultEmulatorProfile`, `DeleteDefaultEmulatorProfile` ## Added (TODO: LocalEmulatorConfigs) Five RPCs + messages: `GetLocalEmulatorConfig`, `ListLocalEmulatorConfigs`, `CreateLocalEmulatorConfig`, `UpdateLocalEmulatorConfig`, `DeleteLocalEmulatorConfig` All new RPCs follow `LibraryService` conventions — singular Get/Create/Update/Delete return the resource directly, List uses a filter request + response wrapper, ID fields carry `REQUIRED` + `google.api.resource_reference` annotations.
| Commit: | f4cacaf | |
|---|---|---|
| Author: | copilot-swe-agent[bot] | |
| Committer: | GitHub | |
fix(proto): update DefaultEmulatorProfile name_field to "id" Co-authored-by: JMBeresford <1373954+JMBeresford@users.noreply.github.com>
| Commit: | 3c4785b | |
|---|---|---|
| Author: | copilot-swe-agent[bot] | |
| Committer: | GitHub | |
feat: finish TODO RPCs in EmulatorService, remove unused messages, add missing messages - Remove all unused message definitions (plural Create/Update/Delete variants, old-style DefaultEmulatorProfiles/LocalEmulatorConfigs/EmulatorPlatforms messages) - Add missing request messages for existing RPCs (GetEmulatorRequest, CreateEmulatorRequest, UpdateEmulatorRequest, DeleteEmulatorRequest, GetEmulatorProfileRequest, CreateEmulatorProfileRequest, UpdateEmulatorProfileRequest, DeleteEmulatorProfileRequest) - Implement DefaultEmulatorProfile RPCs + messages following LibraryService semantics - Implement LocalEmulatorConfig RPCs + messages following LibraryService semantics - Add google/api/field_behavior and resource imports for REQUIRED annotations Co-authored-by: JMBeresford <1373954+JMBeresford@users.noreply.github.com>
| Commit: | ab0f663 | |
|---|---|---|
| Author: | John Beresford | |
wip
| Commit: | 9fbe32f | |
|---|---|---|
| Author: | Copilot | |
| Committer: | GitHub | |
feat: library-level ignore_patterns (#566) This change adds first-class `ignore_patterns` support to `Library` so scan exclusions are persisted per library and enforced during filesystem ingestion. It also introduces schema/migration support to preserve legacy ignore data where present. - **API contract updates** - Added `repeated string ignore_patterns` to `Library`. - Introduced `LibraryIgnorePatternRow` (instead of putting repeated data on `LibraryRow`) to model row-level mapping-table records. - **Database schema + migration path** - Added `library_ignore_patterns` (`library_id`, `pattern`, timestamps, PK `(library_id, pattern)`) to both sqlite and postgres v2 baseline migrations. - Extended sqlite/postgres `updated_at` trigger migrations to include `library_ignore_patterns`. - Added guarded postgres v1-compat backfill logic to populate `library_ignore_patterns` from legacy content-directory ignore pattern sources when those columns/tables exist. - **Library CRUD behavior** - Updated `Create/Get/List/UpdateLibrary` handling to persist and hydrate ignore patterns via `library_ignore_patterns`. - `UpdateLibrary` now replaces prior ignore mappings for the target library before inserting the new set. - Added ignore-pattern regex validation at library write boundaries. - **Scan pipeline integration** - Extended `LibraryScanTarget` loading to include per-library ignore patterns. - Compiled ignore regexes once per target scan and applied filtering across root paths, platform dirs, game entries, and discovered files. - Consolidated ignore matching via a shared helper for consistent behavior. - **Coverage updates** - Added tests for ignore-pattern CRUD round-tripping. - Added scan behavior coverage demonstrating ignored platform/game/file paths are excluded while non-matching entries are still ingested. Example of the persisted mapping shape now used by handlers and scan target loading: ```sql insert into library_ignore_patterns (library_id, pattern) values ($1, '.*/IgnoredPlatform(/.*)?$'), ($1, '.*/skip\.bin$') on conflict do nothing; ```
| Commit: | 749cc88 | |
|---|---|---|
| Author: | copilot-swe-agent[bot] | |
| Committer: | GitHub | |
Add library ignore-pattern schema and service support Co-authored-by: JMBeresford <1373954+JMBeresford@users.noreply.github.com>
| Commit: | 8e3ef3d | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | GitHub | |
chore: update igdb api (#565)
The documentation is generated from this commit.
| Commit: | 2cf06c0 | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
The documentation is generated from this commit.
| Commit: | 66cafdb | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
The documentation is generated from this commit.
| Commit: | 051c1ad | |
|---|---|---|
| Author: | John Beresford | |
chore(service-metadata): standardized provider handlers
| Commit: | 87299bf | |
|---|---|---|
| Author: | JMBeresford | |
| Committer: | John Beresford | |
chore: update igdb protos
| Commit: | 823f61a | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | e08f017 | |
|---|---|---|
| Author: | John Beresford | |
chore: init standardized metadata svc
| Commit: | 8c1e583 | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | 2b25bcd | |
|---|---|---|
| Author: | John Beresford | |
chore: standardized library svc
| Commit: | 202e92f | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | f230d59 | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | 9bdc3bb | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | 85280d5 | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | ec71140 | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | 7477bd9 | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | faaa147 | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | 4309d52 | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | 8e6cc0b | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | 9a1398a | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | 7c8c1c5 | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | ca1de53 | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | 2ba8c10 | |
|---|---|---|
| Author: | JMBeresford | |
chore: update igdb protos
| Commit: | 638efc2 | |
|---|---|---|
| Author: | John Beresford | |
Mark CreateRootDirectoryResponse as deprecated (unused in this file) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| Commit: | c9dad0f | |
|---|---|---|
| Author: | John Beresford | |
chore: clean up library-service protos
| Commit: | 1f8c9d6 | |
|---|---|---|
| Author: | John Beresford | |
chore(codegen): clean up deps + generation
| Commit: | e6d7dde | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore(codegen): fix library service schema
| Commit: | ecb47d8 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | GitHub | |
chore(codegen): fix lint errors
| Commit: | ec39b9a | |
|---|---|---|
| Author: | copilot-swe-agent[bot] | |
| Committer: | GitHub | |
Refine save strategy enum comments Co-authored-by: JMBeresford <1373954+JMBeresford@users.noreply.github.com>
| Commit: | 31aaa33 | |
|---|---|---|
| Author: | copilot-swe-agent[bot] | |
| Committer: | GitHub | |
Fix enum zero-value semantics in codegen protos Co-authored-by: JMBeresford <1373954+JMBeresford@users.noreply.github.com>
| Commit: | 7bf37e6 | |
|---|---|---|
| Author: | copilot-swe-agent[bot] | |
| Committer: | GitHub | |
Fix retrom-codegen Buf lint violations instead of ignoring rules Co-authored-by: JMBeresford <1373954+JMBeresford@users.noreply.github.com>
| Commit: | 72857c4 | |
|---|---|---|
| Author: | copilot-swe-agent[bot] | |
| Committer: | GitHub | |
Fix remaining buf enum naming lint issue Co-authored-by: JMBeresford <1373954+JMBeresford@users.noreply.github.com>
| Commit: | 35354f0 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | GitHub | |
chore: service gateway refactor (#559)
| Commit: | 6420383 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore: clean-up service gateway
| Commit: | f5dc84e | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
chore(service-library): migrate to sqlx (#540) This PR advances the service-layer refactor by moving `retrom-service-library` off Diesel to sqlx-oriented handlers and wiring, and adds the missing `CreateGames`, `CreatePlatforms`, `DeleteLibrary`, `DeleteMissingEntries`, `AddPlatformRootDirectory`, and `AddGameRootDirectory` RPC implementations in `LibraryService` v1. - **Proto contract updates (LibraryService v1)** - Added `CreatePlatforms` and `CreateGames` RPCs to `library-service.proto`. - Added new request/response message types: - `CreatePlatformsRequest` / `CreatePlatformsResponse` - `CreateGamesRequest` / `CreateGamesResponse` - Added full doc comments and field behavior annotations (`OUTPUT_ONLY`, `REQUIRED`) across `library-service.proto` and `models.proto`. - **sqlx migration groundwork in `retrom-service-library`** - Reworked service handler modules (`library`, `root_directory`, `platform`, `game`, `game_file`) to use sqlx query patterns (`QueryBuilder`, `query_as`) against `DbPool`. - Implemented create flows for platforms and games in the new v1 service path; server always generates UUIDv7 IDs, ignoring any client-provided `id`. - Removed legacy Diesel-centric service wiring from the library service crate. - All mutating handlers (`update_games`, `update_game_files`, `delete_games`) wrapped in transactions. - **Fully implemented previously-stubbed RPCs** - `DeleteLibrary` — deletes all non-third-party platforms in a transaction (cascades to `game_platforms`/`game_files`), then removes orphaned games. - `DeleteMissingEntries` — performs filesystem existence checks outside the transaction, then in a transaction identifies orphaned games (no surviving files) and orphaned platforms (no surviving games), and hard-deletes all three sets when `dry_run = false`. - `AddPlatformRootDirectory` — inserts into `platform_root_directories` mapping table with `on conflict do nothing`. - `AddGameRootDirectory` — inserts into `game_root_directories` mapping table with `on conflict do nothing`. - **Service wiring/runtime alignment** - Simplified `library_router` to serve the v1 `LibraryService` handler backed by sqlx pool. - Updated `main.rs` to initialize DB via `retrom_db::connect` and run migrations via `retrom_db::run_migrations`. - **Codegen row-mapping support** - Extended codegen row derive list to include `retrom.services.library.v1.Platform` and `retrom.services.library.v1.GameFile` (`sqlx::FromRow`), enabling direct `query_as` mapping for these models. Example (new RPC surface): ```proto service LibraryService { rpc GetPlatforms(GetPlatformsRequest) returns (GetPlatformsResponse); rpc CreatePlatforms(CreatePlatformsRequest) returns (CreatePlatformsResponse); rpc DeleteLibrary(DeleteLibraryRequest) returns (DeleteLibraryResponse); rpc DeleteMissingEntries(DeleteMissingEntriesRequest) returns (DeleteMissingEntriesResponse); rpc GetGames(GetGamesRequest) returns (GetGamesResponse); rpc CreateGames(CreateGamesRequest) returns (CreateGamesResponse); rpc AddPlatformRootDirectory(AddPlatformRootDirectoryRequest) returns (AddPlatformRootDirectoryResponse); rpc AddGameRootDirectory(AddGameRootDirectoryRequest) returns (AddGameRootDirectoryResponse); } ```
| Commit: | 2aaf1ca | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
chore(service-metadata): migrate to sqlx (#537)
| Commit: | 104ce3e | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
fix(service-common): migrate to versioned codegen types from service layer refactor (#536)
| Commit: | eef87c8 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore: proto clean up
| Commit: | 8c0937a | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
chore(service-saves): migrate to sqlx
| Commit: | 4123b62 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore(service-emulators): migrate to sqlx
| Commit: | 7766a4b | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore: fix schema
| Commit: | 7d04dd1 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore: fix schema
| Commit: | 5c82200 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore(service-clients): migrate to sqlx
| Commit: | c748287 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore: clean up protos
| Commit: | c472742 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat: implement item 2.10 - deprecated service forwarding stubs (#513) ## Summary Implements **item 2.10** from `SERVICE_LAYER_REFACTOR.md`: deprecated service forwarding stubs for `GameService`, `PlatformService`, and `ServerService`. ## Changes ### `packages/codegen/protos/retrom/services/server-service.proto` - Added `option deprecated = true;` to each of the 3 RPC methods (`GetServerInfo`, `GetServerConfig`, `UpdateServerConfig`). The file-level and service-level deprecations were already in place; this completes the method-level annotations required by the acceptance criteria. ### `packages/service-config/src/lib.rs` - Added `ConfigServiceHandlers::with_config(config: Arc<ServerConfigManager>) -> Self` constructor to allow sharing an existing config manager instance instead of always creating a fresh one. ### `packages/grpc-service/src/server/mod.rs` - Rewrote `ServerServiceHandlers` as a true forwarding stub: - Now holds `Arc<ConfigServiceHandlers>` instead of `Arc<ServerConfigManager>`. - Each RPC method delegates to the equivalent `ConfigService` v1 method and performs trivial request/response type conversion (the underlying model types `ServerInfo`/`ServerConfig` are shared between the old and new proto namespaces). - Replaced the old `test_parse_version` unit test with a `test_get_server_info` async test that exercises the full forwarding path. ### `packages/grpc-service/src/lib.rs` - Creates a single `Arc<ConfigServiceHandlers>` backed by the function's `config_manager`. - Uses `ConfigServiceServer::from_arc(config_handlers.clone())` so both `config_service` and `server_service` share the same handler instance. ### `SERVICE_LAYER_REFACTOR.md` - Marked item 2.10 as `[x]`. ## Context `GameServiceHandlers` (games.rs) and `PlatformServiceHandlers` (platforms.rs) were already forwarding stubs from earlier work. This PR completes the trio by forwarding `ServerService` to `ConfigService`.
| Commit: | e71d955 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat: implement TagsService (refactor plan item 2.8) (#508) Implements item 2.8 from `SERVICE_LAYER_REFACTOR.md`: a new `TagsService` that owns all tag domain and tag management, plus game/platform tagging, as a standalone service crate following the established per-crate router pattern. ## Migration (`2026-03-25-101000_phase1-new-standalone-tables`) - Added `created_at` and `updated_at` columns to the `tag_domains` table - Seeds the four well-known domains (`genre`, `favorites`, `franchise`, `region`) directly in the migration ## Proto (`retrom/services/tags/v1/tags-service.proto`) Previously only contained the `TagDomain` and `Tag` message stubs. Now includes: - `TagsService` with 12 RPCs across four concerns: domain management, tag management, game tagging, platform tagging - `Tag` uses a flat `int32 tag_domain_id` field (matching the DB table directly) instead of a nested `TagDomain` message - `GetGameTags` / `GetPlatformTags` operate on a single `game_id` / `platform_id` and return `repeated Tag` directly (no mapping wrapper messages) - `AddGameTags` / `DeleteGameTags` and `AddPlatformTags` / `DeletePlatformTags` replace the previous `UpdateGameTags` / `UpdatePlatformTags` RPCs; requests use `{ int32 *_id; repeated int32 tag_ids; }` shape - Full request/response message set ## Codegen - Added `services.tags.v1` module to `codegen/src/lib.rs` - Added Diesel derives (`Queryable`, `Selectable`, `Identifiable`, `Insertable`, `AsChangeset`) to both `TagDomain` and `Tag` in `build.rs` — both map directly to their respective DB tables ## New crate: `retrom-service-tags` - `TagServiceHandlers` implements all 12 RPCs against the `tag_domains`, `tags`, `game_tag_maps`, and `platform_tag_maps` tables - Uses `Tag` directly via `Tag::as_select()` with no local helper structs - `CreateTagDomains` and `CreateTags` use single bulk `INSERT` statements; `CreateTags` validates all `tag_domain_id`s upfront - `GetGameTags` / `GetPlatformTags` use a single `INNER JOIN` query against the mapping tables to return tags directly, avoiding a separate round-trip - `AddGameTags` / `AddPlatformTags` insert mapping rows in bulk with `ON CONFLICT DO NOTHING` and use `.returning(tag_id)` to return only the actually-inserted rows, without an extra transaction - `DeleteGameTags` / `DeletePlatformTags` use `.returning(tag_id)` on the delete statement to retrieve affected tag IDs, then fetch and return the full `Tag` rows - `DeleteTagDomains` rejects well-known domains with `Status::failed_precondition` - Exports `tags_router(db_pool: Arc<Pool>) -> axum::Router` per the established pattern ## Registration (`retrom-grpc-service`) - `TagsServiceServer` added to the routes builder
| Commit: | 0bb1b1f | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat: extract FileExplorerService to its own crate (refactor 2.7) (#507)
| Commit: | 1fa9c4f | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat(2.6): Add dedicated Job Service gRPC crate (#503)
| Commit: | 673da80 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat: Updated Emulator Service — mapping-table RPCs (refactor plan 2.4) (#500)
| Commit: | b98abf0 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat(metadata): implement refactor plan item 2.3 — provider-aware MetadataService v1 (#499) Implements item 2.3 of `SERVICE_LAYER_REFACTOR.md`: introduce a versioned `retrom.services.metadata.v1.MetadataService` that adds provider-awareness to the metadata layer. ### Proto - **`retrom/models/metadata.proto`** — added `optional int32 provider_id` to `UpdatedGameMetadata` (field 17) and `UpdatedPlatformMetadata` (field 9) so write operations can now carry and persist a provider FK. - **`retrom/services/metadata/v1/metadata-service.proto`** — added `MetadataService` service definition mirroring all legacy RPCs (via `retrom.*` type imports) plus the new RPC: ```protobuf rpc GetMetadataProviders(GetMetadataProvidersRequest) returns (GetMetadataProvidersResponse); ``` ### Codegen (`packages/codegen`) - Registered `services.metadata.v1.MetadataProvider` in `build.rs` `queryable_models` → Diesel derives against `metadata_providers` table. - Exposed `retrom::services::metadata::v1` module in `src/lib.rs`. ### gRPC service (`packages/grpc-service`) - `MetadataServiceHandlers` gains `#[derive(Clone)]` to allow sharing across legacy and v1 servers. - New `impl MetadataServiceV1 for MetadataServiceHandlers` — existing RPCs delegate via UFCS; `get_metadata_providers` queries the `metadata_providers` table: ```rust let providers = schema::metadata_providers::table .load::<MetadataProviderModel>(&mut conn) .await?; ``` - `MetadataServiceServerV1` wired into the Axum router alongside the legacy server (same pattern as `LibraryServiceServerV1`).
| Commit: | 3dc94f2 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat(service): implement 2.2 Enhanced Library Service (#497) Implements Phase 2.2 of the service layer refactor: surface all game and platform CRUD through `retrom.services.library.v1.LibraryService`, making `GameService` and `PlatformService` redundant forwarding stubs. - **`library/v1/library-service.proto`** — promotes from model-only to a full service definition with 18 RPCs: existing library ops + Library CRUD (`GetLibraries`, `CreateLibraries`, `UpdateLibraries`) + Root Directory management (full CRUD) + platform ops + game/game-file ops. All new request/response types live in `retrom.services.library.v1`; model types imported from the existing `retrom` package. - **`game-service.proto` / `platform-service.proto`** — `option deprecated = true` at file, service, and method levels. - `build.rs` — Diesel `Queryable`/`Selectable`/`Identifiable`/`Insertable`/`AsChangeset` type attributes added for `Library` and `RootDirectory` v1 types so handlers can use them directly in queries. - `src/lib.rs` — adds `retrom::services::library::v1` via `tonic::include_proto!`. - **`library/game_handlers.rs`** / **`library/platform_handlers.rs`** *(new)* — shared free-function handler logic extracted from the top-level `games.rs` / `platforms.rs`. - **`library/library_handlers.rs`** / **`library/root_directory_handlers.rs`** *(new)* — new CRUD handlers against the `libraries` and `root_directories` tables. - **`library/mod.rs`** — `LibraryServiceHandlers` derives `Clone` and now implements *both* the legacy `retrom::LibraryService` trait and the new `retrom::services::library::v1::LibraryService` trait: ```rust impl LibraryServiceV1 for LibraryServiceHandlers { async fn get_libraries(&self, request: Request<GetLibrariesRequest>) -> ... { library_handlers::get_libraries(self.db_pool.clone(), request.into_inner()) .await.map(Response::new) } async fn get_games(&self, request: Request<GetGamesRequest>) -> ... { // converts v1 ↔ retrom package types, delegates to game_handlers } // ...all 18 RPCs } ``` - **`games.rs`** / **`platforms.rs`** — reduced to forwarding stubs; all logic now lives in `library/{game,platform}_handlers.rs`. - **`lib.rs`** — registers `LibraryServiceServerV1` alongside the existing services.
| Commit: | e1b4cc3 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat(service-config): implement ConfigService to replace ServerService (refactor plan 2.1) (#496) Implements item 2.1 from the service layer refactor plan: introduces a versioned `ConfigService` under `retrom.services.config.v1` and deprecates the existing `ServerService`. - New file `retrom/services/config/v1/config-service.proto` — `ConfigService` with `GetServerInfo`, `GetServerConfig`, `UpdateServerConfig` RPCs (each with focused doc comments), reusing existing `retrom.ServerConfig` / `retrom.ServerInfo` model types - `server-service.proto` marked `option deprecated = true` at both file and service level - `ServerConfigManager` and `RetromDirs` moved from `retrom-service-common` into this crate (`src/config.rs` and `src/retrom_dirs.rs`) — `retrom-service-config` is now the sole owner of the config file on disk - `retrom-service-common` re-exports both types via `#[deprecated]` type aliases for backward compatibility — existing callers continue to compile but receive deprecation warnings guiding them to import from `retrom-service-config` directly (or use the gRPC API for config access) - `ConfigServiceHandlers` creates and owns its own `Arc<ServerConfigManager>` internally — `new()` takes no arguments - Replaces `.unwrap()` on optional request field with `tonic::Status::invalid_argument` - Exports `config_router() -> axum::Router` for per-service router composition (Phase 3); the router creates the handler (and manager) internally ```rust pub fn config_router() -> axum::Router { let config_service = ConfigServiceServer::new(ConfigServiceHandlers::new()); let mut routes_builder = tonic::service::Routes::builder(); routes_builder.add_service(config_service); routes_builder.routes().into_axum_router() } ``` - Includes `src/main.rs` and a `[[bin]]` entry in `Cargo.toml` so the service can be started as a standalone process — reads initial config for telemetry setup, initialises tracing, and serves on port 5103 - `retrom-service-config` added to the Cargo workspace and as a dependency of `retrom-grpc-service` - `ConfigServiceServer` registered in `grpc_service()` alongside the still-present `ServerServiceServer` for backward compatibility - `grpc_service()` no longer passes `config_manager` to `ConfigServiceHandlers` — the handler manages its own instance - Section 2.1: clarifies that only `ConfigService` owns `ServerConfigManager`; all other services must fetch config via gRPC - Section 3.1: updated to require all future per-service crates to include a `src/main.rs` and `[[bin]]` entry, and explicitly states they must **not** use `ServerConfigManager` directly — they must connect to the already-running `ConfigService` over gRPC
| Commit: | 38c1416 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat: Phase 1 — data layer foundation for service layer refactor (#494) Implements Phase 1 of `SERVICE_LAYER_REFACTOR.md`: all DB schema additions required before the service interface redesign can begin. All changes are purely additive — no existing columns, tables, or FK relationships are removed. ## DB migrations (6, all reversible) - **`game_metadata.id`** — sequence-backed surrogate integer `id` (NOT NULL, unique); required as FK target for the new media tables - **New standalone tables** — `libraries` (with `structure_definition` path-template field), `root_directories`, `metadata_providers`, `tag_domains` (with `is_well_known` flag for seeded domains: `genre`, `favorites`, `franchise`, `region`) - **`tags`** — `(tag_domain_id, value)` unique pair; replaces the IGDB-specific `game_genres` system (data migration in Phase 4) - **Media metadata tables** — `video_metadata`, `screenshot_metadata`, `artwork_metadata` each with FK → `game_metadata.id`; normalises the deprecated `video_urls`/`screenshot_urls`/`artwork_urls` array columns - **Mapping tables** — 8 many-to-many join tables: library↔dir, platform↔dir, game↔dir, library↔platform, game↔platform, platform↔tag, game↔tag, emulator↔platform - **Existing table additions** — nullable `provider_id` + `logo_url` on `game_metadata`; `provider_id` + `icon_url` on `platform_metadata`; `default_profile_id`, `bios_directory`, `extra_files_directory` on `local_emulator_configs` ## Proto model additions (`retrom.services.*`) Three new proto files under versioned packages (Phase 2 will add service RPCs on top of these): - `retrom/services/library/v1/` — `Library`, `RootDirectory`; `structure_definition` documented with well-known tokens (`{library}`, `{platform}`, `{game}`) and arbitrary token semantics - `retrom/services/metadata/v1/` — `MetadataProvider`, `VideoMetadata`, `ScreenshotMetadata`, `ArtworkMetadata` - `retrom/services/tags/v1/` — `TagDomain` (with `is_well_known`), `Tag` Updated `retrom/models/metadata.proto` (new fields 17–19 on `GameMetadata`; fields 9–10 on `PlatformMetadata`) and `retrom/models/emulators.proto` (fields 10–12 on all three `LocalEmulatorConfig` variants). No existing field numbers touched. ## Diesel schema `schema.rs` updated with all 16 new tables and new columns; `joinable!` and `allow_tables_to_appear_in_same_query!` extended accordingly. `schema.patch` hunk headers updated to reflect the shifted line numbers.
| Commit: | 7982041 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
chore(service-library): migrate to sqlx (#540) This PR advances the service-layer refactor by moving `retrom-service-library` off Diesel to sqlx-oriented handlers and wiring, and adds the missing `CreateGames`, `CreatePlatforms`, `DeleteLibrary`, `DeleteMissingEntries`, `AddPlatformRootDirectory`, and `AddGameRootDirectory` RPC implementations in `LibraryService` v1. - **Proto contract updates (LibraryService v1)** - Added `CreatePlatforms` and `CreateGames` RPCs to `library-service.proto`. - Added new request/response message types: - `CreatePlatformsRequest` / `CreatePlatformsResponse` - `CreateGamesRequest` / `CreateGamesResponse` - Added full doc comments and field behavior annotations (`OUTPUT_ONLY`, `REQUIRED`) across `library-service.proto` and `models.proto`. - **sqlx migration groundwork in `retrom-service-library`** - Reworked service handler modules (`library`, `root_directory`, `platform`, `game`, `game_file`) to use sqlx query patterns (`QueryBuilder`, `query_as`) against `DbPool`. - Implemented create flows for platforms and games in the new v1 service path; server always generates UUIDv7 IDs, ignoring any client-provided `id`. - Removed legacy Diesel-centric service wiring from the library service crate. - All mutating handlers (`update_games`, `update_game_files`, `delete_games`) wrapped in transactions. - **Fully implemented previously-stubbed RPCs** - `DeleteLibrary` — deletes all non-third-party platforms in a transaction (cascades to `game_platforms`/`game_files`), then removes orphaned games. - `DeleteMissingEntries` — performs filesystem existence checks outside the transaction, then in a transaction identifies orphaned games (no surviving files) and orphaned platforms (no surviving games), and hard-deletes all three sets when `dry_run = false`. - `AddPlatformRootDirectory` — inserts into `platform_root_directories` mapping table with `on conflict do nothing`. - `AddGameRootDirectory` — inserts into `game_root_directories` mapping table with `on conflict do nothing`. - **Service wiring/runtime alignment** - Simplified `library_router` to serve the v1 `LibraryService` handler backed by sqlx pool. - Updated `main.rs` to initialize DB via `retrom_db::connect` and run migrations via `retrom_db::run_migrations`. - **Codegen row-mapping support** - Extended codegen row derive list to include `retrom.services.library.v1.Platform` and `retrom.services.library.v1.GameFile` (`sqlx::FromRow`), enabling direct `query_as` mapping for these models. Example (new RPC surface): ```proto service LibraryService { rpc GetPlatforms(GetPlatformsRequest) returns (GetPlatformsResponse); rpc CreatePlatforms(CreatePlatformsRequest) returns (CreatePlatformsResponse); rpc DeleteLibrary(DeleteLibraryRequest) returns (DeleteLibraryResponse); rpc DeleteMissingEntries(DeleteMissingEntriesRequest) returns (DeleteMissingEntriesResponse); rpc GetGames(GetGamesRequest) returns (GetGamesResponse); rpc CreateGames(CreateGamesRequest) returns (CreateGamesResponse); rpc AddPlatformRootDirectory(AddPlatformRootDirectoryRequest) returns (AddPlatformRootDirectoryResponse); rpc AddGameRootDirectory(AddGameRootDirectoryRequest) returns (AddGameRootDirectoryResponse); } ```
| Commit: | 7fad503 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
chore(service-metadata): migrate to sqlx (#537)
| Commit: | 720a501 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
fix(service-common): migrate to versioned codegen types from service layer refactor (#536)
| Commit: | 4e02ea8 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore: proto clean up
| Commit: | 2fb6a40 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
chore(service-saves): migrate to sqlx
| Commit: | 0ed3ea8 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore(service-emulators): migrate to sqlx
| Commit: | 1211927 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore: fix schema
| Commit: | 9cb05b0 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore: fix schema
| Commit: | a7b06b5 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore(service-clients): migrate to sqlx
| Commit: | c0738be | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore: clean up protos
| Commit: | 871b87f | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat: implement item 2.10 - deprecated service forwarding stubs (#513) ## Summary Implements **item 2.10** from `SERVICE_LAYER_REFACTOR.md`: deprecated service forwarding stubs for `GameService`, `PlatformService`, and `ServerService`. ## Changes ### `packages/codegen/protos/retrom/services/server-service.proto` - Added `option deprecated = true;` to each of the 3 RPC methods (`GetServerInfo`, `GetServerConfig`, `UpdateServerConfig`). The file-level and service-level deprecations were already in place; this completes the method-level annotations required by the acceptance criteria. ### `packages/service-config/src/lib.rs` - Added `ConfigServiceHandlers::with_config(config: Arc<ServerConfigManager>) -> Self` constructor to allow sharing an existing config manager instance instead of always creating a fresh one. ### `packages/grpc-service/src/server/mod.rs` - Rewrote `ServerServiceHandlers` as a true forwarding stub: - Now holds `Arc<ConfigServiceHandlers>` instead of `Arc<ServerConfigManager>`. - Each RPC method delegates to the equivalent `ConfigService` v1 method and performs trivial request/response type conversion (the underlying model types `ServerInfo`/`ServerConfig` are shared between the old and new proto namespaces). - Replaced the old `test_parse_version` unit test with a `test_get_server_info` async test that exercises the full forwarding path. ### `packages/grpc-service/src/lib.rs` - Creates a single `Arc<ConfigServiceHandlers>` backed by the function's `config_manager`. - Uses `ConfigServiceServer::from_arc(config_handlers.clone())` so both `config_service` and `server_service` share the same handler instance. ### `SERVICE_LAYER_REFACTOR.md` - Marked item 2.10 as `[x]`. ## Context `GameServiceHandlers` (games.rs) and `PlatformServiceHandlers` (platforms.rs) were already forwarding stubs from earlier work. This PR completes the trio by forwarding `ServerService` to `ConfigService`.
| Commit: | 89abab5 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat: implement TagsService (refactor plan item 2.8) (#508) Implements item 2.8 from `SERVICE_LAYER_REFACTOR.md`: a new `TagsService` that owns all tag domain and tag management, plus game/platform tagging, as a standalone service crate following the established per-crate router pattern. ## Migration (`2026-03-25-101000_phase1-new-standalone-tables`) - Added `created_at` and `updated_at` columns to the `tag_domains` table - Seeds the four well-known domains (`genre`, `favorites`, `franchise`, `region`) directly in the migration ## Proto (`retrom/services/tags/v1/tags-service.proto`) Previously only contained the `TagDomain` and `Tag` message stubs. Now includes: - `TagsService` with 12 RPCs across four concerns: domain management, tag management, game tagging, platform tagging - `Tag` uses a flat `int32 tag_domain_id` field (matching the DB table directly) instead of a nested `TagDomain` message - `GetGameTags` / `GetPlatformTags` operate on a single `game_id` / `platform_id` and return `repeated Tag` directly (no mapping wrapper messages) - `AddGameTags` / `DeleteGameTags` and `AddPlatformTags` / `DeletePlatformTags` replace the previous `UpdateGameTags` / `UpdatePlatformTags` RPCs; requests use `{ int32 *_id; repeated int32 tag_ids; }` shape - Full request/response message set ## Codegen - Added `services.tags.v1` module to `codegen/src/lib.rs` - Added Diesel derives (`Queryable`, `Selectable`, `Identifiable`, `Insertable`, `AsChangeset`) to both `TagDomain` and `Tag` in `build.rs` — both map directly to their respective DB tables ## New crate: `retrom-service-tags` - `TagServiceHandlers` implements all 12 RPCs against the `tag_domains`, `tags`, `game_tag_maps`, and `platform_tag_maps` tables - Uses `Tag` directly via `Tag::as_select()` with no local helper structs - `CreateTagDomains` and `CreateTags` use single bulk `INSERT` statements; `CreateTags` validates all `tag_domain_id`s upfront - `GetGameTags` / `GetPlatformTags` use a single `INNER JOIN` query against the mapping tables to return tags directly, avoiding a separate round-trip - `AddGameTags` / `AddPlatformTags` insert mapping rows in bulk with `ON CONFLICT DO NOTHING` and use `.returning(tag_id)` to return only the actually-inserted rows, without an extra transaction - `DeleteGameTags` / `DeletePlatformTags` use `.returning(tag_id)` on the delete statement to retrieve affected tag IDs, then fetch and return the full `Tag` rows - `DeleteTagDomains` rejects well-known domains with `Status::failed_precondition` - Exports `tags_router(db_pool: Arc<Pool>) -> axum::Router` per the established pattern ## Registration (`retrom-grpc-service`) - `TagsServiceServer` added to the routes builder
| Commit: | 4850919 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat: extract FileExplorerService to its own crate (refactor 2.7) (#507)
| Commit: | a39d1a0 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat(2.6): Add dedicated Job Service gRPC crate (#503)
| Commit: | 9ba40bb | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat: Updated Emulator Service — mapping-table RPCs (refactor plan 2.4) (#500)
| Commit: | 8fa9283 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat(metadata): implement refactor plan item 2.3 — provider-aware MetadataService v1 (#499) Implements item 2.3 of `SERVICE_LAYER_REFACTOR.md`: introduce a versioned `retrom.services.metadata.v1.MetadataService` that adds provider-awareness to the metadata layer. ### Proto - **`retrom/models/metadata.proto`** — added `optional int32 provider_id` to `UpdatedGameMetadata` (field 17) and `UpdatedPlatformMetadata` (field 9) so write operations can now carry and persist a provider FK. - **`retrom/services/metadata/v1/metadata-service.proto`** — added `MetadataService` service definition mirroring all legacy RPCs (via `retrom.*` type imports) plus the new RPC: ```protobuf rpc GetMetadataProviders(GetMetadataProvidersRequest) returns (GetMetadataProvidersResponse); ``` ### Codegen (`packages/codegen`) - Registered `services.metadata.v1.MetadataProvider` in `build.rs` `queryable_models` → Diesel derives against `metadata_providers` table. - Exposed `retrom::services::metadata::v1` module in `src/lib.rs`. ### gRPC service (`packages/grpc-service`) - `MetadataServiceHandlers` gains `#[derive(Clone)]` to allow sharing across legacy and v1 servers. - New `impl MetadataServiceV1 for MetadataServiceHandlers` — existing RPCs delegate via UFCS; `get_metadata_providers` queries the `metadata_providers` table: ```rust let providers = schema::metadata_providers::table .load::<MetadataProviderModel>(&mut conn) .await?; ``` - `MetadataServiceServerV1` wired into the Axum router alongside the legacy server (same pattern as `LibraryServiceServerV1`).
| Commit: | 1990e78 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat(service): implement 2.2 Enhanced Library Service (#497) Implements Phase 2.2 of the service layer refactor: surface all game and platform CRUD through `retrom.services.library.v1.LibraryService`, making `GameService` and `PlatformService` redundant forwarding stubs. - **`library/v1/library-service.proto`** — promotes from model-only to a full service definition with 18 RPCs: existing library ops + Library CRUD (`GetLibraries`, `CreateLibraries`, `UpdateLibraries`) + Root Directory management (full CRUD) + platform ops + game/game-file ops. All new request/response types live in `retrom.services.library.v1`; model types imported from the existing `retrom` package. - **`game-service.proto` / `platform-service.proto`** — `option deprecated = true` at file, service, and method levels. - `build.rs` — Diesel `Queryable`/`Selectable`/`Identifiable`/`Insertable`/`AsChangeset` type attributes added for `Library` and `RootDirectory` v1 types so handlers can use them directly in queries. - `src/lib.rs` — adds `retrom::services::library::v1` via `tonic::include_proto!`. - **`library/game_handlers.rs`** / **`library/platform_handlers.rs`** *(new)* — shared free-function handler logic extracted from the top-level `games.rs` / `platforms.rs`. - **`library/library_handlers.rs`** / **`library/root_directory_handlers.rs`** *(new)* — new CRUD handlers against the `libraries` and `root_directories` tables. - **`library/mod.rs`** — `LibraryServiceHandlers` derives `Clone` and now implements *both* the legacy `retrom::LibraryService` trait and the new `retrom::services::library::v1::LibraryService` trait: ```rust impl LibraryServiceV1 for LibraryServiceHandlers { async fn get_libraries(&self, request: Request<GetLibrariesRequest>) -> ... { library_handlers::get_libraries(self.db_pool.clone(), request.into_inner()) .await.map(Response::new) } async fn get_games(&self, request: Request<GetGamesRequest>) -> ... { // converts v1 ↔ retrom package types, delegates to game_handlers } // ...all 18 RPCs } ``` - **`games.rs`** / **`platforms.rs`** — reduced to forwarding stubs; all logic now lives in `library/{game,platform}_handlers.rs`. - **`lib.rs`** — registers `LibraryServiceServerV1` alongside the existing services.
| Commit: | e56e3ce | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat(service-config): implement ConfigService to replace ServerService (refactor plan 2.1) (#496) Implements item 2.1 from the service layer refactor plan: introduces a versioned `ConfigService` under `retrom.services.config.v1` and deprecates the existing `ServerService`. - New file `retrom/services/config/v1/config-service.proto` — `ConfigService` with `GetServerInfo`, `GetServerConfig`, `UpdateServerConfig` RPCs (each with focused doc comments), reusing existing `retrom.ServerConfig` / `retrom.ServerInfo` model types - `server-service.proto` marked `option deprecated = true` at both file and service level - `ServerConfigManager` and `RetromDirs` moved from `retrom-service-common` into this crate (`src/config.rs` and `src/retrom_dirs.rs`) — `retrom-service-config` is now the sole owner of the config file on disk - `retrom-service-common` re-exports both types via `#[deprecated]` type aliases for backward compatibility — existing callers continue to compile but receive deprecation warnings guiding them to import from `retrom-service-config` directly (or use the gRPC API for config access) - `ConfigServiceHandlers` creates and owns its own `Arc<ServerConfigManager>` internally — `new()` takes no arguments - Replaces `.unwrap()` on optional request field with `tonic::Status::invalid_argument` - Exports `config_router() -> axum::Router` for per-service router composition (Phase 3); the router creates the handler (and manager) internally ```rust pub fn config_router() -> axum::Router { let config_service = ConfigServiceServer::new(ConfigServiceHandlers::new()); let mut routes_builder = tonic::service::Routes::builder(); routes_builder.add_service(config_service); routes_builder.routes().into_axum_router() } ``` - Includes `src/main.rs` and a `[[bin]]` entry in `Cargo.toml` so the service can be started as a standalone process — reads initial config for telemetry setup, initialises tracing, and serves on port 5103 - `retrom-service-config` added to the Cargo workspace and as a dependency of `retrom-grpc-service` - `ConfigServiceServer` registered in `grpc_service()` alongside the still-present `ServerServiceServer` for backward compatibility - `grpc_service()` no longer passes `config_manager` to `ConfigServiceHandlers` — the handler manages its own instance - Section 2.1: clarifies that only `ConfigService` owns `ServerConfigManager`; all other services must fetch config via gRPC - Section 3.1: updated to require all future per-service crates to include a `src/main.rs` and `[[bin]]` entry, and explicitly states they must **not** use `ServerConfigManager` directly — they must connect to the already-running `ConfigService` over gRPC
| Commit: | f0eea84 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
feat: Phase 1 — data layer foundation for service layer refactor (#494) Implements Phase 1 of `SERVICE_LAYER_REFACTOR.md`: all DB schema additions required before the service interface redesign can begin. All changes are purely additive — no existing columns, tables, or FK relationships are removed. ## DB migrations (6, all reversible) - **`game_metadata.id`** — sequence-backed surrogate integer `id` (NOT NULL, unique); required as FK target for the new media tables - **New standalone tables** — `libraries` (with `structure_definition` path-template field), `root_directories`, `metadata_providers`, `tag_domains` (with `is_well_known` flag for seeded domains: `genre`, `favorites`, `franchise`, `region`) - **`tags`** — `(tag_domain_id, value)` unique pair; replaces the IGDB-specific `game_genres` system (data migration in Phase 4) - **Media metadata tables** — `video_metadata`, `screenshot_metadata`, `artwork_metadata` each with FK → `game_metadata.id`; normalises the deprecated `video_urls`/`screenshot_urls`/`artwork_urls` array columns - **Mapping tables** — 8 many-to-many join tables: library↔dir, platform↔dir, game↔dir, library↔platform, game↔platform, platform↔tag, game↔tag, emulator↔platform - **Existing table additions** — nullable `provider_id` + `logo_url` on `game_metadata`; `provider_id` + `icon_url` on `platform_metadata`; `default_profile_id`, `bios_directory`, `extra_files_directory` on `local_emulator_configs` ## Proto model additions (`retrom.services.*`) Three new proto files under versioned packages (Phase 2 will add service RPCs on top of these): - `retrom/services/library/v1/` — `Library`, `RootDirectory`; `structure_definition` documented with well-known tokens (`{library}`, `{platform}`, `{game}`) and arbitrary token semantics - `retrom/services/metadata/v1/` — `MetadataProvider`, `VideoMetadata`, `ScreenshotMetadata`, `ArtworkMetadata` - `retrom/services/tags/v1/` — `TagDomain` (with `is_well_known`), `Tag` Updated `retrom/models/metadata.proto` (new fields 17–19 on `GameMetadata`; fields 9–10 on `PlatformMetadata`) and `retrom/models/emulators.proto` (fields 10–12 on all three `LocalEmulatorConfig` variants). No existing field numbers touched. ## Diesel schema `schema.rs` updated with all 16 new tables and new columns; `joinable!` and `allow_tables_to_appear_in_same_query!` extended accordingly. `schema.patch` hunk headers updated to reflect the shifted line numbers.
| Commit: | 762be0d | |
|---|---|---|
| Author: | Copilot | |
| Committer: | GitHub | |
chore(service-library): migrate to sqlx (#540) This PR advances the service-layer refactor by moving `retrom-service-library` off Diesel to sqlx-oriented handlers and wiring, and adds the missing `CreateGames`, `CreatePlatforms`, `DeleteLibrary`, `DeleteMissingEntries`, `AddPlatformRootDirectory`, and `AddGameRootDirectory` RPC implementations in `LibraryService` v1. - **Proto contract updates (LibraryService v1)** - Added `CreatePlatforms` and `CreateGames` RPCs to `library-service.proto`. - Added new request/response message types: - `CreatePlatformsRequest` / `CreatePlatformsResponse` - `CreateGamesRequest` / `CreateGamesResponse` - Added full doc comments and field behavior annotations (`OUTPUT_ONLY`, `REQUIRED`) across `library-service.proto` and `models.proto`. - **sqlx migration groundwork in `retrom-service-library`** - Reworked service handler modules (`library`, `root_directory`, `platform`, `game`, `game_file`) to use sqlx query patterns (`QueryBuilder`, `query_as`) against `DbPool`. - Implemented create flows for platforms and games in the new v1 service path; server always generates UUIDv7 IDs, ignoring any client-provided `id`. - Removed legacy Diesel-centric service wiring from the library service crate. - All mutating handlers (`update_games`, `update_game_files`, `delete_games`) wrapped in transactions. - **Fully implemented previously-stubbed RPCs** - `DeleteLibrary` — deletes all non-third-party platforms in a transaction (cascades to `game_platforms`/`game_files`), then removes orphaned games. - `DeleteMissingEntries` — performs filesystem existence checks outside the transaction, then in a transaction identifies orphaned games (no surviving files) and orphaned platforms (no surviving games), and hard-deletes all three sets when `dry_run = false`. - `AddPlatformRootDirectory` — inserts into `platform_root_directories` mapping table with `on conflict do nothing`. - `AddGameRootDirectory` — inserts into `game_root_directories` mapping table with `on conflict do nothing`. - **Service wiring/runtime alignment** - Simplified `library_router` to serve the v1 `LibraryService` handler backed by sqlx pool. - Updated `main.rs` to initialize DB via `retrom_db::connect` and run migrations via `retrom_db::run_migrations`. - **Codegen row-mapping support** - Extended codegen row derive list to include `retrom.services.library.v1.Platform` and `retrom.services.library.v1.GameFile` (`sqlx::FromRow`), enabling direct `query_as` mapping for these models. Example (new RPC surface): ```proto service LibraryService { rpc GetPlatforms(GetPlatformsRequest) returns (GetPlatformsResponse); rpc CreatePlatforms(CreatePlatformsRequest) returns (CreatePlatformsResponse); rpc DeleteLibrary(DeleteLibraryRequest) returns (DeleteLibraryResponse); rpc DeleteMissingEntries(DeleteMissingEntriesRequest) returns (DeleteMissingEntriesResponse); rpc GetGames(GetGamesRequest) returns (GetGamesResponse); rpc CreateGames(CreateGamesRequest) returns (CreateGamesResponse); rpc AddPlatformRootDirectory(AddPlatformRootDirectoryRequest) returns (AddPlatformRootDirectoryResponse); rpc AddGameRootDirectory(AddGameRootDirectoryRequest) returns (AddGameRootDirectoryResponse); } ```
| Commit: | c46f46b | |
|---|---|---|
| Author: | John Beresford | |
chore: init buf linting
| Commit: | 389fcf2 | |
|---|---|---|
| Author: | John Beresford | |
chore(service-metadata): get_similar_games RPC
| Commit: | 2531783 | |
|---|---|---|
| Author: | John Beresford | |
chore(service-library): fix up add_*_root_directory RPCs
| Commit: | 71249f4 | |
|---|---|---|
| Author: | John Beresford | |
chore(service-library): clean up
| Commit: | 8e58c9d | |
|---|---|---|
| Author: | John Beresford | |
chore(service-library): init metadata handlers
| Commit: | 27a8ae7 | |
|---|---|---|
| Author: | John Beresford | |
chore(service-metadata): rpc cleanups
| Commit: | 4269c27 | |
|---|---|---|
| Author: | John Beresford | |
chore: clean up
| Commit: | f337c39 | |
|---|---|---|
| Author: | John Beresford | |
chore(service-metadata): idiomatic rpc definitions
| Commit: | 12096dc | |
|---|---|---|
| Author: | John Beresford | |
chore: fix protos
| Commit: | dff0c13 | |
|---|---|---|
| Author: | John Beresford | |
chore(service-library): rename rpc
| Commit: | 9ef067b | |
|---|---|---|
| Author: | copilot-swe-agent[bot] | |
| Committer: | GitHub | |
Address review feedback for transactions and proto docs Co-authored-by: JMBeresford <1373954+JMBeresford@users.noreply.github.com>
| Commit: | 4327509 | |
|---|---|---|
| Author: | copilot-swe-agent[bot] | |
| Committer: | GitHub | |
fix service-library review feedback Co-authored-by: JMBeresford <1373954+JMBeresford@users.noreply.github.com>
| Commit: | 91d6a73 | |
|---|---|---|
| Author: | John Beresford | |
chore: fix proto field types
| Commit: | f458a55 | |
|---|---|---|
| Author: | copilot-swe-agent[bot] | |
| Committer: | GitHub | |
feat(service-library): add create games/platforms RPC scaffolding Co-authored-by: JMBeresford <1373954+JMBeresford@users.noreply.github.com>
| Commit: | e8c2bc3 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore: fix schema
| Commit: | f08173b | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
chore(service-metadata): migrate to sqlx (#537)
| Commit: | f55da24 | |
|---|---|---|
| Author: | Copilot | |
| Committer: | John Beresford | |
fix(service-common): migrate to versioned codegen types from service layer refactor (#536)
| Commit: | e2fa829 | |
|---|---|---|
| Author: | John Beresford | |
| Committer: | John Beresford | |
chore: proto clean up