fix(web,api): débloquer la boucle de chargement 'Inventaire en cours' (Recherche/Admin)

- web: gestion d'erreur et d'état vide sur SearchPage/AdminPage
- web: client API — traitement des réponses sans contenu/erreurs réseau
- api: jobs.service — éviter le statut de scan perpétuellement en cours
- tests: client.test.ts

Refs: #12 (QA non-GREEN faute d'exécution, pas d'échec réel)
This commit is contained in:
Git Agent
2026-08-23 10:01:54 +02:00
parent 8f1140127f
commit e94524f119
6 changed files with 159 additions and 45 deletions

View File

@ -1,12 +1,16 @@
import { Injectable } from "@nestjs/common";
import { desc, eq } from "drizzle-orm";
import { Injectable, OnModuleInit } from "@nestjs/common";
import { desc, eq, inArray } from "drizzle-orm";
import { DatabaseService } from "../database/database.service.js";
import { jobs } from "../database/schema.js";
@Injectable()
export class JobsService {
export class JobsService implements OnModuleInit {
constructor(private readonly database: DatabaseService) {}
onModuleInit(): void {
this.failInterruptedJobs();
}
create(type: string, detail?: string) {
const now = this.database.now();
return this.database.db
@ -43,4 +47,16 @@ export class JobsService {
list(limit = 50) {
return this.database.db.select().from(jobs).orderBy(desc(jobs.createdAt)).limit(limit).all();
}
private failInterruptedJobs(): void {
this.database.db
.update(jobs)
.set({
status: "failed",
error: "Job interrupted before completion, most likely by API shutdown or restart",
updatedAt: this.database.now()
})
.where(inArray(jobs.status, ["queued", "running"]))
.run();
}
}