183 lines
4.0 KiB
TypeScript
183 lines
4.0 KiB
TypeScript
import { Transaction } from 'sequelize'
|
|
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Table, UpdatedAt } from 'sequelize-typescript'
|
|
import { MEvent } from '@server/types/models/index.js'
|
|
import { VideoChannelModel } from './video-channel.js'
|
|
import { SequelizeModel } from '../shared/index.js'
|
|
|
|
export enum EventState {
|
|
ACTIVE = 'active',
|
|
DISABLED = 'disabled'
|
|
}
|
|
|
|
@Table({
|
|
tableName: 'event',
|
|
indexes: [
|
|
{
|
|
fields: [ 'channelId' ]
|
|
},
|
|
{
|
|
fields: [ 'state' ]
|
|
},
|
|
{
|
|
fields: [ 'startTime' ]
|
|
}
|
|
]
|
|
})
|
|
export class EventModel extends SequelizeModel<EventModel> {
|
|
@AllowNull(false)
|
|
@Column
|
|
declare title: string
|
|
|
|
@AllowNull(true)
|
|
@Column(DataType.TEXT)
|
|
declare description: string | null
|
|
|
|
@AllowNull(false)
|
|
@Column
|
|
declare startTime: Date
|
|
|
|
@AllowNull(false)
|
|
@Column
|
|
declare endTime: Date
|
|
|
|
@AllowNull(true)
|
|
@Column
|
|
declare thumbnailFilename: string | null
|
|
|
|
@AllowNull(true)
|
|
@Column(DataType.BLOB)
|
|
declare thumbnailData: Buffer | null
|
|
|
|
@AllowNull(true)
|
|
@Column
|
|
declare thumbnailMimeType: string | null
|
|
|
|
@AllowNull(true)
|
|
@Column(DataType.BIGINT)
|
|
declare thumbnailSize: number | null
|
|
|
|
@AllowNull(true)
|
|
@Column
|
|
declare thumbnailEtag: string | null
|
|
|
|
@AllowNull(true)
|
|
@Column(DataType.TEXT)
|
|
declare liveUrl: string | null
|
|
|
|
@AllowNull(false)
|
|
@Default(EventState.ACTIVE)
|
|
@Column
|
|
declare state: EventState
|
|
|
|
@CreatedAt
|
|
declare createdAt: Date
|
|
|
|
@UpdatedAt
|
|
declare updatedAt: Date
|
|
|
|
@ForeignKey(() => VideoChannelModel)
|
|
@Column
|
|
declare channelId: number
|
|
|
|
@BelongsTo(() => VideoChannelModel, {
|
|
foreignKey: {
|
|
allowNull: false
|
|
},
|
|
onDelete: 'cascade'
|
|
})
|
|
declare Channel: Awaited<VideoChannelModel>
|
|
|
|
static listByChannelId (channelId: number, transaction?: Transaction) {
|
|
const query = {
|
|
where: {
|
|
channelId
|
|
},
|
|
order: [ [ 'startTime', 'DESC' ] ] as any,
|
|
transaction
|
|
}
|
|
|
|
return EventModel.findAll<MEvent>(query)
|
|
}
|
|
|
|
static findByIdAndChannelId (eventId: number, channelId: number, transaction?: Transaction) {
|
|
const query = {
|
|
where: {
|
|
id: eventId,
|
|
channelId
|
|
},
|
|
transaction
|
|
}
|
|
|
|
return EventModel.findOne<MEvent>(query)
|
|
}
|
|
|
|
static loadByThumbnailFilename (thumbnailFilename: string, transaction?: Transaction) {
|
|
return EventModel.findOne<MEvent>({
|
|
where: {
|
|
thumbnailFilename
|
|
},
|
|
transaction
|
|
})
|
|
}
|
|
|
|
static listPublicEvents (limit?: number, states?: string[]) {
|
|
const query: any = {
|
|
order: [ [ 'startTime', 'DESC' ] ] as any,
|
|
limit
|
|
}
|
|
|
|
// Only filter by state if explicitly provided; otherwise return all events
|
|
if (states && states.length > 0) {
|
|
query.where = { state: states }
|
|
}
|
|
|
|
return EventModel.findAll<MEvent>(query)
|
|
}
|
|
|
|
static async deleteByIdAndChannelId (eventId: number, channelId: number, transaction?: Transaction) {
|
|
const event = await EventModel.findByIdAndChannelId(eventId, channelId, transaction)
|
|
if (!event) return false
|
|
|
|
await event.destroy({ transaction })
|
|
return true
|
|
}
|
|
|
|
static async updateEventState (eventId: number, newState: EventState, transaction?: Transaction) {
|
|
const query = {
|
|
where: {
|
|
id: eventId
|
|
},
|
|
transaction
|
|
}
|
|
|
|
return EventModel.update({ state: newState }, query)
|
|
}
|
|
|
|
toFormattedJSON (this: EventModel) {
|
|
return {
|
|
id: this.id,
|
|
title: this.title,
|
|
description: this.description,
|
|
startTime: this.startTime.toISOString(),
|
|
endTime: this.endTime.toISOString(),
|
|
thumbnailFilename: this.thumbnailFilename,
|
|
liveUrl: this.liveUrl,
|
|
state: this.state,
|
|
channelId: this.channelId,
|
|
createdAt: this.createdAt.toISOString(),
|
|
updatedAt: this.updatedAt.toISOString()
|
|
}
|
|
}
|
|
|
|
toLogKeys (this: EventModel) {
|
|
return {
|
|
id: this.id,
|
|
title: this.title,
|
|
state: this.state,
|
|
startTime: this.startTime,
|
|
endTime: this.endTime,
|
|
channelId: this.channelId
|
|
}
|
|
}
|
|
}
|