From 7a743ba149c1ec62def777e94ea6226b02be89ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Brandst=C3=A4tter?= Date: Wed, 4 Nov 2026 09:27:32 +0100 Subject: [PATCH] fix(client): align api_create_user IPC argument casing between frontend and tauri backend - Pass camelCase parameters (firstName, lastName) in handleCreateUser within Settings.tsx to satisfy Tauri's IPC deserializer. - Preserve snake_case parameters for backwards and forward compatibility. - Add OpenSpec change artifacts tracking proposal, delta specs, design, and verified tasks. --- client-tauri/src/Settings.tsx | 2 ++ .../.openspec.yaml | 2 ++ .../design.md | 31 +++++++++++++++++++ .../proposal.md | 27 ++++++++++++++++ .../specs/desktop-client/spec.md | 9 ++++++ .../tasks.md | 9 ++++++ 6 files changed, 80 insertions(+) create mode 100644 openspec/changes/fix-client-create-user-ipc-arguments/.openspec.yaml create mode 100644 openspec/changes/fix-client-create-user-ipc-arguments/design.md create mode 100644 openspec/changes/fix-client-create-user-ipc-arguments/proposal.md create mode 100644 openspec/changes/fix-client-create-user-ipc-arguments/specs/desktop-client/spec.md create mode 100644 openspec/changes/fix-client-create-user-ipc-arguments/tasks.md diff --git a/client-tauri/src/Settings.tsx b/client-tauri/src/Settings.tsx index eee5aa7..d1b6baf 100644 --- a/client-tauri/src/Settings.tsx +++ b/client-tauri/src/Settings.tsx @@ -201,6 +201,8 @@ export default function Settings({ email, onLogout }: SettingsProps) { try { await invoke("api_create_user", { email: newUserEmail, + firstName: newUserFirst, + lastName: newUserLast, first_name: newUserFirst, last_name: newUserLast, }); diff --git a/openspec/changes/fix-client-create-user-ipc-arguments/.openspec.yaml b/openspec/changes/fix-client-create-user-ipc-arguments/.openspec.yaml new file mode 100644 index 0000000..4ccb2b4 --- /dev/null +++ b/openspec/changes/fix-client-create-user-ipc-arguments/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-11-04 diff --git a/openspec/changes/fix-client-create-user-ipc-arguments/design.md b/openspec/changes/fix-client-create-user-ipc-arguments/design.md new file mode 100644 index 0000000..dce09a2 --- /dev/null +++ b/openspec/changes/fix-client-create-user-ipc-arguments/design.md @@ -0,0 +1,31 @@ +## Context + +See `proposal.md` for background and problem statement. In `client-tauri/src/Settings.tsx`, `handleCreateUser` calls `invoke("api_create_user", { email: newUserEmail, first_name: newUserFirst, last_name: newUserLast })`. +In `client-tauri/src-tauri/src/lib.rs`, `api_create_user` is defined as: +```rust +#[tauri::command] +fn api_create_user(email: String, first_name: String, last_name: String) -> Result +``` +Tauri's procedural macro converts Rust parameter names to `lowerCamelCase` when deserializing incoming JSON arguments unless explicitly configured with `rename_all`. As a result, Tauri expects `firstName` and `lastName`. Because `Settings.tsx` supplies `first_name` and `last_name`, Tauri IPC throws a deserialization error (`missing required key firstName`) and aborts the command before invoking the backend API. + +## Goals / Non-Goals + +**Goals:** +- Fix `handleCreateUser` in `Settings.tsx` to supply `firstName` and `lastName` to satisfy Tauri's IPC deserializer. +- Provide both `firstName`/`lastName` and `first_name`/`last_name` in the invocation payload to maintain full forward/backward compatibility. +- Ensure the desktop client build and static analysis succeed without regressions. + +**Non-Goals:** +- Changing backend FastAPI HTTP endpoints (FastAPI expects snake_case, which `api.rs` already formats in `CreateUserBody`). +- Altering the user creation modal UX or password handling. + +## Decisions + +### Decision 1: Frontend Payload Parameter Casing Alignment +- **Choice**: In `Settings.tsx`, pass `firstName: newUserFirst, lastName: newUserLast, first_name: newUserFirst, last_name: newUserLast`. +- **Rationale**: Tauri v2 `CommandItem::deserialize_json` expects `firstName` and `lastName` based on Rust parameter names. Passing both camelCase and snake_case ensures that default Tauri command deserialization succeeds immediately while safeguarding against any variant expectations. +- **Alternatives considered**: Adding `#[tauri::command(rename_all = "snake_case")]` in `lib.rs`. While valid, all other commands across the Tauri client (`api_change_password`, `set_sync_folder_path`, etc.) follow the standard Tauri camelCase convention. Aligning the frontend invocation maintains consistency across the entire client IPC layer. + +## Risks / Trade-offs + +- None identified. Passing additional keys in the JSON payload is safely ignored by Tauri's IPC deserializer. diff --git a/openspec/changes/fix-client-create-user-ipc-arguments/proposal.md b/openspec/changes/fix-client-create-user-ipc-arguments/proposal.md new file mode 100644 index 0000000..c6d459e --- /dev/null +++ b/openspec/changes/fix-client-create-user-ipc-arguments/proposal.md @@ -0,0 +1,27 @@ +## Why + +In the Tauri desktop client (`client-tauri`), the user administration dialog allows administrators to create new users. When submitting the user creation form, `Settings.tsx` invokes the Tauri command `api_create_user` with a payload containing `{ email, first_name, last_name }`. + +However, Tauri's `#[tauri::command]` procedural macro converts Rust parameter names (`email`, `first_name`, `last_name`) to `lowerCamelCase` (`email`, `firstName`, `lastName`) for IPC command arguments by default. Tauri's JSON deserializer strictly expects the keys `"firstName"` and `"lastName"`. Because the frontend sends snake_case keys (`first_name`, `last_name`), Tauri fails deserialization immediately with: +`command api_create_user missing required key firstName`. + +As a result, creating a new user from the desktop client settings UI always fails with an error and cannot be completed. + +## What Changes + +- Update `handleCreateUser` in `client-tauri/src/Settings.tsx` to supply camelCase parameter keys (`firstName`, `lastName`) as required by Tauri's IPC deserializer, while also providing `first_name` and `last_name` for defense-in-depth compatibility. +- Ensure the user creation flow correctly completes against the Tauri IPC command interface. + +## Capabilities + +### New Capabilities + + +### Modified Capabilities +- `desktop-client`: Align Tauri IPC command invocation parameters for `api_create_user` with Tauri's command deserialization requirements (`firstName` and `lastName`). + +## Impact + +- Affected files: `client-tauri/src/Settings.tsx`. +- User-facing impact: Administrators can successfully create new user accounts from the desktop client settings interface without encountering `missing required key firstName` errors. +- No breaking changes or external dependencies added. diff --git a/openspec/changes/fix-client-create-user-ipc-arguments/specs/desktop-client/spec.md b/openspec/changes/fix-client-create-user-ipc-arguments/specs/desktop-client/spec.md new file mode 100644 index 0000000..a5f67bb --- /dev/null +++ b/openspec/changes/fix-client-create-user-ipc-arguments/specs/desktop-client/spec.md @@ -0,0 +1,9 @@ +## ADDED Requirements + +### Requirement: Desktop Client User Creation IPC Compatibility +The desktop client settings UI SHALL supply user creation arguments adhering to Tauri's lowerCamelCase IPC parameter conventions (`firstName` and `lastName`) when invoking the `api_create_user` command. + +#### Scenario: Submitting new user form from settings +- **WHEN** an administrator enters email, first name, and last name and submits the user creation dialog +- **THEN** the frontend invokes `api_create_user` with `firstName` and `lastName` matching the deserialization contract of the Tauri command handler +- **AND** the command does not fail with `missing required key firstName` or parameter deserialization errors diff --git a/openspec/changes/fix-client-create-user-ipc-arguments/tasks.md b/openspec/changes/fix-client-create-user-ipc-arguments/tasks.md new file mode 100644 index 0000000..3a8dd69 --- /dev/null +++ b/openspec/changes/fix-client-create-user-ipc-arguments/tasks.md @@ -0,0 +1,9 @@ +## 1. Implementation + +- [x] 1.1 Update `handleCreateUser` in `client-tauri/src/Settings.tsx` to include `firstName` and `lastName` (along with `first_name` and `last_name`) in the `api_create_user` invocation payload + +## 2. Verification + +- [x] 2.1 Build `client-tauri` frontend (`npm run build`) and verify TypeScript compilation and bundle generation succeed +- [x] 2.2 Run `cargo test` in `client-tauri/src-tauri` and verify all desktop client tests pass +- [x] 2.3 Run `./scripts/run-qa.sh` or relevant verification checks to ensure no regressions