refactor(tripService): reuse service functions in getTripSummary
Replace inline DB queries in getTripSummary with calls to existing service functions: listDays, listAccommodations, listBudgetItems, listPackingItems, listReservations, listCollabNotes, getTripOwner, and listMembers. Budget and packing stats are now derived from the service results instead of separate COUNT/SUM queries.
This commit is contained in:
@@ -2,6 +2,11 @@ import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { db, canAccessTrip, isOwner } from '../db/database';
|
||||
import { Trip, User } from '../types';
|
||||
import { listDays, listAccommodations } from './dayService';
|
||||
import { listBudgetItems } from './budgetService';
|
||||
import { listItems as listPackingItems } from './packingService';
|
||||
import { listReservations } from './reservationService';
|
||||
import { listNotes as listCollabNotes } from './collabService';
|
||||
|
||||
export const MS_PER_DAY = 86400000;
|
||||
export const MAX_TRIP_DAYS = 365;
|
||||
@@ -412,92 +417,40 @@ export function getTripSummary(tripId: number) {
|
||||
const trip = db.prepare('SELECT * FROM trips WHERE id = ?').get(tripId) as Record<string, unknown> | undefined;
|
||||
if (!trip) return null;
|
||||
|
||||
const owner = db.prepare('SELECT id, username, avatar FROM users WHERE id = ?').get(trip.user_id as number);
|
||||
const members = db.prepare(`
|
||||
SELECT u.id, u.username, u.avatar, tm.added_at
|
||||
FROM trip_members tm JOIN users u ON tm.user_id = u.id
|
||||
WHERE tm.trip_id = ?
|
||||
`).all(tripId);
|
||||
const ownerRow = getTripOwner(tripId);
|
||||
if (!ownerRow) return null;
|
||||
const { owner, members } = listMembers(tripId, ownerRow.user_id);
|
||||
|
||||
const days = db.prepare('SELECT * FROM days WHERE trip_id = ? ORDER BY day_number ASC').all(tripId) as (Record<string, unknown> & { id: number })[];
|
||||
const dayIds = days.map(d => d.id);
|
||||
const assignmentsByDay: Record<number, unknown[]> = {};
|
||||
const dayNotesByDay: Record<number, unknown[]> = {};
|
||||
const { days: rawDays } = listDays(tripId);
|
||||
const days = rawDays.map(({ notes_items, ...day }) => ({ ...day, notes: notes_items }));
|
||||
|
||||
if (dayIds.length > 0) {
|
||||
const placeholders = dayIds.map(() => '?').join(',');
|
||||
const assignments = db.prepare(`
|
||||
SELECT da.id, da.day_id, da.order_index, da.notes as assignment_notes,
|
||||
p.id as place_id, p.name, p.address, p.lat, p.lng,
|
||||
COALESCE(da.assignment_time, p.place_time) as place_time,
|
||||
c.name as category_name, c.icon as category_icon
|
||||
FROM day_assignments da
|
||||
JOIN places p ON da.place_id = p.id
|
||||
LEFT JOIN categories c ON p.category_id = c.id
|
||||
WHERE da.day_id IN (${placeholders})
|
||||
ORDER BY da.order_index ASC
|
||||
`).all(...dayIds) as (Record<string, unknown> & { day_id: number })[];
|
||||
for (const a of assignments) {
|
||||
if (!assignmentsByDay[a.day_id]) assignmentsByDay[a.day_id] = [];
|
||||
assignmentsByDay[a.day_id].push(a);
|
||||
}
|
||||
const accommodations = listAccommodations(tripId);
|
||||
|
||||
const dayNotes = db.prepare(`
|
||||
SELECT * FROM day_notes WHERE day_id IN (${placeholders}) ORDER BY sort_order ASC
|
||||
`).all(...dayIds) as (Record<string, unknown> & { day_id: number })[];
|
||||
for (const n of dayNotes) {
|
||||
if (!dayNotesByDay[n.day_id]) dayNotesByDay[n.day_id] = [];
|
||||
dayNotesByDay[n.day_id].push(n);
|
||||
}
|
||||
}
|
||||
const budgetItems = listBudgetItems(tripId);
|
||||
const budget = {
|
||||
item_count: budgetItems.length,
|
||||
total: budgetItems.reduce((sum, i) => sum + (i.total_price || 0), 0),
|
||||
currency: trip.currency,
|
||||
};
|
||||
|
||||
const daysWithAssignments = days.map(d => ({
|
||||
...d,
|
||||
assignments: assignmentsByDay[d.id] || [],
|
||||
notes: dayNotesByDay[d.id] || [],
|
||||
}));
|
||||
const packingItems = listPackingItems(tripId);
|
||||
const packing = {
|
||||
total: packingItems.length,
|
||||
checked: (packingItems as { checked: number }[]).filter(i => i.checked).length,
|
||||
};
|
||||
|
||||
const accommodations = db.prepare(`
|
||||
SELECT da.*, p.name as place_name, ds.day_number as start_day_number, de.day_number as end_day_number
|
||||
FROM day_accommodations da
|
||||
JOIN places p ON da.place_id = p.id
|
||||
LEFT JOIN days ds ON da.start_day_id = ds.id
|
||||
LEFT JOIN days de ON da.end_day_id = de.id
|
||||
WHERE da.trip_id = ?
|
||||
ORDER BY ds.day_number ASC
|
||||
`).all(tripId);
|
||||
|
||||
const budgetStats = db.prepare(`
|
||||
SELECT COUNT(*) as item_count, COALESCE(SUM(total_price), 0) as total
|
||||
FROM budget_items WHERE trip_id = ?
|
||||
`).get(tripId) as { item_count: number; total: number };
|
||||
|
||||
const packingStats = db.prepare(`
|
||||
SELECT COUNT(*) as total, SUM(CASE WHEN checked = 1 THEN 1 ELSE 0 END) as checked
|
||||
FROM packing_items WHERE trip_id = ?
|
||||
`).get(tripId) as { total: number; checked: number };
|
||||
|
||||
const reservations = db.prepare(`
|
||||
SELECT r.*, d.day_number
|
||||
FROM reservations r
|
||||
LEFT JOIN days d ON r.day_id = d.id
|
||||
WHERE r.trip_id = ?
|
||||
ORDER BY r.reservation_time ASC, r.created_at ASC
|
||||
`).all(tripId);
|
||||
|
||||
const collabNotes = db.prepare(
|
||||
'SELECT * FROM collab_notes WHERE trip_id = ? ORDER BY pinned DESC, updated_at DESC'
|
||||
).all(tripId);
|
||||
const reservations = listReservations(tripId);
|
||||
const collab_notes = listCollabNotes(tripId);
|
||||
|
||||
return {
|
||||
trip,
|
||||
members: { owner, collaborators: members },
|
||||
days: daysWithAssignments,
|
||||
days,
|
||||
accommodations,
|
||||
budget: { ...budgetStats, currency: trip.currency },
|
||||
packing: packingStats,
|
||||
budget,
|
||||
packing,
|
||||
reservations,
|
||||
collab_notes: collabNotes,
|
||||
collab_notes,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user