383 lines
9.9 KiB
JavaScript
Executable File
383 lines
9.9 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
||
|
||
/**
|
||
* Directus Collection Setup Script
|
||
* This script creates collections for our custom database tables in Directus
|
||
*/
|
||
|
||
const axios = require('axios');
|
||
|
||
const DIRECTUS_URL = 'http://localhost:8055';
|
||
const ADMIN_EMAIL = 'admin@assetmanagement.com';
|
||
const ADMIN_PASSWORD = 'AssetAdmin2024!';
|
||
|
||
let authToken = null;
|
||
|
||
// Create axios instance
|
||
const api = axios.create({
|
||
baseURL: DIRECTUS_URL,
|
||
timeout: 10000,
|
||
});
|
||
|
||
// Add auth token to requests
|
||
api.interceptors.request.use((config) => {
|
||
if (authToken) {
|
||
config.headers.Authorization = `Bearer ${authToken}`;
|
||
}
|
||
return config;
|
||
});
|
||
|
||
async function authenticate() {
|
||
try {
|
||
console.log('🔑 Authenticating with Directus...');
|
||
const response = await api.post('/auth/login', {
|
||
email: ADMIN_EMAIL,
|
||
password: ADMIN_PASSWORD,
|
||
});
|
||
|
||
authToken = response.data.data.access_token;
|
||
console.log('✅ Authentication successful');
|
||
return authToken;
|
||
} catch (error) {
|
||
console.error('❌ Authentication failed:', error.response?.data || error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
async function createCollection(collection) {
|
||
try {
|
||
console.log(`📁 Creating collection: ${collection.collection}`);
|
||
|
||
// Check if collection already exists
|
||
try {
|
||
await api.get(`/collections/${collection.collection}`);
|
||
console.log(`ℹ️ Collection ${collection.collection} already exists, skipping...`);
|
||
return;
|
||
} catch (error) {
|
||
// Collection doesn't exist, create it
|
||
}
|
||
|
||
await api.post('/collections', collection);
|
||
console.log(`✅ Collection ${collection.collection} created successfully`);
|
||
} catch (error) {
|
||
console.error(`❌ Failed to create collection ${collection.collection}:`,
|
||
error.response?.data || error.message);
|
||
}
|
||
}
|
||
|
||
async function setupCollections() {
|
||
console.log('🚀 Setting up Directus collections...\n');
|
||
|
||
// Define our collections based on the database schema
|
||
const collections = [
|
||
{
|
||
collection: 'organizations',
|
||
meta: {
|
||
accountability: 'all',
|
||
archive_app_filter: true,
|
||
archive_field: null,
|
||
archive_value: null,
|
||
collapse: 'open',
|
||
collection: 'organizations',
|
||
color: '#6644FF',
|
||
display_template: '{{ name }}',
|
||
group: null,
|
||
hidden: false,
|
||
icon: 'business',
|
||
item_duplication_fields: null,
|
||
note: 'SaaS tenant organizations',
|
||
preview_url: null,
|
||
singleton: false,
|
||
sort: 1,
|
||
sort_field: null,
|
||
translations: null,
|
||
unarchive_value: null,
|
||
versioning: false
|
||
},
|
||
schema: null
|
||
},
|
||
{
|
||
collection: 'subscription_plans',
|
||
meta: {
|
||
accountability: 'all',
|
||
archive_app_filter: true,
|
||
archive_field: null,
|
||
archive_value: null,
|
||
collapse: 'open',
|
||
collection: 'subscription_plans',
|
||
color: '#00C897',
|
||
display_template: '{{ display_name }}',
|
||
group: null,
|
||
hidden: false,
|
||
icon: 'paid',
|
||
item_duplication_fields: null,
|
||
note: 'Available subscription plans',
|
||
preview_url: null,
|
||
singleton: false,
|
||
sort: 2,
|
||
sort_field: null,
|
||
translations: null,
|
||
unarchive_value: null,
|
||
versioning: false
|
||
},
|
||
schema: null
|
||
},
|
||
{
|
||
collection: 'asset_categories',
|
||
meta: {
|
||
accountability: 'all',
|
||
archive_app_filter: true,
|
||
archive_field: null,
|
||
archive_value: null,
|
||
collapse: 'open',
|
||
collection: 'asset_categories',
|
||
color: '#FF6B35',
|
||
display_template: '{{ name }}',
|
||
group: null,
|
||
hidden: false,
|
||
icon: 'category',
|
||
item_duplication_fields: null,
|
||
note: 'Asset categorization',
|
||
preview_url: null,
|
||
singleton: false,
|
||
sort: 3,
|
||
sort_field: null,
|
||
translations: null,
|
||
unarchive_value: null,
|
||
versioning: false
|
||
},
|
||
schema: null
|
||
},
|
||
{
|
||
collection: 'locations',
|
||
meta: {
|
||
accountability: 'all',
|
||
archive_app_filter: true,
|
||
archive_field: null,
|
||
archive_value: null,
|
||
collapse: 'open',
|
||
collection: 'locations',
|
||
color: '#4CAF50',
|
||
display_template: '{{ name }}',
|
||
group: null,
|
||
hidden: false,
|
||
icon: 'place',
|
||
item_duplication_fields: null,
|
||
note: 'Asset locations and facilities',
|
||
preview_url: null,
|
||
singleton: false,
|
||
sort: 4,
|
||
sort_field: null,
|
||
translations: null,
|
||
unarchive_value: null,
|
||
versioning: false
|
||
},
|
||
schema: null
|
||
},
|
||
{
|
||
collection: 'vendors',
|
||
meta: {
|
||
accountability: 'all',
|
||
archive_app_filter: true,
|
||
archive_field: null,
|
||
archive_value: null,
|
||
collapse: 'open',
|
||
collection: 'vendors',
|
||
color: '#9C27B0',
|
||
display_template: '{{ name }}',
|
||
group: null,
|
||
hidden: false,
|
||
icon: 'store',
|
||
item_duplication_fields: null,
|
||
note: 'Vendors and suppliers',
|
||
preview_url: null,
|
||
singleton: false,
|
||
sort: 5,
|
||
sort_field: null,
|
||
translations: null,
|
||
unarchive_value: null,
|
||
versioning: false
|
||
},
|
||
schema: null
|
||
},
|
||
{
|
||
collection: 'assets',
|
||
meta: {
|
||
accountability: 'all',
|
||
archive_app_filter: true,
|
||
archive_field: null,
|
||
archive_value: null,
|
||
collapse: 'open',
|
||
collection: 'assets',
|
||
color: '#0078D4',
|
||
display_template: '{{ name }} ({{ asset_identifier }})',
|
||
group: null,
|
||
hidden: false,
|
||
icon: 'inventory',
|
||
item_duplication_fields: null,
|
||
note: 'Main asset registry',
|
||
preview_url: null,
|
||
singleton: false,
|
||
sort: 6,
|
||
sort_field: null,
|
||
translations: null,
|
||
unarchive_value: null,
|
||
versioning: false
|
||
},
|
||
schema: null
|
||
},
|
||
{
|
||
collection: 'asset_components',
|
||
meta: {
|
||
accountability: 'all',
|
||
archive_app_filter: true,
|
||
archive_field: null,
|
||
archive_value: null,
|
||
collapse: 'open',
|
||
collection: 'asset_components',
|
||
color: '#FF9800',
|
||
display_template: '{{ name }}',
|
||
group: null,
|
||
hidden: false,
|
||
icon: 'construction',
|
||
item_duplication_fields: null,
|
||
note: 'Asset components and parts',
|
||
preview_url: null,
|
||
singleton: false,
|
||
sort: 7,
|
||
sort_field: null,
|
||
translations: null,
|
||
unarchive_value: null,
|
||
versioning: false
|
||
},
|
||
schema: null
|
||
},
|
||
{
|
||
collection: 'asset_qr_codes',
|
||
meta: {
|
||
accountability: 'all',
|
||
archive_app_filter: true,
|
||
archive_field: null,
|
||
archive_value: null,
|
||
collapse: 'open',
|
||
collection: 'asset_qr_codes',
|
||
color: '#795548',
|
||
display_template: 'QR Code for {{ asset_id }}',
|
||
group: null,
|
||
hidden: false,
|
||
icon: 'qr_code',
|
||
item_duplication_fields: null,
|
||
note: 'QR codes for assets',
|
||
preview_url: null,
|
||
singleton: false,
|
||
sort: 8,
|
||
sort_field: null,
|
||
translations: null,
|
||
unarchive_value: null,
|
||
versioning: false
|
||
},
|
||
schema: null
|
||
},
|
||
{
|
||
collection: 'work_order_types',
|
||
meta: {
|
||
accountability: 'all',
|
||
archive_app_filter: true,
|
||
archive_field: null,
|
||
archive_value: null,
|
||
collapse: 'open',
|
||
collection: 'work_order_types',
|
||
color: '#E91E63',
|
||
display_template: '{{ name }}',
|
||
group: null,
|
||
hidden: false,
|
||
icon: 'assignment',
|
||
item_duplication_fields: null,
|
||
note: 'Work order categories',
|
||
preview_url: null,
|
||
singleton: false,
|
||
sort: 9,
|
||
sort_field: null,
|
||
translations: null,
|
||
unarchive_value: null,
|
||
versioning: false
|
||
},
|
||
schema: null
|
||
},
|
||
{
|
||
collection: 'work_orders',
|
||
meta: {
|
||
accountability: 'all',
|
||
archive_app_filter: true,
|
||
archive_field: null,
|
||
archive_value: null,
|
||
collapse: 'open',
|
||
collection: 'work_orders',
|
||
color: '#2196F3',
|
||
display_template: '{{ title }} ({{ work_order_number }})',
|
||
group: null,
|
||
hidden: false,
|
||
icon: 'build',
|
||
item_duplication_fields: null,
|
||
note: 'Work orders and maintenance requests',
|
||
preview_url: null,
|
||
singleton: false,
|
||
sort: 10,
|
||
sort_field: null,
|
||
translations: null,
|
||
unarchive_value: null,
|
||
versioning: false
|
||
},
|
||
schema: null
|
||
},
|
||
{
|
||
collection: 'asset_reminders',
|
||
meta: {
|
||
accountability: 'all',
|
||
archive_app_filter: true,
|
||
archive_field: null,
|
||
archive_value: null,
|
||
collapse: 'open',
|
||
collection: 'asset_reminders',
|
||
color: '#FF5722',
|
||
display_template: '{{ title }}',
|
||
group: null,
|
||
hidden: false,
|
||
icon: 'notifications',
|
||
item_duplication_fields: null,
|
||
note: 'Maintenance reminders and alerts',
|
||
preview_url: null,
|
||
singleton: false,
|
||
sort: 11,
|
||
sort_field: null,
|
||
translations: null,
|
||
unarchive_value: null,
|
||
versioning: false
|
||
},
|
||
schema: null
|
||
}
|
||
];
|
||
|
||
try {
|
||
await authenticate();
|
||
|
||
console.log('\n📁 Creating collections...\n');
|
||
|
||
for (const collection of collections) {
|
||
await createCollection(collection);
|
||
}
|
||
|
||
console.log('\n🎉 Collection setup completed successfully!');
|
||
console.log('\n📋 Next steps:');
|
||
console.log('1. Visit http://localhost:8055/admin to configure field permissions');
|
||
console.log('2. Test the frontend connection');
|
||
console.log('3. Create some test assets\n');
|
||
|
||
} catch (error) {
|
||
console.error('\n❌ Setup failed:', error.message);
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
// Run the setup
|
||
setupCollections().catch(console.error); |