Sync drifted shared DTO fields, drop vestigial ticket copies (MAPPS-378) #443

Merged
nrupard merged 1 commit from fix/MAPPS-378-mokosh-types into main 2026-07-24 17:53:13 +02:00
Owner

What

Repair the drift between the SPA's hand-copied shared DTOs and mokosh-server's mokosh-types crate, and delete the dead wrong-derive copies. This is the field-sync fallback for MAPPS-378; full crate-adoption is deferred (see Why).

Why

  • MAPPS-378 wants the SPA to stop hand-maintaining DTOs that silently drift from the server's mokosh-types source of truth, so a future server field the SPA needs fails the build instead of deserializing to a default.
  • Full crate-adoption (add mokosh-types as a pinned git dependency and re-export from it) was feasibility-tested first against the real Docker just pre-commit gate and is NOT CI-viable: the rust-builder-glibc container tries to fetch ssh://git@git.a8n.run/psa-systems/mokosh-server.git but has no known-hosts entry and no SSH credentials (the gate mounts neither ~/.ssh nor an agent socket), so cargo check aborts at dependency resolution with error: unknown SSH host key. The Forgejo check.yml runner has no cross-repo deploy key either. Making the git dep work needs infra changes outside this repo (SSH host-key + deploy-key provisioning in both the local gate and CI, or publishing mokosh-types to a registry), so it is not a quick fix.
  • The fallback still fixes the actual drift today, with no new dependency, and keeps the gate green.

Changes

  • CurrentUser (src/modules/auth/models.rs) gains theme_base_mode: Option<String> and theme_accent_id: Option<String> (PMS-410), matching mokosh_types::auth::CurrentUser field names, types, and #[serde(default)]. All ten construction sites are updated: User::to_current_user, the two runtime builders in src/hooks/auth.rs, the OIDC-callback builder in src/pages/auth_callback.rs, and six test fixtures.
  • TicketNote and TicketNoteResponse (src/modules/tickets/models.rs) gain created_by_contact_id: Option<Uuid> (PMS-468 / PMS-449), matching mokosh_types::tickets including the #[serde(default)] and #[serde(default, skip_serializing_if = "Option::is_none")] attributes respectively. The SPA already consumes this field via its own portal subset struct (src/pages/portal.rs), so the copies were the only place missing it.
  • The vestigial derive-inverted copies are deleted: CreateTicketRequest (derived only Deserialize) and TicketResponse (derived only Serialize) were byte-copies of the server structs carrying client-inappropriate derives, referenced only in doc comments and never in code. TicketResponse's exclusive helper structs TicketStatusSummary and TicketPrioritySummary are removed with it (nothing else referenced them). The SPA renders tickets through its own purpose-built subset structs RemoteTicket / RemoteTicketDetail, which are untouched.

Deferred / intentionally out of scope

  • Full mokosh-types crate-adoption (the durable fix) is deferred until the crate is published to a registry or the Docker gate and Forgejo runner are provisioned with SSH access to the mokosh-server repo. This PR documents the blocker so the follow-up is tracked.
  • The TicketCategory / Upsert*TicketLookup DTO families that exist in mokosh-types but not in the SPA are intentionally NOT hand-added. They are not existing hand-copied structs, the SPA reads lookups via its own RemoteTicketLookup subset, and manufacturing unused copies would grow exactly the drift surface MAPPS-378 removes. They come in enforced (at zero maintenance cost) with the deferred full adoption.

Tests

  • Full Docker just pre-commit gate green (exit 0): cargo fmt --all --check, cargo clippy --all-targets -- -D warnings, cargo check --target wasm32-unknown-unknown, and cargo test --lib (223 passed, 0 failed).
## What Repair the drift between the SPA's hand-copied shared DTOs and mokosh-server's `mokosh-types` crate, and delete the dead wrong-derive copies. This is the field-sync fallback for MAPPS-378; full crate-adoption is deferred (see Why). ## Why - MAPPS-378 wants the SPA to stop hand-maintaining DTOs that silently drift from the server's `mokosh-types` source of truth, so a future server field the SPA needs fails the build instead of deserializing to a default. - Full crate-adoption (add `mokosh-types` as a pinned git dependency and re-export from it) was feasibility-tested first against the real Docker `just pre-commit` gate and is NOT CI-viable: the `rust-builder-glibc` container tries to fetch `ssh://git@git.a8n.run/psa-systems/mokosh-server.git` but has no known-hosts entry and no SSH credentials (the gate mounts neither `~/.ssh` nor an agent socket), so `cargo check` aborts at dependency resolution with `error: unknown SSH host key`. The Forgejo `check.yml` runner has no cross-repo deploy key either. Making the git dep work needs infra changes outside this repo (SSH host-key + deploy-key provisioning in both the local gate and CI, or publishing `mokosh-types` to a registry), so it is not a quick fix. - The fallback still fixes the actual drift today, with no new dependency, and keeps the gate green. ## Changes - `CurrentUser` (src/modules/auth/models.rs) gains `theme_base_mode: Option<String>` and `theme_accent_id: Option<String>` (PMS-410), matching `mokosh_types::auth::CurrentUser` field names, types, and `#[serde(default)]`. All ten construction sites are updated: `User::to_current_user`, the two runtime builders in src/hooks/auth.rs, the OIDC-callback builder in src/pages/auth_callback.rs, and six test fixtures. - `TicketNote` and `TicketNoteResponse` (src/modules/tickets/models.rs) gain `created_by_contact_id: Option<Uuid>` (PMS-468 / PMS-449), matching `mokosh_types::tickets` including the `#[serde(default)]` and `#[serde(default, skip_serializing_if = "Option::is_none")]` attributes respectively. The SPA already consumes this field via its own portal subset struct (src/pages/portal.rs), so the copies were the only place missing it. - The vestigial derive-inverted copies are deleted: `CreateTicketRequest` (derived only `Deserialize`) and `TicketResponse` (derived only `Serialize`) were byte-copies of the server structs carrying client-inappropriate derives, referenced only in doc comments and never in code. `TicketResponse`'s exclusive helper structs `TicketStatusSummary` and `TicketPrioritySummary` are removed with it (nothing else referenced them). The SPA renders tickets through its own purpose-built subset structs `RemoteTicket` / `RemoteTicketDetail`, which are untouched. ## Deferred / intentionally out of scope - Full `mokosh-types` crate-adoption (the durable fix) is deferred until the crate is published to a registry or the Docker gate and Forgejo runner are provisioned with SSH access to the mokosh-server repo. This PR documents the blocker so the follow-up is tracked. - The `TicketCategory` / `Upsert*TicketLookup` DTO families that exist in `mokosh-types` but not in the SPA are intentionally NOT hand-added. They are not existing hand-copied structs, the SPA reads lookups via its own `RemoteTicketLookup` subset, and manufacturing unused copies would grow exactly the drift surface MAPPS-378 removes. They come in enforced (at zero maintenance cost) with the deferred full adoption. ## Tests - Full Docker `just pre-commit` gate green (exit 0): `cargo fmt --all --check`, `cargo clippy --all-targets -- -D warnings`, `cargo check --target wasm32-unknown-unknown`, and `cargo test --lib` (223 passed, 0 failed).
fix(models): sync drifted shared DTO fields, drop vestigial copies
All checks were successful
Check / fmt + clippy + tests (pull_request) Successful in 1m23s
Create release / Create release from merged PR (pull_request) Has been skipped
cec5d47124
MAPPS-378 aims to stop the SPA hand-copying shared DTOs that have drifted from mokosh-server's mokosh-types crate. Full crate-adoption (a git dependency on mokosh-types) was feasibility-tested against the Docker pre-commit gate and is not CI-viable: the rust-builder container tries to fetch ssh://git@git.a8n.run with no known-hosts entry and no SSH credentials (the gate mounts neither ~/.ssh nor an agent socket), and the Forgejo check runner has no cross-repo deploy key either, so cargo can neither resolve nor wasm-compile the crate. Adoption is deferred until mokosh-types is published to a registry or the gate/runner are provisioned with SSH access.

This is the field-sync fallback: repair the drift in place on the structs the SPA still hand-maintains, and remove the dead wrong-derive copies. CurrentUser gains theme_base_mode and theme_accent_id (PMS-410) to match mokosh_types::auth::CurrentUser, updated at all ten construction sites. TicketNote and TicketNoteResponse gain created_by_contact_id (PMS-468 / PMS-449) to match mokosh_types::tickets.

The vestigial derive-inverted copies are removed: CreateTicketRequest (derived only Deserialize) and TicketResponse (derived only Serialize) were byte-copies of the server structs with client-inappropriate derives, referenced only in doc comments and never in code. TicketResponse's exclusive helper structs TicketStatusSummary and TicketPrioritySummary are removed with it. The SPA reads tickets through its own purpose-built subset structs (RemoteTicket, RemoteTicketDetail), which are untouched.

The absent TicketCategory / Upsert*TicketLookup DTO families are intentionally not hand-added: they are not existing hand-copied structs, the SPA consumes lookups via its own RemoteTicketLookup subset, and manufacturing unused copies would grow the exact drift surface this issue removes. They come with the deferred full adoption.

Gate green via Docker just pre-commit: fmt --check, clippy --all-targets -D warnings, cargo check --target wasm32-unknown-unknown, and cargo test --lib (223 passed, 0 failed).

#MAPPS-378

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nrupard deleted branch fix/MAPPS-378-mokosh-types 2026-07-24 17:53:14 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-apps!443
No description provided.