commit
32a36cceff
444 files changed
+67186
No files matched your search
@@ -0,0 +1,260 @@
|
||||
const { query, toISODate, closePool, dbReady } = require('./db');
|
||||
const Cycle = require('../models/Cycle');
|
||||
const Camera = require('../models/Camera');
|
||||
const ApiKey = require('../models/ApiKey');
|
||||
const crypto = require('crypto');
|
||||
|
||||
// Helper function to hash API keys
|
||||
function hashApiKey(key) {
|
||||
return crypto.createHash('sha256').update(key).digest('hex');
|
||||
}
|
||||
|
||||
// Helper function to generate API key
|
||||
function generateApiKey() {
|
||||
const randomBytes = crypto.randomBytes(24);
|
||||
return 'cpa_' + randomBytes.toString('hex');
|
||||
}
|
||||
|
||||
// Seed data - minimal cycles with no assumed data
|
||||
const cycles = [
|
||||
{
|
||||
id: 'CYCLE-JBW-2025-05-20',
|
||||
totalDays: 42,
|
||||
currentDay: 42,
|
||||
startDate: new Date('2025-05-20'),
|
||||
status: 'Completed',
|
||||
docInCount: null,
|
||||
chickInWeight: null,
|
||||
},
|
||||
{
|
||||
id: 'CYCLE-JBW-2025-07-11',
|
||||
totalDays: 42,
|
||||
currentDay: 42,
|
||||
startDate: new Date('2025-07-11'),
|
||||
status: 'Completed',
|
||||
docInCount: null,
|
||||
chickInWeight: null,
|
||||
},
|
||||
{
|
||||
id: 'CYCLE-JBW-2025-10-22',
|
||||
totalDays: 42,
|
||||
currentDay: 42,
|
||||
startDate: new Date('2025-10-22'),
|
||||
status: 'Completed',
|
||||
docInCount: null,
|
||||
chickInWeight: null,
|
||||
},
|
||||
{
|
||||
id: 'CYCLE-JBW-2025-12-10',
|
||||
totalDays: 42,
|
||||
currentDay: 42,
|
||||
startDate: new Date('2025-12-10'),
|
||||
status: 'Completed',
|
||||
docInCount: null,
|
||||
chickInWeight: null,
|
||||
},
|
||||
{
|
||||
id: 'CYCLE-JBW-2026-02-09',
|
||||
totalDays: 42,
|
||||
currentDay: 2,
|
||||
startDate: new Date('2026-02-09'),
|
||||
status: 'Active',
|
||||
docInCount: 20000,
|
||||
chickInWeight: null,
|
||||
},
|
||||
];
|
||||
|
||||
// Location hierarchy seed data
|
||||
const locations = [
|
||||
{
|
||||
id: 'loc1',
|
||||
name: 'Peternakan Pusat, Jawa Barat',
|
||||
address: 'Jl. Peternakan No. 123, Bandung, Jawa Barat',
|
||||
},
|
||||
];
|
||||
|
||||
const coops = [
|
||||
{
|
||||
id: 'coop1',
|
||||
name: 'Kandang A (Broiler)',
|
||||
locationId: 'loc1',
|
||||
capacity: 15000,
|
||||
},
|
||||
{
|
||||
id: 'coop2',
|
||||
name: 'Kandang B (Layer)',
|
||||
locationId: 'loc1',
|
||||
capacity: 12000,
|
||||
},
|
||||
];
|
||||
|
||||
const floors = [
|
||||
{
|
||||
id: 'floor1',
|
||||
name: 'Lantai 1',
|
||||
coopId: 'coop1',
|
||||
floorNumber: 1,
|
||||
},
|
||||
{
|
||||
id: 'floor2',
|
||||
name: 'Lantai 2',
|
||||
coopId: 'coop1',
|
||||
floorNumber: 2,
|
||||
},
|
||||
{
|
||||
id: 'floor3',
|
||||
name: 'Lantai 1',
|
||||
coopId: 'coop2',
|
||||
floorNumber: 1,
|
||||
},
|
||||
];
|
||||
|
||||
const cameras = [
|
||||
{
|
||||
id: 'cam1',
|
||||
name: 'Kamera Sudut Kanan Zona A',
|
||||
cameraType: 'STANDARD',
|
||||
floorId: 'floor1',
|
||||
model: 'HIK-2MP-IR',
|
||||
status: 'online',
|
||||
},
|
||||
{
|
||||
id: 'cam2',
|
||||
name: 'Kamera Sudut Kiri Zona A',
|
||||
cameraType: 'STANDARD',
|
||||
floorId: 'floor1',
|
||||
model: 'HIK-2MP-IR',
|
||||
status: 'online',
|
||||
},
|
||||
{
|
||||
id: 'cam3',
|
||||
name: 'Kamera Tengah Zona B',
|
||||
cameraType: 'INFRARED',
|
||||
floorId: 'floor2',
|
||||
model: 'HIK-4MP-IR',
|
||||
status: 'online',
|
||||
},
|
||||
{
|
||||
id: 'cam4',
|
||||
name: 'Kamera Pintu Masuk',
|
||||
cameraType: 'STANDARD',
|
||||
floorId: 'floor2',
|
||||
model: 'HIK-2MP',
|
||||
status: 'online',
|
||||
},
|
||||
{
|
||||
id: 'cam5',
|
||||
name: 'Kamera Zona Layer 1',
|
||||
cameraType: 'STANDARD',
|
||||
floorId: 'floor3',
|
||||
model: 'HIK-2MP-IR',
|
||||
status: 'online',
|
||||
},
|
||||
];
|
||||
|
||||
async function seedDatabase() {
|
||||
try {
|
||||
// Wait for schema to be initialized before querying
|
||||
await dbReady;
|
||||
|
||||
// Check if cycles already exist
|
||||
const existingCycles = await query('SELECT COUNT(*) as count FROM cycles', []);
|
||||
const cycleCount = parseInt(existingCycles.rows[0].count);
|
||||
|
||||
if (cycleCount > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert locations (skip if already exist)
|
||||
for (const loc of locations) {
|
||||
await query(
|
||||
'INSERT INTO locations (id, name, address) VALUES ($1, $2, $3) ON CONFLICT (id) DO NOTHING',
|
||||
[loc.id, loc.name, loc.address || null]
|
||||
);
|
||||
}
|
||||
|
||||
// Insert coops (skip if already exist)
|
||||
for (const coop of coops) {
|
||||
await query(
|
||||
'INSERT INTO coops (id, name, location_id, capacity) VALUES ($1, $2, $3, $4) ON CONFLICT (id) DO NOTHING',
|
||||
[coop.id, coop.name, coop.locationId, coop.capacity || null]
|
||||
);
|
||||
}
|
||||
|
||||
// Insert floors (skip if already exist)
|
||||
for (const floor of floors) {
|
||||
await query(
|
||||
'INSERT INTO floors (id, name, coop_id, floor_number) VALUES ($1, $2, $3, $4) ON CONFLICT (id) DO NOTHING',
|
||||
[floor.id, floor.name, floor.coopId, floor.floorNumber || null]
|
||||
);
|
||||
}
|
||||
for (const cam of cameras) {
|
||||
await Camera.create({
|
||||
id: cam.id,
|
||||
name: cam.name,
|
||||
cameraType: cam.cameraType,
|
||||
floorId: cam.floorId || null,
|
||||
model: cam.model || null,
|
||||
status: cam.status,
|
||||
});
|
||||
}
|
||||
for (const cycle of cycles) {
|
||||
const endDate = new Date(cycle.startDate);
|
||||
endDate.setDate(endDate.getDate() + cycle.totalDays - 1);
|
||||
|
||||
await Cycle.create({
|
||||
id: cycle.id,
|
||||
totalDays: cycle.totalDays,
|
||||
currentDay: cycle.currentDay,
|
||||
startDate: cycle.startDate,
|
||||
endDate: endDate,
|
||||
chickInWeight: cycle.chickInWeight,
|
||||
docInCount: cycle.docInCount,
|
||||
status: cycle.status,
|
||||
});
|
||||
}
|
||||
|
||||
// Display seeded cycles
|
||||
const seededCycles = await Cycle.getAll();
|
||||
seededCycles.forEach((c) => {});
|
||||
const devKey = generateApiKey();
|
||||
const keyHash = hashApiKey(devKey);
|
||||
const keyId = 'apk_dev_' + Date.now();
|
||||
|
||||
await query(
|
||||
`INSERT INTO api_keys (id, key_hash, name, description, created_by, is_active)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)`,
|
||||
[
|
||||
keyId,
|
||||
keyHash,
|
||||
'Development Key',
|
||||
'Auto-generated key for testing and development',
|
||||
'seed-script',
|
||||
1,
|
||||
]
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('✗ Error seeding database:', error.message);
|
||||
console.error(error.stack);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Run seed if this file is executed directly
|
||||
if (require.main === module) {
|
||||
seedDatabase()
|
||||
.then(() => {
|
||||
return closePool();
|
||||
})
|
||||
.then(() => {
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Fatal error:', error);
|
||||
closePool().then(() => {
|
||||
process.exit(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { seedDatabase };
|
||||
Reference in new issue
Block a user