Sync broccolini-bot: rename from zammad, docs in docs/, security gitignore, remove zammad deps

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
samkintop
2026-02-12 02:56:00 -06:00
parent 08a16b4a75
commit 29a13768f7
37 changed files with 1093 additions and 3229 deletions

20
scripts/backup-env.js Normal file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env node
/**
* Copy .env to .env.backup. Run whenever you want to save a snapshot.
* .env.backup is in .gitignore and is never committed.
*/
const fs = require('fs');
const path = require('path');
const root = path.resolve(__dirname, '..');
const src = path.join(root, '.env');
const dest = path.join(root, '.env.backup');
if (!fs.existsSync(src)) {
console.error('No .env file found. Nothing to backup.');
process.exit(1);
}
fs.copyFileSync(src, dest);
console.log('Backup written to .env.backup');

View File

@@ -1,97 +0,0 @@
/**
* Create Zammad objects to match the bridge schema (groups, etc.).
* Uses same .env as the bridge (ZAMMAD_URL, ZAMMAD_TOKEN).
*
* Run from gmail-bridge: node scripts/create-zammad-objects.js
*/
const axios = require('axios');
const { ZAMMAD } = require('../config');
const baseURL = ZAMMAD.URL?.replace(/\/+$/, '') || '';
const headers = {
Authorization: `Token token=${ZAMMAD.TOKEN}`,
'Content-Type': 'application/json'
};
async function apiGet(path) {
const { data } = await axios.get(`${baseURL}${path}`, { headers });
return data;
}
async function apiPost(path, body) {
const { data } = await axios.post(`${baseURL}${path}`, body, { headers });
return data;
}
async function main() {
if (!baseURL || !ZAMMAD.TOKEN) {
console.error('Set ZAMMAD_URL and ZAMMAD_TOKEN in .env');
process.exit(1);
}
console.log('Zammad base URL:', baseURL);
console.log('');
// --- Groups (bridge uses ZAMMAD_EMAIL_GROUP and ZAMMAD_DISCORD_GROUP) ---
const groupNames = [
ZAMMAD.EMAIL_GROUP || 'Email Users',
ZAMMAD.DISCORD_GROUP || 'Discord Users'
];
let groups;
try {
groups = await apiGet('/api/v1/groups');
} catch (e) {
console.error('GET /api/v1/groups failed:', e.response?.status, e.response?.data || e.message);
process.exit(1);
}
const existingNames = (groups || []).map((g) => g.name);
for (const name of groupNames) {
if (existingNames.includes(name)) {
console.log(`Group "${name}" already exists.`);
continue;
}
try {
await apiPost('/api/v1/groups', { name, active: true });
console.log(`Created group: "${name}"`);
} catch (e) {
console.error(`Create group "${name}" failed:`, e.response?.status, e.response?.data || e.message);
}
}
console.log('');
// --- Ticket priorities (for bridge priority sync: low / normal / high) ---
try {
const priorities = await apiGet('/api/v1/ticket_priorities');
console.log('Ticket priorities (for /priority and buttons):');
(priorities || []).forEach((p) => {
console.log(` id=${p.id} name="${p.name}" default_create=${p.default_create}`);
});
} catch (e) {
console.error('GET /api/v1/ticket_priorities failed:', e.response?.status, e.message);
}
console.log('');
// --- Ticket states (bridge uses state "new" on create, "closed" on force-close) ---
try {
const states = await apiGet('/api/v1/ticket_states');
console.log('Ticket states (bridge uses "new" and "closed"):');
(states || []).forEach((s) => {
console.log(` id=${s.id} name="${s.name}" default_create=${s.default_create}`);
});
} catch (e) {
console.error('GET /api/v1/ticket_states failed:', e.response?.status, e.message);
}
console.log('');
console.log('Done. Bridge expects group names in .env: ZAMMAD_EMAIL_GROUP, ZAMMAD_DISCORD_GROUP.');
}
main().catch((e) => {
console.error(e);
process.exit(1);
});

45
scripts/test-mongodb.js Normal file
View File

@@ -0,0 +1,45 @@
/**
* Test MongoDB connection using the native driver.
* Uses MONGODB_URI from .env (or ENV_FILE when set). Run: npm run test-mongodb
*/
const path = require('path');
const dotenv = require('dotenv');
const envPath = process.env.ENV_FILE ? path.resolve(process.cwd(), process.env.ENV_FILE) : undefined;
dotenv.config({ path: envPath });
const { MongoClient, ServerApiVersion } = require('mongodb');
const uri = (process.env.MONGODB_URI || '').trim();
const scheme = uri.split('://')[0];
if (!uri) {
console.error('MONGODB_URI is not set in .env');
process.exit(1);
}
if (scheme !== 'mongodb' && scheme !== 'mongodb+srv') {
console.error('MONGODB_URI must start with mongodb:// or mongodb+srv://');
process.exit(1);
}
const client = new MongoClient(uri, {
serverApi: {
version: ServerApiVersion.v1,
strict: true,
deprecationErrors: true,
},
});
async function run() {
try {
await client.connect();
await client.db('admin').command({ ping: 1 });
console.log('Pinged your deployment. You successfully connected to MongoDB!');
} finally {
await client.close();
}
}
run().catch((err) => {
console.error(err);
process.exit(1);
});