feat: Add communities management routes and integrate community selection in FilterManager for enhanced user experience
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 4m19s

This commit is contained in:
2025-08-10 17:14:55 +07:00
parent bbad45dfad
commit 76dee39843
7 changed files with 488 additions and 7 deletions
+92
View File
@@ -226,6 +226,98 @@ app.post('/api/ip-ranges', async (req, res) => {
}
});
// --- Communities Directory Routes ---
// Get communities from S3
app.get('/api/communities', async (req, res) => {
const params = {
Bucket: BUCKET_NAME,
Key: 'bgp_data/communities.json',
};
try {
const data = await s3.getObject(params).promise();
const fileContent = data.Body.toString('utf-8');
let communities = [];
try {
const parsed = JSON.parse(fileContent);
communities = Array.isArray(parsed) ? parsed : [];
} catch (parseError) {
console.error('Error parsing communities.json:', parseError);
communities = [];
}
// Basic normalization
communities = communities
.filter((c) => c && typeof c.value === 'string' && c.value.trim().length > 0)
.map((c) => ({
value: String(c.value).trim(),
name: c.name ? String(c.name) : '',
description: c.description ? String(c.description) : '',
tags: Array.isArray(c.tags) ? c.tags.map(String) : [],
gatewayDefault: c.gatewayDefault ? String(c.gatewayDefault) : '',
color: c.color ? String(c.color) : ''
}));
res.json(communities);
} catch (error) {
if (error.code === 'NoSuchKey') {
// If file missing, start with empty list
return res.json([]);
}
console.error('Error reading communities from S3:', error);
res.status(500).send('Error reading communities from S3');
}
});
// Update communities in S3
app.post('/api/communities', async (req, res) => {
const { communities } = req.body;
if (!Array.isArray(communities)) {
return res.status(400).send('communities must be an array');
}
// Validate entries and ensure unique values
const seen = new Set();
const normalized = [];
for (let i = 0; i < communities.length; i++) {
const entry = communities[i] || {};
const value = typeof entry.value === 'string' ? entry.value.trim() : '';
if (!value) {
return res.status(400).send(`Community at index ${i} is missing required field: value`);
}
if (seen.has(value)) {
return res.status(400).send(`Duplicate community value at index ${i}: ${value}`);
}
seen.add(value);
normalized.push({
value,
name: entry.name ? String(entry.name) : '',
description: entry.description ? String(entry.description) : '',
tags: Array.isArray(entry.tags) ? entry.tags.map(String) : [],
gatewayDefault: entry.gatewayDefault ? String(entry.gatewayDefault) : '',
color: entry.color ? String(entry.color) : ''
});
}
const params = {
Bucket: BUCKET_NAME,
Key: 'bgp_data/communities.json',
Body: JSON.stringify(normalized, null, 2),
ContentType: 'application/json',
};
try {
await s3.putObject(params).promise();
res.send('Communities updated successfully');
} catch (error) {
console.error('Error writing communities to S3:', error);
res.status(500).send('Error writing communities to S3');
}
});
// --- Servers Routes (JSON format) ---
// Get servers from S3