fix: add separate original_path field for directory sync

fix: add separate original_path field for directory sync
Previously, meta.name was overloaded to store the full path for directory
sync comparison (e.g., "docs/subfolder/readme.md"). This caused potential
downstream effects since meta.name is used for display and downloads.
Changes:
- Revert meta.name to store only the sanitized base filename
- Add new meta.original_path field that preserves the full upload path
- Update sync compare logic to prioritize original_path for matching
- Fallback chain for legacy files: original_path -> name -> filename
This maintains backwards compatibility with existing files while enabling
directory structure preservation for the sync feature.
This commit is contained in:
DrMelone 2026-01-28 22:15:01 +01:00
parent 0c61f0b9da
commit a22aaecd45
2 changed files with 15 additions and 10 deletions

View file

@ -260,11 +260,12 @@ async def upload_file_handler(
**({'status': 'pending'} if process else {}),
},
'meta': {
# Store original filename with path for sync comparison
'name': unsanitized_filename,
'name': name,
'content_type': (file.content_type if isinstance(file.content_type, str) else None),
'size': len(contents),
'file_hash': file_hash,
# Store original path for directory sync (includes subdirectories)
'original_path': unsanitized_filename,
'data': file_metadata,
},
}

View file

@ -1167,12 +1167,16 @@ async def compare_files_for_sync(
# Get all files currently in the knowledge base
existing_files = await Knowledges.get_files_by_id(id, db=db)
# Build a map of existing files by filename for quick lookup
existing_by_filename: dict[str, FileModel] = {}
# Build a map of existing files by their sync path for quick lookup
# Priority: original_path (for directory sync) > name > filename
existing_by_path: dict[str, FileModel] = {}
for file in existing_files:
# Use the original filename from meta if available, otherwise use filename field
filename = file.meta.get('name', file.filename) if file.meta else file.filename
existing_by_filename[filename] = file
if file.meta:
# Use original_path for sync comparison (includes subdirectory structure)
sync_path = file.meta.get('original_path') or file.meta.get('name', file.filename)
else:
sync_path = file.filename
existing_by_path[sync_path] = file
# Track files from the incoming directory
incoming_filenames = set()
@ -1185,7 +1189,7 @@ async def compare_files_for_sync(
incoming_filenames.add(incoming_file.file_path)
# Check if file exists in knowledge base
existing_file = existing_by_filename.get(incoming_file.file_path)
existing_file = existing_by_path.get(incoming_file.file_path)
if existing_file:
# Check if hash is already stored in meta (files uploaded after this feature)
@ -1228,8 +1232,8 @@ async def compare_files_for_sync(
new_files.append(incoming_file.file_path)
# Find files to delete (exist in KB but not in incoming directory)
for filename, file in existing_by_filename.items():
if filename not in incoming_filenames:
for sync_path, file in existing_by_path.items():
if sync_path not in incoming_filenames:
removed_file_ids.append(file.id)