- Add POST /api/v1/libs/:id/versions/discover endpoint that calls versionService.discoverTags() for local repos and returns empty tags gracefully for GitHub repos or git failures - Enhance POST /api/v1/libs/:id/index to also enqueue jobs for all registered versions on default-branch re-index, returning versionJobs in the response - Replace read-only Indexed Versions section with interactive Versions panel in the repo detail page: per-version state badges, Index/Remove buttons, inline Add version form, and Discover tags flow for local repos - Add unit tests for both new/changed backend endpoints (8 new test cases) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
68 lines
2.4 KiB
TypeScript
68 lines
2.4 KiB
TypeScript
/**
|
|
* POST /api/v1/libs/:id/index — trigger an indexing job for a repository.
|
|
*
|
|
* Also enqueues jobs for all registered versions so that re-indexing a repo
|
|
* automatically covers its secondary versions.
|
|
*/
|
|
import { json } from '@sveltejs/kit';
|
|
import type { RequestHandler } from './$types';
|
|
import { getClient } from '$lib/server/db/client';
|
|
import { IndexingJobMapper } from '$lib/server/mappers/indexing-job.mapper.js';
|
|
import { RepositoryService } from '$lib/server/services/repository.service';
|
|
import { VersionService } from '$lib/server/services/version.service';
|
|
import { getQueue } from '$lib/server/pipeline/startup';
|
|
import { handleServiceError, NotFoundError } from '$lib/server/utils/validation';
|
|
|
|
export const POST: RequestHandler = async ({ params, request }) => {
|
|
try {
|
|
const db = getClient();
|
|
const service = new RepositoryService(db);
|
|
const versionService = new VersionService(db);
|
|
const id = decodeURIComponent(params.id);
|
|
|
|
const repo = service.get(id);
|
|
if (!repo) throw new NotFoundError(`Repository ${id} not found`);
|
|
|
|
let versionId: string | undefined;
|
|
try {
|
|
const body = await request.json();
|
|
versionId = body.version ?? undefined;
|
|
} catch {
|
|
// body is optional
|
|
}
|
|
|
|
// Use the queue so processNext() is triggered immediately.
|
|
// Falls back to direct DB insert if the queue isn't initialised yet.
|
|
const queue = getQueue();
|
|
const job = queue ? queue.enqueue(id, versionId) : service.createIndexingJob(id, versionId);
|
|
|
|
// Also enqueue jobs for all registered versions (dedup in queue makes this safe).
|
|
// Only when this is a default-branch re-index (no explicit versionId requested).
|
|
let versionJobs: ReturnType<typeof IndexingJobMapper.toDto>[] = [];
|
|
if (!versionId) {
|
|
const versions = versionService.list(id);
|
|
versionJobs = versions.map((version) => {
|
|
const vJob = queue
|
|
? queue.enqueue(id, version.id)
|
|
: service.createIndexingJob(id, version.id);
|
|
return IndexingJobMapper.toDto(vJob);
|
|
});
|
|
}
|
|
|
|
return json({ job: IndexingJobMapper.toDto(job), versionJobs }, { status: 202 });
|
|
} catch (err) {
|
|
return handleServiceError(err);
|
|
}
|
|
};
|
|
|
|
export const OPTIONS: RequestHandler = () => {
|
|
return new Response(null, {
|
|
status: 204,
|
|
headers: {
|
|
'Access-Control-Allow-Origin': '*',
|
|
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
|
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
|
|
}
|
|
});
|
|
};
|