You are working on OpusSuite, a NestJS 10 + Prisma 5.22.0 + MySQL 8 backend. The app is located at: ~/www/opsustuidio.alexanderpaez.com.ve/backend/ Your mission: fix ALL TypeScript compilation errors and make `npm run build` succeed with zero errors. Work autonomously without stopping to ask questions. ## RULES - Never ask for confirmation. Fix and move forward. - Run `npx tsc --noEmit 2>&1 | grep "error TS" | grep -v "node_modules" | head -30` after every batch of fixes to track progress. - When an error says a field doesn't exist on a type, check the Prisma schema first — if the field is missing, ADD it to the schema. If it's a relation that needs an include, add `as any` cast. - Never remove business logic. Fix type issues with casts (`as any`, `as ProjectStatus`) when the underlying logic is correct. - If a module import fails (Cannot find module), create the missing file with correct exports. - Run `npm install --legacy-peer-deps` if any package is missing. ## KNOWN PENDING ISSUES TO FIX ### 1. PRISMA SCHEMA — run `prisma db push` after any schema change File: prisma/schema.prisma Check and ensure these fields/models exist: - User: `deletedAt DateTime?`, `organization Organization? @relation(...)` back-reference - Project: `shootDate DateTime?`, `editingDeadline DateTime?`, `city String?`, `price Decimal @default(0)`, `priority Int @default(0)`, `progress Int @default(0)`, `statusChangedAt DateTime?`, `tags Json?` - Client: `source String @default("WEB")`, `totalSpent Decimal @default(0)`, `pendingAmount Decimal @default(0)`, `lastContactAt DateTime?`, `tags Json?` - Contract: `signatureToken String? @unique`, `sentAt DateTime?`, `signerIp String?`, `signerEmail String?`, `signerUserAgent String?`, `bodyHtml String @db.LongText`, `amount Decimal @default(0)`, `templateId String?`, `createdById String?` - Gallery: `slug String? @unique`, `type String?`, `accessType String @default("PUBLIC")`, `downloadCount Int @default(0)`, `publishedAt DateTime?`, `pinHash String?` - Invoice: `paidAmount Decimal @default(0)`, `taxRate Decimal @default(0)`, `sentAt DateTime?`, `stripeInvoiceId String?`, relation `invoiceLineItems InvoiceItem[]`, relation `payments Payment[]` - InvoiceItem: field named `amount` (not `total`), field named `position` (not `order`) - Organization: `stripeAccountId String?` - UserSession: `userAgent String?` - Enums: ProjectStatus must include INQUIRY, CANCELLED; ProjectType must include BODA; ContractStatus must include VOIDED; InvoiceStatus must include PARTIAL, VOIDED Missing models to add if not present: - `Payment` (invoiceId, clientId, amount, method, status, paidAt) - `PaymentSchedule` (invoiceId, label, amount, dueDate, paidAt, status) - `ProjectStatusHistory` (projectId, status ProjectStatus, changedAt, note) - `Task` (projectId, organizationId, title, dueDate, completed) - `BoardSettings` (organizationId @unique, wipLimits Json?, settings Json?) - `AuditLog` (organizationId, userId, action, entityType, entityId, meta, ipAddress) - `AutomationExecution` (organizationId, trigger, entityType, entityId, result) - `ContractTemplate` (organizationId, title, bodyHtml LongText, isDefault Boolean) ### 2. MISSING SOURCE FILES — create if not present - `src/modules/auth/interfaces/auth-request.interface.ts` Content: export interface AuthenticatedRequest extends Request { user: { sub: string; email: string; organizationId: string; role: string; mfaEnabled?: boolean } } - `src/modules/dashboard/dto/dashboard-query.dto.ts` Content: export class DashboardQueryDto { @IsOptional() @IsIn(['7d','30d','90d','1y']) period?: string = '30d'; } - `src/modules/notifications/types.ts` Content: export type NotificationType = 'project_created'|'contract_signed'|'invoice_paid'|'gallery_viewed'|'team_invite'|'payment_received'|'system'; export type NotificationChannel = 'in_app'|'email'|'push'; - `src/storage/r2.module.ts` — Module that provides and exports R2Service - `src/queues/image-queue.module.ts` — BullMQ module for image processing queue - `src/database/database.module.ts` — Module that provides and exports PrismaService ### 3. SERVICE FIXES **auth.service.ts:** - Change `import * as bcrypt from 'bcryptjs'` → `import * as bcrypt from 'bcrypt'` - Remove `mode: 'insensitive'` from all Prisma where clauses (MySQL doesn't support it) - The `organization` include on User is valid — User now has organization relation **billing.service.ts + invoices.service.ts:** - Stripe apiVersion must be `'2023-10-16'` (string literal type) **invoices.service.ts:** - `tx.invoiceLineItem` → `tx.invoiceItem` (Prisma model name) - `_sum: { pendingAmount: true }` → `_sum: { total: true }` then cast result - `inv.pendingAmount` → `Number(inv.total) - Number(inv.paidAmount)` - InvoiceItem line items must include `amount` field (not `total`) **integrations.service.ts + team.service.ts:** - All shorthand `{ orgId }` in Prisma WHERE clauses must be `{ organizationId: orgId }` - `orgId,` in data objects → `organizationId: orgId,` **galleries.service.ts + image-processor.ts:** - `this.prisma.asset` → `this.prisma.galleryAsset` (Prisma model is GalleryAsset) **r2.service.ts:** - Add `upload(payload: {key, buffer, mimeType, metadata?}): Promise` method - Add `delete(url: string|null|undefined): Promise` method - Import `@aws-sdk/s3-request-presigner` wrapped in try/catch (optional package) **email.service.ts:** - Add missing methods: `sendTeamInvite`, `sendSignedContractCopies`, `sendDigest`, `sendNotificationEmail` - All methods accept object parameters `{to, subject, ...}` **notifications.service.ts:** - Cast `meta: (input.meta ?? {}) as any` **dashboard.service.ts:** - `this.prisma.payment` is now valid (Payment model added) - `published: true` → `status: 'PUBLISHED'` - Cast relation access: `(c as any).client`, `(p as any).shootDate` **contracts.service.ts:** - `signToken` → `signatureToken` everywhere - Cast missing relation access: `(contract as any).client`, `(contract as any).bodyHtml` - `tx.auditLog.create` is now valid (AuditLog model added) **projects.service.ts:** - `_count: { select: { contracts: true } }` → `_count: { select: { invoices: true, kanbanCards: true } }` - Cast `status: 'INQUIRY' as any` for initial project creation - `tx.projectStatusHistory.create` is now valid - `tx.task.create` is now valid - `this.prisma.boardSettings.findUnique` is now valid **pdf.schema.ts:** - Replace `import * as puppeteer from 'puppeteer'` with `let puppeteer: any; try { puppeteer = require('puppeteer'); } catch {}` ### 4. PACKAGES — install if missing Run: `npm install --legacy-peer-deps` Ensure package.json has: nanoid@^3.3.7, bcrypt (already there), @aws-sdk/s3-request-presigner@^3.511.0, resend@^2.1.0 ### 5. FINAL SEQUENCE After all fixes: ```bash cd ~/www/opsustuidio.alexanderpaez.com.ve/backend ./node_modules/.bin/prisma generate ./node_modules/.bin/prisma db push --skip-generate npm run build ``` If `npm run build` has remaining errors, fix them iteratively until zero errors. Do not stop until the build succeeds. Report: final error count, tables created in MySQL, and confirm dist/main.js exists.