Spaces:
Paused
Paused
Download controllers/destinations.controller.js from imkrish/yatra-x-admin: direct link, hf CLI and curl.
- Browser
- Download file 5.55 kB
-
https://huggingface.co/spaces/imkrish/yatra-x-admin/resolve/main/controllers/destinations.controller.js
- Command line
-
hf download hf://spaces/imkrish/yatra-x-admin/controllers/destinations.controller.js
-
curl -L -o destinations.controller.js https://huggingface.co/spaces/imkrish/yatra-x-admin/resolve/main/controllers/destinations.controller.js
5.55 kB
| /** | |
| * Destinations Controller - READ-ONLY (PostgreSQL) | |
| */ | |
| const { getPool } = require('../db'); | |
| const transportService = require('../services/transport_service'); | |
| function safeJson(value, fallback) { | |
| if (value === null || value === undefined) return fallback; | |
| if (typeof value === 'object') return value; | |
| if (typeof value === 'string') { | |
| try { | |
| return JSON.parse(value); | |
| } catch { | |
| return fallback; | |
| } | |
| } | |
| return fallback; | |
| } | |
| function normalizeDestination(row) { | |
| return { | |
| ...row, | |
| highlights: safeJson(row.highlights, []), | |
| media: safeJson(row.media, []), | |
| nearby_attractions: safeJson(row.nearby_attractions, []), | |
| ai_data: safeJson(row.ai_data, {}) | |
| }; | |
| } | |
| async function list(req, res) { | |
| const pool = getPool(); | |
| if (!pool) { | |
| return res.status(500).json({ error: 'Database connection not established' }); | |
| } | |
| try { | |
| const { category, district, search, limit = 100, offset = 0 } = req.query; | |
| let query = 'SELECT * FROM destinations WHERE is_active = true'; | |
| const params = []; | |
| let paramCounter = 1; | |
| if (category) { | |
| query += ` AND category = $${paramCounter++}`; | |
| params.push(category); | |
| } | |
| if (district) { | |
| query += ` AND district ILIKE $${paramCounter++}`; | |
| params.push(`%${district}%`); | |
| } | |
| if (search) { | |
| query += ` AND (LOWER(name) LIKE $${paramCounter++} OR LOWER(description) LIKE $${paramCounter++})`; | |
| const term = `%${String(search).toLowerCase()}%`; | |
| params.push(term, term); | |
| } | |
| query += ` ORDER BY rating DESC NULLS LAST LIMIT $${paramCounter++} OFFSET $${paramCounter++}`; | |
| params.push(parseInt(limit, 10), parseInt(offset, 10)); | |
| const result = await pool.query(query, params); | |
| const destinations = result.rows.map(normalizeDestination); | |
| res.json({ success: true, count: destinations.length, data: destinations }); | |
| } catch (error) { | |
| console.error('[Destination Controller] list error:', { | |
| message: error.message, | |
| stack: error.stack, | |
| query: req.query | |
| }); | |
| res.status(500).json({ | |
| error: 'Failed to fetch destinations from database', | |
| details: process.env.NODE_ENV === 'development' ? error.message : undefined | |
| }); | |
| } | |
| } | |
| async function show(req, res) { | |
| const pool = getPool(); | |
| if (!pool) { | |
| return res.status(500).json({ error: 'Database connection not established' }); | |
| } | |
| try { | |
| const slug = req.params.slug; | |
| const normalizedSlug = slug.replace(/-/g, '_'); | |
| const result = await pool.query( | |
| 'SELECT * FROM destinations WHERE (slug = $1 OR slug = $2 OR LOWER(slug) = LOWER($1)) AND is_active = true', | |
| [slug, normalizedSlug] | |
| ); | |
| if (result.rows.length === 0) { | |
| return res.status(404).json({ error: 'Destination not found' }); | |
| } | |
| res.json({ success: true, data: normalizeDestination(result.rows[0]) }); | |
| } catch (error) { | |
| console.error('[Destination Controller] show error:', { | |
| slug: req.params.slug, | |
| message: error.message, | |
| stack: error.stack | |
| }); | |
| res.status(500).json({ | |
| error: 'Failed to fetch destination from database', | |
| details: process.env.NODE_ENV === 'development' ? error.message : undefined | |
| }); | |
| } | |
| } | |
| async function districtStats(req, res) { | |
| const pool = getPool(); | |
| if (!pool) { | |
| return res.status(500).json({ error: 'Database connection not established' }); | |
| } | |
| try { | |
| const result = await pool.query(` | |
| SELECT | |
| district, | |
| COUNT(*)::integer as count, | |
| ROUND(COALESCE(AVG(rating), 0)::numeric, 2)::float as avg_rating | |
| FROM destinations | |
| WHERE is_active = true AND latitude IS NOT NULL | |
| GROUP BY district | |
| ORDER BY count DESC | |
| `); | |
| res.json({ success: true, data: result.rows }); | |
| } catch (error) { | |
| console.error('[Destination Controller] districtStats error:', { | |
| message: error.message, | |
| stack: error.stack | |
| }); | |
| res.status(500).json({ | |
| error: 'Failed to fetch district stats from database', | |
| details: process.env.NODE_ENV === 'development' ? error.message : undefined | |
| }); | |
| } | |
| } | |
| async function districtDestinations(req, res) { | |
| const pool = getPool(); | |
| if (!pool) { | |
| return res.status(500).json({ error: 'Database connection not established' }); | |
| } | |
| try { | |
| const { district } = req.params; | |
| const { limit = 3 } = req.query; | |
| const result = await pool.query( | |
| `SELECT id, name, slug, media, rating, category | |
| FROM destinations | |
| WHERE district = $1 AND is_active = true | |
| ORDER BY rating DESC NULLS LAST | |
| LIMIT $2`, | |
| [district, parseInt(limit, 10)] | |
| ); | |
| res.json({ success: true, data: result.rows }); | |
| } catch (error) { | |
| console.error('[Destination Controller] districtDestinations error:', { | |
| district: req.params.district, | |
| message: error.message, | |
| stack: error.stack | |
| }); | |
| res.status(500).json({ | |
| error: 'Failed to fetch district destinations from database', | |
| details: process.env.NODE_ENV === 'development' ? error.message : undefined | |
| }); | |
| } | |
| } | |
| async function transportHubs(req, res) { | |
| try { | |
| const { district } = req.query; | |
| const hubs = await transportService.getNearbyHubs(district); | |
| res.json({ success: true, count: hubs.length, data: hubs }); | |
| } catch (error) { | |
| console.error('[Transport Error]', error.message); | |
| res.status(500).json({ error: 'Failed to fetch transport hubs' }); | |
| } | |
| } | |
| module.exports = { | |
| list, | |
| show, | |
| districtStats, | |
| districtDestinations, | |
| transportHubs | |
| }; | |