This commit is contained in:
Ryan Shpeherd
2026-09-15 12:39:47 -04:00
parent 639c29c2c4
commit 1611485a66
38 changed files with 313 additions and 4728 deletions
+76 -17
View File
@@ -83,12 +83,39 @@ post '/api/v1/video' => sub {
get '/api/v1/tasks' => sub {
my $status = query_parameters->get("status") || 'PENDING';
my $sth = database->prepare("SELECT id, video_id, status FROM tasks WHERE status=? ORDER BY id");
$sth->execute($status);
my $type = query_parameters->get("type");
unless ($type) {
send_error("Missing 'type' query parameter", 400);
}
# Optional pagination
my $page = query_parameters->get("page") || 1;
my $per_page = query_parameters->get("per_page") || 20;
my $offset = ($page - 1) * $per_page;
my $sth = database->prepare(
"SELECT id, video_id, task_type AS type, status FROM tasks WHERE status=? AND task_type=? ORDER BY id LIMIT ? OFFSET ?"
);
$sth->execute($status, $type, $per_page, $offset);
my $ref = $sth->fetchall_hashref('id');
$sth->finish();
return $ref;
# Total count for pagination metadata
my $count_sth = database->prepare(
"SELECT COUNT(*) AS cnt FROM tasks WHERE status=? AND task_type=?"
);
$count_sth->execute($status, $type);
my $cnt = ($count_sth->fetchrow_hashref() || { cnt => 0 })->{cnt};
$count_sth->finish();
return {
tasks => $ref,
page => $page,
per_page => $per_page,
total => $cnt,
total_pages => max(1, int(($cnt + $per_page - 1) / $per_page)),
};
};
get '/api/v1/task/:task' => sub {
@@ -129,7 +156,7 @@ get '/api/v1/nexttask/:type' => sub {
};
post '/api/v1/task/:task/complete' => sub {
my $task = route_parameters->get("task");
my $task_id = route_parameters->get("task");
# Accept both JSON body and form-encoded data for assign_key/results.
my ($assign_key, $results);
@@ -143,24 +170,31 @@ post '/api/v1/task/:task/complete' => sub {
$results = body_parameters->get("results");
}
unless ($assign_key) {
send_error("Missing assign_key", 400);
}
# Optional worker verification: if assign_key is provided, require IN_PROGRESS + matching key.
# When omitted (e.g., UI-driven workflows), skip worker checks and just complete the task.
if ($assign_key) {
my $sth = database->prepare("SELECT * FROM tasks WHERE id=? AND assign_key=? AND status='IN_PROGRESS'");
$sth->execute($task_id, $assign_key);
my $ref = $sth->fetchrow_hashref();
$sth->finish();
# Verify the task is assigned to the worker
my $sth = database->prepare("SELECT * FROM tasks WHERE id=? AND assign_key=? AND status='IN_PROGRESS'");
$sth->execute($task, $assign_key);
my $ref = $sth->fetchrow_hashref();
$sth->finish();
unless(ref $ref) {
send_error("Task not assigned to this worker or not in progress", 403);
unless(ref $ref) {
send_error("Task not assigned to this worker or not in progress", 403);
}
} else {
# No assign_key provided — caller may be an unauthenticated UI, etc.
my $sth = database->prepare("SELECT id FROM tasks WHERE id=?");
$sth->execute($task_id);
unless ($sth->fetchrow_hashref()) {
send_error("Task not found", 404);
}
$sth->finish();
}
# Update the task as completed (store results as JSON text for MariaDB)
my $results_json = defined $results ? encode_json($results) : 'null';
my $update_sth = database->prepare("UPDATE tasks SET status='COMPLETED', results=?, updated_at=NOW() WHERE id=?");
$update_sth->execute($results_json, $task);
$update_sth->execute($results_json, $task_id);
if($update_sth->rows == 0) {
send_error("Failed to complete task", 500);
}
@@ -183,4 +217,29 @@ post '/api/v1/task' => sub {
return { id => $task_id };
};
start();
post '/api/v1/task/:task/unassign' => sub {
my $task_id = route_parameters->get("task");
my $update_sth = database->prepare(
"UPDATE tasks SET status='PENDING', assign_key=NULL, assigned_at=NULL, updated_at=NOW() WHERE id=?"
);
$update_sth->execute($task_id);
if ($update_sth->rows == 0) {
send_error("Task not found or already in PENDING state", 404);
}
return { message => 'Task unassigned' };
};
start();
sub max {
return (sort { $b <=> $a } @_)[0];
}
sub min {
return (sort { $a <=> $b } @_)[0];
}
+1 -1
View File
@@ -18,7 +18,7 @@ plugins:
dbi_params:
RaiseError: 1
AutoCommit: 1
on_connect_do: ["SET NAMES 'utf8'", "SET CHARACTER SET 'utf8'" ]
on_connect_do: ["SET NAMES 'utf8mb4'", "SET CHARACTER SET 'utf8mb4'" ]
log_queries: 1
server: