You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
3.6 KiB
Java
147 lines
3.6 KiB
Java
package at.procon.ted.model.entity;
|
|
|
|
import jakarta.persistence.*;
|
|
import lombok.AllArgsConstructor;
|
|
import lombok.Builder;
|
|
import lombok.Data;
|
|
import lombok.NoArgsConstructor;
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.util.UUID;
|
|
|
|
/**
|
|
* Entity for tracking processed mail attachments.
|
|
* Uses content hash for idempotent processing to avoid duplicate handling.
|
|
*
|
|
* @author Martin.Schweitzer@procon.co.at and claude.ai
|
|
*/
|
|
@Entity
|
|
@Table(name = "processed_attachment", schema = "ted",
|
|
indexes = {
|
|
@Index(name = "idx_processed_attachment_hash", columnList = "content_hash", unique = true),
|
|
@Index(name = "idx_processed_attachment_status", columnList = "processing_status"),
|
|
@Index(name = "idx_processed_attachment_type", columnList = "file_type")
|
|
})
|
|
@Data
|
|
@Builder
|
|
@NoArgsConstructor
|
|
@AllArgsConstructor
|
|
public class ProcessedAttachment {
|
|
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.UUID)
|
|
private UUID id;
|
|
|
|
/**
|
|
* SHA-256 hash of the attachment content for idempotent processing.
|
|
*/
|
|
@Column(name = "content_hash", nullable = false, unique = true, length = 64)
|
|
private String contentHash;
|
|
|
|
/**
|
|
* Original filename of the attachment.
|
|
*/
|
|
@Column(name = "original_filename", nullable = false, length = 500)
|
|
private String originalFilename;
|
|
|
|
/**
|
|
* Detected or declared file type (e.g., PDF, ZIP, XML).
|
|
*/
|
|
@Column(name = "file_type", length = 50)
|
|
private String fileType;
|
|
|
|
/**
|
|
* MIME content type.
|
|
*/
|
|
@Column(name = "content_type", length = 255)
|
|
private String contentType;
|
|
|
|
/**
|
|
* File size in bytes.
|
|
*/
|
|
@Column(name = "file_size")
|
|
private Long fileSize;
|
|
|
|
/**
|
|
* Processing status of the attachment.
|
|
*/
|
|
@Enumerated(EnumType.STRING)
|
|
@Column(name = "processing_status", nullable = false, length = 20)
|
|
private ProcessingStatus processingStatus;
|
|
|
|
/**
|
|
* Extracted text content (for PDF, etc.).
|
|
*/
|
|
@Column(name = "extracted_text", columnDefinition = "TEXT")
|
|
private String extractedText;
|
|
|
|
/**
|
|
* Path where the attachment was saved.
|
|
*/
|
|
@Column(name = "saved_path", length = 1000)
|
|
private String savedPath;
|
|
|
|
/**
|
|
* Email subject from which the attachment was extracted.
|
|
*/
|
|
@Column(name = "mail_subject", length = 500)
|
|
private String mailSubject;
|
|
|
|
/**
|
|
* Email sender.
|
|
*/
|
|
@Column(name = "mail_from", length = 500)
|
|
private String mailFrom;
|
|
|
|
/**
|
|
* Parent attachment hash (for files extracted from ZIP).
|
|
*/
|
|
@Column(name = "parent_hash", length = 64)
|
|
private String parentHash;
|
|
|
|
/**
|
|
* Error message if processing failed.
|
|
*/
|
|
@Column(name = "error_message", columnDefinition = "TEXT")
|
|
private String errorMessage;
|
|
|
|
/**
|
|
* Number of child attachments (for ZIP files).
|
|
*/
|
|
@Column(name = "child_count")
|
|
private Integer childCount;
|
|
|
|
/**
|
|
* When the attachment was first received.
|
|
*/
|
|
@Column(name = "received_at", nullable = false)
|
|
private LocalDateTime receivedAt;
|
|
|
|
/**
|
|
* When processing was completed.
|
|
*/
|
|
@Column(name = "processed_at")
|
|
private LocalDateTime processedAt;
|
|
|
|
/**
|
|
* Processing status enum.
|
|
*/
|
|
public enum ProcessingStatus {
|
|
PENDING,
|
|
PROCESSING,
|
|
COMPLETED,
|
|
FAILED,
|
|
DUPLICATE
|
|
}
|
|
|
|
@PrePersist
|
|
protected void onCreate() {
|
|
if (receivedAt == null) {
|
|
receivedAt = LocalDateTime.now();
|
|
}
|
|
if (processingStatus == null) {
|
|
processingStatus = ProcessingStatus.PENDING;
|
|
}
|
|
}
|
|
}
|