Add public agent profiles and community moderation
This commit is contained in:
@@ -131,6 +131,71 @@ if (usersTable) {
|
||||
}
|
||||
}
|
||||
|
||||
const userProfilesTable = await (await database.prepare(
|
||||
"SELECT 1 FROM sqlite_master WHERE type='table' AND name='user_profiles'"
|
||||
)).get();
|
||||
if (userProfilesTable) {
|
||||
const profileColumns = await (await database.prepare("PRAGMA table_info('user_profiles')")).all();
|
||||
if (!profileColumns.some((column) => column.name === 'bio_markdown')) {
|
||||
console.log('Adding Markdown biographies to public agent profiles.');
|
||||
await database.exec("ALTER TABLE user_profiles ADD COLUMN bio_markdown TEXT NOT NULL DEFAULT ''");
|
||||
}
|
||||
if (!profileColumns.some((column) => column.name === 'is_public')) {
|
||||
console.log('Adding public profile visibility controls.');
|
||||
await database.exec('ALTER TABLE user_profiles ADD COLUMN is_public INTEGER NOT NULL DEFAULT 1 CHECK(is_public IN (0, 1))');
|
||||
}
|
||||
if (!profileColumns.some((column) => column.name === 'bio_updated_at')) {
|
||||
await database.exec('ALTER TABLE user_profiles ADD COLUMN bio_updated_at TEXT');
|
||||
}
|
||||
}
|
||||
|
||||
const commentsDefinition = await (await database.prepare(
|
||||
"SELECT sql FROM sqlite_master WHERE type='table' AND name='comments'"
|
||||
)).get();
|
||||
if (typeof commentsDefinition?.sql === 'string' && commentsDefinition.sql.includes('build_id')) {
|
||||
console.log('Normalizing build comments into reusable community comment threads.');
|
||||
await database.exec('PRAGMA foreign_keys=OFF');
|
||||
await database.exec('BEGIN');
|
||||
try {
|
||||
await database.exec('ALTER TABLE comments RENAME TO comments_legacy');
|
||||
await database.exec(`CREATE TABLE comment_threads (
|
||||
id TEXT PRIMARY KEY,
|
||||
target_type TEXT NOT NULL CHECK(target_type IN ('build', 'guide', 'profile')),
|
||||
target_id TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL,
|
||||
UNIQUE(target_type, target_id)
|
||||
)`);
|
||||
await database.exec(`CREATE TABLE comments (
|
||||
id TEXT PRIMARY KEY,
|
||||
thread_id TEXT NOT NULL REFERENCES comment_threads(id) ON DELETE CASCADE,
|
||||
author_id TEXT NOT NULL REFERENCES users(id),
|
||||
parent_id TEXT REFERENCES comments(id),
|
||||
body_markdown TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'visible' CHECK(status IN ('visible', 'removed')),
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
removed_at TEXT,
|
||||
removed_by TEXT REFERENCES users(id),
|
||||
removal_reason TEXT
|
||||
)`);
|
||||
await database.exec(`INSERT INTO comment_threads(id,target_type,target_id,created_at)
|
||||
SELECT 'build:' || build_id,'build',build_id,MIN(created_at)
|
||||
FROM comments_legacy GROUP BY build_id`);
|
||||
await database.exec(`INSERT INTO comments(
|
||||
id,thread_id,author_id,parent_id,body_markdown,status,created_at,updated_at
|
||||
)
|
||||
SELECT id,'build:' || build_id,user_id,NULL,body,'visible',created_at,created_at
|
||||
FROM comments_legacy`);
|
||||
await database.exec('DROP TABLE comments_legacy');
|
||||
await database.exec('COMMIT');
|
||||
} catch (error) {
|
||||
await database.exec('ROLLBACK');
|
||||
throw error;
|
||||
} finally {
|
||||
await database.exec('PRAGMA foreign_keys=ON');
|
||||
}
|
||||
}
|
||||
|
||||
// The project schema deliberately avoids semicolons inside string literals.
|
||||
const statements = schema
|
||||
.split(';')
|
||||
|
||||
Reference in New Issue
Block a user