Files
query-orchestration/internal/fieldextraction/service.go
T
Jay Brown c45e1dd427 Merged in feature/textExtractionsPart1 (pull request #192)
all schema and rest apis for text extraction support

* in progress

* stage 8 complete

* phase 9 completed

* phase 9 complete

* ongoing - s3 path fix

* working

* optimize ci build

* e2e tests

* missing test
2025-11-26 19:23:42 +00:00

155 lines
4.8 KiB
Go

package fieldextraction
import (
"context"
"fmt"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/serviceconfig"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
)
// Service provides field extraction operations
type Service struct {
cfg serviceconfig.ConfigProvider
}
// New creates a new field extraction service
func New(cfg serviceconfig.ConfigProvider) *Service {
return &Service{cfg: cfg}
}
// CreateFieldExtraction creates a new field extraction with all single and array fields
// in a single transaction. All array fields must have consistent length.
// Returns the created field extraction record.
func (s *Service) CreateFieldExtraction(ctx context.Context, input *CreateFieldExtractionInput) (*repository.Documentfieldextraction, error) {
if input == nil {
return nil, fmt.Errorf("input cannot be nil")
}
if input.DocumentID == uuid.Nil {
return nil, fmt.Errorf("documentID cannot be nil")
}
if input.SingleFields == nil {
return nil, fmt.Errorf("singleFields cannot be nil")
}
if input.SingleFields.Createdby == "" {
return nil, fmt.Errorf("createdBy cannot be empty")
}
// Validate array consistency
_, err := ValidateArrayConsistency(input.ArrayFields)
if err != nil {
return nil, fmt.Errorf("array validation failed: %w", err)
}
// Begin transaction
tx, err := s.cfg.GetDBPool().Begin(ctx)
if err != nil {
return nil, fmt.Errorf("failed to begin transaction: %w", err)
}
defer func() {
_ = tx.Rollback(ctx)
}()
queries := s.cfg.GetDBQueries().WithTx(tx)
// Set document ID in single fields
input.SingleFields.Documentid = input.DocumentID
// Create main field extraction record with single fields
fieldExtraction, err := queries.AddFieldExtraction(ctx, input.SingleFields)
if err != nil {
return nil, fmt.Errorf("failed to create field extraction: %w", err)
}
// Get the next version number for this document
history, err := queries.GetFieldExtractionsByDocumentID(ctx, input.DocumentID)
if err != nil {
return nil, fmt.Errorf("failed to get field extraction history: %w", err)
}
version := int64(len(history))
// Create version entry
err = queries.AddFieldExtractionEntry(ctx, &repository.AddFieldExtractionEntryParams{
Fieldextractionid: fieldExtraction.ID,
Version: version,
Createdby: input.SingleFields.Createdby,
})
if err != nil {
return nil, fmt.Errorf("failed to create field extraction version entry: %w", err)
}
// Insert all array field rows
for arrayIndex, arrayField := range input.ArrayFields {
// Set field extraction ID and array index
arrayField.Fieldextractionid = fieldExtraction.ID
//nolint:gosec // Array index is expected to be small, int16 is sufficient
arrayField.Arrayindex = int16(arrayIndex)
err = queries.AddFieldExtractionArrayField(ctx, arrayField)
if err != nil {
return nil, fmt.Errorf("failed to create array field at index %d: %w", arrayIndex, err)
}
}
// Commit transaction
if err := tx.Commit(ctx); err != nil {
return nil, fmt.Errorf("failed to commit transaction: %w", err)
}
return fieldExtraction, nil
}
// GetCurrentFieldExtraction retrieves the most recent field extraction for a document
// Returns nil if no field extraction exists for the document
func (s *Service) GetCurrentFieldExtraction(ctx context.Context, documentID uuid.UUID) (*repository.Currentfieldextraction, error) {
if documentID == uuid.Nil {
return nil, fmt.Errorf("documentID cannot be nil")
}
fieldExtraction, err := s.cfg.GetDBQueries().GetCurrentFieldExtraction(ctx, documentID)
if err != nil {
if err == pgx.ErrNoRows {
return nil, nil
}
return nil, fmt.Errorf("failed to get current field extraction: %w", err)
}
return fieldExtraction, nil
}
// GetFieldExtractionHistory retrieves all field extraction versions for a document
// ordered by version (most recent first)
func (s *Service) GetFieldExtractionHistory(ctx context.Context, documentID uuid.UUID) ([]*repository.GetFieldExtractionHistoryRow, error) {
if documentID == uuid.Nil {
return nil, fmt.Errorf("documentID cannot be nil")
}
history, err := s.cfg.GetDBQueries().GetFieldExtractionHistory(ctx, documentID)
if err != nil {
return nil, fmt.Errorf("failed to get field extraction history: %w", err)
}
return history, nil
}
// GetFieldExtractionArrayFields retrieves all array fields for a specific field extraction
// ordered by arrayIndex
func (s *Service) GetFieldExtractionArrayFields(ctx context.Context, fieldExtractionID uuid.UUID) ([]*repository.Documentfieldextractionarrayfield, error) {
if fieldExtractionID == uuid.Nil {
return nil, fmt.Errorf("fieldExtractionID cannot be nil")
}
arrayFields, err := s.cfg.GetDBQueries().GetFieldExtractionArrayFields(ctx, fieldExtractionID)
if err != nil {
return nil, fmt.Errorf("failed to get array fields: %w", err)
}
return arrayFields, nil
}