From 7e5a868a6fd73e1a99466c701ad06b44c0e79268 Mon Sep 17 00:00:00 2001 From: Jeff Man Date: Mon, 20 Jul 2026 14:32:20 +0100 Subject: [PATCH 1/2] feat: email reminders for follow-up dates via Brevo Adds a background job that sends follow-up reminder emails 24 h before a scheduled follow-up date using the Brevo transactional email API. - reminderSentAt DateTime? column on JobApplication (Prisma + migration) - IEmailService port + BrevoEmailService (raw fetch, no SDK) - findDueForReminder() + updateReminderSentAt() on IApplicationRepository implemented in PrismaApplicationRepository and delegated in CachedApplicationRepository - SendFollowUpRemindersUseCase: queries due apps, looks up user email, sends, marks sent - reminders.plugin.ts: Fastify plugin with 1-hour setInterval, registered in app.ts - container.ts: emailService (SINGLETON) + sendFollowUpRemindersUseCase (TRANSIENT) - env.example: BREVO_API_KEY, FROM_EMAIL, FROM_NAME - Unit tests: sends email, skips missing user, continues past individual failures - Web: "Email reminder will be sent 24 h before this date" note on detail page --- apps/api/.env.example | 5 ++ .../migration.sql | 1 + apps/api/prisma/schema.prisma | 7 +- .../SendFollowUpRemindersUseCase.test.ts | 89 +++++++++++++++++++ .../api/src/__tests__/helpers/createTestDb.ts | 1 + apps/api/src/__tests__/helpers/mocks.ts | 3 + apps/api/src/app.ts | 3 + .../api/src/domain/application/Application.ts | 1 + apps/api/src/http/container.ts | 6 ++ apps/api/src/http/plugins/reminders.plugin.ts | 18 ++++ .../CachedApplicationRepository.ts | 9 ++ .../PrismaApplicationRepository.ts | 24 ++++- .../infrastructure/email/BrevoEmailService.ts | 44 +++++++++ .../use-cases/ports/IApplicationRepository.ts | 2 + apps/api/src/use-cases/ports/IEmailService.ts | 8 ++ .../reminders/SendFollowUpRemindersUseCase.ts | 32 +++++++ .../applications/$applicationId/index.tsx | 15 ++-- 17 files changed, 259 insertions(+), 9 deletions(-) create mode 100644 apps/api/prisma/migrations/20260721000001_add_reminder_sent_at/migration.sql create mode 100644 apps/api/src/__tests__/application/reminders/SendFollowUpRemindersUseCase.test.ts create mode 100644 apps/api/src/http/plugins/reminders.plugin.ts create mode 100644 apps/api/src/infrastructure/email/BrevoEmailService.ts create mode 100644 apps/api/src/use-cases/ports/IEmailService.ts create mode 100644 apps/api/src/use-cases/reminders/SendFollowUpRemindersUseCase.ts diff --git a/apps/api/.env.example b/apps/api/.env.example index c6007369..17fcf5d8 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -20,3 +20,8 @@ R2_SECRET_ACCESS_KEY= # CORS CORS_ORIGIN=http://localhost:3000 + +# Brevo email (for follow-up reminders) +BREVO_API_KEY= +FROM_EMAIL=noreply@yourdomain.com +FROM_NAME=Job Finder diff --git a/apps/api/prisma/migrations/20260721000001_add_reminder_sent_at/migration.sql b/apps/api/prisma/migrations/20260721000001_add_reminder_sent_at/migration.sql new file mode 100644 index 00000000..83f9ce99 --- /dev/null +++ b/apps/api/prisma/migrations/20260721000001_add_reminder_sent_at/migration.sql @@ -0,0 +1 @@ +ALTER TABLE "JobApplication" ADD COLUMN "reminderSentAt" DATETIME; diff --git a/apps/api/prisma/schema.prisma b/apps/api/prisma/schema.prisma index afc2e1f1..d21059da 100644 --- a/apps/api/prisma/schema.prisma +++ b/apps/api/prisma/schema.prisma @@ -42,9 +42,10 @@ model JobApplication { appliedAt DateTime? starred Boolean @default(false) source String? - followUpAt DateTime? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt + followUpAt DateTime? + reminderSentAt DateTime? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) interviewRounds InterviewRound[] notes Note[] diff --git a/apps/api/src/__tests__/application/reminders/SendFollowUpRemindersUseCase.test.ts b/apps/api/src/__tests__/application/reminders/SendFollowUpRemindersUseCase.test.ts new file mode 100644 index 00000000..e7952664 --- /dev/null +++ b/apps/api/src/__tests__/application/reminders/SendFollowUpRemindersUseCase.test.ts @@ -0,0 +1,89 @@ +import { describe, it, expect, vi } from 'vitest'; +import { SendFollowUpRemindersUseCase } from '@/use-cases/reminders/SendFollowUpRemindersUseCase.js'; +import { makeApplicationRepository, makeUserRepository, makeApplication, makeUser } from '@/__tests__/helpers/mocks.js'; +import type { IEmailService } from '@/use-cases/ports/IEmailService.js'; + +const makeEmailService = (overrides?: Partial): IEmailService => ({ + sendFollowUpReminder: vi.fn().mockResolvedValue(undefined), + ...overrides, +}); + +describe('SendFollowUpRemindersUseCase', () => { + it('sends email and updates reminderSentAt for due applications', async () => { + const followUpAt = new Date(Date.now() + 12 * 60 * 60 * 1000); + const app = makeApplication({ followUpAt }); + const user = makeUser(); + const applicationRepository = makeApplicationRepository({ + findDueForReminder: vi.fn().mockResolvedValue([app]), + updateReminderSentAt: vi.fn().mockResolvedValue(undefined), + }); + const userRepository = makeUserRepository({ + findById: vi.fn().mockResolvedValue(user), + }); + const emailService = makeEmailService(); + + const useCase = new SendFollowUpRemindersUseCase({ + applicationRepository, + userRepository, + emailService, + }); + await useCase.execute(); + + expect(emailService.sendFollowUpReminder).toHaveBeenCalledWith( + user.email, + app.company, + app.role, + followUpAt, + ); + expect(applicationRepository.updateReminderSentAt).toHaveBeenCalledWith( + app.id, + expect.any(Date), + ); + }); + + it('skips applications when user is not found', async () => { + const app = makeApplication({ followUpAt: new Date() }); + const applicationRepository = makeApplicationRepository({ + findDueForReminder: vi.fn().mockResolvedValue([app]), + updateReminderSentAt: vi.fn(), + }); + const userRepository = makeUserRepository({ + findById: vi.fn().mockResolvedValue(null), + }); + const emailService = makeEmailService(); + + await new SendFollowUpRemindersUseCase({ applicationRepository, userRepository, emailService }).execute(); + + expect(emailService.sendFollowUpReminder).not.toHaveBeenCalled(); + expect(applicationRepository.updateReminderSentAt).not.toHaveBeenCalled(); + }); + + it('continues past individual email failures without throwing', async () => { + const apps = [ + makeApplication({ id: 'app-1', followUpAt: new Date() }), + makeApplication({ id: 'app-2', followUpAt: new Date() }), + ]; + const user = makeUser(); + const applicationRepository = makeApplicationRepository({ + findDueForReminder: vi.fn().mockResolvedValue(apps), + updateReminderSentAt: vi.fn().mockResolvedValue(undefined), + }); + const userRepository = makeUserRepository({ + findById: vi.fn().mockResolvedValue(user), + }); + const emailService = makeEmailService({ + sendFollowUpReminder: vi.fn() + .mockRejectedValueOnce(new Error('Brevo timeout')) + .mockResolvedValueOnce(undefined), + }); + + await expect( + new SendFollowUpRemindersUseCase({ applicationRepository, userRepository, emailService }).execute(), + ).resolves.not.toThrow(); + + expect(emailService.sendFollowUpReminder).toHaveBeenCalledTimes(2); + // Only the second app (which succeeded) should have reminderSentAt updated + expect(applicationRepository.updateReminderSentAt).toHaveBeenCalledTimes(1); + expect(applicationRepository.updateReminderSentAt).toHaveBeenCalledWith('app-2', expect.any(Date)); + }); +}); diff --git a/apps/api/src/__tests__/helpers/createTestDb.ts b/apps/api/src/__tests__/helpers/createTestDb.ts index d78d1bcb..fc9a8330 100644 --- a/apps/api/src/__tests__/helpers/createTestDb.ts +++ b/apps/api/src/__tests__/helpers/createTestDb.ts @@ -36,6 +36,7 @@ const SCHEMA_STATEMENTS = [ "starred" INTEGER NOT NULL DEFAULT 0, "source" TEXT, "followUpAt" DATETIME, + "reminderSentAt" DATETIME, "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE diff --git a/apps/api/src/__tests__/helpers/mocks.ts b/apps/api/src/__tests__/helpers/mocks.ts index affbee63..7b9da612 100644 --- a/apps/api/src/__tests__/helpers/mocks.ts +++ b/apps/api/src/__tests__/helpers/mocks.ts @@ -33,6 +33,8 @@ export const makeApplicationRepository = ( create: vi.fn(), update: vi.fn(), delete: vi.fn(), + findDueForReminder: vi.fn().mockResolvedValue([]), + updateReminderSentAt: vi.fn().mockResolvedValue(undefined), ...overrides, }); @@ -136,6 +138,7 @@ export const makeApplication = (overrides?: Partial): Application = source: null, followUpAt: null, tags: [], + reminderSentAt: null, createdAt: new Date('2024-01-01'), updatedAt: new Date('2024-01-01'), ...overrides, diff --git a/apps/api/src/app.ts b/apps/api/src/app.ts index 465ab90b..89bdc094 100644 --- a/apps/api/src/app.ts +++ b/apps/api/src/app.ts @@ -5,6 +5,7 @@ import cookie from '@fastify/cookie'; import authPlugin from '@/http/plugins/auth.plugin.js'; import corsPlugin from '@/http/plugins/cors.plugin.js'; +import remindersPlugin from '@/http/plugins/reminders.plugin.js'; import { buildContainer } from '@/http/container.js'; import { schema } from '@/http/schema/index.js'; import { formatError } from '@/http/errors/formatError.js'; @@ -24,6 +25,8 @@ export async function buildApp() { buildContainer(fastify); + await fastify.register(remindersPlugin); + await fastify.register(mercurius, { schema, graphiql: process.env.NODE_ENV !== 'production', diff --git a/apps/api/src/domain/application/Application.ts b/apps/api/src/domain/application/Application.ts index f434d5fb..7f4a9b4c 100644 --- a/apps/api/src/domain/application/Application.ts +++ b/apps/api/src/domain/application/Application.ts @@ -15,6 +15,7 @@ export interface Application { source: string | null; followUpAt: Date | null; tags: string[]; + reminderSentAt: Date | null; createdAt: Date; updatedAt: Date; } diff --git a/apps/api/src/http/container.ts b/apps/api/src/http/container.ts index c1affcbf..6ff4077a 100644 --- a/apps/api/src/http/container.ts +++ b/apps/api/src/http/container.ts @@ -71,6 +71,8 @@ import { CreateContactUseCase } from '@/use-cases/contacts/CreateContactUseCase. import { GetContactsUseCase } from '@/use-cases/contacts/GetContactsUseCase.js'; import { UpdateContactUseCase } from '@/use-cases/contacts/UpdateContactUseCase.js'; import { DeleteContactUseCase } from '@/use-cases/contacts/DeleteContactUseCase.js'; +import { BrevoEmailService } from '@/infrastructure/email/BrevoEmailService.js'; +import { SendFollowUpRemindersUseCase } from '@/use-cases/reminders/SendFollowUpRemindersUseCase.js'; import type { FastifyInstance } from 'fastify'; @@ -149,6 +151,8 @@ declare module '@fastify/awilix' { getContactsUseCase: GetContactsUseCase; updateContactUseCase: UpdateContactUseCase; deleteContactUseCase: DeleteContactUseCase; + emailService: BrevoEmailService; + sendFollowUpRemindersUseCase: SendFollowUpRemindersUseCase; } } @@ -242,5 +246,7 @@ export function buildContainer(fastify: FastifyInstance): void { getContactsUseCase: asClass(GetContactsUseCase, { lifetime: Lifetime.TRANSIENT }), updateContactUseCase: asClass(UpdateContactUseCase, { lifetime: Lifetime.TRANSIENT }), deleteContactUseCase: asClass(DeleteContactUseCase, { lifetime: Lifetime.TRANSIENT }), + emailService: asClass(BrevoEmailService, { lifetime: Lifetime.SINGLETON }), + sendFollowUpRemindersUseCase: asClass(SendFollowUpRemindersUseCase, { lifetime: Lifetime.TRANSIENT }), }); } diff --git a/apps/api/src/http/plugins/reminders.plugin.ts b/apps/api/src/http/plugins/reminders.plugin.ts new file mode 100644 index 00000000..51d2ef5e --- /dev/null +++ b/apps/api/src/http/plugins/reminders.plugin.ts @@ -0,0 +1,18 @@ +import fp from 'fastify-plugin'; +import type { FastifyInstance } from 'fastify'; + +export default fp(async (fastify: FastifyInstance) => { + const INTERVAL_MS = 60 * 60 * 1000; // 1 hour + + const run = async () => { + try { + const { sendFollowUpRemindersUseCase } = fastify.diContainer.cradle; + await sendFollowUpRemindersUseCase.execute(); + } catch { + // swallow — don't crash the server + } + }; + + const timer = setInterval(run, INTERVAL_MS); + fastify.addHook('onClose', () => { clearInterval(timer); }); +}); diff --git a/apps/api/src/infrastructure/db/repositories/CachedApplicationRepository.ts b/apps/api/src/infrastructure/db/repositories/CachedApplicationRepository.ts index 2b619041..52a89dd5 100644 --- a/apps/api/src/infrastructure/db/repositories/CachedApplicationRepository.ts +++ b/apps/api/src/infrastructure/db/repositories/CachedApplicationRepository.ts @@ -70,4 +70,13 @@ export class CachedApplicationRepository implements IApplicationRepository { this.userIdByAppId.delete(id); if (userId) this.cache.deleteByPrefix(`apps:list:${userId}:`); } + + async findDueForReminder(): Promise { + return this.inner.findDueForReminder(); + } + + async updateReminderSentAt(id: string, sentAt: Date): Promise { + await this.inner.updateReminderSentAt(id, sentAt); + this.cache.delete(`apps:byId:${id}`); + } } diff --git a/apps/api/src/infrastructure/db/repositories/PrismaApplicationRepository.ts b/apps/api/src/infrastructure/db/repositories/PrismaApplicationRepository.ts index af3fba11..6aca8c28 100644 --- a/apps/api/src/infrastructure/db/repositories/PrismaApplicationRepository.ts +++ b/apps/api/src/infrastructure/db/repositories/PrismaApplicationRepository.ts @@ -24,6 +24,7 @@ type PrismaApp = { starred: boolean; source: string | null; followUpAt: Date | null; + reminderSentAt: Date | null; createdAt: Date; updatedAt: Date; tags: PrismaTag[]; @@ -127,6 +128,26 @@ export class PrismaApplicationRepository implements IApplicationRepository { await this.db.jobApplication.delete({ where: { id } }); } + async findDueForReminder(): Promise { + const now = new Date(); + const in24h = new Date(now.getTime() + 24 * 60 * 60 * 1000); + const rows = await this.db.jobApplication.findMany({ + where: { + followUpAt: { gte: now, lte: in24h }, + OR: [ + { reminderSentAt: null }, + { reminderSentAt: { lte: new Date(now.getTime() - 23 * 60 * 60 * 1000) } }, + ], + }, + include: INCLUDE_TAGS, + }); + return rows.map(this.toEntity); + } + + async updateReminderSentAt(id: string, sentAt: Date): Promise { + await this.db.jobApplication.update({ where: { id }, data: { reminderSentAt: sentAt } }); + } + private toEntity(row: PrismaApp): Application { return { id: row.id, @@ -142,7 +163,8 @@ export class PrismaApplicationRepository implements IApplicationRepository { starred: row.starred, source: row.source, followUpAt: row.followUpAt, - tags: row.tags.map((t) => t.name), + tags: row.tags?.map((t: { name: string }) => t.name) ?? [], + reminderSentAt: row.reminderSentAt, createdAt: row.createdAt, updatedAt: row.updatedAt, }; diff --git a/apps/api/src/infrastructure/email/BrevoEmailService.ts b/apps/api/src/infrastructure/email/BrevoEmailService.ts new file mode 100644 index 00000000..d55b52f9 --- /dev/null +++ b/apps/api/src/infrastructure/email/BrevoEmailService.ts @@ -0,0 +1,44 @@ +import type { IEmailService } from '@/use-cases/ports/IEmailService.js'; + +export class BrevoEmailService implements IEmailService { + private readonly apiKey: string; + private readonly fromEmail: string; + private readonly fromName: string; + + constructor() { + this.apiKey = process.env.BREVO_API_KEY ?? ''; + this.fromEmail = process.env.FROM_EMAIL ?? 'noreply@jobfinder.app'; + this.fromName = process.env.FROM_NAME ?? 'Job Finder'; + } + + async sendFollowUpReminder( + to: string, + company: string, + role: string, + followUpAt: Date, + ): Promise { + const date = followUpAt.toLocaleDateString('en-US', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + }); + const response = await fetch('https://api.brevo.com/v3/smtp/email', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'api-key': this.apiKey, + }, + body: JSON.stringify({ + sender: { name: this.fromName, email: this.fromEmail }, + to: [{ email: to }], + subject: `Reminder: Follow up on ${role} at ${company}`, + htmlContent: `

This is a reminder to follow up on your ${role} application at ${company}.

Your scheduled follow-up date is ${date}.

`, + }), + }); + if (!response.ok && response.status !== 201) { + const body = await response.text(); + throw new Error(`Brevo API error ${response.status}: ${body}`); + } + } +} diff --git a/apps/api/src/use-cases/ports/IApplicationRepository.ts b/apps/api/src/use-cases/ports/IApplicationRepository.ts index f08d8a8c..f983985d 100644 --- a/apps/api/src/use-cases/ports/IApplicationRepository.ts +++ b/apps/api/src/use-cases/ports/IApplicationRepository.ts @@ -38,4 +38,6 @@ export interface IApplicationRepository { create(data: CreateApplicationData): Promise; update(id: string, data: UpdateApplicationData): Promise; delete(id: string): Promise; + findDueForReminder(): Promise; + updateReminderSentAt(id: string, sentAt: Date): Promise; } diff --git a/apps/api/src/use-cases/ports/IEmailService.ts b/apps/api/src/use-cases/ports/IEmailService.ts new file mode 100644 index 00000000..c9fbc714 --- /dev/null +++ b/apps/api/src/use-cases/ports/IEmailService.ts @@ -0,0 +1,8 @@ +export interface IEmailService { + sendFollowUpReminder( + to: string, + company: string, + role: string, + followUpAt: Date, + ): Promise; +} diff --git a/apps/api/src/use-cases/reminders/SendFollowUpRemindersUseCase.ts b/apps/api/src/use-cases/reminders/SendFollowUpRemindersUseCase.ts new file mode 100644 index 00000000..5f6a3106 --- /dev/null +++ b/apps/api/src/use-cases/reminders/SendFollowUpRemindersUseCase.ts @@ -0,0 +1,32 @@ +import type { IApplicationRepository } from '@/use-cases/ports/IApplicationRepository.js'; +import type { IUserRepository } from '@/use-cases/ports/IUserRepository.js'; +import type { IEmailService } from '@/use-cases/ports/IEmailService.js'; + +interface Deps { + applicationRepository: IApplicationRepository; + userRepository: IUserRepository; + emailService: IEmailService; +} + +export class SendFollowUpRemindersUseCase { + constructor(private readonly deps: Deps) {} + + async execute(): Promise { + const apps = await this.deps.applicationRepository.findDueForReminder(); + for (const app of apps) { + const user = await this.deps.userRepository.findById(app.userId); + if (!user) continue; + try { + await this.deps.emailService.sendFollowUpReminder( + user.email, + app.company, + app.role, + app.followUpAt!, + ); + await this.deps.applicationRepository.updateReminderSentAt(app.id, new Date()); + } catch { + // continue — one failure shouldn't block the rest + } + } + } +} diff --git a/apps/web/src/routes/_authenticated/applications/$applicationId/index.tsx b/apps/web/src/routes/_authenticated/applications/$applicationId/index.tsx index e72871c2..f08a3baf 100644 --- a/apps/web/src/routes/_authenticated/applications/$applicationId/index.tsx +++ b/apps/web/src/routes/_authenticated/applications/$applicationId/index.tsx @@ -183,11 +183,16 @@ export function ApplicationDetailPage() { )} {app.source && } {app.followUpAt && ( - +
+ +

+ Email reminder will be sent 24 h before this date. +

+
)} {app.tags.length > 0 && (
From bf24b268117a66fc6258a84de993e2f906da8074 Mon Sep 17 00:00:00 2001 From: Jeff Man Date: Mon, 20 Jul 2026 16:39:45 +0100 Subject: [PATCH 2/2] fix: regenerate graphql types after rebase --- apps/web/src/graphql/generated/gql.ts | 12 ++++++------ apps/web/src/graphql/generated/graphql.ts | 16 ++++------------ 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/apps/web/src/graphql/generated/gql.ts b/apps/web/src/graphql/generated/gql.ts index 19d4ef58..74a22d55 100644 --- a/apps/web/src/graphql/generated/gql.ts +++ b/apps/web/src/graphql/generated/gql.ts @@ -17,13 +17,13 @@ type Documents = { "mutation CreateApplication($input: CreateApplicationInput!) {\n createApplication(input: $input) {\n id\n company\n role\n status\n jobUrl\n location\n salaryRange\n description\n appliedAt\n starred\n source\n followUpAt\n tags\n createdAt\n updatedAt\n }\n}\n\nmutation UpdateApplication($id: ID!, $input: UpdateApplicationInput!) {\n updateApplication(id: $id, input: $input) {\n id\n company\n role\n status\n jobUrl\n location\n salaryRange\n description\n appliedAt\n starred\n source\n followUpAt\n tags\n createdAt\n updatedAt\n }\n}\n\nmutation DeleteApplication($id: ID!) {\n deleteApplication(id: $id)\n}": typeof types.CreateApplicationDocument, "mutation Register($email: String!, $password: String!) {\n register(email: $email, password: $password)\n}\n\nmutation Login($email: String!, $password: String!) {\n login(email: $email, password: $password)\n}\n\nmutation RefreshToken {\n refreshToken\n}\n\nmutation Logout {\n logout\n}": typeof types.RegisterDocument, "mutation CreateContact($applicationId: ID!, $name: String!, $role: String, $email: String, $phone: String, $linkedinUrl: String, $notes: String) {\n createContact(\n applicationId: $applicationId\n name: $name\n role: $role\n email: $email\n phone: $phone\n linkedinUrl: $linkedinUrl\n notes: $notes\n ) {\n id\n applicationId\n name\n role\n email\n phone\n linkedinUrl\n notes\n createdAt\n updatedAt\n }\n}\n\nmutation UpdateContact($id: ID!, $name: String, $role: String, $email: String, $phone: String, $linkedinUrl: String, $notes: String) {\n updateContact(\n id: $id\n name: $name\n role: $role\n email: $email\n phone: $phone\n linkedinUrl: $linkedinUrl\n notes: $notes\n ) {\n id\n applicationId\n name\n role\n email\n phone\n linkedinUrl\n notes\n createdAt\n updatedAt\n }\n}\n\nmutation DeleteContact($id: ID!) {\n deleteContact(id: $id)\n}": typeof types.CreateContactDocument, - "mutation RequestUploadUrl($input: RequestUploadUrlInput!) {\n requestUploadUrl(input: $input) {\n uploadUrl\n storageKey\n }\n}\n\nmutation ConfirmDocument($input: ConfirmDocumentInput!) {\n confirmDocument(input: $input) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n createdAt\n }\n}\n\nmutation DeleteDocument($id: ID!) {\n deleteDocument(id: $id)\n}": typeof types.RequestUploadUrlDocument, + "mutation RequestUploadUrl($input: RequestUploadUrlInput!) {\n requestUploadUrl(input: $input) {\n uploadUrl\n storageKey\n }\n}\n\nmutation ConfirmDocument($input: ConfirmDocumentInput!) {\n confirmDocument(input: $input) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n documentType\n version\n createdAt\n }\n}\n\nmutation DeleteDocument($id: ID!) {\n deleteDocument(id: $id)\n}": typeof types.RequestUploadUrlDocument, "mutation CreateInterviewRound($input: CreateInterviewRoundInput!) {\n createInterviewRound(input: $input) {\n id\n applicationId\n type\n scheduledAt\n completedAt\n interviewerName\n notes\n outcome\n createdAt\n updatedAt\n }\n}\n\nmutation UpdateInterviewRound($id: ID!, $input: UpdateInterviewRoundInput!) {\n updateInterviewRound(id: $id, input: $input) {\n id\n applicationId\n type\n scheduledAt\n completedAt\n interviewerName\n notes\n outcome\n createdAt\n updatedAt\n }\n}\n\nmutation DeleteInterviewRound($id: ID!) {\n deleteInterviewRound(id: $id)\n}": typeof types.CreateInterviewRoundDocument, "mutation CreateNote($applicationId: ID!, $content: String!) {\n createNote(applicationId: $applicationId, content: $content) {\n id\n applicationId\n content\n createdAt\n updatedAt\n }\n}\n\nmutation UpdateNote($id: ID!, $content: String!) {\n updateNote(id: $id, content: $content) {\n id\n applicationId\n content\n createdAt\n updatedAt\n }\n}\n\nmutation DeleteNote($id: ID!) {\n deleteNote(id: $id)\n}": typeof types.CreateNoteDocument, "query ActivityLogs($applicationId: ID!) {\n activityLogs(applicationId: $applicationId) {\n id\n applicationId\n actorId\n eventType\n payload\n createdAt\n }\n}": typeof types.ActivityLogsDocument, "query Applications($status: ApplicationStatus) {\n applications(status: $status) {\n id\n company\n role\n status\n jobUrl\n location\n salaryRange\n appliedAt\n starred\n source\n followUpAt\n tags\n createdAt\n updatedAt\n }\n}\n\nquery Application($id: ID!) {\n application(id: $id) {\n id\n company\n role\n status\n jobUrl\n location\n salaryRange\n description\n appliedAt\n starred\n source\n followUpAt\n tags\n createdAt\n updatedAt\n }\n}": typeof types.ApplicationsDocument, "query Contacts($applicationId: ID!) {\n contacts(applicationId: $applicationId) {\n id\n applicationId\n name\n role\n email\n phone\n linkedinUrl\n notes\n createdAt\n updatedAt\n }\n}": typeof types.ContactsDocument, - "query Documents($applicationId: ID!) {\n documents(applicationId: $applicationId) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n createdAt\n }\n}": typeof types.DocumentsDocument, + "query Documents($applicationId: ID!) {\n documents(applicationId: $applicationId) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n documentType\n version\n createdAt\n }\n}": typeof types.DocumentsDocument, "query InterviewRounds($applicationId: ID!) {\n interviewRounds(applicationId: $applicationId) {\n id\n applicationId\n type\n scheduledAt\n completedAt\n interviewerName\n notes\n outcome\n createdAt\n updatedAt\n }\n}": typeof types.InterviewRoundsDocument, "query Notes($applicationId: ID!) {\n notes(applicationId: $applicationId) {\n id\n applicationId\n content\n createdAt\n updatedAt\n }\n}": typeof types.NotesDocument, }; @@ -31,13 +31,13 @@ const documents: Documents = { "mutation CreateApplication($input: CreateApplicationInput!) {\n createApplication(input: $input) {\n id\n company\n role\n status\n jobUrl\n location\n salaryRange\n description\n appliedAt\n starred\n source\n followUpAt\n tags\n createdAt\n updatedAt\n }\n}\n\nmutation UpdateApplication($id: ID!, $input: UpdateApplicationInput!) {\n updateApplication(id: $id, input: $input) {\n id\n company\n role\n status\n jobUrl\n location\n salaryRange\n description\n appliedAt\n starred\n source\n followUpAt\n tags\n createdAt\n updatedAt\n }\n}\n\nmutation DeleteApplication($id: ID!) {\n deleteApplication(id: $id)\n}": types.CreateApplicationDocument, "mutation Register($email: String!, $password: String!) {\n register(email: $email, password: $password)\n}\n\nmutation Login($email: String!, $password: String!) {\n login(email: $email, password: $password)\n}\n\nmutation RefreshToken {\n refreshToken\n}\n\nmutation Logout {\n logout\n}": types.RegisterDocument, "mutation CreateContact($applicationId: ID!, $name: String!, $role: String, $email: String, $phone: String, $linkedinUrl: String, $notes: String) {\n createContact(\n applicationId: $applicationId\n name: $name\n role: $role\n email: $email\n phone: $phone\n linkedinUrl: $linkedinUrl\n notes: $notes\n ) {\n id\n applicationId\n name\n role\n email\n phone\n linkedinUrl\n notes\n createdAt\n updatedAt\n }\n}\n\nmutation UpdateContact($id: ID!, $name: String, $role: String, $email: String, $phone: String, $linkedinUrl: String, $notes: String) {\n updateContact(\n id: $id\n name: $name\n role: $role\n email: $email\n phone: $phone\n linkedinUrl: $linkedinUrl\n notes: $notes\n ) {\n id\n applicationId\n name\n role\n email\n phone\n linkedinUrl\n notes\n createdAt\n updatedAt\n }\n}\n\nmutation DeleteContact($id: ID!) {\n deleteContact(id: $id)\n}": types.CreateContactDocument, - "mutation RequestUploadUrl($input: RequestUploadUrlInput!) {\n requestUploadUrl(input: $input) {\n uploadUrl\n storageKey\n }\n}\n\nmutation ConfirmDocument($input: ConfirmDocumentInput!) {\n confirmDocument(input: $input) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n createdAt\n }\n}\n\nmutation DeleteDocument($id: ID!) {\n deleteDocument(id: $id)\n}": types.RequestUploadUrlDocument, + "mutation RequestUploadUrl($input: RequestUploadUrlInput!) {\n requestUploadUrl(input: $input) {\n uploadUrl\n storageKey\n }\n}\n\nmutation ConfirmDocument($input: ConfirmDocumentInput!) {\n confirmDocument(input: $input) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n documentType\n version\n createdAt\n }\n}\n\nmutation DeleteDocument($id: ID!) {\n deleteDocument(id: $id)\n}": types.RequestUploadUrlDocument, "mutation CreateInterviewRound($input: CreateInterviewRoundInput!) {\n createInterviewRound(input: $input) {\n id\n applicationId\n type\n scheduledAt\n completedAt\n interviewerName\n notes\n outcome\n createdAt\n updatedAt\n }\n}\n\nmutation UpdateInterviewRound($id: ID!, $input: UpdateInterviewRoundInput!) {\n updateInterviewRound(id: $id, input: $input) {\n id\n applicationId\n type\n scheduledAt\n completedAt\n interviewerName\n notes\n outcome\n createdAt\n updatedAt\n }\n}\n\nmutation DeleteInterviewRound($id: ID!) {\n deleteInterviewRound(id: $id)\n}": types.CreateInterviewRoundDocument, "mutation CreateNote($applicationId: ID!, $content: String!) {\n createNote(applicationId: $applicationId, content: $content) {\n id\n applicationId\n content\n createdAt\n updatedAt\n }\n}\n\nmutation UpdateNote($id: ID!, $content: String!) {\n updateNote(id: $id, content: $content) {\n id\n applicationId\n content\n createdAt\n updatedAt\n }\n}\n\nmutation DeleteNote($id: ID!) {\n deleteNote(id: $id)\n}": types.CreateNoteDocument, "query ActivityLogs($applicationId: ID!) {\n activityLogs(applicationId: $applicationId) {\n id\n applicationId\n actorId\n eventType\n payload\n createdAt\n }\n}": types.ActivityLogsDocument, "query Applications($status: ApplicationStatus) {\n applications(status: $status) {\n id\n company\n role\n status\n jobUrl\n location\n salaryRange\n appliedAt\n starred\n source\n followUpAt\n tags\n createdAt\n updatedAt\n }\n}\n\nquery Application($id: ID!) {\n application(id: $id) {\n id\n company\n role\n status\n jobUrl\n location\n salaryRange\n description\n appliedAt\n starred\n source\n followUpAt\n tags\n createdAt\n updatedAt\n }\n}": types.ApplicationsDocument, "query Contacts($applicationId: ID!) {\n contacts(applicationId: $applicationId) {\n id\n applicationId\n name\n role\n email\n phone\n linkedinUrl\n notes\n createdAt\n updatedAt\n }\n}": types.ContactsDocument, - "query Documents($applicationId: ID!) {\n documents(applicationId: $applicationId) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n createdAt\n }\n}": types.DocumentsDocument, + "query Documents($applicationId: ID!) {\n documents(applicationId: $applicationId) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n documentType\n version\n createdAt\n }\n}": types.DocumentsDocument, "query InterviewRounds($applicationId: ID!) {\n interviewRounds(applicationId: $applicationId) {\n id\n applicationId\n type\n scheduledAt\n completedAt\n interviewerName\n notes\n outcome\n createdAt\n updatedAt\n }\n}": types.InterviewRoundsDocument, "query Notes($applicationId: ID!) {\n notes(applicationId: $applicationId) {\n id\n applicationId\n content\n createdAt\n updatedAt\n }\n}": types.NotesDocument, }; @@ -71,7 +71,7 @@ export function graphql(source: "mutation CreateContact($applicationId: ID!, $na /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "mutation RequestUploadUrl($input: RequestUploadUrlInput!) {\n requestUploadUrl(input: $input) {\n uploadUrl\n storageKey\n }\n}\n\nmutation ConfirmDocument($input: ConfirmDocumentInput!) {\n confirmDocument(input: $input) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n createdAt\n }\n}\n\nmutation DeleteDocument($id: ID!) {\n deleteDocument(id: $id)\n}"): (typeof documents)["mutation RequestUploadUrl($input: RequestUploadUrlInput!) {\n requestUploadUrl(input: $input) {\n uploadUrl\n storageKey\n }\n}\n\nmutation ConfirmDocument($input: ConfirmDocumentInput!) {\n confirmDocument(input: $input) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n createdAt\n }\n}\n\nmutation DeleteDocument($id: ID!) {\n deleteDocument(id: $id)\n}"]; +export function graphql(source: "mutation RequestUploadUrl($input: RequestUploadUrlInput!) {\n requestUploadUrl(input: $input) {\n uploadUrl\n storageKey\n }\n}\n\nmutation ConfirmDocument($input: ConfirmDocumentInput!) {\n confirmDocument(input: $input) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n documentType\n version\n createdAt\n }\n}\n\nmutation DeleteDocument($id: ID!) {\n deleteDocument(id: $id)\n}"): (typeof documents)["mutation RequestUploadUrl($input: RequestUploadUrlInput!) {\n requestUploadUrl(input: $input) {\n uploadUrl\n storageKey\n }\n}\n\nmutation ConfirmDocument($input: ConfirmDocumentInput!) {\n confirmDocument(input: $input) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n documentType\n version\n createdAt\n }\n}\n\nmutation DeleteDocument($id: ID!) {\n deleteDocument(id: $id)\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -95,7 +95,7 @@ export function graphql(source: "query Contacts($applicationId: ID!) {\n contac /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "query Documents($applicationId: ID!) {\n documents(applicationId: $applicationId) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n createdAt\n }\n}"): (typeof documents)["query Documents($applicationId: ID!) {\n documents(applicationId: $applicationId) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n createdAt\n }\n}"]; +export function graphql(source: "query Documents($applicationId: ID!) {\n documents(applicationId: $applicationId) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n documentType\n version\n createdAt\n }\n}"): (typeof documents)["query Documents($applicationId: ID!) {\n documents(applicationId: $applicationId) {\n id\n applicationId\n name\n mimeType\n sizeBytes\n url\n documentType\n version\n createdAt\n }\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/apps/web/src/graphql/generated/graphql.ts b/apps/web/src/graphql/generated/graphql.ts index c85402c0..b0699ad0 100644 --- a/apps/web/src/graphql/generated/graphql.ts +++ b/apps/web/src/graphql/generated/graphql.ts @@ -62,14 +62,6 @@ export type ConfirmDocumentInput = { version?: InputMaybe; }; -export type CreateApiTokenPayload = { - __typename?: 'CreateApiTokenPayload'; - createdAt?: Maybe; - id?: Maybe; - name?: Maybe; - token?: Maybe; -}; - export type Contact = { __typename?: 'Contact'; applicationId?: Maybe; @@ -525,7 +517,7 @@ export type ConfirmDocumentMutationVariables = Exact<{ }>; -export type ConfirmDocumentMutation = { __typename?: 'Mutation', confirmDocument?: { __typename?: 'Document', id?: string | null, applicationId?: string | null, name?: string | null, mimeType?: string | null, sizeBytes?: number | null, url?: string | null, createdAt?: string | null } | null }; +export type ConfirmDocumentMutation = { __typename?: 'Mutation', confirmDocument?: { __typename?: 'Document', id?: string | null, applicationId?: string | null, name?: string | null, mimeType?: string | null, sizeBytes?: number | null, url?: string | null, documentType?: string | null, version?: string | null, createdAt?: string | null } | null }; export type DeleteDocumentMutationVariables = Exact<{ id: Scalars['ID']['input']; @@ -612,7 +604,7 @@ export type DocumentsQueryVariables = Exact<{ }>; -export type DocumentsQuery = { __typename?: 'Query', documents?: Array<{ __typename?: 'Document', id?: string | null, applicationId?: string | null, name?: string | null, mimeType?: string | null, sizeBytes?: number | null, url?: string | null, createdAt?: string | null }> | null }; +export type DocumentsQuery = { __typename?: 'Query', documents?: Array<{ __typename?: 'Document', id?: string | null, applicationId?: string | null, name?: string | null, mimeType?: string | null, sizeBytes?: number | null, url?: string | null, documentType?: string | null, version?: string | null, createdAt?: string | null }> | null }; export type InterviewRoundsQueryVariables = Exact<{ applicationId: Scalars['ID']['input']; @@ -640,7 +632,7 @@ export const CreateContactDocument = {"kind":"Document","definitions":[{"kind":" export const UpdateContactDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateContact"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"role"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phone"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"linkedinUrl"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"notes"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateContact"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}},{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}},{"kind":"Argument","name":{"kind":"Name","value":"role"},"value":{"kind":"Variable","name":{"kind":"Name","value":"role"}}},{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"phone"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phone"}}},{"kind":"Argument","name":{"kind":"Name","value":"linkedinUrl"},"value":{"kind":"Variable","name":{"kind":"Name","value":"linkedinUrl"}}},{"kind":"Argument","name":{"kind":"Name","value":"notes"},"value":{"kind":"Variable","name":{"kind":"Name","value":"notes"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"linkedinUrl"}},{"kind":"Field","name":{"kind":"Name","value":"notes"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; export const DeleteContactDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteContact"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteContact"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}]}}]} as unknown as DocumentNode; export const RequestUploadUrlDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RequestUploadUrl"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"RequestUploadUrlInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"requestUploadUrl"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uploadUrl"}},{"kind":"Field","name":{"kind":"Name","value":"storageKey"}}]}}]}}]} as unknown as DocumentNode; -export const ConfirmDocumentDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ConfirmDocument"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ConfirmDocumentInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"confirmDocument"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"mimeType"}},{"kind":"Field","name":{"kind":"Name","value":"sizeBytes"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]} as unknown as DocumentNode; +export const ConfirmDocumentDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ConfirmDocument"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ConfirmDocumentInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"confirmDocument"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"mimeType"}},{"kind":"Field","name":{"kind":"Name","value":"sizeBytes"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"documentType"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]} as unknown as DocumentNode; export const DeleteDocumentDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteDocument"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteDocument"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}]}}]} as unknown as DocumentNode; export const CreateInterviewRoundDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateInterviewRound"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateInterviewRoundInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createInterviewRound"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"scheduledAt"}},{"kind":"Field","name":{"kind":"Name","value":"completedAt"}},{"kind":"Field","name":{"kind":"Name","value":"interviewerName"}},{"kind":"Field","name":{"kind":"Name","value":"notes"}},{"kind":"Field","name":{"kind":"Name","value":"outcome"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; export const UpdateInterviewRoundDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateInterviewRound"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateInterviewRoundInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateInterviewRound"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"scheduledAt"}},{"kind":"Field","name":{"kind":"Name","value":"completedAt"}},{"kind":"Field","name":{"kind":"Name","value":"interviewerName"}},{"kind":"Field","name":{"kind":"Name","value":"notes"}},{"kind":"Field","name":{"kind":"Name","value":"outcome"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; @@ -652,6 +644,6 @@ export const ActivityLogsDocument = {"kind":"Document","definitions":[{"kind":"O export const ApplicationsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Applications"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"status"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ApplicationStatus"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"applications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"status"},"value":{"kind":"Variable","name":{"kind":"Name","value":"status"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"jobUrl"}},{"kind":"Field","name":{"kind":"Name","value":"location"}},{"kind":"Field","name":{"kind":"Name","value":"salaryRange"}},{"kind":"Field","name":{"kind":"Name","value":"appliedAt"}},{"kind":"Field","name":{"kind":"Name","value":"starred"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"followUpAt"}},{"kind":"Field","name":{"kind":"Name","value":"tags"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; export const ApplicationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Application"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"application"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"jobUrl"}},{"kind":"Field","name":{"kind":"Name","value":"location"}},{"kind":"Field","name":{"kind":"Name","value":"salaryRange"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"appliedAt"}},{"kind":"Field","name":{"kind":"Name","value":"starred"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"followUpAt"}},{"kind":"Field","name":{"kind":"Name","value":"tags"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; export const ContactsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Contacts"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"applicationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"contacts"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"applicationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"applicationId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"linkedinUrl"}},{"kind":"Field","name":{"kind":"Name","value":"notes"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; -export const DocumentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Documents"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"applicationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documents"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"applicationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"applicationId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"mimeType"}},{"kind":"Field","name":{"kind":"Name","value":"sizeBytes"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]} as unknown as DocumentNode; +export const DocumentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Documents"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"applicationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documents"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"applicationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"applicationId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"mimeType"}},{"kind":"Field","name":{"kind":"Name","value":"sizeBytes"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"documentType"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]} as unknown as DocumentNode; export const InterviewRoundsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"InterviewRounds"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"applicationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"interviewRounds"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"applicationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"applicationId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"scheduledAt"}},{"kind":"Field","name":{"kind":"Name","value":"completedAt"}},{"kind":"Field","name":{"kind":"Name","value":"interviewerName"}},{"kind":"Field","name":{"kind":"Name","value":"notes"}},{"kind":"Field","name":{"kind":"Name","value":"outcome"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; export const NotesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Notes"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"applicationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"notes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"applicationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"applicationId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"content"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file