diff --git a/src/basic_memory/services/project_service.py b/src/basic_memory/services/project_service.py index 5e5df6b9..c962d6c0 100644 --- a/src/basic_memory/services/project_service.py +++ b/src/basic_memory/services/project_service.py @@ -256,6 +256,19 @@ class ProjectService: await self.repository.set_as_default(created_project.id) self.config_manager.set_default_project(name) logger.info(f"Project '{name}' set as default") + else: + config_default = self.config_manager.default_project + if config_default is not None: + db_default_project = await self.repository.get_by_name(config_default) + if db_default_project is None: + await self.repository.set_as_default(created_project.id) + self.config_manager.set_default_project(name) + logger.info( + "Promoted project '%s' to default because configured default '%s' " + "is missing from database", + name, + config_default, + ) logger.info(f"Project '{name}' added at {resolved_path}") diff --git a/tests/services/test_project_service.py b/tests/services/test_project_service.py index 57063f18..43942d07 100644 --- a/tests/services/test_project_service.py +++ b/tests/services/test_project_service.py @@ -434,6 +434,52 @@ async def test_add_project_with_set_default_false(project_service: ProjectServic await project_service.remove_project(test_project_name) +@pytest.mark.asyncio +async def test_add_project_promotes_when_config_default_missing_from_db( + config_home, app_config, config_manager, engine_factory +): + """Regression #974: config default exists only in config, not DB — promote on add.""" + from basic_memory import config as config_module + from basic_memory.config import ProjectConfig, ProjectEntry + from basic_memory.markdown.entity_parser import EntityParser + from basic_memory.markdown.markdown_processor import MarkdownProcessor + from basic_memory.repository.project_repository import ProjectRepository + from basic_memory.services.file_service import FileService + + config_module._CONFIG_CACHE = None + config_module._CONFIG_MTIME = None + config_module._CONFIG_SIZE = None + + main_home = config_home / "basic-memory" + main_home.mkdir(parents=True, exist_ok=True) + qa_path = config_home / "qa-notes" + qa_path.mkdir(parents=True, exist_ok=True) + + fresh_config = app_config.model_copy( + update={ + "projects": {"main": ProjectEntry(path=str(main_home))}, + "default_project": "main", + } + ) + config_manager.save_config(fresh_config) + + _, session_maker = engine_factory + repo = ProjectRepository(session_maker) + for project in await repo.find_all(): + await repo.delete(project.id) + + file_service = FileService(qa_path, MarkdownProcessor(EntityParser(qa_path))) + service = ProjectService(repository=repo, file_service=file_service) + + await service.add_project("qa", str(qa_path), set_default=False) + + assert service.default_project == "qa" + qa_project = await repo.get_by_name("qa") + assert qa_project is not None + assert qa_project.is_default is True + assert await repo.get_by_name("main") is None + + @pytest.mark.asyncio async def test_add_project_default_parameter_omitted(project_service: ProjectService): """Test adding a project without set_default parameter defaults to False behavior."""