feat(personal): add scanned PDF OCR schema
This commit is contained in:
+12
-1
@@ -45,7 +45,18 @@ public final class PersonalAssistantDto {
|
|||||||
|
|
||||||
public record ItemResponse(long id, String sourceType, String title, String originalUrl, String mimeType,
|
public record ItemResponse(long id, String sourceType, String title, String originalUrl, String mimeType,
|
||||||
long sizeBytes, String status, String errorCode, String errorMessage, String summary,
|
long sizeBytes, String status, String errorCode, String errorMessage, String summary,
|
||||||
List<String> tags, LocalDateTime capturedAt, LocalDateTime parsedAt) {
|
List<String> tags, LocalDateTime capturedAt, LocalDateTime parsedAt,
|
||||||
|
OcrProgressResponse ocr) {
|
||||||
|
public ItemResponse(long id, String sourceType, String title, String originalUrl, String mimeType,
|
||||||
|
long sizeBytes, String status, String errorCode, String errorMessage, String summary,
|
||||||
|
List<String> tags, LocalDateTime capturedAt, LocalDateTime parsedAt) {
|
||||||
|
this(id, sourceType, title, originalUrl, mimeType, sizeBytes, status, errorCode, errorMessage, summary,
|
||||||
|
tags, capturedAt, parsedAt, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record OcrProgressResponse(boolean required, String status, int totalPages, int processedPages,
|
||||||
|
int successPages, int failedPages, List<Integer> failedPageNumbers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public record PageResponse<T>(List<T> rows, long total, int pageNum, int pageSize) {
|
public record PageResponse<T>(List<T> rows, long total, int pageNum, int pageSize) {
|
||||||
|
|||||||
+17
-1
@@ -59,8 +59,10 @@ class PersonalSchemaContractTest {
|
|||||||
String session = tableDefinition(sql, "aihr_personal_chat_session");
|
String session = tableDefinition(sql, "aihr_personal_chat_session");
|
||||||
String message = tableDefinition(sql, "aihr_personal_chat_message");
|
String message = tableDefinition(sql, "aihr_personal_chat_message");
|
||||||
String cleanup = tableDefinition(sql, "aihr_personal_cleanup_job");
|
String cleanup = tableDefinition(sql, "aihr_personal_cleanup_job");
|
||||||
|
String ocrJob = tableDefinition(sql, "aihr_personal_ocr_job");
|
||||||
|
String ocrPage = tableDefinition(sql, "aihr_personal_ocr_page");
|
||||||
|
|
||||||
for (String definition : new String[] {space, item, fragment, session, message, cleanup}) {
|
for (String definition : new String[] {space, item, fragment, session, message, cleanup, ocrJob, ocrPage}) {
|
||||||
assertTrue(definition.contains("`owner_user_id` bigint not null"),
|
assertTrue(definition.contains("`owner_user_id` bigint not null"),
|
||||||
"Every personal table must carry a non-null owner_user_id");
|
"Every personal table must carry a non-null owner_user_id");
|
||||||
}
|
}
|
||||||
@@ -123,6 +125,20 @@ class PersonalSchemaContractTest {
|
|||||||
assertTrue(cleanup.contains("unique key `uk_personal_cleanup_item` (`tenant_id`, `owner_user_id`, `item_id`)"));
|
assertTrue(cleanup.contains("unique key `uk_personal_cleanup_item` (`tenant_id`, `owner_user_id`, `item_id`)"));
|
||||||
assertTrue(cleanup.contains("key `idx_personal_cleanup_status` (`status`, `update_time`)"));
|
assertTrue(cleanup.contains("key `idx_personal_cleanup_status` (`status`, `update_time`)"));
|
||||||
|
|
||||||
|
assertTrue(ocrJob.contains("`total_pages` int not null"));
|
||||||
|
assertTrue(ocrJob.contains("`processed_pages` int not null default 0"));
|
||||||
|
assertTrue(ocrJob.contains("`success_pages` int not null default 0"));
|
||||||
|
assertTrue(ocrJob.contains("`failed_pages` int not null default 0"));
|
||||||
|
assertTrue(ocrJob.contains("`failed_page_numbers_json` json"));
|
||||||
|
assertTrue(ocrJob.contains("unique key `uk_personal_ocr_job_item` (`tenant_id`, `owner_user_id`, `item_id`)"));
|
||||||
|
assertTrue(ocrJob.contains("key `idx_personal_ocr_job_status` (`status`, `update_time`)"));
|
||||||
|
|
||||||
|
assertTrue(ocrPage.contains("`page_number` int not null"));
|
||||||
|
assertTrue(ocrPage.contains("`ocr_text` longtext"));
|
||||||
|
assertTrue(ocrPage.contains("`attempt_count` int not null default 0"));
|
||||||
|
assertTrue(ocrPage.contains("unique key `uk_personal_ocr_page_number` (`tenant_id`, `owner_user_id`, `item_id`, `page_number`)"));
|
||||||
|
assertTrue(ocrPage.contains("key `idx_personal_ocr_page_status` (`status`, `update_time`)"));
|
||||||
|
|
||||||
assertFalse(sql.contains("alter table aihr_knowledge_fragment"),
|
assertFalse(sql.contains("alter table aihr_knowledge_fragment"),
|
||||||
"Personal schema must not mutate enterprise knowledge tables");
|
"Personal schema must not mutate enterprise knowledge tables");
|
||||||
assertFalse(sql.contains("alter table `aihr_knowledge_fragment`"),
|
assertFalse(sql.contains("alter table `aihr_knowledge_fragment`"),
|
||||||
|
|||||||
@@ -128,3 +128,42 @@ CREATE TABLE IF NOT EXISTS `aihr_personal_cleanup_job` (
|
|||||||
UNIQUE KEY `uk_personal_cleanup_item` (`tenant_id`, `owner_user_id`, `item_id`),
|
UNIQUE KEY `uk_personal_cleanup_item` (`tenant_id`, `owner_user_id`, `item_id`),
|
||||||
KEY `idx_personal_cleanup_status` (`status`, `update_time`)
|
KEY `idx_personal_cleanup_status` (`status`, `update_time`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='个人AI助理资料清理任务';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='个人AI助理资料清理任务';
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `aihr_personal_ocr_job` (
|
||||||
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'OCR任务ID',
|
||||||
|
`tenant_id` varchar(20) NOT NULL COMMENT '租户编号',
|
||||||
|
`owner_user_id` bigint NOT NULL COMMENT '资料所属用户ID',
|
||||||
|
`item_id` bigint NOT NULL COMMENT '资料ID',
|
||||||
|
`status` varchar(20) NOT NULL DEFAULT 'PENDING' COMMENT 'PENDING/RUNNING/RETRY/COMPLETED/FAILED',
|
||||||
|
`total_pages` int NOT NULL COMMENT 'PDF总页数',
|
||||||
|
`processed_pages` int NOT NULL DEFAULT 0 COMMENT '已处理页数',
|
||||||
|
`success_pages` int NOT NULL DEFAULT 0 COMMENT '识别成功页数',
|
||||||
|
`failed_pages` int NOT NULL DEFAULT 0 COMMENT '识别失败页数',
|
||||||
|
`failed_page_numbers_json` json COMMENT '识别失败页码JSON',
|
||||||
|
`next_page` int NOT NULL DEFAULT 1 COMMENT '下一待处理页码,从1开始',
|
||||||
|
`attempt_count` int NOT NULL DEFAULT 0 COMMENT '任务领取次数',
|
||||||
|
`last_error_code` varchar(80) DEFAULT NULL COMMENT '脱敏后的错误码',
|
||||||
|
`lease_until` datetime DEFAULT NULL COMMENT '任务租约截止时间',
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `uk_personal_ocr_job_item` (`tenant_id`, `owner_user_id`, `item_id`),
|
||||||
|
KEY `idx_personal_ocr_job_status` (`status`, `update_time`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='个人AI助理扫描PDF OCR任务';
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `aihr_personal_ocr_page` (
|
||||||
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'OCR页记录ID',
|
||||||
|
`tenant_id` varchar(20) NOT NULL COMMENT '租户编号',
|
||||||
|
`owner_user_id` bigint NOT NULL COMMENT '资料所属用户ID',
|
||||||
|
`item_id` bigint NOT NULL COMMENT '资料ID',
|
||||||
|
`page_number` int NOT NULL COMMENT '页码,从1开始',
|
||||||
|
`status` varchar(20) NOT NULL DEFAULT 'PENDING' COMMENT 'PENDING/RUNNING/SUCCESS/FAILED',
|
||||||
|
`ocr_text` longtext COMMENT '页级OCR文本',
|
||||||
|
`attempt_count` int NOT NULL DEFAULT 0 COMMENT '识别尝试次数',
|
||||||
|
`last_error_code` varchar(80) DEFAULT NULL COMMENT '脱敏后的错误码',
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `uk_personal_ocr_page_number` (`tenant_id`, `owner_user_id`, `item_id`, `page_number`),
|
||||||
|
KEY `idx_personal_ocr_page_status` (`status`, `update_time`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='个人AI助理扫描PDF OCR页结果';
|
||||||
|
|||||||
Reference in New Issue
Block a user