fix: promote first project when config default is missing from DB

Fresh CLI installs auto-create main in config but never sync it to the
projects table; the first project add now becomes default when the
configured default has no DB row. Fixes #974.

Signed-off-by: rudi193-cmd <rudi193@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
rudi193-cmd
2026-06-12 06:44:55 -06:00
committed by Paul Hernandez
parent 0247ef0ead
commit b92b0340d5
2 changed files with 59 additions and 0 deletions
@@ -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}")
+46
View File
@@ -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."""