All files / src/platform/widgets/schemas widget.schema.ts

0% Statements 0/49
0% Branches 0/4
100% Functions 0/0
0% Lines 0/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                                                                                                                                                                                                                         
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document, Schema as MongooseSchema } from 'mongoose';
 
@Schema({ timestamps: true, collection: 'widget_definitions' })
export class WidgetDefinition extends Document {
  @Prop({ required: true, unique: true, index: true })
  key: string; // e.g. 'kpi.totalRevenue', 'chart.salesTrend'
 
  @Prop({ required: true })
  name: string;
 
  @Prop({ required: true })
  type: string; // 'KPI' | 'CHART' | 'TABLE' | 'ACTIVITY' | 'TASK' | 'CALENDAR' | 'PROGRESS' | 'REPORT' | 'QUICK_ACTION' | 'ANNOUNCEMENT'
 
  @Prop({ default: null })
  moduleKey: string; // Widget belongs to this module
 
  @Prop({ type: MongooseSchema.Types.Mixed, default: {} })
  defaultConfig: any;
 
  @Prop({ default: null })
  description: string;
 
  @Prop({ default: 'medium' })
  defaultSize: string; // 'small' | 'medium' | 'large'
 
  @Prop({ default: true })
  isActive: boolean;
}
export const WidgetDefinitionSchema =
  SchemaFactory.createForClass(WidgetDefinition);
 
@Schema({ timestamps: true, collection: 'dashboard_definitions' })
export class DashboardDefinition extends Document {
  @Prop({ required: true, index: true })
  tenantId: string;
 
  @Prop({ default: null, index: true })
  userId: string; // null means shared/default dashboard
 
  @Prop({ default: null })
  role: string;
 
  @Prop({ required: true })
  name: string;
 
  @Prop({ required: true, default: 'TENANT' })
  scope: string; // 'PLATFORM' | 'TENANT' | 'ROLE' | 'USER' | 'BRANCH' | 'DEPARTMENT'
 
  @Prop({ default: false })
  isDefault: boolean;
}
export const DashboardDefinitionSchema =
  SchemaFactory.createForClass(DashboardDefinition);
DashboardDefinitionSchema.index({ tenantId: 1, scope: 1, userId: 1 });
 
@Schema({ timestamps: true, collection: 'dashboard_layouts' })
export class DashboardLayout extends Document {
  @Prop({ required: true, unique: true, index: true })
  dashboardId: string;
 
  @Prop({
    type: MongooseSchema.Types.Mixed,
    default: { desktop: [], tablet: [], mobile: [] },
  })
  gridPositions: any; // { desktop: [{widgetKey, x, y, w, h}], tablet: [...], mobile: [...] }
}
export const DashboardLayoutSchema =
  SchemaFactory.createForClass(DashboardLayout);
 
@Schema({ timestamps: true, collection: 'dashboard_widget_instances' })
export class DashboardWidgetInstance extends Document {
  @Prop({ required: true, index: true })
  dashboardId: string;
 
  @Prop({ required: true })
  widgetKey: string;
 
  @Prop({ type: MongooseSchema.Types.Mixed, default: {} })
  config: any; // User-specific override config for this widget instance
 
  @Prop({ default: 300 })
  refreshIntervalSeconds: number;
 
  @Prop({ type: MongooseSchema.Types.Mixed, default: null })
  savedFilters: any;
}
export const DashboardWidgetInstanceSchema = SchemaFactory.createForClass(
  DashboardWidgetInstance,
);
 
@Schema({ timestamps: true, collection: 'widget_data_cache' })
export class WidgetDataCache extends Document {
  @Prop({ required: true, index: true })
  tenantId: string;
 
  @Prop({ required: true })
  widgetKey: string;
 
  @Prop({ type: MongooseSchema.Types.Mixed, default: null })
  data: any;
 
  @Prop({ required: true })
  expiresAt: Date;
}
export const WidgetDataCacheSchema =
  SchemaFactory.createForClass(WidgetDataCache);
WidgetDataCacheSchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 }); // TTL index