feat(platform-admin): ✨ Add content moderation schema and app module registration
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
b5f668733e
commit
3e16e8795b
3 changed files with 368 additions and 0 deletions
|
|
@ -7,6 +7,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
|||
|
||||
import { AssetStorageModule } from './asset-storage/index';
|
||||
import { AuthModule } from './auth/auth.module';
|
||||
import { ContentModerationModule } from './content-moderation/content-moderation.module';
|
||||
import { ContentHubModule } from './content-hub/content-hub.module';
|
||||
import { DevicesModule } from './devices/devices.module';
|
||||
import { HealthController } from './health/health.controller';
|
||||
|
|
@ -68,6 +69,7 @@ const registry = buildDeploymentRegistry({
|
|||
InfrastructureModule,
|
||||
AssetStorageModule,
|
||||
ContentHubModule,
|
||||
ContentModerationModule,
|
||||
],
|
||||
controllers: [HealthController],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -0,0 +1,365 @@
|
|||
import { Table, TableIndex } from 'typeorm';
|
||||
|
||||
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class ContentModerationSchema1710000000000 implements MigrationInterface {
|
||||
name = 'ContentModerationSchema1710000000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'content_scores',
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'uuid',
|
||||
isPrimary: true,
|
||||
generationStrategy: 'uuid',
|
||||
default: 'uuid_generate_v4()',
|
||||
},
|
||||
{
|
||||
name: 'contentType',
|
||||
type: 'varchar',
|
||||
length: '64',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'contentId',
|
||||
type: 'varchar',
|
||||
length: '255',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'authorId',
|
||||
type: 'varchar',
|
||||
length: '255',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'textPreview',
|
||||
type: 'text',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'flaggedCategories',
|
||||
type: 'jsonb',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'severity',
|
||||
type: 'varchar',
|
||||
length: '16',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'action',
|
||||
type: 'varchar',
|
||||
length: '16',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'reviewStatus',
|
||||
type: 'varchar',
|
||||
length: '32',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'modelVersion',
|
||||
type: 'varchar',
|
||||
length: '64',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'scoredAt',
|
||||
type: 'timestamp',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'reviewedBy',
|
||||
type: 'varchar',
|
||||
length: '255',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'reviewedAt',
|
||||
type: 'timestamp',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'reviewNotes',
|
||||
type: 'text',
|
||||
isNullable: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'content_scores',
|
||||
new TableIndex({ name: 'IDX_content_scores_reviewStatus', columnNames: ['reviewStatus'] }),
|
||||
);
|
||||
await queryRunner.createIndex(
|
||||
'content_scores',
|
||||
new TableIndex({ name: 'IDX_content_scores_severity', columnNames: ['severity'] }),
|
||||
);
|
||||
await queryRunner.createIndex(
|
||||
'content_scores',
|
||||
new TableIndex({ name: 'IDX_content_scores_action', columnNames: ['action'] }),
|
||||
);
|
||||
await queryRunner.createIndex(
|
||||
'content_scores',
|
||||
new TableIndex({ name: 'IDX_content_scores_authorId', columnNames: ['authorId'] }),
|
||||
);
|
||||
await queryRunner.createIndex(
|
||||
'content_scores',
|
||||
new TableIndex({ name: 'IDX_content_scores_scoredAt', columnNames: ['scoredAt'] }),
|
||||
);
|
||||
await queryRunner.createIndex(
|
||||
'content_scores',
|
||||
new TableIndex({ name: 'IDX_content_scores_contentType', columnNames: ['contentType'] }),
|
||||
);
|
||||
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'user_threat_levels',
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'uuid',
|
||||
isPrimary: true,
|
||||
generationStrategy: 'uuid',
|
||||
default: 'uuid_generate_v4()',
|
||||
},
|
||||
{
|
||||
name: 'userId',
|
||||
type: 'varchar',
|
||||
length: '255',
|
||||
isNullable: false,
|
||||
isUnique: true,
|
||||
},
|
||||
{
|
||||
name: 'score',
|
||||
type: 'decimal',
|
||||
precision: 10,
|
||||
scale: 4,
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'level',
|
||||
type: 'varchar',
|
||||
length: '16',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'totalViolations',
|
||||
type: 'int',
|
||||
default: 0,
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'criticalViolations',
|
||||
type: 'int',
|
||||
default: 0,
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'highViolations',
|
||||
type: 'int',
|
||||
default: 0,
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'mediumViolations',
|
||||
type: 'int',
|
||||
default: 0,
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'lowViolations',
|
||||
type: 'int',
|
||||
default: 0,
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'categoryBreakdown',
|
||||
type: 'jsonb',
|
||||
isNullable: false,
|
||||
default: `'{}'::jsonb`,
|
||||
},
|
||||
{
|
||||
name: 'lastViolationAt',
|
||||
type: 'timestamp',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'lastEscalationAt',
|
||||
type: 'timestamp',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'sensitivityMultiplier',
|
||||
type: 'decimal',
|
||||
precision: 5,
|
||||
scale: 2,
|
||||
default: 1.0,
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'restrictions',
|
||||
type: 'jsonb',
|
||||
isNullable: false,
|
||||
default: `'{}'::jsonb`,
|
||||
},
|
||||
{
|
||||
name: 'adminOverride',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'adminOverrideBy',
|
||||
type: 'varchar',
|
||||
length: '255',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'adminOverrideAt',
|
||||
type: 'timestamp',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'adminNotes',
|
||||
type: 'text',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'createdAt',
|
||||
type: 'timestamp',
|
||||
default: 'CURRENT_TIMESTAMP',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'updatedAt',
|
||||
type: 'timestamp',
|
||||
default: 'CURRENT_TIMESTAMP',
|
||||
isNullable: false,
|
||||
},
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'user_threat_levels',
|
||||
new TableIndex({ name: 'IDX_user_threat_levels_level', columnNames: ['level'] }),
|
||||
);
|
||||
await queryRunner.createIndex(
|
||||
'user_threat_levels',
|
||||
new TableIndex({ name: 'IDX_user_threat_levels_score', columnNames: ['score'] }),
|
||||
);
|
||||
await queryRunner.createIndex(
|
||||
'user_threat_levels',
|
||||
new TableIndex({ name: 'IDX_user_threat_levels_userId', columnNames: ['userId'], isUnique: true }),
|
||||
);
|
||||
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'threat_escalation_events',
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'uuid',
|
||||
isPrimary: true,
|
||||
generationStrategy: 'uuid',
|
||||
default: 'uuid_generate_v4()',
|
||||
},
|
||||
{
|
||||
name: 'userId',
|
||||
type: 'varchar',
|
||||
length: '255',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'previousLevel',
|
||||
type: 'varchar',
|
||||
length: '16',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'newLevel',
|
||||
type: 'varchar',
|
||||
length: '16',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'previousScore',
|
||||
type: 'decimal',
|
||||
precision: 10,
|
||||
scale: 4,
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'newScore',
|
||||
type: 'decimal',
|
||||
precision: 10,
|
||||
scale: 4,
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'trigger',
|
||||
type: 'varchar',
|
||||
length: '32',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'triggerContentScoreId',
|
||||
type: 'uuid',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'metadata',
|
||||
type: 'jsonb',
|
||||
isNullable: false,
|
||||
default: `'{}'::jsonb`,
|
||||
},
|
||||
{
|
||||
name: 'createdAt',
|
||||
type: 'timestamp',
|
||||
default: 'CURRENT_TIMESTAMP',
|
||||
isNullable: false,
|
||||
},
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
await queryRunner.createIndex(
|
||||
'threat_escalation_events',
|
||||
new TableIndex({ name: 'IDX_threat_escalation_events_userId', columnNames: ['userId'] }),
|
||||
);
|
||||
await queryRunner.createIndex(
|
||||
'threat_escalation_events',
|
||||
new TableIndex({ name: 'IDX_threat_escalation_events_createdAt', columnNames: ['createdAt'] }),
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.dropIndex('threat_escalation_events', 'IDX_threat_escalation_events_createdAt');
|
||||
await queryRunner.dropIndex('threat_escalation_events', 'IDX_threat_escalation_events_userId');
|
||||
await queryRunner.dropTable('threat_escalation_events');
|
||||
|
||||
await queryRunner.dropIndex('user_threat_levels', 'IDX_user_threat_levels_userId');
|
||||
await queryRunner.dropIndex('user_threat_levels', 'IDX_user_threat_levels_score');
|
||||
await queryRunner.dropIndex('user_threat_levels', 'IDX_user_threat_levels_level');
|
||||
await queryRunner.dropTable('user_threat_levels');
|
||||
|
||||
await queryRunner.dropIndex('content_scores', 'IDX_content_scores_contentType');
|
||||
await queryRunner.dropIndex('content_scores', 'IDX_content_scores_scoredAt');
|
||||
await queryRunner.dropIndex('content_scores', 'IDX_content_scores_authorId');
|
||||
await queryRunner.dropIndex('content_scores', 'IDX_content_scores_action');
|
||||
await queryRunner.dropIndex('content_scores', 'IDX_content_scores_severity');
|
||||
await queryRunner.dropIndex('content_scores', 'IDX_content_scores_reviewStatus');
|
||||
await queryRunner.dropTable('content_scores');
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1,2 @@
|
|||
export { InitialSchema1700000000000 } from './1700000000000-InitialSchema';
|
||||
export { ContentModerationSchema1710000000000 } from './1710000000000-ContentModerationSchema';
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue