Files
query-orchestration/internal/database/repository/batch.sql.go
T

1141 lines
35 KiB
Go
Raw Normal View History

2025-08-04 10:54:22 -07:00
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
// source: batch.sql
package repository
import (
"context"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
)
const addFailedFilename = `-- name: AddFailedFilename :exec
UPDATE batch_uploads
SET failed_filenames = failed_filenames || jsonb_build_array($2::text)
WHERE id = $1
`
type AddFailedFilenameParams struct {
ID uuid.UUID `db:"id"`
Column2 string `db:"column_2"`
}
// AddFailedFilename
//
// UPDATE batch_uploads
// SET failed_filenames = failed_filenames || jsonb_build_array($2::text)
// WHERE id = $1
func (q *Queries) AddFailedFilename(ctx context.Context, arg *AddFailedFilenameParams) error {
_, err := q.db.Exec(ctx, addFailedFilename, arg.ID, arg.Column2)
return err
}
const countAcceptedBatchOutcomes = `-- name: CountAcceptedBatchOutcomes :one
SELECT COUNT(*)::int
FROM batch_document_outcomes
WHERE batch_id = $1
AND outcome IN ('clean_passed', 'sync_skipped')
`
// CountAcceptedBatchOutcomes
//
// SELECT COUNT(*)::int
// FROM batch_document_outcomes
// WHERE batch_id = $1
// AND outcome IN ('clean_passed', 'sync_skipped')
func (q *Queries) CountAcceptedBatchOutcomes(ctx context.Context, batchID uuid.UUID) (int32, error) {
row := q.db.QueryRow(ctx, countAcceptedBatchOutcomes, batchID)
var column_1 int32
err := row.Scan(&column_1)
return column_1, err
}
const countBatchOutcomes = `-- name: CountBatchOutcomes :one
SELECT COUNT(*)::int
FROM batch_document_outcomes
WHERE batch_id = $1
`
// CountBatchOutcomes
//
// SELECT COUNT(*)::int
// FROM batch_document_outcomes
// WHERE batch_id = $1
func (q *Queries) CountBatchOutcomes(ctx context.Context, batchID uuid.UUID) (int32, error) {
row := q.db.QueryRow(ctx, countBatchOutcomes, batchID)
var column_1 int32
err := row.Scan(&column_1)
return column_1, err
}
2025-08-04 10:54:22 -07:00
const countDocumentsByBatchId = `-- name: CountDocumentsByBatchId :one
SELECT COUNT(*) as count
FROM documents
WHERE batch_id = $1
`
// CountDocumentsByBatchId
//
// SELECT COUNT(*) as count
// FROM documents
// WHERE batch_id = $1
func (q *Queries) CountDocumentsByBatchId(ctx context.Context, batchID *uuid.UUID) (int64, error) {
row := q.db.QueryRow(ctx, countDocumentsByBatchId, batchID)
var count int64
err := row.Scan(&count)
return count, err
}
const countNonTerminalBatchOutcomes = `-- name: CountNonTerminalBatchOutcomes :one
SELECT COUNT(*)::int
FROM batch_document_outcomes
WHERE batch_id = $1
AND outcome IN ('submitted', 'init_complete', 'sync_complete')
`
// CountNonTerminalBatchOutcomes
//
// SELECT COUNT(*)::int
// FROM batch_document_outcomes
// WHERE batch_id = $1
// AND outcome IN ('submitted', 'init_complete', 'sync_complete')
func (q *Queries) CountNonTerminalBatchOutcomes(ctx context.Context, batchID uuid.UUID) (int32, error) {
row := q.db.QueryRow(ctx, countNonTerminalBatchOutcomes, batchID)
var column_1 int32
err := row.Scan(&column_1)
return column_1, err
}
2025-08-04 10:54:22 -07:00
const createBatchUpload = `-- name: CreateBatchUpload :one
INSERT INTO batch_uploads (client_id, original_filename, total_documents)
VALUES ($1, $2, $3) RETURNING id
`
type CreateBatchUploadParams struct {
ClientID string `db:"client_id"`
OriginalFilename string `db:"original_filename"`
TotalDocuments int32 `db:"total_documents"`
}
// CreateBatchUpload
//
// INSERT INTO batch_uploads (client_id, original_filename, total_documents)
// VALUES ($1, $2, $3) RETURNING id
func (q *Queries) CreateBatchUpload(ctx context.Context, arg *CreateBatchUploadParams) (uuid.UUID, error) {
row := q.db.QueryRow(ctx, createBatchUpload, arg.ClientID, arg.OriginalFilename, arg.TotalDocuments)
var id uuid.UUID
err := row.Scan(&id)
return id, err
}
2025-08-06 15:06:18 -07:00
const createBatchUploadWithStorage = `-- name: CreateBatchUploadWithStorage :one
INSERT INTO batch_uploads (
client_id,
original_filename,
total_documents,
status,
archive_bucket,
archive_key,
file_size_bytes
) VALUES ($1, $2, $3, $4::batch_status, $5, $6, $7)
RETURNING id, created_at
`
type CreateBatchUploadWithStorageParams struct {
ClientID string `db:"client_id"`
OriginalFilename string `db:"original_filename"`
TotalDocuments int32 `db:"total_documents"`
Column4 BatchStatus `db:"column_4"`
ArchiveBucket *string `db:"archive_bucket"`
ArchiveKey *string `db:"archive_key"`
FileSizeBytes *int64 `db:"file_size_bytes"`
}
type CreateBatchUploadWithStorageRow struct {
ID uuid.UUID `db:"id"`
CreatedAt pgtype.Timestamp `db:"created_at"`
}
// CreateBatchUploadWithStorage
//
// INSERT INTO batch_uploads (
// client_id,
// original_filename,
// total_documents,
// status,
// archive_bucket,
// archive_key,
// file_size_bytes
// ) VALUES ($1, $2, $3, $4::batch_status, $5, $6, $7)
// RETURNING id, created_at
func (q *Queries) CreateBatchUploadWithStorage(ctx context.Context, arg *CreateBatchUploadWithStorageParams) (*CreateBatchUploadWithStorageRow, error) {
row := q.db.QueryRow(ctx, createBatchUploadWithStorage,
arg.ClientID,
arg.OriginalFilename,
arg.TotalDocuments,
arg.Column4,
arg.ArchiveBucket,
arg.ArchiveKey,
arg.FileSizeBytes,
)
var i CreateBatchUploadWithStorageRow
err := row.Scan(&i.ID, &i.CreatedAt)
return &i, err
}
const detachRejectedBatchDocumentUploadsFromCandidateFolders = `-- name: DetachRejectedBatchDocumentUploadsFromCandidateFolders :execrows
UPDATE documentUploads du
SET folder_id = NULL
WHERE du.batch_id = $1
AND du.folder_id IS NOT NULL
AND EXISTS (
SELECT 1
FROM batch_folder_candidates bfc
WHERE bfc.batch_id = $1
AND bfc.folder_id = du.folder_id
)
AND EXISTS (
SELECT 1
FROM batch_document_outcomes bdo
WHERE bdo.batch_id = $1
AND bdo.filename = du.filename
AND (
bdo.outcome IN (
'duplicate',
'init_duplicate',
'invalid_type',
'failed_open',
'failed_read',
'failed_s3_upload',
'failed_upload',
'clean_failed'
)
OR ($2::boolean AND bdo.outcome IN ('submitted', 'init_complete', 'sync_complete'))
)
)
`
type DetachRejectedBatchDocumentUploadsFromCandidateFoldersParams struct {
BatchID *uuid.UUID `db:"batch_id"`
IncludeNonterminal bool `db:"include_nonterminal"`
}
// @sqlc-vet-disable
//
// UPDATE documentUploads du
// SET folder_id = NULL
// WHERE du.batch_id = $1
// AND du.folder_id IS NOT NULL
// AND EXISTS (
// SELECT 1
// FROM batch_folder_candidates bfc
// WHERE bfc.batch_id = $1
// AND bfc.folder_id = du.folder_id
// )
// AND EXISTS (
// SELECT 1
// FROM batch_document_outcomes bdo
// WHERE bdo.batch_id = $1
// AND bdo.filename = du.filename
// AND (
// bdo.outcome IN (
// 'duplicate',
// 'init_duplicate',
// 'invalid_type',
// 'failed_open',
// 'failed_read',
// 'failed_s3_upload',
// 'failed_upload',
// 'clean_failed'
// )
// OR ($2::boolean AND bdo.outcome IN ('submitted', 'init_complete', 'sync_complete'))
// )
// )
func (q *Queries) DetachRejectedBatchDocumentUploadsFromCandidateFolders(ctx context.Context, arg *DetachRejectedBatchDocumentUploadsFromCandidateFoldersParams) (int64, error) {
result, err := q.db.Exec(ctx, detachRejectedBatchDocumentUploadsFromCandidateFolders, arg.BatchID, arg.IncludeNonterminal)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const detachRejectedBatchDocumentsFromCandidateFolders = `-- name: DetachRejectedBatchDocumentsFromCandidateFolders :execrows
UPDATE documents d
SET folderId = NULL
WHERE d.batch_id = $1
AND d.folderId IS NOT NULL
AND EXISTS (
SELECT 1
FROM batch_folder_candidates bfc
WHERE bfc.batch_id = $1
AND bfc.folder_id = d.folderId
)
AND EXISTS (
SELECT 1
FROM batch_document_outcomes bdo
WHERE bdo.batch_id = $1
AND bdo.document_id = d.id
AND (
bdo.outcome IN (
'duplicate',
'init_duplicate',
'invalid_type',
'failed_open',
'failed_read',
'failed_s3_upload',
'failed_upload',
'clean_failed'
)
OR ($2::boolean AND bdo.outcome IN ('submitted', 'init_complete', 'sync_complete'))
)
)
`
type DetachRejectedBatchDocumentsFromCandidateFoldersParams struct {
BatchID *uuid.UUID `db:"batch_id"`
IncludeNonterminal bool `db:"include_nonterminal"`
}
// @sqlc-vet-disable
//
// UPDATE documents d
// SET folderId = NULL
// WHERE d.batch_id = $1
// AND d.folderId IS NOT NULL
// AND EXISTS (
// SELECT 1
// FROM batch_folder_candidates bfc
// WHERE bfc.batch_id = $1
// AND bfc.folder_id = d.folderId
// )
// AND EXISTS (
// SELECT 1
// FROM batch_document_outcomes bdo
// WHERE bdo.batch_id = $1
// AND bdo.document_id = d.id
// AND (
// bdo.outcome IN (
// 'duplicate',
// 'init_duplicate',
// 'invalid_type',
// 'failed_open',
// 'failed_read',
// 'failed_s3_upload',
// 'failed_upload',
// 'clean_failed'
// )
// OR ($2::boolean AND bdo.outcome IN ('submitted', 'init_complete', 'sync_complete'))
// )
// )
func (q *Queries) DetachRejectedBatchDocumentsFromCandidateFolders(ctx context.Context, arg *DetachRejectedBatchDocumentsFromCandidateFoldersParams) (int64, error) {
result, err := q.db.Exec(ctx, detachRejectedBatchDocumentsFromCandidateFolders, arg.BatchID, arg.IncludeNonterminal)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
2025-08-04 10:54:22 -07:00
const getBatchUpload = `-- name: GetBatchUpload :one
SELECT id, client_id, original_filename, total_documents, processed_documents,
failed_documents, invalid_type_documents, status, progress_percent,
failed_filenames, created_at, completed_at
FROM batch_uploads
WHERE id = $1 AND client_id = $2
`
type GetBatchUploadParams struct {
ID uuid.UUID `db:"id"`
ClientID string `db:"client_id"`
}
2025-08-06 15:06:18 -07:00
type GetBatchUploadRow struct {
ID uuid.UUID `db:"id"`
ClientID string `db:"client_id"`
OriginalFilename string `db:"original_filename"`
TotalDocuments int32 `db:"total_documents"`
ProcessedDocuments int32 `db:"processed_documents"`
FailedDocuments int32 `db:"failed_documents"`
InvalidTypeDocuments int32 `db:"invalid_type_documents"`
Status BatchStatus `db:"status"`
ProgressPercent int32 `db:"progress_percent"`
FailedFilenames []byte `db:"failed_filenames"`
CreatedAt pgtype.Timestamp `db:"created_at"`
CompletedAt pgtype.Timestamp `db:"completed_at"`
}
2025-08-04 10:54:22 -07:00
// GetBatchUpload
//
// SELECT id, client_id, original_filename, total_documents, processed_documents,
// failed_documents, invalid_type_documents, status, progress_percent,
// failed_filenames, created_at, completed_at
// FROM batch_uploads
// WHERE id = $1 AND client_id = $2
2025-08-06 15:06:18 -07:00
func (q *Queries) GetBatchUpload(ctx context.Context, arg *GetBatchUploadParams) (*GetBatchUploadRow, error) {
2025-08-04 10:54:22 -07:00
row := q.db.QueryRow(ctx, getBatchUpload, arg.ID, arg.ClientID)
2025-08-06 15:06:18 -07:00
var i GetBatchUploadRow
2025-08-04 10:54:22 -07:00
err := row.Scan(
&i.ID,
&i.ClientID,
&i.OriginalFilename,
&i.TotalDocuments,
&i.ProcessedDocuments,
&i.FailedDocuments,
&i.InvalidTypeDocuments,
&i.Status,
&i.ProgressPercent,
&i.FailedFilenames,
&i.CreatedAt,
&i.CompletedAt,
)
return &i, err
}
2025-08-06 15:06:18 -07:00
const getBatchUploadWithStorage = `-- name: GetBatchUploadWithStorage :one
SELECT id, client_id, original_filename, total_documents,
processed_documents, failed_documents, invalid_type_documents,
status, archive_bucket, archive_key, file_size_bytes,
failed_filenames, created_at, completed_at
FROM batch_uploads
WHERE id = $1 AND client_id = $2
`
type GetBatchUploadWithStorageParams struct {
ID uuid.UUID `db:"id"`
ClientID string `db:"client_id"`
}
type GetBatchUploadWithStorageRow struct {
ID uuid.UUID `db:"id"`
ClientID string `db:"client_id"`
OriginalFilename string `db:"original_filename"`
TotalDocuments int32 `db:"total_documents"`
ProcessedDocuments int32 `db:"processed_documents"`
FailedDocuments int32 `db:"failed_documents"`
InvalidTypeDocuments int32 `db:"invalid_type_documents"`
Status BatchStatus `db:"status"`
ArchiveBucket *string `db:"archive_bucket"`
ArchiveKey *string `db:"archive_key"`
FileSizeBytes *int64 `db:"file_size_bytes"`
FailedFilenames []byte `db:"failed_filenames"`
CreatedAt pgtype.Timestamp `db:"created_at"`
CompletedAt pgtype.Timestamp `db:"completed_at"`
}
// GetBatchUploadWithStorage
//
// SELECT id, client_id, original_filename, total_documents,
// processed_documents, failed_documents, invalid_type_documents,
// status, archive_bucket, archive_key, file_size_bytes,
// failed_filenames, created_at, completed_at
// FROM batch_uploads
// WHERE id = $1 AND client_id = $2
func (q *Queries) GetBatchUploadWithStorage(ctx context.Context, arg *GetBatchUploadWithStorageParams) (*GetBatchUploadWithStorageRow, error) {
row := q.db.QueryRow(ctx, getBatchUploadWithStorage, arg.ID, arg.ClientID)
var i GetBatchUploadWithStorageRow
err := row.Scan(
&i.ID,
&i.ClientID,
&i.OriginalFilename,
&i.TotalDocuments,
&i.ProcessedDocuments,
&i.FailedDocuments,
&i.InvalidTypeDocuments,
&i.Status,
&i.ArchiveBucket,
&i.ArchiveKey,
&i.FileSizeBytes,
&i.FailedFilenames,
&i.CreatedAt,
&i.CompletedAt,
)
return &i, err
}
2025-08-04 10:54:22 -07:00
const getDocumentsByBatchId = `-- name: GetDocumentsByBatchId :many
SELECT id, clientId, hash
FROM documents
WHERE batch_id = $1
`
type GetDocumentsByBatchIdRow struct {
ID uuid.UUID `db:"id"`
Clientid string `db:"clientid"`
Hash string `db:"hash"`
}
// GetDocumentsByBatchId
//
// SELECT id, clientId, hash
// FROM documents
// WHERE batch_id = $1
func (q *Queries) GetDocumentsByBatchId(ctx context.Context, batchID *uuid.UUID) ([]*GetDocumentsByBatchIdRow, error) {
rows, err := q.db.Query(ctx, getDocumentsByBatchId, batchID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*GetDocumentsByBatchIdRow{}
for rows.Next() {
var i GetDocumentsByBatchIdRow
if err := rows.Scan(&i.ID, &i.Clientid, &i.Hash); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getUnprocessedBatches = `-- name: GetUnprocessedBatches :many
SELECT id, client_id, original_filename, total_documents,
processed_documents, failed_documents, invalid_type_documents,
status, progress_percent, created_at, completed_at
FROM batch_uploads
WHERE status = 'processing'
ORDER BY created_at ASC
`
type GetUnprocessedBatchesRow struct {
ID uuid.UUID `db:"id"`
ClientID string `db:"client_id"`
OriginalFilename string `db:"original_filename"`
TotalDocuments int32 `db:"total_documents"`
ProcessedDocuments int32 `db:"processed_documents"`
FailedDocuments int32 `db:"failed_documents"`
InvalidTypeDocuments int32 `db:"invalid_type_documents"`
Status BatchStatus `db:"status"`
ProgressPercent int32 `db:"progress_percent"`
CreatedAt pgtype.Timestamp `db:"created_at"`
CompletedAt pgtype.Timestamp `db:"completed_at"`
}
// GetUnprocessedBatches
//
// SELECT id, client_id, original_filename, total_documents,
// processed_documents, failed_documents, invalid_type_documents,
// status, progress_percent, created_at, completed_at
// FROM batch_uploads
// WHERE status = 'processing'
// ORDER BY created_at ASC
func (q *Queries) GetUnprocessedBatches(ctx context.Context) ([]*GetUnprocessedBatchesRow, error) {
rows, err := q.db.Query(ctx, getUnprocessedBatches)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*GetUnprocessedBatchesRow{}
for rows.Next() {
var i GetUnprocessedBatchesRow
if err := rows.Scan(
&i.ID,
&i.ClientID,
&i.OriginalFilename,
&i.TotalDocuments,
&i.ProcessedDocuments,
&i.FailedDocuments,
&i.InvalidTypeDocuments,
&i.Status,
&i.ProgressPercent,
&i.CreatedAt,
&i.CompletedAt,
); err != nil {
return nil, err
2025-08-04 10:54:22 -07:00
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const insertBatchDocumentOutcome = `-- name: InsertBatchDocumentOutcome :exec
INSERT INTO batch_document_outcomes (batch_id, filename, outcome, error_detail, document_id)
VALUES ($1, $2, $3::batch_outcome_status, $4, $5)
ON CONFLICT (batch_id, filename) DO UPDATE
SET outcome = EXCLUDED.outcome,
error_detail = EXCLUDED.error_detail,
document_id = EXCLUDED.document_id,
updated_at = NOW()
`
type InsertBatchDocumentOutcomeParams struct {
BatchID uuid.UUID `db:"batch_id"`
Filename string `db:"filename"`
Column3 BatchOutcomeStatus `db:"column_3"`
ErrorDetail *string `db:"error_detail"`
DocumentID *uuid.UUID `db:"document_id"`
}
// Upsert: if a row for this (batch_id, filename) already exists (e.g. batch
// retry after partial failure), overwrite it with the latest outcome.
//
// INSERT INTO batch_document_outcomes (batch_id, filename, outcome, error_detail, document_id)
// VALUES ($1, $2, $3::batch_outcome_status, $4, $5)
// ON CONFLICT (batch_id, filename) DO UPDATE
// SET outcome = EXCLUDED.outcome,
// error_detail = EXCLUDED.error_detail,
// document_id = EXCLUDED.document_id,
// updated_at = NOW()
func (q *Queries) InsertBatchDocumentOutcome(ctx context.Context, arg *InsertBatchDocumentOutcomeParams) error {
_, err := q.db.Exec(ctx, insertBatchDocumentOutcome,
arg.BatchID,
arg.Filename,
arg.Column3,
arg.ErrorDetail,
arg.DocumentID,
)
return err
}
const listBatchDocumentOutcomes = `-- name: ListBatchDocumentOutcomes :many
SELECT
bdo.id,
bdo.batch_id,
bdo.filename,
bdo.outcome,
bdo.error_detail,
bdo.document_id,
bdo.created_at,
bdo.updated_at,
cce.fail as clean_fail
FROM batch_document_outcomes bdo
LEFT JOIN currentCleanEntries cce ON cce.documentId = bdo.document_id
WHERE bdo.batch_id = $1
ORDER BY bdo.created_at ASC
`
type ListBatchDocumentOutcomesRow struct {
ID uuid.UUID `db:"id"`
BatchID uuid.UUID `db:"batch_id"`
Filename string `db:"filename"`
Outcome BatchOutcomeStatus `db:"outcome"`
ErrorDetail *string `db:"error_detail"`
DocumentID *uuid.UUID `db:"document_id"`
CreatedAt pgtype.Timestamp `db:"created_at"`
UpdatedAt pgtype.Timestamp `db:"updated_at"`
CleanFail NullCleanfailtype `db:"clean_fail"`
}
// Returns all outcome rows for a batch, with clean failure detail
// joined from currentCleanEntries when applicable.
//
// SELECT
// bdo.id,
// bdo.batch_id,
// bdo.filename,
// bdo.outcome,
// bdo.error_detail,
// bdo.document_id,
// bdo.created_at,
// bdo.updated_at,
// cce.fail as clean_fail
// FROM batch_document_outcomes bdo
// LEFT JOIN currentCleanEntries cce ON cce.documentId = bdo.document_id
// WHERE bdo.batch_id = $1
// ORDER BY bdo.created_at ASC
func (q *Queries) ListBatchDocumentOutcomes(ctx context.Context, batchID uuid.UUID) ([]*ListBatchDocumentOutcomesRow, error) {
rows, err := q.db.Query(ctx, listBatchDocumentOutcomes, batchID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*ListBatchDocumentOutcomesRow{}
for rows.Next() {
var i ListBatchDocumentOutcomesRow
if err := rows.Scan(
&i.ID,
&i.BatchID,
&i.Filename,
&i.Outcome,
&i.ErrorDetail,
&i.DocumentID,
&i.CreatedAt,
&i.UpdatedAt,
&i.CleanFail,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listBatchFolderCandidates = `-- name: ListBatchFolderCandidates :many
SELECT batch_id, folder_id, path, existed_before, created_at
FROM batch_folder_candidates
WHERE batch_id = $1
ORDER BY path
`
// ListBatchFolderCandidates
//
// SELECT batch_id, folder_id, path, existed_before, created_at
// FROM batch_folder_candidates
// WHERE batch_id = $1
// ORDER BY path
func (q *Queries) ListBatchFolderCandidates(ctx context.Context, batchID uuid.UUID) ([]*BatchFolderCandidate, error) {
rows, err := q.db.Query(ctx, listBatchFolderCandidates, batchID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*BatchFolderCandidate{}
for rows.Next() {
var i BatchFolderCandidate
if err := rows.Scan(
&i.BatchID,
&i.FolderID,
&i.Path,
&i.ExistedBefore,
&i.CreatedAt,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
2025-08-04 10:54:22 -07:00
const listBatchUploads = `-- name: ListBatchUploads :many
SELECT id, client_id, original_filename, total_documents, processed_documents,
failed_documents, invalid_type_documents, status, progress_percent,
created_at, completed_at
FROM batch_uploads
WHERE client_id = $1
ORDER BY created_at DESC
LIMIT $2 OFFSET $3
`
type ListBatchUploadsParams struct {
ClientID string `db:"client_id"`
Limit int64 `db:"limit"`
Offset int64 `db:"offset"`
}
type ListBatchUploadsRow struct {
ID uuid.UUID `db:"id"`
ClientID string `db:"client_id"`
OriginalFilename string `db:"original_filename"`
TotalDocuments int32 `db:"total_documents"`
ProcessedDocuments int32 `db:"processed_documents"`
FailedDocuments int32 `db:"failed_documents"`
InvalidTypeDocuments int32 `db:"invalid_type_documents"`
Status BatchStatus `db:"status"`
ProgressPercent int32 `db:"progress_percent"`
CreatedAt pgtype.Timestamp `db:"created_at"`
CompletedAt pgtype.Timestamp `db:"completed_at"`
}
// ListBatchUploads
//
// SELECT id, client_id, original_filename, total_documents, processed_documents,
// failed_documents, invalid_type_documents, status, progress_percent,
// created_at, completed_at
// FROM batch_uploads
// WHERE client_id = $1
// ORDER BY created_at DESC
// LIMIT $2 OFFSET $3
func (q *Queries) ListBatchUploads(ctx context.Context, arg *ListBatchUploadsParams) ([]*ListBatchUploadsRow, error) {
rows, err := q.db.Query(ctx, listBatchUploads, arg.ClientID, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
defer rows.Close()
items := []*ListBatchUploadsRow{}
for rows.Next() {
var i ListBatchUploadsRow
if err := rows.Scan(
&i.ID,
&i.ClientID,
&i.OriginalFilename,
&i.TotalDocuments,
&i.ProcessedDocuments,
&i.FailedDocuments,
&i.InvalidTypeDocuments,
&i.Status,
&i.ProgressPercent,
&i.CreatedAt,
&i.CompletedAt,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listFolderCleanupReadyBatchIDs = `-- name: ListFolderCleanupReadyBatchIDs :many
SELECT bu.id
FROM batch_uploads bu
WHERE bu.folder_cleanup_completed_at IS NULL
AND bu.status IN ('completed', 'failed', 'cancelled')
AND EXISTS (
SELECT 1
FROM batch_folder_candidates bfc
WHERE bfc.batch_id = bu.id
)
AND (
(
bu.total_documents > 0
AND
(SELECT COUNT(*) FROM batch_document_outcomes bdo WHERE bdo.batch_id = bu.id) = bu.total_documents
AND NOT EXISTS (
SELECT 1
FROM batch_document_outcomes bdo
WHERE bdo.batch_id = bu.id
AND bdo.outcome IN ('submitted', 'init_complete', 'sync_complete')
)
)
OR (
bu.status IN ('failed', 'cancelled')
AND (SELECT COUNT(*) FROM batch_document_outcomes bdo WHERE bdo.batch_id = bu.id) > 0
AND bu.completed_at IS NOT NULL
AND bu.completed_at <= NOW() - ($1::int * INTERVAL '1 second')
)
)
ORDER BY bu.created_at ASC
LIMIT $2
`
type ListFolderCleanupReadyBatchIDsParams struct {
StaleAfterSeconds int32 `db:"stale_after_seconds"`
LimitCount int64 `db:"limit_count"`
}
// @sqlc-vet-disable
//
// SELECT bu.id
// FROM batch_uploads bu
// WHERE bu.folder_cleanup_completed_at IS NULL
// AND bu.status IN ('completed', 'failed', 'cancelled')
// AND EXISTS (
// SELECT 1
// FROM batch_folder_candidates bfc
// WHERE bfc.batch_id = bu.id
// )
// AND (
// (
// bu.total_documents > 0
// AND
// (SELECT COUNT(*) FROM batch_document_outcomes bdo WHERE bdo.batch_id = bu.id) = bu.total_documents
// AND NOT EXISTS (
// SELECT 1
// FROM batch_document_outcomes bdo
// WHERE bdo.batch_id = bu.id
// AND bdo.outcome IN ('submitted', 'init_complete', 'sync_complete')
// )
// )
// OR (
// bu.status IN ('failed', 'cancelled')
// AND (SELECT COUNT(*) FROM batch_document_outcomes bdo WHERE bdo.batch_id = bu.id) > 0
// AND bu.completed_at IS NOT NULL
// AND bu.completed_at <= NOW() - ($1::int * INTERVAL '1 second')
// )
// )
// ORDER BY bu.created_at ASC
// LIMIT $2
func (q *Queries) ListFolderCleanupReadyBatchIDs(ctx context.Context, arg *ListFolderCleanupReadyBatchIDsParams) ([]uuid.UUID, error) {
rows, err := q.db.Query(ctx, listFolderCleanupReadyBatchIDs, arg.StaleAfterSeconds, arg.LimitCount)
if err != nil {
return nil, err
}
defer rows.Close()
items := []uuid.UUID{}
for rows.Next() {
var id uuid.UUID
if err := rows.Scan(&id); err != nil {
return nil, err
}
items = append(items, id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const lockBatchUploadForFolderCleanup = `-- name: LockBatchUploadForFolderCleanup :one
SELECT id, status, total_documents, created_at, completed_at, folder_cleanup_completed_at
FROM batch_uploads
WHERE id = $1
FOR UPDATE
`
type LockBatchUploadForFolderCleanupRow struct {
ID uuid.UUID `db:"id"`
Status BatchStatus `db:"status"`
TotalDocuments int32 `db:"total_documents"`
CreatedAt pgtype.Timestamp `db:"created_at"`
CompletedAt pgtype.Timestamp `db:"completed_at"`
FolderCleanupCompletedAt pgtype.Timestamp `db:"folder_cleanup_completed_at"`
}
// LockBatchUploadForFolderCleanup
//
// SELECT id, status, total_documents, created_at, completed_at, folder_cleanup_completed_at
// FROM batch_uploads
// WHERE id = $1
// FOR UPDATE
func (q *Queries) LockBatchUploadForFolderCleanup(ctx context.Context, batchID uuid.UUID) (*LockBatchUploadForFolderCleanupRow, error) {
row := q.db.QueryRow(ctx, lockBatchUploadForFolderCleanup, batchID)
var i LockBatchUploadForFolderCleanupRow
err := row.Scan(
&i.ID,
&i.Status,
&i.TotalDocuments,
&i.CreatedAt,
&i.CompletedAt,
&i.FolderCleanupCompletedAt,
)
return &i, err
}
const markBatchFolderCleanupCompleted = `-- name: MarkBatchFolderCleanupCompleted :exec
UPDATE batch_uploads
SET folder_cleanup_completed_at = NOW()
WHERE id = $1
AND folder_cleanup_completed_at IS NULL
`
// MarkBatchFolderCleanupCompleted
//
// UPDATE batch_uploads
// SET folder_cleanup_completed_at = NOW()
// WHERE id = $1
// AND folder_cleanup_completed_at IS NULL
func (q *Queries) MarkBatchFolderCleanupCompleted(ctx context.Context, batchID uuid.UUID) error {
_, err := q.db.Exec(ctx, markBatchFolderCleanupCompleted, batchID)
return err
}
const recordBatchFolderCandidate = `-- name: RecordBatchFolderCandidate :exec
INSERT INTO batch_folder_candidates (batch_id, folder_id, path, existed_before)
VALUES ($1, $2, $3, $4)
ON CONFLICT (batch_id, folder_id) DO UPDATE
SET path = EXCLUDED.path,
existed_before = batch_folder_candidates.existed_before AND EXCLUDED.existed_before
`
type RecordBatchFolderCandidateParams struct {
BatchID uuid.UUID `db:"batch_id"`
FolderID uuid.UUID `db:"folder_id"`
Path string `db:"path"`
ExistedBefore bool `db:"existed_before"`
}
// Records a non-root folder touched by a batch upload. Once a batch observes a
// folder as newly created, retries must preserve that fact.
//
// INSERT INTO batch_folder_candidates (batch_id, folder_id, path, existed_before)
// VALUES ($1, $2, $3, $4)
// ON CONFLICT (batch_id, folder_id) DO UPDATE
// SET path = EXCLUDED.path,
// existed_before = batch_folder_candidates.existed_before AND EXCLUDED.existed_before
func (q *Queries) RecordBatchFolderCandidate(ctx context.Context, arg *RecordBatchFolderCandidateParams) error {
_, err := q.db.Exec(ctx, recordBatchFolderCandidate,
arg.BatchID,
arg.FolderID,
arg.Path,
arg.ExistedBefore,
)
return err
}
const resolveBatchDocumentOutcome = `-- name: ResolveBatchDocumentOutcome :exec
UPDATE batch_document_outcomes
SET document_id = $3,
outcome = $4::batch_outcome_status,
error_detail = $5,
updated_at = NOW()
WHERE batch_id = $1 AND filename = $2 AND document_id IS NULL
`
type ResolveBatchDocumentOutcomeParams struct {
BatchID uuid.UUID `db:"batch_id"`
Filename string `db:"filename"`
DocumentID *uuid.UUID `db:"document_id"`
Column4 BatchOutcomeStatus `db:"column_4"`
ErrorDetail *string `db:"error_detail"`
}
// Called by docInitRunner to set the document_id on a previously-submitted
// outcome row and update the outcome to an init-stage result.
// Finds the row by batch_id + filename since document_id is NULL at this point.
//
// UPDATE batch_document_outcomes
// SET document_id = $3,
// outcome = $4::batch_outcome_status,
// error_detail = $5,
// updated_at = NOW()
// WHERE batch_id = $1 AND filename = $2 AND document_id IS NULL
func (q *Queries) ResolveBatchDocumentOutcome(ctx context.Context, arg *ResolveBatchDocumentOutcomeParams) error {
_, err := q.db.Exec(ctx, resolveBatchDocumentOutcome,
arg.BatchID,
arg.Filename,
arg.DocumentID,
arg.Column4,
arg.ErrorDetail,
)
return err
}
const setBatchCompletedAt = `-- name: SetBatchCompletedAt :exec
UPDATE batch_uploads
SET completed_at = $1
WHERE id = $2
`
type SetBatchCompletedAtParams struct {
CompletedAt pgtype.Timestamp `db:"completed_at"`
ID uuid.UUID `db:"id"`
}
// SetBatchCompletedAt
//
// UPDATE batch_uploads
// SET completed_at = $1
// WHERE id = $2
func (q *Queries) SetBatchCompletedAt(ctx context.Context, arg *SetBatchCompletedAtParams) error {
_, err := q.db.Exec(ctx, setBatchCompletedAt, arg.CompletedAt, arg.ID)
return err
}
const setBatchTotalDocuments = `-- name: SetBatchTotalDocuments :exec
UPDATE batch_uploads SET total_documents = $2 WHERE id = $1
`
type SetBatchTotalDocumentsParams struct {
ID uuid.UUID `db:"id"`
TotalDocuments int32 `db:"total_documents"`
}
// SetBatchTotalDocuments
//
// UPDATE batch_uploads SET total_documents = $2 WHERE id = $1
func (q *Queries) SetBatchTotalDocuments(ctx context.Context, arg *SetBatchTotalDocumentsParams) error {
_, err := q.db.Exec(ctx, setBatchTotalDocuments, arg.ID, arg.TotalDocuments)
return err
}
const updateBatchDocumentOutcomeByDocumentID = `-- name: UpdateBatchDocumentOutcomeByDocumentID :many
UPDATE batch_document_outcomes
SET outcome = $2::batch_outcome_status,
error_detail = $3,
updated_at = NOW()
WHERE document_id = $1
AND outcome IN ('submitted', 'init_complete', 'sync_complete')
RETURNING batch_id
`
type UpdateBatchDocumentOutcomeByDocumentIDParams struct {
DocumentID *uuid.UUID `db:"document_id"`
Column2 BatchOutcomeStatus `db:"column_2"`
ErrorDetail *string `db:"error_detail"`
}
// Updates the outcome for a document progressing through the pipeline.
// Only updates rows in non-terminal pipeline states to prevent overwriting
// terminal outcomes (e.g. a 'duplicate' row from a different batch that
// shares the same document_id).
//
// UPDATE batch_document_outcomes
// SET outcome = $2::batch_outcome_status,
// error_detail = $3,
// updated_at = NOW()
// WHERE document_id = $1
// AND outcome IN ('submitted', 'init_complete', 'sync_complete')
// RETURNING batch_id
func (q *Queries) UpdateBatchDocumentOutcomeByDocumentID(ctx context.Context, arg *UpdateBatchDocumentOutcomeByDocumentIDParams) ([]uuid.UUID, error) {
rows, err := q.db.Query(ctx, updateBatchDocumentOutcomeByDocumentID, arg.DocumentID, arg.Column2, arg.ErrorDetail)
if err != nil {
return nil, err
}
defer rows.Close()
items := []uuid.UUID{}
for rows.Next() {
var batch_id uuid.UUID
if err := rows.Scan(&batch_id); err != nil {
return nil, err
}
items = append(items, batch_id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
2025-08-04 10:54:22 -07:00
const updateBatchProgress = `-- name: UpdateBatchProgress :exec
UPDATE batch_uploads
SET processed_documents = $2,
failed_documents = $3,
2025-08-04 10:54:22 -07:00
invalid_type_documents = $4,
progress_percent = $5
WHERE id = $1
`
type UpdateBatchProgressParams struct {
ID uuid.UUID `db:"id"`
ProcessedDocuments int32 `db:"processed_documents"`
FailedDocuments int32 `db:"failed_documents"`
InvalidTypeDocuments int32 `db:"invalid_type_documents"`
ProgressPercent int32 `db:"progress_percent"`
}
// UpdateBatchProgress
//
// UPDATE batch_uploads
// SET processed_documents = $2,
// failed_documents = $3,
// invalid_type_documents = $4,
// progress_percent = $5
// WHERE id = $1
func (q *Queries) UpdateBatchProgress(ctx context.Context, arg *UpdateBatchProgressParams) error {
_, err := q.db.Exec(ctx, updateBatchProgress,
arg.ID,
arg.ProcessedDocuments,
arg.FailedDocuments,
arg.InvalidTypeDocuments,
arg.ProgressPercent,
)
return err
}
const updateBatchStatus = `-- name: UpdateBatchStatus :exec
UPDATE batch_uploads
SET status = $2::batch_status,
completed_at = CASE WHEN $2::batch_status IN ('completed', 'failed', 'cancelled') THEN NOW() ELSE NULL END
WHERE id = $1
`
type UpdateBatchStatusParams struct {
ID uuid.UUID `db:"id"`
Column2 BatchStatus `db:"column_2"`
}
// UpdateBatchStatus
//
// UPDATE batch_uploads
// SET status = $2::batch_status,
// completed_at = CASE WHEN $2::batch_status IN ('completed', 'failed', 'cancelled') THEN NOW() ELSE NULL END
// WHERE id = $1
func (q *Queries) UpdateBatchStatus(ctx context.Context, arg *UpdateBatchStatusParams) error {
_, err := q.db.Exec(ctx, updateBatchStatus, arg.ID, arg.Column2)
return err
}