diff --git a/.github/workflows/frontend-infrastructure-ci.yml b/.github/workflows/frontend-infrastructure-ci.yml new file mode 100644 index 00000000..14ff6f40 --- /dev/null +++ b/.github/workflows/frontend-infrastructure-ci.yml @@ -0,0 +1,46 @@ +name: Frontend & Docker Infrastructure CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + frontend-validation: + name: Next.js Build & Lint + runs-on: ubuntu-latest + defaults: + run: + working-directory: apps/frontend + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'yarn' + cache-dependency-path: apps/frontend/yarn.lock + + - name: Install Dependencies + run: yarn install --frozen-lockfile + + - name: Run ESLint + run: yarn lint + + - name: Build Next.js Production Bundle + run: yarn build + + docker-dry-run: + name: Docker Compose Build Test + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Verify Docker Compose Build + run: docker compose build \ No newline at end of file diff --git a/apps/frontend/Dockerfile b/apps/frontend/Dockerfile index a5be6be6..fe33f704 100644 --- a/apps/frontend/Dockerfile +++ b/apps/frontend/Dockerfile @@ -1,5 +1,5 @@ # 1. Install dependencies only when needed -FROM node:18-alpine AS deps +FROM node:20-alpine AS deps WORKDIR /app @@ -35,6 +35,7 @@ COPY --from=builder /app/public ./public COPY --from=builder /app/.next ./.next COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/package.json ./package.json +COPY --from=builder /app/next.config.ts ./ # Expose the port Next.js runs on EXPOSE 3000 diff --git a/apps/frontend/next.config.ts b/apps/frontend/next.config.ts index e9ffa308..a726b9e3 100644 --- a/apps/frontend/next.config.ts +++ b/apps/frontend/next.config.ts @@ -2,6 +2,20 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { /* config options here */ + experimental: { + serverActions: { + bodySizeLimit: '100mb', + }, + }, + + async rewrites() { + return [ + { + source: '/api/:path*', + destination: 'http://backend:8000/api/:path*' // Routes traffic safely inside the Docker network + } + ]; + } }; export default nextConfig; diff --git a/apps/frontend/src/app/_home/UploadButtons.tsx b/apps/frontend/src/app/_home/UploadButtons.tsx index 5c141393..466e700f 100644 --- a/apps/frontend/src/app/_home/UploadButtons.tsx +++ b/apps/frontend/src/app/_home/UploadButtons.tsx @@ -6,11 +6,8 @@ import { cn } from "@/lib/utils"; import { UploadDataType, UploadModalityType } from "@/enums"; import { Upload as UploadIcon } from "lucide-react"; import { useAppContext } from "@/providers/AppProvider"; -import { findNiftiFile, findRelevantFiles } from "@/utils"; -import { getReport } from "@/services/apiReport"; import { toast } from "sonner"; import { useRouter } from "next/navigation"; -import { IAllRelevantFilesType } from "@/types"; import { handleBidsUpload, handleDicomUpload } from "./uploadHandlers"; type TUploadDataOptions = (typeof UploadDataType)[keyof typeof UploadDataType]; @@ -62,7 +59,7 @@ const UploadButtons = () => { setApiData(data); if ( data.missing_required_parameters && - data.missing_required_parameters.length > 0 + Number(data.missing_required_parameters.length) > 0 ) { toast.info( "Report generated with missing parameters. Please provide the missing values." diff --git a/apps/frontend/src/app/_home/uploadHandlers.ts b/apps/frontend/src/app/_home/uploadHandlers.ts index 32008058..834df114 100644 --- a/apps/frontend/src/app/_home/uploadHandlers.ts +++ b/apps/frontend/src/app/_home/uploadHandlers.ts @@ -61,7 +61,9 @@ const handleBidsUpload = async ({ files: FileList; setIsLoading: (v: boolean) => void; setUploadedFiles: (files: IAllRelevantFilesType) => void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any setUploadConfig: (config: any) => void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any setUpdatedJsonContent: (content: any) => void; setUpdatedJsonFilename: (filename: string) => void; activeModalityTypeOption: UploadModalityType; diff --git a/apps/frontend/src/services/apiReport.ts b/apps/frontend/src/services/apiReport.ts index 1f74606c..4a7d95ea 100644 --- a/apps/frontend/src/services/apiReport.ts +++ b/apps/frontend/src/services/apiReport.ts @@ -2,7 +2,7 @@ import axios from 'axios'; import {IReportApiResponse} from '@/types'; -const API_BASE_URL = `${process.env.NEXT_PUBLIC_API_BASE_URL}/report`; +const API_BASE_URL = `/api/report`; const client = axios.create({ baseURL: API_BASE_URL,