Skip to content

Conversation

@rahulharpal1603
Copy link
Contributor

@rahulharpal1603 rahulharpal1603 commented Sep 7, 2025

Summary by CodeRabbit

  • New Features

    • Added User Preferences in Settings (choose YOLO model size; toggle GPU acceleration).
    • New onboarding step that waits for local services to start, with loader and error handling.
    • Introduced “Coming Soon” pages for Videos, Albums, and Memories.
  • Improvements

    • Added health check endpoint and frontend health checks.
    • Bundles and launches a separate sync microservice; updated app permissions accordingly.
    • Improved resource organization for more reliable startup.
  • Chores

    • Bumped app version to 1.0.0.

rahulharpal1603 and others added 15 commits June 23, 2025 23:28
- Added `tauri-plugin-process` to Cargo.toml and initialized it in main.rs.
- Updated migrated.json to include process permissions.
- Introduced health check endpoints for main backend and sync microservice.
- Created ServerCheck component to verify the health of services during onboarding.
- Enhanced InfoDialog to conditionally show close button based on state.
- Updated settings page to streamline user preferences query.
- Added CORS middleware to sync microservice for cross-origin requests.
- Refactored API functions to include health check logic.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 7, 2025

Walkthrough

This PR replaces custom backend logging with default Uvicorn logging, renames the health endpoint to /health, updates Tauri packaging (resources, plugins, capabilities), adds sync microservice integration, introduces health-check onboarding, adds user preferences APIs/UI, bumps versions, and adjusts routes and settings. Minor CI/ignore/file-path changes included.

Changes

Cohort / File(s) Summary
CI workflow formatting
.github/workflows/build-and-release.yml
Removed a blank line; no behavioral change.
Gitignore adjustments
backend/.gitignore, sync-microservice/.gitignore
Ignore dist/* but keep dist/README.md tracked in both projects.
Backend logging removal
backend/app/custom_logging.py, backend/app/logging_config.json
Deleted Loguru-based custom logging module and JSON config.
Backend health endpoint and server config
backend/main.py, docs/backend/backend_python/openapi.json
Health check moved from / to /health; switched to log_level="info"; OpenAPI updated accordingly; replaced app logger usage with prints.
Backend sync microservice pathing
backend/app/utils/microservice.py
Adjusted frozen service paths: base two levels up from sys.executable; dir renamed to sync-microservice.
Frontend package/version
frontend/package.json
Version to 1.0.0; add @tauri-apps/plugin-process.
Tauri packaging and plugins
frontend/src-tauri/Cargo.toml, frontend/src-tauri/tauri.conf.json, frontend/src-tauri/src/main.rs, frontend/src-tauri/capabilities/migrated.json, frontend/src-tauri/src/services/mod.rs
Add process plugin and devtools; map backend/dist to resources/backend and add sync-microservice/dist mapping; update resource resolution paths; enable process:default capability; expand CSP connect-src and img-src; set window devtools true; return Ok(()) in setup.
Frontend API clients and endpoints
frontend/src/api/axiosConfig.ts, frontend/src/api/apiEndpoints.ts, frontend/src/config/Backend.ts
Add SYNC_MICROSERVICE_URL and syncApiClient; add /health and /user-preferences/ endpoints; remove IMAGE_ENDPOINT.
Frontend API functions and exports
frontend/src/api/api-functions/health.ts, frontend/src/api/api-functions/user_preferences.ts, frontend/src/api/api-functions/index.ts
Add health-check functions for backend and sync service; add user-preferences types and GET/PUT helpers; re-export new modules.
Onboarding health check
frontend/src/components/OnboardingSteps/ServerCheck.tsx, frontend/src/components/OnboardingSteps/OnboardingStep.tsx, frontend/src/constants/steps.ts
New ServerCheck step runs two health queries with retries, shows loader, errors out and exits on failure, marks step complete on success; register new SERVER_CHECK step in flow.
Info dialog close control
frontend/src/components/Dialog/InfoDialog.tsx, frontend/src/types/infoDialog.ts, frontend/src/features/infoDialogSlice.ts, frontend/src/App.tsx
Add optional showCloseButton prop/state with default true; conditionally render Close button; wire through Redux slice and App usage.
Settings: user preferences
frontend/src/pages/SettingsPage/Settings.tsx
Add UI to fetch/update YOLO model size and GPU acceleration; duplicate preferences card block; show success/error dialogs.
Routes and placeholder page
frontend/src/pages/ComingSoon/ComingSoon.tsx, frontend/src/routes/AppRoutes.tsx
Add ComingSoon page; route Videos/Albums/Memories to ComingSoon.
Sync microservice CORS and logging
sync-microservice/main.py
Add permissive CORS middleware; switch to log_level="info".

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant App as Tauri App
  participant Onboard as Onboarding:ServerCheck
  participant BE as Backend (/health)
  participant Sync as Sync Microservice (/health)
  Note over App: App startup
  App->>Onboard: Start ServerCheck(stepIndex)
  Onboard->>App: Dispatch showLoader("Waiting for servers to start")
  par Parallel health checks
    Onboard->>BE: GET /health
    Onboard->>Sync: GET /health
  end
  alt Any failure
    BE-->>Onboard: Error OR
    Sync-->>Onboard: Error
    Onboard->>App: Dispatch showInfoDialog(title="Error", message="Failed to connect...", showCloseButton=false)
    Note over App: Exit after 2s
    App-->>User: Application exits
  else Both succeed
    BE-->>Onboard: 200 OK
    Sync-->>Onboard: 200 OK
    Onboard->>App: Dispatch hideLoader()
    Onboard->>App: Dispatch markCompleted(stepIndex)
    App-->>User: Continue onboarding
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

In burrows of code, I thump with delight,
Health checks hop—two pings in the night.
Preferences nibble, toggles in tow,
Tauri packs snacks for backend to go.
If servers sleep, we quietly quit—
But when they wake, we zoom with wit! 🐇✨

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@rahulharpal1603 rahulharpal1603 added bug Something isn't working GSoC 2025 CI/CD labels Sep 7, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
backend/app/utils/microservice.py (2)

79-85: Avoid PIPE deadlock; don’t capture child stdout/stderr unless consumed.

stdout=PIPE, stderr=PIPE with no readers can block the parent if the child emits enough output. Redirect instead.

-        process = subprocess.Popen(
-            [str(sync_executable)],
-            stdout=subprocess.PIPE,
-            stderr=subprocess.PIPE,
-            text=True,
-            cwd=str(sync_dir),  # Set working directory to sync service directory
-        )
+        process = subprocess.Popen(
+            [str(sync_executable)],
+            stdout=subprocess.DEVNULL,
+            stderr=subprocess.STDOUT,
+            cwd=str(sync_dir),
+        )

234-241: backend/app/utils/microservice.py (lines 234–241): remove stray print and fix dev startup

Replace the existing dev‐server invocation with a uvicorn command (drops the unnecessary debug print):

-        print(python_executable)
-        cmd = [str(python_executable), "-m", "fastapi", "dev", "--port", "8001"]
+        cmd = [
+            str(python_executable),
+            "-m",
+            "uvicorn",
+            "main:app",
+            "--host",
+            "127.0.0.1",
+            "--port",
+            "8001",
+            "--reload",
+        ]
frontend/src/App.tsx (1)

3-3: Fix import: BrowserRouter must come from react-router-dom

This is likely a build break.

-import { BrowserRouter } from 'react-router';
+import { BrowserRouter } from 'react-router-dom';
🧹 Nitpick comments (30)
sync-microservice/.gitignore (1)

139-140: Ensure dist placeholder exists for clean clones/builds

Good switch to ignore dist contents while tracking a placeholder. Make sure dist/README.md is actually committed; otherwise CI packaging that expects the directory may fail on clean checkouts.

#!/bin/bash
set -euo pipefail
for d in backend sync-microservice; do
  if [[ -f "$d/dist/README.md" ]]; then
    echo "OK: $d/dist/README.md present"
  else
    echo "MISSING: $d/dist/README.md" >&2
    exit 1
  fi
done

Prefer a neutral placeholder file name (e.g., .gitkeep) to avoid bundling docs unintentionally into installers.

frontend/src/constants/steps.ts (1)

2-2: Type-safety: mark STEPS as const

Exporting literal types helps prevent typos downstream.

-export const STEPS = {
+export const STEPS = {
   SERVER_CHECK: 'serverCheck',
   AVATAR_SELECTION_STEP: 'avatarSelection',
   FOLDER_SETUP_STEP: 'folderSetup',
   THEME_SELECTION_STEP: 'themeSelection',
   UPDATE_STEP: 'updates',
-};
+} as const;
+export type StepName = typeof STEPS[keyof typeof STEPS];
backend/.gitignore (1)

139-140: Mirror placeholder check for backend/dist

Same note as sync-microservice: verify dist/README.md is committed so packaging doesn’t break on a clean workspace.

#!/bin/bash
test -f backend/dist/README.md && echo "backend/dist/README.md OK" || { echo "Missing backend/dist/README.md"; exit 1; }

Consider using a .gitkeep instead of README if the file is only to keep the directory.

frontend/src-tauri/Cargo.toml (1)

3-3: Cargo.toml polish + compatibility check

  • Typo in the comment (“definition s”).
  • Confirm tauri = 2.3.1 actually requires/enables the "devtools" crate feature; in Tauri v2, devtools are usually toggled via tauri.conf.json.
  • Versions: Rust tauri-plugin-process = "2.0.0" vs JS @tauri-apps/plugin-process ^2.3.0. Major aligns; please verify runtime compatibility.
-# See more keys and their definition  s at https://doc.rust-lang.org/cargo/reference/manifest.html
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
#!/bin/bash
set -euo pipefail
echo "Rust tauri version feature list:"
rg -nP '^tauri\s*=\s*\{[^}]*features\s*=\s*\[([^\]]*)\]' frontend/src-tauri/Cargo.toml -or '$1'
echo "Rust tauri-plugin-process:"
rg -n 'tauri-plugin-process' frontend/src-tauri/Cargo.toml
echo "JS plugin-process:"
jq -r '.dependencies["@tauri-apps/plugin-process"]' frontend/package.json
echo "Check devtools setting in tauri.conf.json:"
rg -n '"devtools"\s*:\s*(true|false)' frontend/src-tauri/tauri.conf.json || true

Also applies to: 8-8, 14-14, 23-23

frontend/package.json (1)

4-4: Version bump OK; verify plugin-process cross-compat

Major versions match Rust side (2.x). Please confirm the CLI and Rust/JS plugin versions are mutually compatible for your target OS matrix.

#!/bin/bash
set -euo pipefail
echo "CLI:"
jq -r '.devDependencies["@tauri-apps/cli"]' frontend/package.json
echo "JS plugin-process:"
jq -r '.dependencies["@tauri-apps/plugin-process"]' frontend/package.json
echo "Rust plugin-process:"
rg -n 'tauri-plugin-process\s*=\s*".*"' frontend/src-tauri/Cargo.toml

If compat is confirmed, consider using caret-less "2" on the Rust side for easier dependabot bumps to latest compatible minor.

Also applies to: 45-45

frontend/src-tauri/src/services/mod.rs (1)

966-966: Double-check tauri.conf.json mapping consistency

Ensure all resource mappings and any callers expecting “resources/server” are updated.

#!/bin/bash
set -euo pipefail
echo "Searching for old resource path references:"
rg -n 'resources/server' || true
echo "Confirm new mapping exists:"
rg -n '"resources/backend"' frontend/src-tauri/tauri.conf.json

Consider adding a parallel helper for "resources/sync-microservice" for symmetry with the new packaging.

frontend/src-tauri/capabilities/migrated.json (1)

79-79: Scope process permissions minimally

Adding "process:default" grants broad process access. Limit to only what the app needs (e.g., specific allow lists) to reduce attack surface.

#!/bin/bash
set -euo pipefail
echo "Ensure process plugin is actually initialized:"
rg -n 'tauri_plugin_process::init' frontend/src-tauri/src/main.rs || { echo "Missing tauri_plugin_process::init() in main.rs"; exit 1; }
backend/app/utils/microservice.py (2)

118-136: Optional: make dependency install idempotent/noisy-safe.

pip install -r on every start can be slow/noisy. Consider a marker file or hashing requirements.txt to skip when unchanged.


41-44: Optional: ensure logs are visible.

This module uses logging.getLogger(__name__) but the app switched to prints elsewhere. Either configure root logging in the backend on startup or switch these key messages to print for consistency.

frontend/src-tauri/src/main.rs (1)

28-28: Gate debug print to dev builds.

-            println!("Resource path: {:?}", resource_path);
+            #[cfg(debug_assertions)]
+            println!("Resource path: {:?}", resource_path);
backend/main.py (2)

69-93: Gate OpenAPI file generation to dev to avoid write failures in bundled apps.

-    try:
+    try:
+        if os.environ.get("GENERATE_OPENAPI", "0") != "1":
+            return

Usage: set GENERATE_OPENAPI=1 in dev to regenerate.


96-102: Consider restricting CORS in production.

allow_origins=["*"] is okay for local/Tauri, but consider a tighter policy (e.g., only tauri://localhost) when shipping.

frontend/src-tauri/tauri.conf.json (1)

56-58: DevTools enabled in config.

Fine for development; ensure release artifacts don’t ship with DevTools enabled if that’s undesired.

frontend/src/routes/AppRoutes.tsx (1)

10-10: Swap to lazy-load ComingSoon for lighter initial bundle

Optional: code-split ComingSoon since it’s used on multiple routes and not critical-path.

Apply:

-import { ComingSoon } from '@/pages/ComingSoon/ComingSoon';
+const ComingSoon = React.lazy(() => import('@/pages/ComingSoon/ComingSoon'));

And wrap these routes in a Suspense boundary (e.g., around or locally).

frontend/src/components/OnboardingSteps/OnboardingStep.tsx (2)

9-9: Unify import style

Use the alias path for consistency with other imports in this file.

-import { ServerCheck } from './ServerCheck';
+import { ServerCheck } from '@/components/OnboardingSteps/ServerCheck';

41-42: Confirm step list vs. progress count

SERVER_CHECK renders, but VISIBLE_STEPS excludes both SERVER_CHECK and UPDATE_STEP. If you show progress based on totalSteps, this may misreport progress when these steps run.

Consider computing totalSteps from the actual active flow or include these steps when applicable.

frontend/src/api/axiosConfig.ts (1)

13-20: Duped axios config — consider a factory

Both clients share identical config except baseURL. Reduce duplication and centralize headers/timeouts.

-export const syncApiClient = axios.create({
-  baseURL: SYNC_MICROSERVICE_URL,
-  timeout: 10000, // 10 seconds timeout
-  headers: {
-    'Content-Type': 'application/json',
-    Accept: 'application/json',
-  },
-});
+const makeApiClient = (baseURL: string) =>
+  axios.create({
+    baseURL,
+    timeout: 10000,
+    headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
+  });
+
+export const syncApiClient = makeApiClient(SYNC_MICROSERVICE_URL);

Also confirm CORS/cookies needs; add withCredentials if required by the sync service.

frontend/src/api/api-functions/health.ts (1)

1-16: Add minimal error handling or document thrown errors

Calls will throw on non-2xx. If ServerCheck expects a boolean/shape, consider normalizing here; otherwise, ensure the caller has try/catch.

Example normalization:

-export const getMainBackendHealthStatus = async (): Promise<APIResponse> => {
-  const response = await apiClient.get<APIResponse>(healthEndpoints.healthCheck);
-  return response.data;
-};
+export const getMainBackendHealthStatus = async (): Promise<APIResponse> => {
+  try {
+    const { data } = await apiClient.get<APIResponse>(healthEndpoints.healthCheck);
+    return data;
+  } catch (e) {
+    // map to your APIResponse error shape if available
+    throw e;
+  }
+}
frontend/src/components/Dialog/InfoDialog.tsx (1)

66-70: Prevent dismiss via ESC/click-outside when close is hidden

If the intent is a truly non-dismissible dialog, also block onOpenChange when showCloseButton is false.

Add guards:

// around line 49-54
<Dialog
  open={isOpen}
  onOpenChange={(open) => {
    if (!open && showCloseButton === false) return; // ignore outside/Esc
    if (!open) handleClose();
  }}
>
frontend/src/pages/ComingSoon/ComingSoon.tsx (1)

1-47: Solid placeholder; minor a11y tweak

Mark decorative icons as aria-hidden to reduce noise for screen readers.

-              <Clock className="text-primary h-8 w-8" />
+              <Clock aria-hidden="true" className="text-primary h-8 w-8" />
...
-              <Sparkles className="h-5 w-5 text-yellow-500" />
+              <Sparkles aria-hidden="true" className="h-5 w-5 text-yellow-500" />
frontend/src/features/infoDialogSlice.ts (1)

25-30: Minor: streamline defaulting via payload destructuring.

Removes repeated action.payload.* and centralizes defaults.

-      state.title = action.payload.title;
-      state.message = action.payload.message;
-      state.variant = action.payload.variant || 'info';
-      state.showCloseButton = action.payload.showCloseButton ?? true;
+      const {
+        title,
+        message,
+        variant = 'info',
+        showCloseButton = true,
+      } = action.payload;
+      state.title = title;
+      state.message = message;
+      state.variant = variant;
+      state.showCloseButton = showCloseButton;
frontend/src/components/OnboardingSteps/ServerCheck.tsx (2)

23-27: Use unique React Query keys for health checks.

['clusters'] is generic and risks cache collisions with real cluster data. Prefer specific keys.

-  } = usePictoQuery({
-    queryKey: ['clusters'],
+  } = usePictoQuery({
+    queryKey: ['mainBackendHealth'],
     queryFn: getMainBackendHealthStatus,
@@
-  } = usePictoQuery({
-    queryKey: ['syncMicroservice'],
+  } = usePictoQuery({
+    queryKey: ['syncHealth'],
     queryFn: getSyncMicroserviceHealthStatus,

Also applies to: 33-37


38-56: Clear the scheduled exit timeout to avoid leaks/repeated exits.

If the component unmounts or states flap, the pending timeout should be cleared.

-  useEffect(() => {
+  useEffect(() => {
+    let exitTimer: number | undefined;
@@
-      setTimeout(() => {
-        exit(1);
-      }, 2000);
+      exitTimer = window.setTimeout(() => {
+        void exit(1);
+      }, 2000);
     }
@@
-  }, [
+    return () => {
+      if (exitTimer) {
+        clearTimeout(exitTimer);
+      }
+    };
+  }, [
     mainBackendSuccess,
     mainBackendLoading,
     mainBackendError,
     syncMicroserviceSuccess,
     syncMicroserviceLoading,
     syncMicroserviceError,
+    dispatch,
+    stepIndex,
   ]);

Also applies to: 61-68

frontend/src/pages/SettingsPage/Settings.tsx (3)

106-114: Disable controls while saving to prevent rapid re-submits.

Tie UI interactivity to mutation pending state.

   const {
-    mutate: updatePreferencesMutate,
-    isSuccess: updatePreferencesSuccess,
-    isError: updatePreferencesError,
+    mutate: updatePreferencesMutate,
+    isSuccess: updatePreferencesSuccess,
+    isError: updatePreferencesError,
+    isPending: updatePreferencesPending,
   } = usePictoMutation({
     mutationFn: updateUserPreferences,
   });
-                  <Button variant="outline" className="w-32 justify-between">
+                  <Button
+                    variant="outline"
+                    className="w-32 justify-between"
+                    disabled={updatePreferencesPending}
+                  >
                 <Switch
                   id="gpu-acceleration"
                   checked={userPreferences.GPU_Acceleration}
                   onCheckedChange={(checked) =>
                     handlePreferenceUpdate({
                       ...userPreferences,
                       GPU_Acceleration: checked,
                     })
                   }
+                  disabled={updatePreferencesPending}
                 />

Also applies to: 349-353, 406-416


123-126: Make updates atomic with functional setState to avoid stale closures.

Merges patches and ensures the mutation uses the latest state.

-  const handlePreferenceUpdate = (updatedPreferences: UserPreferencesData) => {
-    setUserPreferences(updatedPreferences);
-    updatePreferencesMutate(updatedPreferences);
-  };
+  const handlePreferenceUpdate = (patch: Partial<UserPreferencesData>) => {
+    setUserPreferences(prev => {
+      const next = { ...prev, ...patch };
+      updatePreferencesMutate(next);
+      return next;
+    });
+  };
-                    onClick={() =>
-                      handlePreferenceUpdate({
-                        ...userPreferences,
-                        YOLO_model_size: 'nano',
-                      })
-                    }
+                    onClick={() => handlePreferenceUpdate({ YOLO_model_size: 'nano' })}
-                    onClick={() =>
-                      handlePreferenceUpdate({
-                        ...userPreferences,
-                        YOLO_model_size: 'small',
-                      })
-                    }
+                    onClick={() => handlePreferenceUpdate({ YOLO_model_size: 'small' })}
-                    onClick={() =>
-                      handlePreferenceUpdate({
-                        ...userPreferences,
-                        YOLO_model_size: 'medium',
-                      })
-                    }
+                    onClick={() => handlePreferenceUpdate({ YOLO_model_size: 'medium' })}
-                  onCheckedChange={(checked) =>
-                    handlePreferenceUpdate({
-                      ...userPreferences,
-                      GPU_Acceleration: checked,
-                    })
-                  }
+                  onCheckedChange={(checked) =>
+                    handlePreferenceUpdate({ GPU_Acceleration: checked })
+                  }

Also applies to: 357-362, 367-372, 377-382, 409-414


479-479: Simplify boolean expression.

false || x is just x.

-        showCloseButton={false || !isDownloading}
+        showCloseButton={!isDownloading}
frontend/src/api/api-functions/user_preferences.ts (4)

6-22: DRY the repeated union and future‑proof sizes

Extract a reusable size type/constant and use Partial<UserPreferencesData> for the update request.

-export interface UserPreferencesData {
-  YOLO_model_size: 'nano' | 'small' | 'medium';
-  GPU_Acceleration: boolean;
-}
+export const YOLO_MODEL_SIZES = ['nano', 'small', 'medium'] as const;
+export type YoloModelSize = typeof YOLO_MODEL_SIZES[number];
+export interface UserPreferencesData {
+  YOLO_model_size: YoloModelSize;
+  GPU_Acceleration: boolean;
+}
@@
-export interface UpdateUserPreferencesRequest {
-  YOLO_model_size?: 'nano' | 'small' | 'medium';
-  GPU_Acceleration?: boolean;
-}
+export type UpdateUserPreferencesRequest = Partial<UserPreferencesData>;

Optional: If APIResponse supports generics, prefer APIResponse<UserPreferencesData> over extending and adding user_preferences manually.


6-9: Consider transport vs domain casing

Server-style keys (YOLO_model_size, GPU_Acceleration) are unconventional in TS UIs. Consider mapping to camelCase in the frontend domain model to isolate API wire format from UI types.


24-31: Support request cancellation

Expose an optional AbortSignal to prevent orphaned in-flight calls when navigating away.

-export const getUserPreferences =
-  async (): Promise<GetUserPreferencesResponse> => {
-    const response = await apiClient.get<GetUserPreferencesResponse>(
-      userPreferencesEndpoints.getUserPreferences,
-    );
-    return response.data;
-  };
+export const getUserPreferences =
+  async (options?: { signal?: AbortSignal }): Promise<GetUserPreferencesResponse> => {
+    const response = await apiClient.get<GetUserPreferencesResponse>(
+      userPreferencesEndpoints.getUserPreferences,
+      { signal: options?.signal },
+    );
+    return response.data;
+  };

33-41: PUT with a partial payload — confirm backend contract (else use PATCH)

You’re sending a partial but using PUT (often implies full replacement). Verify backend expects PUT+partial; otherwise switch to PATCH. Added cancellation support in either case.

 export const updateUserPreferences = async (
-  request: UpdateUserPreferencesRequest,
-): Promise<UpdateUserPreferencesResponse> => {
-  const response = await apiClient.put<UpdateUserPreferencesResponse>(
-    userPreferencesEndpoints.updateUserPreferences,
-    request,
-  );
+  request: UpdateUserPreferencesRequest,
+  options?: { signal?: AbortSignal },
+): Promise<UpdateUserPreferencesResponse> => {
+  const response = await apiClient.put<UpdateUserPreferencesResponse>(
+    userPreferencesEndpoints.updateUserPreferences,
+    request,
+    { signal: options?.signal },
+  );
   return response.data;
 };

If backend expects PATCH instead:

-  const response = await apiClient.put<UpdateUserPreferencesResponse>(
+  const response = await apiClient.patch<UpdateUserPreferencesResponse>(

Run to confirm server method/shape:

#!/bin/bash
set -euo pipefail

echo "Find endpoints and method for /user-preferences"
rg -n -C2 -S '/user-preferences' 

echo "PUT/PATCH route defs"
rg -n -C2 -P '@(app|router)\.(put|patch)\s*\(\s*["'\'']/user-preferences/?'

echo "Confirm response keys"
rg -n -C2 -S '\buser_preferences\b|\bYOLO_model_size\b|\bGPU_Acceleration\b'
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e985b25 and 00d7a55.

⛔ Files ignored due to path filters (4)
  • backend/dist/README.md is excluded by !**/dist/**
  • frontend/package-lock.json is excluded by !**/package-lock.json
  • frontend/src-tauri/Cargo.lock is excluded by !**/*.lock
  • sync-microservice/dist/README.md is excluded by !**/dist/**
📒 Files selected for processing (31)
  • .github/workflows/build-and-release.yml (0 hunks)
  • backend/.gitignore (1 hunks)
  • backend/app/custom_logging.py (0 hunks)
  • backend/app/logging_config.json (0 hunks)
  • backend/app/utils/microservice.py (1 hunks)
  • backend/main.py (3 hunks)
  • docs/backend/backend_python/openapi.json (1 hunks)
  • frontend/package.json (2 hunks)
  • frontend/src-tauri/Cargo.toml (2 hunks)
  • frontend/src-tauri/capabilities/migrated.json (1 hunks)
  • frontend/src-tauri/src/main.rs (1 hunks)
  • frontend/src-tauri/src/services/mod.rs (1 hunks)
  • frontend/src-tauri/tauri.conf.json (2 hunks)
  • frontend/src/App.tsx (2 hunks)
  • frontend/src/api/api-functions/health.ts (1 hunks)
  • frontend/src/api/api-functions/index.ts (1 hunks)
  • frontend/src/api/api-functions/user_preferences.ts (1 hunks)
  • frontend/src/api/apiEndpoints.ts (1 hunks)
  • frontend/src/api/axiosConfig.ts (2 hunks)
  • frontend/src/components/Dialog/InfoDialog.tsx (3 hunks)
  • frontend/src/components/OnboardingSteps/OnboardingStep.tsx (2 hunks)
  • frontend/src/components/OnboardingSteps/ServerCheck.tsx (1 hunks)
  • frontend/src/config/Backend.ts (1 hunks)
  • frontend/src/constants/steps.ts (1 hunks)
  • frontend/src/features/infoDialogSlice.ts (2 hunks)
  • frontend/src/pages/ComingSoon/ComingSoon.tsx (1 hunks)
  • frontend/src/pages/SettingsPage/Settings.tsx (4 hunks)
  • frontend/src/routes/AppRoutes.tsx (1 hunks)
  • frontend/src/types/infoDialog.ts (1 hunks)
  • sync-microservice/.gitignore (1 hunks)
  • sync-microservice/main.py (2 hunks)
💤 Files with no reviewable changes (3)
  • .github/workflows/build-and-release.yml
  • backend/app/logging_config.json
  • backend/app/custom_logging.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Tauri Tests
  • GitHub Check: Tauri Build Check (macos-latest, --target aarch64-apple-darwin)
  • GitHub Check: Tauri Build Check (ubuntu-22.04)
  • GitHub Check: Tauri Build Check (windows-latest)
🔇 Additional comments (29)
frontend/src-tauri/src/services/mod.rs (1)

966-966: LGTM: resource path matches new packaging layout

Switch to resources/backend aligns with tauri.conf.json mappings.

sync-microservice/main.py (1)

27-27: ```shell
#!/bin/bash
set -e

echo "Searching for Config class definition"
rg -nP 'class\s+Config' -C3 . || echo "No Config class definition found"

echo "Searching for Config import statements"
rg -nP 'from\s+.*Config' -C3 . || echo "No Config imports found"

echo "Checking for Dockerfile presence"
fd -t f Dockerfile || echo "No Dockerfile found"

echo "Searching for port 8001 references"
rg -n "8001" -n . || echo "No references to port 8001 found"


</blockquote></details>
<details>
<summary>backend/app/utils/microservice.py (2)</summary><blockquote>

`55-62`: **Frozen path calc + new directory name look correct.**

Resolving to `<resources>/sync-microservice` by using `Path(sys.executable).parent.parent / "sync-microservice"` matches the new Tauri resource mapping.

---

`60-69`: **Double-check packaged executable name.**

This expects `PictoPy_Sync(.exe)` inside `resources/sync-microservice`. Verify the PyInstaller output name matches to avoid “file not found” at runtime. 
Would you confirm the generated artifact name in the sync-microservice dist configuration?

</blockquote></details>
<details>
<summary>frontend/src-tauri/src/main.rs (2)</summary><blockquote>

`21-21`: **Process plugin inclusion looks good.**

---

`27-28`: **Resource path change to `resources/backend` matches tauri.conf.json.**

</blockquote></details>
<details>
<summary>docs/backend/backend_python/openapi.json (1)</summary><blockquote>

`19-37`: **Health path and operationId updates align with backend route changes.**

Move from `/` to `/health` and `root_health_get` looks consistent.

</blockquote></details>
<details>
<summary>frontend/src/types/infoDialog.ts (1)</summary><blockquote>

`8-8`: **Prop addition LGTM.**

Optional with sensible default handled by the component.

</blockquote></details>
<details>
<summary>frontend/src/api/apiEndpoints.ts (2)</summary><blockquote>

`20-23`: **User preferences endpoints added correctly.**

Paths match the OpenAPI trailing slash style.

---

`25-27`: **Health endpoint export looks good.**

</blockquote></details>
<details>
<summary>frontend/src/config/Backend.ts (2)</summary><blockquote>

`2-2`: **Sync microservice base URL export LGTM.**

Matches server default (8001) and `/api/v1` base.

---

`1-3`: **Verify no stale IMAGE_ENDPOINT usages remain.** 

```shell
#!/bin/bash
# Find any remaining references to the removed IMAGE_ENDPOINT export
rg -n --hidden -S '\bIMAGE_ENDPOINT\b' -g '!**/dist/**' -g '!**/build/**'
backend/main.py (2)

106-109: /health endpoint change is consistent with docs and frontend.


125-130: Uvicorn config with log_level="info" is fine.

frontend/src-tauri/tauri.conf.json (4)

25-27: Resource mappings updated correctly (backend + sync-microservice).


33-33: Version bump acknowledged.


65-65: CSP updates to allow 8000/8001 over http/ws look correct.


34-34: Update bundle identifier before release.

com.yourcompany.pictopy is a placeholder; use a stable reverse-DNS (e.g., org.aossie.pictopy) for signing/updates.

frontend/src/routes/AppRoutes.tsx (1)

18-22: Placeholder routing looks good

Pointing VIDEOS, ALBUMS, and MEMORIES to ComingSoon is a safe interim. Ensure any deep links or breadcrumbs don’t assume Settings for these paths.

frontend/src/api/api-functions/index.ts (1)

5-6: Re-exports added correctly

Health and user preferences APIs are now publicly exposed. Verify no name collisions with existing exports and that consumers update their imports from this index.

frontend/src/components/Dialog/InfoDialog.tsx (2)

21-21: Prop default LGTM

showCloseButton default keeps prior behavior while enabling non-dismissible dialogs.


55-55: Prop passthrough depends on DialogContent support

Ensure DialogContent accepts showCloseButton; otherwise this prop is ignored.

frontend/src/App.tsx (2)

18-19: InfoDialog wiring looks correct

showCloseButton is plumbed from state to InfoDialog as intended.


32-32: Prop pass-through LGTM

Passing showCloseButton preserves existing behavior while enabling non-dismissible flows.

frontend/src/features/infoDialogSlice.ts (2)

9-10: LGTM: Added showCloseButton with sensible default.

State shape extension is consistent and backwards-safe.


36-37: LGTM: Resetting showCloseButton on hide is correct.

Prevents sticky UI state across dialogs.

frontend/src/components/OnboardingSteps/ServerCheck.tsx (1)

57-60: LGTM: Success path completes the step and hides loader.

Flow is clear and side-effect boundaries are appropriate.

frontend/src/pages/SettingsPage/Settings.tsx (1)

94-105: LGTM: Local userPreferences state + initial fetch hookup.

Reasonable defaults; query integration is straightforward.

frontend/src/api/api-functions/user_preferences.ts (1)

1-3: Verify alias '@' and axios client config to avoid build regressions

Ensure the @ path alias is configured in tsconfig and apiClient has sane defaults (baseURL, timeout, withCredentials) since this module depends on both.

Run:

#!/bin/bash
set -euo pipefail

echo "Check TS alias mapping for @/*"
fd -a -HI -t f 'tsconfig*.json'
rg -n -C2 '"paths"\s*:\s*{[^}]*"@/\*":' $(fd -a -HI -t f 'tsconfig*.json')

echo "Locate axios client config"
fd -a 'axiosConfig.ts'
rg -n -C2 'create\(|baseURL|timeout|withCredentials' $(fd -a 'axiosConfig.ts')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working CI/CD GSoC 2025

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant