This commit is contained in:
2025-12-12 17:19:24 +01:00
parent 6006a912ec
commit 76c9eb38f6

View File

@@ -3,7 +3,6 @@ import {getExtension} from '../../shared/extensions';
import * as animeService from '../anime/anime.service'; import * as animeService from '../anime/anime.service';
import * as booksService from '../books/books.service'; import * as booksService from '../books/books.service';
import * as aniListService from '../anilist/anilist.service'; import * as aniListService from '../anilist/anilist.service';
import {getAnimeById} from "../anime/anime.service";
interface ListEntryData { interface ListEntryData {
entry_type: any; entry_type: any;
@@ -41,35 +40,30 @@ export async function upsertListEntry(entry: any) {
try { try {
prev = await getSingleListEntry(user_id, entry_id, source, entry_type); prev = await getSingleListEntry(user_id, entry_id, source, entry_type);
} catch { } catch {
prev = null; // ✅ si AniList da 404 u otro error → se trata como nuevo prev = null;
} }
const isNew = !prev; const isNew = !prev;
// ✅ NO permitir retroceso SOLO si ya existía
if (!isNew && prev?.progress != null && progress < prev.progress) { if (!isNew && prev?.progress != null && progress < prev.progress) {
return { changes: 0, ignored: true }; return { changes: 0, ignored: true };
} }
const today = new Date().toISOString().slice(0, 10); const today = new Date().toISOString().slice(0, 10);
// ✅ NUNCA borrar start_date si ya existía
if (prev?.start_date && !entry.start_date) { if (prev?.start_date && !entry.start_date) {
entry.start_date = prev.start_date; entry.start_date = prev.start_date;
} }
// ✅ START DATE solo al comenzar de verdad
if (!prev?.start_date && progress === 1) { if (!prev?.start_date && progress === 1) {
entry.start_date = today; entry.start_date = today;
} }
// ✅ TOTAL solo si existe
const total = const total =
prev?.total_episodes ?? prev?.total_episodes ??
prev?.total_chapters ?? prev?.total_chapters ??
null; null;
// ✅ COMPLETED automático
if (total && progress >= total) { if (total && progress >= total) {
entry.status = 'COMPLETED'; entry.status = 'COMPLETED';
entry.end_date = today; entry.end_date = today;
@@ -92,7 +86,6 @@ export async function upsertListEntry(entry: any) {
is_private: entry.is_private is_private: entry.is_private
}); });
return { changes: 0, external: true, anilistResult: result }; return { changes: 0, external: true, anilistResult: result };
} catch (err) { } catch (err) {
console.error("Error actualizando AniList:", err); console.error("Error actualizando AniList:", err);
@@ -139,7 +132,6 @@ export async function upsertListEntry(entry: any) {
entry.is_private ?? 0 entry.is_private ?? 0
]; ];
try { try {
const result = await run(sql, params, USER_DB); const result = await run(sql, params, USER_DB);
return { changes: result.changes, lastID: result.lastID, external: false }; return { changes: result.changes, lastID: result.lastID, external: false };
@@ -309,7 +301,6 @@ export async function getSingleListEntry(
entryType: string entryType: string
): Promise<any> { ): Promise<any> {
// ✅ 1. BUSCAR PRIMERO EN TU BASE DE DATOS
const localSql = ` const localSql = `
SELECT * FROM ListEntry SELECT * FROM ListEntry
WHERE user_id = ? AND entry_id = ? AND source = ? AND entry_type = ?; WHERE user_id = ? AND entry_id = ? AND source = ? AND entry_type = ?;
@@ -364,6 +355,7 @@ export async function getSingleListEntry(
const integration = await queryOne(sql, [userId], USER_DB) as any; const integration = await queryOne(sql, [userId], USER_DB) as any;
if (!integration?.access_token) return null; if (!integration?.access_token) return null;
if (entryType === 'NOVEL') {entryType = 'MANGA'}
const aniEntry = await aniListService.getSingleAniListEntry( const aniEntry = await aniListService.getSingleAniListEntry(
integration.access_token, integration.access_token,
@@ -371,7 +363,6 @@ export async function getSingleListEntry(
entryType as any entryType as any
); );
if (!aniEntry) return null; if (!aniEntry) return null;
const contentDetails: any = const contentDetails: any =
@@ -475,13 +466,12 @@ export async function getUserListByFilter(
let finalList: any[] = []; let finalList: any[] = [];
// ✅ FILTRADO LOCAL (MANGA + NOVEL)
const filteredLocal = dbList.filter((entry) => { const filteredLocal = dbList.filter((entry) => {
if (mappedStatus && entry.status !== mappedStatus) return false; if (mappedStatus && entry.status !== mappedStatus) return false;
if (entryType) { if (entryType) {
if (entryType === 'MANGA') { if (entryType === 'MANGA') {
// ✅ AHORA ACEPTA MANGA Y NOVEL
if (!['MANGA', 'NOVEL'].includes(entry.entry_type)) return false; if (!['MANGA', 'NOVEL'].includes(entry.entry_type)) return false;
} else { } else {
if (entry.entry_type !== entryType) return false; if (entry.entry_type !== entryType) return false;
@@ -491,7 +481,6 @@ export async function getUserListByFilter(
return true; return true;
}); });
// ✅ FILTRADO ANILIST (MANGA + NOVEL TAMBIÉN)
let filteredAniList: any[] = []; let filteredAniList: any[] = [];
if (connected) { if (connected) {
@@ -516,7 +505,6 @@ export async function getUserListByFilter(
const enrichedListPromises = finalList.map(async (entry) => { const enrichedListPromises = finalList.map(async (entry) => {
// ✅ AniList directo
if (entry.source === 'anilist') { if (entry.source === 'anilist') {
let finalTitle = entry.title; let finalTitle = entry.title;
@@ -535,7 +523,6 @@ export async function getUserListByFilter(
}; };
} }
// ✅ LOCAL → FETCH EXTERNO
let contentDetails: any | null = null; let contentDetails: any | null = null;
const id = entry.entry_id; const id = entry.entry_id;
const type = entry.entry_type; const type = entry.entry_type;