video preview version
This commit is contained in:
172
server/db.js
172
server/db.js
@@ -152,98 +152,17 @@ function initialize() {
|
||||
);
|
||||
`);
|
||||
|
||||
// ─── Ownership columns (link to users table) ───
|
||||
const addOwnership = (table, column) => {
|
||||
const cols = db.prepare(`PRAGMA table_info(${table})`).all().map(c => c.name);
|
||||
if (!cols.includes(column)) {
|
||||
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} INTEGER REFERENCES users(id)`);
|
||||
console.log(`✅ Added ${column} column to ${table}`);
|
||||
}
|
||||
};
|
||||
addOwnership('posts', 'created_by_user_id');
|
||||
addOwnership('tasks', 'created_by_user_id');
|
||||
addOwnership('campaigns', 'created_by_user_id');
|
||||
addOwnership('projects', 'created_by_user_id');
|
||||
|
||||
// Add phone column to team_members if missing
|
||||
const teamMemberCols = db.prepare("PRAGMA table_info(team_members)").all().map(c => c.name);
|
||||
if (!teamMemberCols.includes('phone')) {
|
||||
db.exec("ALTER TABLE team_members ADD COLUMN phone TEXT");
|
||||
console.log('✅ Added phone column to team_members');
|
||||
}
|
||||
|
||||
// Migrations — add columns if they don't exist
|
||||
const campaignCols = db.prepare("PRAGMA table_info(campaigns)").all().map(c => c.name);
|
||||
if (!campaignCols.includes('platforms')) {
|
||||
db.exec("ALTER TABLE campaigns ADD COLUMN platforms TEXT DEFAULT '[]'");
|
||||
console.log('✅ Added platforms column to campaigns');
|
||||
}
|
||||
|
||||
// Campaign performance tracking columns
|
||||
if (!campaignCols.includes('budget_spent')) {
|
||||
db.exec("ALTER TABLE campaigns ADD COLUMN budget_spent REAL DEFAULT 0");
|
||||
console.log('✅ Added budget_spent column to campaigns');
|
||||
}
|
||||
if (!campaignCols.includes('revenue')) {
|
||||
db.exec("ALTER TABLE campaigns ADD COLUMN revenue REAL DEFAULT 0");
|
||||
console.log('✅ Added revenue column to campaigns');
|
||||
}
|
||||
if (!campaignCols.includes('impressions')) {
|
||||
db.exec("ALTER TABLE campaigns ADD COLUMN impressions INTEGER DEFAULT 0");
|
||||
console.log('✅ Added impressions column to campaigns');
|
||||
}
|
||||
if (!campaignCols.includes('clicks')) {
|
||||
db.exec("ALTER TABLE campaigns ADD COLUMN clicks INTEGER DEFAULT 0");
|
||||
console.log('✅ Added clicks column to campaigns');
|
||||
}
|
||||
if (!campaignCols.includes('conversions')) {
|
||||
db.exec("ALTER TABLE campaigns ADD COLUMN conversions INTEGER DEFAULT 0");
|
||||
console.log('✅ Added conversions column to campaigns');
|
||||
}
|
||||
if (!campaignCols.includes('cost_per_click')) {
|
||||
db.exec("ALTER TABLE campaigns ADD COLUMN cost_per_click REAL DEFAULT 0");
|
||||
console.log('✅ Added cost_per_click column to campaigns');
|
||||
}
|
||||
if (!campaignCols.includes('notes')) {
|
||||
db.exec("ALTER TABLE campaigns ADD COLUMN notes TEXT DEFAULT ''");
|
||||
console.log('✅ Added notes column to campaigns');
|
||||
}
|
||||
|
||||
// Add track_id to posts
|
||||
const postCols = db.prepare("PRAGMA table_info(posts)").all().map(c => c.name);
|
||||
if (!postCols.includes('track_id')) {
|
||||
db.exec("ALTER TABLE posts ADD COLUMN track_id INTEGER REFERENCES campaign_tracks(id)");
|
||||
console.log('✅ Added track_id column to posts');
|
||||
}
|
||||
if (!postCols.includes('campaign_id')) {
|
||||
db.exec("ALTER TABLE posts ADD COLUMN campaign_id INTEGER REFERENCES campaigns(id)");
|
||||
console.log('✅ Added campaign_id column to posts');
|
||||
}
|
||||
if (!postCols.includes('platforms')) {
|
||||
// Add platforms column, migrate existing platform values
|
||||
db.exec("ALTER TABLE posts ADD COLUMN platforms TEXT DEFAULT '[]'");
|
||||
// Migrate: copy single platform value into platforms JSON array
|
||||
const rows = db.prepare("SELECT id, platform FROM posts WHERE platform IS NOT NULL AND platform != ''").all();
|
||||
const migrate = db.prepare("UPDATE posts SET platforms = ? WHERE id = ?");
|
||||
for (const row of rows) {
|
||||
migrate.run(JSON.stringify([row.platform]), row.id);
|
||||
}
|
||||
console.log(`✅ Added platforms column to posts, migrated ${rows.length} rows`);
|
||||
}
|
||||
|
||||
// Add campaign_id to assets
|
||||
const assetCols = db.prepare("PRAGMA table_info(assets)").all().map(c => c.name);
|
||||
if (!assetCols.includes('campaign_id')) {
|
||||
db.exec("ALTER TABLE assets ADD COLUMN campaign_id INTEGER REFERENCES campaigns(id)");
|
||||
console.log('✅ Added campaign_id column to assets');
|
||||
}
|
||||
|
||||
// ─── Link users to team_members ───
|
||||
const userCols = db.prepare("PRAGMA table_info(users)").all().map(c => c.name);
|
||||
if (!userCols.includes('team_member_id')) {
|
||||
db.exec("ALTER TABLE users ADD COLUMN team_member_id INTEGER REFERENCES team_members(id)");
|
||||
console.log('✅ Added team_member_id column to users');
|
||||
}
|
||||
// ─── Comments / discussion table ───
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS comments (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
entity_type TEXT NOT NULL,
|
||||
entity_id INTEGER NOT NULL,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
||||
content TEXT NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
`);
|
||||
|
||||
// ─── Post attachments table ───
|
||||
db.exec(`
|
||||
@@ -259,30 +178,61 @@ function initialize() {
|
||||
);
|
||||
`);
|
||||
|
||||
// ─── Publication links column on posts ───
|
||||
if (!postCols.includes('publication_links')) {
|
||||
db.exec("ALTER TABLE posts ADD COLUMN publication_links TEXT DEFAULT '[]'");
|
||||
console.log('✅ Added publication_links column to posts');
|
||||
// ─── Column migrations ───
|
||||
// Helper: adds a column to a table if it does not already exist.
|
||||
function addColumnIfMissing(table, column, definition) {
|
||||
const cols = db.prepare(`PRAGMA table_info(${table})`).all().map(c => c.name);
|
||||
if (!cols.includes(column)) {
|
||||
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
||||
console.log(`Added ${column} column to ${table}`);
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Merge team_members into users ───
|
||||
if (!userCols.includes('team_role')) {
|
||||
db.exec("ALTER TABLE users ADD COLUMN team_role TEXT");
|
||||
console.log('✅ Added team_role column to users');
|
||||
// Ownership columns (link to users table)
|
||||
for (const table of ['posts', 'tasks', 'campaigns', 'projects']) {
|
||||
addColumnIfMissing(table, 'created_by_user_id', 'INTEGER REFERENCES users(id)');
|
||||
}
|
||||
if (!userCols.includes('brands')) {
|
||||
db.exec("ALTER TABLE users ADD COLUMN brands TEXT DEFAULT '[]'");
|
||||
console.log('✅ Added brands column to users');
|
||||
}
|
||||
if (!userCols.includes('phone')) {
|
||||
db.exec("ALTER TABLE users ADD COLUMN phone TEXT");
|
||||
console.log('✅ Added phone column to users');
|
||||
}
|
||||
if (!userCols.includes('tutorial_completed')) {
|
||||
db.exec("ALTER TABLE users ADD COLUMN tutorial_completed INTEGER DEFAULT 0");
|
||||
console.log('✅ Added tutorial_completed column to users');
|
||||
|
||||
// team_members additions
|
||||
addColumnIfMissing('team_members', 'phone', 'TEXT');
|
||||
|
||||
// campaigns additions
|
||||
addColumnIfMissing('campaigns', 'platforms', "TEXT DEFAULT '[]'");
|
||||
addColumnIfMissing('campaigns', 'budget_spent', 'REAL DEFAULT 0');
|
||||
addColumnIfMissing('campaigns', 'revenue', 'REAL DEFAULT 0');
|
||||
addColumnIfMissing('campaigns', 'impressions', 'INTEGER DEFAULT 0');
|
||||
addColumnIfMissing('campaigns', 'clicks', 'INTEGER DEFAULT 0');
|
||||
addColumnIfMissing('campaigns', 'conversions', 'INTEGER DEFAULT 0');
|
||||
addColumnIfMissing('campaigns', 'cost_per_click', 'REAL DEFAULT 0');
|
||||
addColumnIfMissing('campaigns', 'notes', "TEXT DEFAULT ''");
|
||||
|
||||
// posts additions
|
||||
addColumnIfMissing('posts', 'track_id', 'INTEGER REFERENCES campaign_tracks(id)');
|
||||
addColumnIfMissing('posts', 'campaign_id', 'INTEGER REFERENCES campaigns(id)');
|
||||
addColumnIfMissing('posts', 'publication_links', "TEXT DEFAULT '[]'");
|
||||
|
||||
// posts.platforms with data migration from single platform field
|
||||
const postCols = db.prepare("PRAGMA table_info(posts)").all().map(c => c.name);
|
||||
if (!postCols.includes('platforms')) {
|
||||
db.exec("ALTER TABLE posts ADD COLUMN platforms TEXT DEFAULT '[]'");
|
||||
const rows = db.prepare("SELECT id, platform FROM posts WHERE platform IS NOT NULL AND platform != ''").all();
|
||||
const migrate = db.prepare("UPDATE posts SET platforms = ? WHERE id = ?");
|
||||
for (const row of rows) {
|
||||
migrate.run(JSON.stringify([row.platform]), row.id);
|
||||
}
|
||||
console.log(`Added platforms column to posts, migrated ${rows.length} rows`);
|
||||
}
|
||||
|
||||
// assets additions
|
||||
addColumnIfMissing('assets', 'campaign_id', 'INTEGER REFERENCES campaigns(id)');
|
||||
|
||||
// users additions
|
||||
addColumnIfMissing('users', 'team_member_id', 'INTEGER REFERENCES team_members(id)');
|
||||
addColumnIfMissing('users', 'team_role', 'TEXT');
|
||||
addColumnIfMissing('users', 'brands', "TEXT DEFAULT '[]'");
|
||||
addColumnIfMissing('users', 'phone', 'TEXT');
|
||||
addColumnIfMissing('users', 'tutorial_completed', 'INTEGER DEFAULT 0');
|
||||
|
||||
// Migrate team_members to users (one-time migration)
|
||||
const teamMembers = db.prepare('SELECT * FROM team_members').all();
|
||||
const defaultPasswordHash = bcrypt.hashSync('changeme123', 10);
|
||||
|
||||
Reference in New Issue
Block a user