Skip to content

feat: Implement invoice CRUD, file uploads, seed scripts, and CI/CD pipeline - #34

Merged
Levi-Ojukwu merged 24 commits into
mainfrom
feat/CI-pipeline
Jul 10, 2026
Merged

Levi-Ojukwu merged 24 commits into
mainfrom
feat/CI-pipeline

Conversation

@Levi-Ojukwu

Copy link
Copy Markdown
Member

Summary

Resolves 4 open issues in the backend repository with comprehensive implementations for invoice management, file uploads, database seeding, and CI/CD automation.

closes #33 Invoice Creation and Management Endpoints ✅

  • Zod Validation Schemas (src/validators/invoice.schema.ts): Input validation for create, update, and query operations with line items support
  • Custom Error Classes (src/utils/AppError.ts): AppError, NotFoundError, ForbiddenError, ValidationError, ConflictError
  • Error Handler (src/middleware/errorHandler.ts): Global error middleware with structured JSON responses
  • Validation Middleware (src/middleware/validate.ts): Generic Zod validation for body, query, and params
  • Auth Middleware (src/middleware/auth.ts): JWT authentication and role-based authorization
  • Invoice Controller (src/controllers/invoice.controller.ts):
    • Create invoice (freelancers only)
    • List invoices with pagination, filters, search, and sorting
    • Get invoice by ID with access control
    • Update invoice with status transition validation
    • Delete invoice (draft status only)
  • Invoice Routes (src/routes/invoice.routes.ts): Full REST API with auth and validation
  • Schema Update (prisma/schema.prisma): Added lineItems JSON field to Invoice model

closes #32 Database Migration and Seeding Scripts ✅

  • Seed Script (prisma/seed.ts): 5 test users, 5 invoices with different statuses, 2 escrows, 3 notifications
  • DB Reset Script (scripts/db-reset.sh): Reset database and reseed for local development
  • DB Migrate Script (scripts/db-migrate.sh): Run development migrations
  • DB Deploy Script (scripts/db-deploy.sh): Deploy migrations to production
  • Package.json: Added db:reset, db:migrate, db:deploy scripts

closes #31 File Upload Service ✅

  • Upload Service (src/services/upload.service.ts):
    • S3 client configuration with presigned URL support
    • Avatar resize to 3 sizes (64px, 128px, 256px)
    • File type validation (JPEG, PNG, WebP, GIF, PDF)
    • File size validation (10MB limit)
    • Presigned URL generation for direct uploads
  • Upload Controller (src/controllers/upload.controller.ts):
    • Upload avatar with automatic resizing
    • Upload invoice attachments with ownership validation
    • Generate presigned URLs for client-side uploads
  • Upload Routes (src/routes/upload.routes.ts): REST API for file uploads
  • Config Update (src/config/index.ts): Added S3 configuration
  • Environment Variables (.env.example): Added AWS S3 settings

closes #30 CI/CD Pipeline ✅

  • CI Workflow (.github/workflows/ci.yml):
    • Lint job (ESLint)
    • Type check job (tsc)
    • Test job (Vitest + PostgreSQL service)
    • Build job with artifact upload
    • Runs on push/PR to main and develop branches
  • Deploy Workflow (.github/workflows/deploy.yml):
    • Deploy to staging on push to main
    • Deploy to production after staging
    • Prisma migrations before deployment
    • Environment-specific secrets

Files Changed (19)

File Issue Description
src/validators/invoice.schema.ts #33 Zod validation schemas
src/utils/AppError.ts #33 Custom error classes
src/middleware/errorHandler.ts #33 Error handler middleware
src/middleware/validate.ts #33 Validation middleware
src/middleware/auth.ts #33 JWT auth middleware
src/controllers/invoice.controller.ts #33 Invoice CRUD controller
src/routes/invoice.routes.ts #33 Invoice API routes
prisma/schema.prisma #33 Added lineItems field
prisma/seed.ts #32 Database seed script
scripts/db-reset.sh #32 DB reset script
scripts/db-migrate.sh #32 DB migrate script
scripts/db-deploy.sh #32 DB deploy script
package.json #32, #31 Dependencies and scripts
src/services/upload.service.ts #31 S3 upload service
src/controllers/upload.controller.ts #31 Upload controller
src/routes/upload.routes.ts #31 Upload routes
src/config/index.ts #31 S3 config
.env.example #31 S3 env vars
src/index.ts #33, #31 Route registration
.github/workflows/ci.yml #30 CI pipeline
.github/workflows/deploy.yml #30 Deploy pipeline

- Create invoiceSchema with line items support
- Add updateInvoiceSchema with status transition validation
- Add query schema for pagination, filtering, and sorting
- Create base AppError class with statusCode and isOperational flag
- Add NotFoundError, UnauthorizedError, ForbiddenError, ValidationError
- Add ConflictError for state transition violations
- Handle AppError, ValidationError, and unexpected errors
- Return structured JSON error responses
- Include field-level validation errors for 400 responses
- Support validation for body, query, and params
- Return structured error responses with field-level messages
- Auto-assign parsed data back to request object
- Implement Bearer token verification
- Add authenticate middleware for protected routes
- Add authorize middleware with role-based access control
- Extend Express Request type with user payload
…issions

- Create invoice (freelancers only)
- List invoices with pagination, filters, and search
- Get invoice by ID with access control
- Update invoice with status transition validation
- Delete invoice (draft status only)
- Enforce DRAFT→PENDING→FUNDED→IN_ESCROW→COMPLETED state machine
- POST /api/invoices - Create invoice (freelancers)
- GET /api/invoices - List invoices with query filters
- GET /api/invoices/:id - Get invoice by ID
- PATCH /api/invoices/:id - Update invoice (freelancers)
- DELETE /api/invoices/:id - Delete invoice (freelancers)
- Add lineItems field with default empty array
- Support structured line item data for invoices
- Create 5 test users (freelancers, clients, admin)
- Add 5 sample invoices with different statuses
- Create 2 escrow records
- Add sample notifications
- Include line items for invoice items
- db-reset.sh: Reset database and reseed
- db-migrate.sh: Run development migrations
- db-deploy.sh: Deploy migrations to production
- Add multer for file upload handling
- Add sharp for image resizing
- Add AWS SDK for S3 integration
- Add @types/multer for TypeScript support
- Add DB management scripts to package.json
- S3 client configuration with presigned URL support
- Avatar resize to thumbnail (64px), small (128px), medium (256px)
- File type validation for images and PDFs
- File size validation (10MB limit)
- Presigned URL generation for direct uploads
- Upload avatar with automatic resizing
- Upload invoice attachments with ownership validation
- Generate presigned URLs for direct client uploads
- Validate file types and sizes
- POST /api/uploads/avatar - Upload user avatar
- POST /api/uploads/invoice/:invoiceId - Upload invoice attachment
- GET /api/uploads/presigned-url - Get presigned upload URL
- Add AWS region, bucket, access key, secret key
- Support custom S3 endpoint for MinIO compatibility
- Add forcePathStyle option for local development
- AWS_REGION, AWS_S3_BUCKET
- AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
- Optional AWS_S3_ENDPOINT for MinIO
- Optional AWS_S3_FORCE_PATH_STYLE
- Register /api/invoices routes
- Register /api/uploads routes
- Add global error handler middleware
- Lint job with ESLint
- Type check job with tsc
- Test job with Vitest and PostgreSQL service
- Build job with artifact upload
- Run on push/PR to main and develop branches
- Deploy to staging on push to main
- Deploy to production after staging
- Run Prisma migrations before deployment
- Environment-specific secrets for each stage
- Configure ESLint 9 flat config format
- Add typescript-eslint for TypeScript support
- Disable no-namespace rule for Express type augmentation
- Add typescript-eslint@8.34.0 for ESLint TypeScript support
- Use --legacy-peer-deps due to TypeScript 6.x compatibility
- Test AppError, NotFoundError, UnauthorizedError, ForbiddenError
- Test invoice create schema validation (valid and invalid)
- Test file type and size validation logic
- Test file key generation patterns
- Fix jwt.verify cast with unknown intermediate type
- Add undefined check for token after split
- Fix req.params access with explicit casting
- Fix S3Client config with conditional endpoint
- Fix Prisma profileImage nullable update
- Upgrade typescript-eslint to ^8.63.0 (supports TypeScript 6.x)
- Regenerate package-lock.json for clean npm ci
- Update CI workflow to use Node 22 (Node 20 deprecated)
@Levi-Ojukwu
Levi-Ojukwu merged commit d6c1ef6 into main Jul 10, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant