Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ COOL_OFF_PERIOD=10
SCHEMA_VERSION=beta
BACKUP_KEEP_DAYS=7

# Spectra Parsing Configuration
NMRKIT_API_URL=https://nmrkit.nmrxiv.org/latest/spectra/parse/url
BIOSCHEMA_API_URL=https://nmrxiv.org/api/v1/schemas/bioschemas
SPECTRA_STORAGE_DISK=local
SPECTRA_STORAGE_PATH=spectra_parse
SPECTRA_JOB_TRIES=3
SPECTRA_JOB_TIMEOUT=600
SPECTRA_RETRY_COUNT=3
SPECTRA_DOWNLOAD_TIMEOUT=300
SPECTRA_API_TIMEOUT=300

# ============================================================================
# Logging Configuration
# ============================================================================
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/public/vendor/swagger-api
/storage/*.key
/storage/pail
/storage/app/spectra_parse
/vendor
.env
.env.production
Expand Down
182 changes: 0 additions & 182 deletions app/Console/Commands/ExtractSpectra.php

This file was deleted.

126 changes: 126 additions & 0 deletions app/Console/Commands/QueueMetadataExtractionBagitGenerationJobs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?php

namespace App\Console\Commands;

use App\Jobs\ProcessMetadataExtractionBagitGenerationJob;
use App\Models\Study;
use Illuminate\Console\Command;

class QueueMetadataExtractionBagitGenerationJobs extends Command
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The console command is missing comprehensive test coverage. Following the codebase convention where similar commands like VerifyFileIntegrityCommand have corresponding tests, this command should have tests covering the various options (--limit, --ids, --fresh, --retry-failed) and ensure jobs are dispatched correctly.

Copilot uses AI. Check for mistakes.
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'nmrxiv:queue-metadata-extraction
{--limit= : Limit number of studies to process}
{--ids= : Comma-separated study IDs to process}
{--fresh : Clear existing status and start fresh}
{--retry-failed : Retry failed jobs}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Queue metadata extraction and BagIt generation jobs for eligible studies';

/**
* Execute the console command.
*/
public function handle(): int
{
if ($this->option('fresh')) {
if ($this->confirm('This will reset all BagIt status for all studies. Continue?', false)) {
Study::query()->update([
'metadata_bagit_generation_status' => null,
'metadata_bagit_generation_logs' => null,
]);
$this->info('✓ Cleared all existing BagIt status data');
} else {
return self::SUCCESS;
}
}

$query = Study::query()
->where('has_nmrium', true)
->where('is_public', true)
->whereNotNull('download_url');

// Filter by specific study IDs if provided
if ($ids = $this->option('ids')) {
$studyIds = array_map('trim', explode(',', $ids));
$query->whereIn('id', $studyIds);
$this->info('Processing '.count($studyIds).' specific study IDs...');
}

if ($this->option('retry-failed')) {
// Get failed study IDs from database
$failedStudies = Study::where('metadata_bagit_generation_status', 'failed')->get();

if ($failedStudies->isEmpty()) {
$this->warn('No failed jobs to retry.');

return self::SUCCESS;
}

$query->whereIn('id', $failedStudies->pluck('id'));
$this->info('Retrying '.$failedStudies->count().' failed jobs...');

// Reset status to pending
Study::where('metadata_bagit_generation_status', 'failed')
->whereIn('id', $failedStudies->pluck('id'))
->update(['metadata_bagit_generation_status' => 'pending']);
Comment on lines +70 to +74
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using the --retry-failed option, the status is reset to 'pending' before dispatching jobs. However, if job dispatching fails for any reason after the status update, those studies will be marked as 'pending' but won't actually have jobs in the queue. Consider updating the status to 'pending' only after successful job dispatch, or use a transaction to ensure atomicity.

Suggested change
// Reset status to pending
Study::where('metadata_bagit_generation_status', 'failed')
->whereIn('id', $failedStudies->pluck('id'))
->update(['metadata_bagit_generation_status' => 'pending']);

Copilot uses AI. Check for mistakes.
} elseif (! $this->option('ids')) {
// Only exclude already processed studies when not targeting specific IDs
$query->where(function ($q) {
$q->whereNull('metadata_bagit_generation_status')
->orWhereIn('metadata_bagit_generation_status', ['failed']);
});
}

if ($limit = $this->option('limit')) {
$query->limit((int) $limit);
}

$studies = $query->get();

if ($studies->isEmpty()) {
$this->warn('No eligible studies found to process.');

return self::SUCCESS;
}

$this->info("Found {$studies->count()} studies to process");

$bar = $this->output->createProgressBar($studies->count());
$bar->setFormat('verbose');

$jobsDispatched = 0;

foreach ($studies as $study) {
// Mark as pending with queued timestamp
$study->update([
'metadata_bagit_generation_status' => 'pending',
'metadata_bagit_generation_logs' => [
'queued_at' => now()->toIso8601String(),
'study_identifier' => str_replace('NMRXIV:', '', $study->identifier),
],
]);

// Dispatch job to queue
ProcessMetadataExtractionBagitGenerationJob::dispatch($study->id);

$jobsDispatched++;
$bar->advance();
}

$bar->finish();
$this->newLine(2);

$this->info("✓ Successfully dispatched {$jobsDispatched} jobs to the queue");

return self::SUCCESS;
}
}
Loading
Loading