feat(annotation): implement file version management for annotation feature

Add support for detecting new file versions and switching to them:

Backend Changes:
- Add file_version column to AnnotationResult model
- Create Alembic migration for database schema update
- Implement check_file_version() method to compare annotation and file versions
- Implement use_new_version() method to clear annotations and update version
- Update upsert_annotation() to record file version when saving
- Add new API endpoints: GET /version and POST /use-new-version
- Add FileVersionCheckResponse and UseNewVersionResponse schemas

Frontend Changes:
- Add checkFileVersionUsingGet and useNewVersionUsingPost API calls
- Add version warning banner showing current vs latest file version
- Add 'Use New Version' button with confirmation dialog
- Clear version info state when switching files to avoid stale warnings

Bug Fixes:
- Fix previousFileVersion returning updated value (save before update)
- Handle null file_version for historical data compatibility
- Fix segmented annotation clearing (preserve structure, clear results)
- Fix files without annotations incorrectly showing new version warnings
- Preserve total_segments when clearing segmented annotations

Files Modified:
- frontend/src/pages/DataAnnotation/Annotate/LabelStudioTextEditor.tsx
- frontend/src/pages/DataAnnotation/annotation.api.ts
- runtime/datamate-python/app/db/models/annotation_management.py
- runtime/datamate-python/app/module/annotation/interface/editor.py
- runtime/datamate-python/app/module/annotation/schema/editor.py
- runtime/datamate-python/app/module/annotation/service/editor.py

New Files:
- runtime/datamate-python/alembic.ini
- runtime/datamate-python/alembic/env.py
- runtime/datamate-python/alembic/script.py.mako
- runtime/datamate-python/alembic/versions/20250205_0001_add_file_version.py
This commit is contained in:
2026-02-05 20:12:07 +08:00
parent 4143bc75f9
commit f5cb265667
10 changed files with 915 additions and 171 deletions

View File

@@ -88,7 +88,7 @@ export function getEditorTaskSegmentUsingGet(
return get(`/api/annotation/editor/projects/${projectId}/tasks/${fileId}/segments`, params);
}
export function upsertEditorAnnotationUsingPut(
export function upsertEditorAnnotationUsingPut(
projectId: string,
fileId: string,
data: {
@@ -97,8 +97,31 @@ export function upsertEditorAnnotationUsingPut(
segmentIndex?: number;
}
) {
return put(`/api/annotation/editor/projects/${projectId}/tasks/${fileId}/annotation`, data);
}
return put(`/api/annotation/editor/projects/${projectId}/tasks/${fileId}/annotation`, data);
}
export interface FileVersionCheckResponse {
fileId: string;
currentFileVersion: number;
annotationFileVersion: number | null;
hasNewVersion: boolean;
}
export function checkFileVersionUsingGet(projectId: string, fileId: string) {
return get(`/api/annotation/editor/projects/${projectId}/files/${fileId}/version`);
}
export interface UseNewVersionResponse {
fileId: string;
previousFileVersion: number | null;
currentFileVersion: number;
message: string;
}
export function useNewVersionUsingPost(projectId: string, fileId: string) {
return post(`/api/annotation/editor/projects/${projectId}/files/${fileId}/use-new-version`, {});
}
// =====================
// 标注数据导出