freealberta/influence/app/controllers/representatives.js

185 lines
6.4 KiB
JavaScript

const representAPI = require('../services/represent-api');
const nocoDB = require('../services/nocodb');
// Helper function to cache representatives
async function cacheRepresentatives(postalCode, representatives, representData) {
try {
// Cache the postal code info
await nocoDB.storePostalCodeInfo({
postal_code: postalCode,
city: representData.city,
province: representData.province
});
// Cache representatives using the existing method
const result = await nocoDB.storeRepresentatives(postalCode, representatives);
if (result.success) {
console.log(`Successfully cached ${result.count} representatives for ${postalCode}`);
} else {
console.log(`Partial success caching representatives for ${postalCode}: ${result.error || 'unknown error'}`);
}
} catch (error) {
console.log(`Failed to cache representatives for ${postalCode}:`, error.message);
// Don't throw - caching is optional and should never break the main flow
}
}
class RepresentativesController {
async testConnection(req, res, next) {
try {
const result = await representAPI.testConnection();
res.json(result);
} catch (error) {
console.error('Test connection error:', error);
res.status(500).json({
error: 'Failed to test connection',
message: error.message
});
}
}
async getByPostalCode(req, res, next) {
try {
const { postalCode } = req.params;
const formattedPostalCode = postalCode.replace(/\s/g, '').toUpperCase();
// Try to check cached data first, but don't fail if NocoDB is down
let cachedData = [];
try {
cachedData = await nocoDB.getRepresentativesByPostalCode(formattedPostalCode);
console.log(`Cache check for ${formattedPostalCode}: found ${cachedData.length} records`);
if (cachedData && cachedData.length > 0) {
return res.json({
success: true,
source: 'Local Cache',
data: {
postalCode: formattedPostalCode,
location: {
city: cachedData[0]?.city || 'Alberta',
province: 'AB'
},
representatives: cachedData
}
});
}
} catch (cacheError) {
console.log(`Cache unavailable for ${formattedPostalCode}, proceeding with API call:`, cacheError.message);
}
// If not in cache, fetch from Represent API
console.log(`Fetching representatives from Represent API for ${postalCode}`);
const representData = await representAPI.getRepresentativesByPostalCode(postalCode);
if (!representData) {
return res.json({
success: false,
message: 'No data found for this postal code',
data: {
postalCode,
location: null,
representatives: []
}
});
}
// Process representatives from both concordance and centroid
let representatives = [];
// Add concordance representatives (if any)
if (representData.boundaries_concordance && representData.boundaries_concordance.length > 0) {
representatives = representatives.concat(representData.boundaries_concordance);
}
// Add centroid representatives (if any) - these are the actual elected officials
if (representData.representatives_centroid && representData.representatives_centroid.length > 0) {
representatives = representatives.concat(representData.representatives_centroid);
}
// Representatives already include office information, no need for additional API calls
console.log('Using representatives data with existing office information');
console.log(`Representatives concordance count: ${representData.boundaries_concordance ? representData.boundaries_concordance.length : 0}`);
console.log(`Representatives centroid count: ${representData.representatives_centroid ? representData.representatives_centroid.length : 0}`);
console.log(`Total representatives found: ${representatives.length}`);
if (representatives.length === 0) {
return res.json({
success: false,
message: 'No representatives found for this postal code',
data: {
postalCode,
location: {
city: representData.city,
province: representData.province
},
representatives: []
}
});
}
// Try to cache the results (will fail gracefully if NocoDB is down)
console.log(`Attempting to cache ${representatives.length} representatives for ${postalCode}`);
await cacheRepresentatives(postalCode, representatives, representData);
res.json({
success: true,
source: 'Open North',
data: {
postalCode,
location: {
city: representData.city,
province: representData.province
},
representatives
}
});
} catch (error) {
console.error('Get representatives error:', error);
res.status(500).json({
error: 'Failed to fetch representatives',
message: error.message
});
}
}
async refreshPostalCode(req, res, next) {
try {
const { postalCode } = req.params;
const formattedPostalCode = postalCode.replace(/\s/g, '').toUpperCase();
// Clear cached data
await nocoDB.clearRepresentativesByPostalCode(formattedPostalCode);
// Fetch fresh data from API
const representData = await representAPI.getRepresentativesByPostalCode(formattedPostalCode);
if (!representData || !representData.representatives_concordance) {
return res.status(404).json({
error: 'No representatives found for this postal code',
postalCode: formattedPostalCode
});
}
// Cache the fresh results
await nocoDB.storeRepresentatives(formattedPostalCode, representData.representatives_concordance);
res.json({
source: 'Open North',
postalCode: formattedPostalCode,
representatives: representData.representatives_concordance,
city: representData.city,
province: representData.province
});
} catch (error) {
console.error('Refresh representatives error:', error);
res.status(500).json({
error: 'Failed to refresh representatives',
message: error.message
});
}
}
}
module.exports = new RepresentativesController();