diff --git a/backend/app/routes/folders.py b/backend/app/routes/folders.py index a66cca27c..59c306dae 100644 --- a/backend/app/routes/folders.py +++ b/backend/app/routes/folders.py @@ -450,6 +450,8 @@ def get_all_folders(): ai_tagging, tagging_completed, ) = folder_data + # Check if folder path still exists on filesystem + folder_exists = os.path.isdir(folder_path) folders.append( FolderDetails( folder_id=folder_id, @@ -458,6 +460,7 @@ def get_all_folders(): last_modified_time=last_modified_time, AI_Tagging=ai_tagging, taggingCompleted=tagging_completed, + exists=folder_exists, ) ) diff --git a/backend/app/schemas/folders.py b/backend/app/schemas/folders.py index 63045241b..0af0a9a71 100644 --- a/backend/app/schemas/folders.py +++ b/backend/app/schemas/folders.py @@ -30,6 +30,7 @@ class FolderDetails(BaseModel): last_modified_time: int AI_Tagging: bool taggingCompleted: Optional[bool] = None + exists: bool = True class GetAllFoldersData(BaseModel): diff --git a/backend/tests/test_folders.py b/backend/tests/test_folders.py index a0d26f0e5..4882fa925 100644 --- a/backend/tests/test_folders.py +++ b/backend/tests/test_folders.py @@ -586,11 +586,13 @@ def test_delete_folders_database_error(self, mock_delete_batch, client): # ============================================================================ @patch("app.routes.folders.db_get_all_folder_details") + @patch("app.routes.folders.os.path.isdir") def test_get_all_folders_success( - self, mock_get_all_folders, client, sample_folder_details + self, mock_isdir, mock_get_all_folders, client, sample_folder_details ): """Test successfully retrieving all folders.""" mock_get_all_folders.return_value = sample_folder_details + mock_isdir.return_value = True response = client.get("/folders/all-folders") @@ -608,8 +610,10 @@ def test_get_all_folders_success( assert first_folder["parent_folder_id"] is None assert first_folder["AI_Tagging"] is True assert first_folder["taggingCompleted"] is False + assert first_folder["exists"] is True mock_get_all_folders.assert_called_once() + assert mock_isdir.call_count == 2 @patch("app.routes.folders.db_get_all_folder_details") def test_get_all_folders_empty(self, mock_get_all_folders, client): diff --git a/docs/backend/backend_python/openapi.json b/docs/backend/backend_python/openapi.json index fbf40091b..ec0ee9daf 100644 --- a/docs/backend/backend_python/openapi.json +++ b/docs/backend/backend_python/openapi.json @@ -1686,6 +1686,11 @@ } ], "title": "Taggingcompleted" + }, + "exists": { + "type": "boolean", + "title": "Exists", + "default": true } }, "type": "object", diff --git a/frontend/src/hooks/useFolderOperations.tsx b/frontend/src/hooks/useFolderOperations.tsx index ff747ff0b..e40872bdf 100644 --- a/frontend/src/hooks/useFolderOperations.tsx +++ b/frontend/src/hooks/useFolderOperations.tsx @@ -25,6 +25,8 @@ export const useFolderOperations = () => { const foldersQuery = usePictoQuery({ queryKey: ['folders'], queryFn: getAllFolders, + // Ensure we re-check filesystem existence when navigating back to Settings + refetchOnMount: 'always', }); const taggingStatusQuery = usePictoQuery({ diff --git a/frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx b/frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx index db4b029fa..f374c72a8 100644 --- a/frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx +++ b/frontend/src/pages/SettingsPage/components/FolderManagementCard.tsx @@ -37,11 +37,14 @@ const FolderManagementCard: React.FC = () => { > {folders.length > 0 ? (