Files
ShreejitPanchal 6601501eff Init commit
2026-05-19 19:56:02 +08:00

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
}
}
}