diff --git a/storage/framework/core/queue/src/process.ts b/storage/framework/core/queue/src/process.ts index c63e0fe31..1fd0613e3 100644 --- a/storage/framework/core/queue/src/process.ts +++ b/storage/framework/core/queue/src/process.ts @@ -1,6 +1,6 @@ import { ok, type Ok } from '@stacksjs/error-handling' import { log } from '@stacksjs/logging' -import { Job, type JobModel } from '../../../orm/src/models/Job' +import { Job } from '../../../orm/src/models/Job' import { runJob } from './job' interface QueuePayload { @@ -16,7 +16,8 @@ export async function processJobs(queue: string | undefined): Promise { const jobs = await Job.when(queue !== undefined, (query: any) => query.where('queue', queue)).get() for (const job of jobs) { + if (!job.payload) + continue - if (!job.payload) continue - - if (job.available_at && job.available_at > timestampNow()) continue + if (job.available_at && job.available_at > timestampNow()) + continue const body: QueuePayload = JSON.parse(job.payload) const currentAttempts = job.attempts || 0 @@ -55,7 +57,8 @@ async function executeJobs(queue: string | undefined): Promise { await job.delete() log.info(`Successfully ran job: ${body.displayName}`) - } catch (error) { + } + catch (error) { log.error(`Job failed: ${body.displayName}`, error) } } @@ -64,7 +67,8 @@ async function executeJobs(queue: string | undefined): Promise { async function updateJobAttempts(job: any, currentAttempts: number): Promise { try { await job.update({ attempts: currentAttempts + 1 }) - } catch (error) { + } + catch (error) { log.error('Failed to update job attempts:', error) } } diff --git a/storage/framework/core/queue/src/utils.ts b/storage/framework/core/queue/src/utils.ts index 1c0aa7b04..823c69c79 100644 --- a/storage/framework/core/queue/src/utils.ts +++ b/storage/framework/core/queue/src/utils.ts @@ -13,7 +13,7 @@ export async function storeJob(name: string, options: QueueOption): Promise 'default', }, - + queue: { required: true, fillable: true, @@ -62,6 +62,6 @@ export default { rule: schema.date(), }, factory: () => '2024-12-23 13:32:19', - } + }, }, } satisfies Model diff --git a/storage/framework/orm/src/models/FailedJob.ts b/storage/framework/orm/src/models/FailedJob.ts new file mode 100644 index 000000000..a9bad4779 --- /dev/null +++ b/storage/framework/orm/src/models/FailedJob.ts @@ -0,0 +1,851 @@ +import type { Insertable, Selectable, Updateable } from 'kysely' +import { cache } from '@stacksjs/cache' +import { db, sql } from '@stacksjs/database' +import { HttpError } from '@stacksjs/error-handling' + +export interface FailedJobsTable { + id?: number + connection?: string + queue?: string + payload?: string + exception?: string + failed_at?: Date + + created_at?: Date + + updated_at?: Date + +} + +interface FailedJobResponse { + data: FailedJobs + paging: { + total_records: number + page: number + total_pages: number + } + next_cursor: number | null +} + +export type FailedJobType = Selectable +export type NewFailedJob = Partial> +export type FailedJobUpdate = Updateable +export type FailedJobs = FailedJobType[] + +export type FailedJobColumn = FailedJobs +export type FailedJobColumns = Array + + type SortDirection = 'asc' | 'desc' +interface SortOptions { column: FailedJobType, order: SortDirection } +// Define a type for the options parameter +interface QueryOptions { + sort?: SortOptions + limit?: number + offset?: number + page?: number +} + +export class FailedJobModel { + private hidden = [] + private fillable = ['connection', 'queue', 'payload', 'exception', 'failed_at', 'uuid'] + private softDeletes = false + protected selectFromQuery: any + protected withRelations: string[] + protected updateFromQuery: any + protected deleteFromQuery: any + protected hasSelect: boolean + public id: number + public connection: string | undefined + public queue: string | undefined + public payload: string | undefined + public exception: string | undefined + public failed_at: Date | undefined + + public created_at: Date | undefined + public updated_at: Date | undefined + + constructor(failedjob: Partial | null) { + this.id = failedjob?.id || 1 + this.connection = failedjob?.connection + this.queue = failedjob?.queue + this.payload = failedjob?.payload + this.exception = failedjob?.exception + this.failed_at = failedjob?.failed_at + + this.created_at = failedjob?.created_at + + this.updated_at = failedjob?.updated_at + + this.withRelations = [] + this.selectFromQuery = db.selectFrom('failed_jobs') + this.updateFromQuery = db.updateTable('failed_jobs') + this.deleteFromQuery = db.deleteFrom('failed_jobs') + this.hasSelect = false + } + + // Method to find a FailedJob by ID + async find(id: number): Promise { + const query = db.selectFrom('failed_jobs').where('id', '=', id).selectAll() + + const model = await query.executeTakeFirst() + + if (!model) + return undefined + + const result = await this.mapWith(model) + + const data = new FailedJobModel(result as FailedJobType) + + cache.getOrSet(`failedjob:${id}`, JSON.stringify(model)) + + return data + } + + // Method to find a FailedJob by ID + static async find(id: number): Promise { + const model = await db.selectFrom('failed_jobs').where('id', '=', id).selectAll().executeTakeFirst() + + if (!model) + return undefined + + const instance = new FailedJobModel(null) + + const result = await instance.mapWith(model) + + const data = new FailedJobModel(result as FailedJobType) + + cache.getOrSet(`failedjob:${id}`, JSON.stringify(model)) + + return data + } + + async mapWith(model: FailedJobType): Promise { + return model + } + + static async all(): Promise { + const models = await db.selectFrom('failed_jobs').selectAll().execute() + + const data = await Promise.all(models.map(async (model: FailedJobType) => { + const instance = new FailedJobModel(model) + + const results = await instance.mapWith(model) + + return new FailedJobModel(results) + })) + + return data + } + + static async findOrFail(id: number): Promise { + const model = await db.selectFrom('failed_jobs').where('id', '=', id).selectAll().executeTakeFirst() + + const instance = new FailedJobModel(null) + + if (model === undefined) + throw new HttpError(404, `No FailedJobModel results for ${id}`) + + cache.getOrSet(`failedjob:${id}`, JSON.stringify(model)) + + const result = await instance.mapWith(model) + + const data = new FailedJobModel(result as FailedJobType) + + return data + } + + async findOrFail(id: number): Promise { + const model = await db.selectFrom('failed_jobs').where('id', '=', id).selectAll().executeTakeFirst() + + if (model === undefined) + throw new HttpError(404, `No FailedJobModel results for ${id}`) + + cache.getOrSet(`failedjob:${id}`, JSON.stringify(model)) + + const result = await this.mapWith(model) + + const data = new FailedJobModel(result as FailedJobType) + + return data + } + + static async findMany(ids: number[]): Promise { + let query = db.selectFrom('failed_jobs').where('id', 'in', ids) + + const instance = new FailedJobModel(null) + + query = query.selectAll() + + const model = await query.execute() + + return model.map(modelItem => instance.parseResult(new FailedJobModel(modelItem))) + } + + static async get(): Promise { + const instance = new FailedJobModel(null) + + let models + + if (instance.hasSelect) { + models = await instance.selectFromQuery.execute() + } + else { + models = await instance.selectFromQuery.selectAll().execute() + } + + const data = await Promise.all(models.map(async (model: FailedJobModel) => { + const instance = new FailedJobModel(model) + + const results = await instance.mapWith(model) + + return new FailedJobModel(results) + })) + + return data + } + + // Method to get a FailedJob by criteria + async get(): Promise { + if (this.hasSelect) { + const model = await this.selectFromQuery.execute() + + return model.map((modelItem: FailedJobModel) => new FailedJobModel(modelItem)) + } + + const model = await this.selectFromQuery.selectAll().execute() + + return model.map((modelItem: FailedJobModel) => new FailedJobModel(modelItem)) + } + + static async count(): Promise { + const instance = new FailedJobModel(null) + + const results = await instance.selectFromQuery.selectAll().execute() + + return results.length + } + + async count(): Promise { + if (this.hasSelect) { + const results = await this.selectFromQuery.execute() + + return results.length + } + + const results = await this.selectFromQuery.execute() + + return results.length + } + + // Method to get all failed_jobs + static async paginate(options: QueryOptions = { limit: 10, offset: 0, page: 1 }): Promise { + const totalRecordsResult = await db.selectFrom('failed_jobs') + .select(db.fn.count('id').as('total')) // Use 'id' or another actual column name + .executeTakeFirst() + + const totalRecords = Number(totalRecordsResult?.total) || 0 + const totalPages = Math.ceil(totalRecords / (options.limit ?? 10)) + + const failed_jobsWithExtra = await db.selectFrom('failed_jobs') + .selectAll() + .orderBy('id', 'asc') // Assuming 'id' is used for cursor-based pagination + .limit((options.limit ?? 10) + 1) // Fetch one extra record + .offset(((options.page ?? 1) - 1) * (options.limit ?? 10)) // Ensure options.page is not undefined + .execute() + + let nextCursor = null + if (failed_jobsWithExtra.length > (options.limit ?? 10)) + nextCursor = failed_jobsWithExtra.pop()?.id ?? null + + return { + data: failed_jobsWithExtra, + paging: { + total_records: totalRecords, + page: options.page || 1, + total_pages: totalPages, + }, + next_cursor: nextCursor, + } + } + + // Method to create a new failedjob + static async create(newFailedJob: NewFailedJob): Promise { + const instance = new FailedJobModel(null) + + const filteredValues = Object.fromEntries( + Object.entries(newFailedJob).filter(([key]) => instance.fillable.includes(key)), + ) as NewFailedJob + + const result = await db.insertInto('failed_jobs') + .values(filteredValues) + .executeTakeFirst() + + const model = await find(Number(result.numInsertedOrUpdatedRows)) as FailedJobModel + + return model + } + + static async createMany(newFailedJobs: NewFailedJob[]): Promise { + const instance = new FailedJobModel(null) + + const filteredValues = newFailedJobs.map(newUser => + Object.fromEntries( + Object.entries(newUser).filter(([key]) => instance.fillable.includes(key)), + ) as NewFailedJob, + ) + + await db.insertInto('failed_jobs') + .values(filteredValues) + .executeTakeFirst() + } + + static async forceCreate(newFailedJob: NewFailedJob): Promise { + const result = await db.insertInto('failed_jobs') + .values(newFailedJob) + .executeTakeFirst() + + const model = await find(Number(result.numInsertedOrUpdatedRows)) as FailedJobModel + + return model + } + + // Method to remove a FailedJob + static async remove(id: number): Promise { + return await db.deleteFrom('failed_jobs') + .where('id', '=', id) + .execute() + } + + where(...args: (string | number | boolean | undefined | null)[]): FailedJobModel { + let column: any + let operator: any + let value: any + + if (args.length === 2) { + [column, value] = args + operator = '=' + } + else if (args.length === 3) { + [column, operator, value] = args + } + else { + throw new HttpError(500, 'Invalid number of arguments') + } + + this.selectFromQuery = this.selectFromQuery.where(column, operator, value) + + this.updateFromQuery = this.updateFromQuery.where(column, operator, value) + this.deleteFromQuery = this.deleteFromQuery.where(column, operator, value) + + return this + } + + orWhere(...args: Array<[string, string, any]>): FailedJobModel { + if (args.length === 0) { + throw new HttpError(500, 'At least one condition must be provided') + } + + // Use the expression builder to append the OR conditions + this.selectFromQuery = this.selectFromQuery.where((eb: any) => + eb.or( + args.map(([column, operator, value]) => eb(column, operator, value)), + ), + ) + + this.updateFromQuery = this.updateFromQuery.where((eb: any) => + eb.or( + args.map(([column, operator, value]) => eb(column, operator, value)), + ), + ) + + this.deleteFromQuery = this.deleteFromQuery.where((eb: any) => + eb.or( + args.map(([column, operator, value]) => eb(column, operator, value)), + ), + ) + + return this + } + + static orWhere(...args: Array<[string, string, any]>): FailedJobModel { + const instance = new FailedJobModel(null) + + if (args.length === 0) { + throw new HttpError(500, 'At least one condition must be provided') + } + + // Use the expression builder to append the OR conditions + instance.selectFromQuery = instance.selectFromQuery.where((eb: any) => + eb.or( + args.map(([column, operator, value]) => eb(column, operator, value)), + ), + ) + + instance.updateFromQuery = instance.updateFromQuery.where((eb: any) => + eb.or( + args.map(([column, operator, value]) => eb(column, operator, value)), + ), + ) + + instance.deleteFromQuery = instance.deleteFromQuery.where((eb: any) => + eb.or( + args.map(([column, operator, value]) => eb(column, operator, value)), + ), + ) + + return instance + } + + static where(...args: (string | number | boolean | undefined | null)[]): FailedJobModel { + let column: any + let operator: any + let value: any + + const instance = new FailedJobModel(null) + + if (args.length === 2) { + [column, value] = args + operator = '=' + } + else if (args.length === 3) { + [column, operator, value] = args + } + else { + throw new HttpError(500, 'Invalid number of arguments') + } + + instance.selectFromQuery = instance.selectFromQuery.where(column, operator, value) + + instance.updateFromQuery = instance.updateFromQuery.where(column, operator, value) + + instance.deleteFromQuery = instance.deleteFromQuery.where(column, operator, value) + + return instance + } + + static when( + condition: boolean, + callback: (query: any) => FailedJobModel, + ): FailedJobModel { + let instance = new FailedJobModel(null) + + if (condition) + instance = callback(instance) + + return instance + } + + when( + condition: boolean, + callback: (query: any) => FailedJobModel, + ): FailedJobModel { + if (condition) + callback(this.selectFromQuery) + + return this + } + + static whereNull(column: string): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.selectFromQuery = instance.selectFromQuery.where((eb: any) => + eb(column, '=', '').or(column, 'is', null), + ) + + instance.updateFromQuery = instance.updateFromQuery.where((eb: any) => + eb(column, '=', '').or(column, 'is', null), + ) + + return instance + } + + whereNull(column: string): FailedJobModel { + this.selectFromQuery = this.selectFromQuery.where((eb: any) => + eb(column, '=', '').or(column, 'is', null), + ) + + this.updateFromQuery = this.updateFromQuery.where((eb: any) => + eb(column, '=', '').or(column, 'is', null), + ) + + return this + } + + static whereConnection(value: string): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.selectFromQuery = instance.selectFromQuery.where('connection', '=', value) + + return instance + } + + static whereQueue(value: string): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.selectFromQuery = instance.selectFromQuery.where('queue', '=', value) + + return instance + } + + static wherePayload(value: string): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.selectFromQuery = instance.selectFromQuery.where('payload', '=', value) + + return instance + } + + static whereException(value: string): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.selectFromQuery = instance.selectFromQuery.where('exception', '=', value) + + return instance + } + + static whereFailedAt(value: string): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.selectFromQuery = instance.selectFromQuery.where('failed_at', '=', value) + + return instance + } + + static whereIn(column: keyof FailedJobType, values: any[]): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.selectFromQuery = instance.selectFromQuery.where(column, 'in', values) + + instance.updateFromQuery = instance.updateFromQuery.where(column, 'in', values) + + instance.deleteFromQuery = instance.deleteFromQuery.where(column, 'in', values) + + return instance + } + + async first(): Promise { + const model = await this.selectFromQuery.selectAll().executeTakeFirst() + + if (!model) + return undefined + + const result = await this.mapWith(model) + + const data = new FailedJobModel(result as FailedJobType) + + return data + } + + async firstOrFail(): Promise { + const model = await this.selectFromQuery.executeTakeFirst() + + if (model === undefined) + throw new HttpError(404, 'No FailedJobModel results found for query') + + const instance = new FailedJobModel(null) + + const result = await instance.mapWith(model) + + const data = new FailedJobModel(result as FailedJobType) + + return data + } + + async exists(): Promise { + const model = await this.selectFromQuery.executeTakeFirst() + + return model !== null || model !== undefined + } + + static async first(): Promise { + const model = await db.selectFrom('failed_jobs') + .selectAll() + .executeTakeFirst() + + if (!model) + return undefined + + const instance = new FailedJobModel(null) + + const result = await instance.mapWith(model) + + const data = new FailedJobModel(result as FailedJobType) + + return data + } + + with(relations: string[]): FailedJobModel { + this.withRelations = relations + + return this + } + + static with(relations: string[]): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.withRelations = relations + + return instance + } + + async last(): Promise { + return await db.selectFrom('failed_jobs') + .selectAll() + .orderBy('id', 'desc') + .executeTakeFirst() + } + + static async last(): Promise { + const model = await db.selectFrom('failed_jobs').selectAll().orderBy('id', 'desc').executeTakeFirst() + + if (!model) + return undefined + + const instance = new FailedJobModel(null) + + const result = await instance.mapWith(model) + + const data = new FailedJobModel(result as FailedJobType) + + return data + } + + static orderBy(column: keyof FailedJobType, order: 'asc' | 'desc'): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.selectFromQuery = instance.selectFromQuery.orderBy(column, order) + + return instance + } + + orderBy(column: keyof FailedJobType, order: 'asc' | 'desc'): FailedJobModel { + this.selectFromQuery = this.selectFromQuery.orderBy(column, order) + + return this + } + + static orderByDesc(column: keyof FailedJobType): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.selectFromQuery = instance.selectFromQuery.orderBy(column, 'desc') + + return instance + } + + orderByDesc(column: keyof FailedJobType): FailedJobModel { + this.selectFromQuery = this.orderBy(column, 'desc') + + return this + } + + static orderByAsc(column: keyof FailedJobType): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.selectFromQuery = instance.selectFromQuery.orderBy(column, 'asc') + + return instance + } + + orderByAsc(column: keyof FailedJobType): FailedJobModel { + this.selectFromQuery = this.selectFromQuery.orderBy(column, 'desc') + + return this + } + + async update(failedjob: FailedJobUpdate): Promise { + const filteredValues = Object.fromEntries( + Object.entries(failedjob).filter(([key]) => this.fillable.includes(key)), + ) as NewFailedJob + + if (this.id === undefined) { + this.updateFromQuery.set(filteredValues).execute() + } + + await db.updateTable('failed_jobs') + .set(filteredValues) + .where('id', '=', this.id) + .executeTakeFirst() + + const model = await this.find(this.id) + + return model + } + + async forceUpdate(failedjob: FailedJobUpdate): Promise { + if (this.id === undefined) { + this.updateFromQuery.set(failedjob).execute() + } + + await db.updateTable('failed_jobs') + .set(failedjob) + .where('id', '=', this.id) + .executeTakeFirst() + + const model = await this.find(this.id) + + return model + } + + async save(): Promise { + if (!this) + throw new HttpError(500, 'FailedJob data is undefined') + + if (this.id === undefined) { + await db.insertInto('failed_jobs') + .values(this as NewFailedJob) + .executeTakeFirstOrThrow() + } + else { + await this.update(this) + } + } + + // Method to delete (soft delete) the failedjob instance + async delete(): Promise { + if (this.id === undefined) + this.deleteFromQuery.execute() + + return await db.deleteFrom('failed_jobs') + .where('id', '=', this.id) + .execute() + } + + distinct(column: keyof FailedJobType): FailedJobModel { + this.selectFromQuery = this.selectFromQuery.select(column).distinct() + + this.hasSelect = true + + return this + } + + static distinct(column: keyof FailedJobType): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.selectFromQuery = instance.selectFromQuery.select(column).distinct() + + instance.hasSelect = true + + return instance + } + + join(table: string, firstCol: string, secondCol: string): FailedJobModel { + this.selectFromQuery = this.selectFromQuery(table, firstCol, secondCol) + + return this + } + + static join(table: string, firstCol: string, secondCol: string): FailedJobModel { + const instance = new FailedJobModel(null) + + instance.selectFromQuery = instance.selectFromQuery.innerJoin(table, firstCol, secondCol) + + return instance + } + + static async rawQuery(rawQuery: string): Promise { + return await sql`${rawQuery}`.execute(db) + } + + toJSON() { + const output: Partial = { + + id: this.id, + connection: this.connection, + queue: this.queue, + payload: this.payload, + exception: this.exception, + failed_at: this.failed_at, + + created_at: this.created_at, + + updated_at: this.updated_at, + + } + + type FailedJob = Omit + + return output as FailedJob + } + + parseResult(model: FailedJobModel): FailedJobModel { + for (const hiddenAttribute of this.hidden) { + delete model[hiddenAttribute as keyof FailedJobModel] + } + + return model + } +} + +async function find(id: number): Promise { + const query = db.selectFrom('failed_jobs').where('id', '=', id).selectAll() + + const model = await query.executeTakeFirst() + + if (!model) + return undefined + + return new FailedJobModel(model) +} + +export async function count(): Promise { + const results = await FailedJobModel.count() + + return results +} + +export async function create(newFailedJob: NewFailedJob): Promise { + const result = await db.insertInto('failed_jobs') + .values(newFailedJob) + .executeTakeFirstOrThrow() + + return await find(Number(result.numInsertedOrUpdatedRows)) as FailedJobModel +} + +export async function rawQuery(rawQuery: string): Promise { + return await sql`${rawQuery}`.execute(db) +} + +export async function remove(id: number): Promise { + await db.deleteFrom('failed_jobs') + .where('id', '=', id) + .execute() +} + +export async function whereConnection(value: string): Promise { + const query = db.selectFrom('failed_jobs').where('connection', '=', value) + const results = await query.execute() + + return results.map(modelItem => new FailedJobModel(modelItem)) +} + +export async function whereQueue(value: string): Promise { + const query = db.selectFrom('failed_jobs').where('queue', '=', value) + const results = await query.execute() + + return results.map(modelItem => new FailedJobModel(modelItem)) +} + +export async function wherePayload(value: string): Promise { + const query = db.selectFrom('failed_jobs').where('payload', '=', value) + const results = await query.execute() + + return results.map(modelItem => new FailedJobModel(modelItem)) +} + +export async function whereException(value: string): Promise { + const query = db.selectFrom('failed_jobs').where('exception', '=', value) + const results = await query.execute() + + return results.map(modelItem => new FailedJobModel(modelItem)) +} + +export async function whereFailedAt(value: Date): Promise { + const query = db.selectFrom('failed_jobs').where('failed_at', '=', value) + const results = await query.execute() + + return results.map(modelItem => new FailedJobModel(modelItem)) +} + +export const FailedJob = FailedJobModel + +export default FailedJob diff --git a/storage/framework/orm/src/types.ts b/storage/framework/orm/src/types.ts index d08c31389..9382ef9bb 100644 --- a/storage/framework/orm/src/types.ts +++ b/storage/framework/orm/src/types.ts @@ -1,6 +1,7 @@ import type { PersonalAccessTokensTable } from '../src/models/AccessToken' import type { DeploymentsTable } from '../src/models/Deployment' import type { ErrorsTable } from '../src/models/Error' +import type { FailedJobsTable } from '../src/models/FailedJob' import type { JobsTable } from '../src/models/Job' import type { PaymentMethodsTable } from '../src/models/PaymentMethod' import type { PostsTable } from '../src/models/Post' @@ -63,6 +64,7 @@ export interface Database { releases: ReleasesTable users: UsersTable posts: PostsTable + failed_jobs: FailedJobsTable products: ProductsTable payment_methods: PaymentMethodsTable transactions: TransactionsTable diff --git a/storage/framework/requests/FailedJobRequest.ts b/storage/framework/requests/FailedJobRequest.ts new file mode 100644 index 000000000..75d31876b --- /dev/null +++ b/storage/framework/requests/FailedJobRequest.ts @@ -0,0 +1,43 @@ +import type { FailedJobRequestType } from '../types/requests' +import { Request } from '@stacksjs/router' +import { customValidate, validateField } from '@stacksjs/validation' + +interface ValidationField { + rule: ReturnType + message: Record +} + +interface CustomAttributes { + [key: string]: ValidationField +} +interface RequestDataFailedJob { + id: number + connection: string + queue: string + payload: string + exception: string + failed_at: date + created_at?: Date + updated_at?: Date +} +export class FailedJobRequest extends Request implements FailedJobRequestType { + public id = 1 + public connection = '' + public queue = '' + public payload = '' + public exception = '' + public failed_at = '' + public created_at = new Date() + public updated_at = new Date() + + public async validate(attributes?: CustomAttributes): Promise { + if (attributes === undefined || attributes === null) { + await validateField('FailedJob', this.all()) + } + else { + await customValidate(attributes, this.all()) + } + } +} + +export const request = new FailedJobRequest() diff --git a/storage/framework/types/requests.d.ts b/storage/framework/types/requests.d.ts index d0cf98162..de2497f71 100644 --- a/storage/framework/types/requests.d.ts +++ b/storage/framework/types/requests.d.ts @@ -235,6 +235,31 @@ export interface PostRequestType extends Request { updated_at?: Date } +interface RequestDataFailedJob { + id: number + connection: string + queue: string + payload: string + exception: string + failed_at: date + created_at?: Date + updated_at?: Date +} +export interface FailedJobRequestType extends Request { + validate: (attributes?: CustomAttributes) => void + get: ((key: 'id') => number) & ((key: 'connection' | 'queue' | 'payload' | 'exception') => string) & ((key: 'failed_at') => date) + + all: () => RequestDataFailedJob + id: number + connection: string + queue: string + payload: string + exception: string + failed_at: date + created_at?: Date + updated_at?: Date +} + interface RequestDataProduct { id: number name: string @@ -413,4 +438,4 @@ export interface ErrorRequestType extends Request { updated_at?: Date } -export type ModelRequest = ProjectRequestType | SubscriberEmailRequestType | AccessTokenRequestType | TeamRequestType | SubscriberRequestType | DeploymentRequestType | ReleaseRequestType | UserRequestType | PostRequestTypeProductRequestTypePaymentMethodRequestTypeTransactionRequestTypeJobRequestTypeSubscriptionRequestTypeErrorRequestType +export type ModelRequest = ProjectRequestType | SubscriberEmailRequestType | AccessTokenRequestType | TeamRequestType | SubscriberRequestType | DeploymentRequestType | ReleaseRequestType | UserRequestType | PostRequestTypeFailedJobRequestTypeProductRequestTypePaymentMethodRequestTypeTransactionRequestTypeJobRequestTypeSubscriptionRequestTypeErrorRequestType