diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index da21617..1032c8f 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -102,6 +102,7 @@ jobs: continue-on-error: true - name: Run ESLint (admin-frontend) + id: eslint-check run: | cd admin-frontend npm run lint @@ -112,6 +113,12 @@ jobs: cd viewer-frontend npm ci + - name: Generate Prisma Clients (for type-check) + run: | + cd viewer-frontend + npm run prisma:generate:all || true + continue-on-error: true + - name: Audit viewer-frontend dependencies run: | cd viewer-frontend @@ -119,11 +126,31 @@ jobs: continue-on-error: true - name: Type check (viewer-frontend) + id: type-check run: | cd viewer-frontend npm run type-check continue-on-error: true + - name: Check for lint/type-check failures + if: always() + run: | + FAILED=false + if [ "x${{ steps.eslint-check.outcome }}" = "xfailure" ]; then + echo "❌ ESLint check failed" + FAILED=true + fi + if [ "x${{ steps.type-check.outcome }}" = "xfailure" ]; then + echo "❌ Type check failed" + FAILED=true + fi + if [ "$FAILED" = "true" ]; then + echo "❌ One or more checks failed. Failing job." + exit 1 + else + echo "✅ All checks passed" + fi + python-lint: needs: skip-ci-check runs-on: ubuntu-latest @@ -145,15 +172,36 @@ jobs: pip install --no-cache-dir flake8 black mypy pylint - name: Check Python syntax + id: python-syntax-check run: | find backend -name "*.py" -exec python -m py_compile {} \; continue-on-error: true - name: Run flake8 + id: flake8-check run: | flake8 backend --max-line-length=100 --ignore=E501,W503 continue-on-error: true + - name: Check for Python lint failures + if: always() + run: | + FAILED=false + if [ "x${{ steps.python-syntax-check.outcome }}" = "xfailure" ]; then + echo "❌ Python syntax check failed" + FAILED=true + fi + if [ "x${{ steps.flake8-check.outcome }}" = "xfailure" ]; then + echo "❌ Flake8 check failed" + FAILED=true + fi + if [ "$FAILED" = "true" ]; then + echo "❌ One or more Python lint checks failed. Failing job." + exit 1 + else + echo "✅ All Python lint checks passed" + fi + test-backend: needs: skip-ci-check runs-on: ubuntu-latest @@ -388,6 +436,7 @@ jobs: echo "✅ Database schemas initialized (main and auth)" - name: Run backend tests + id: backend-tests run: | export PYTHONPATH=$(pwd) export SKIP_DEEPFACE_IN_TESTS=1 @@ -395,6 +444,16 @@ jobs: echo "⚠️ DeepFace/TensorFlow disabled in tests to avoid CPU instruction errors" python -m pytest tests/ -v --tb=short --cov=backend --cov-report=term-missing --cov-report=xml --junit-xml=test-results.xml || true continue-on-error: true + + - name: Check for test failures + if: always() + run: | + if [ "x${{ steps.backend-tests.outcome }}" = "xfailure" ]; then + echo "❌ Backend tests failed. Failing job." + exit 1 + else + echo "✅ Backend tests passed" + fi - name: Test results summary if: always() @@ -461,6 +520,7 @@ jobs: uses: actions/checkout@v4 - name: Validate backend (imports and app instantiation) + id: validate-backend continue-on-error: true run: | # Install Python 3.12 using pyenv (required for modern type hints like str | None) @@ -557,9 +617,10 @@ jobs: continue-on-error: true - name: Build admin-frontend + id: build-admin-frontend run: | cd admin-frontend - npm run build || true + npm run build continue-on-error: true env: VITE_API_URL: http://localhost:8000 @@ -582,10 +643,34 @@ jobs: continue-on-error: true - name: Build viewer-frontend + id: build-viewer-frontend run: | cd viewer-frontend - npm run build || true + npm run build continue-on-error: true + + - name: Check for build failures + if: always() + run: | + FAILED=false + if [ "x${{ steps.validate-backend.outcome }}" = "xfailure" ]; then + echo "❌ Backend validation failed" + FAILED=true + fi + if [ "x${{ steps.build-admin-frontend.outcome }}" = "xfailure" ]; then + echo "❌ Admin frontend build failed" + FAILED=true + fi + if [ "x${{ steps.build-viewer-frontend.outcome }}" = "xfailure" ]; then + echo "❌ Viewer frontend build failed" + FAILED=true + fi + if [ "$FAILED" = "true" ]; then + echo "❌ One or more builds failed. Failing job." + exit 1 + else + echo "✅ All builds passed" + fi env: DATABASE_URL: postgresql://postgres:postgres@localhost:5432/punimtag DATABASE_URL_AUTH: postgresql://postgres:postgres@localhost:5432/punimtag_auth diff --git a/viewer-frontend/app/api/search/route.ts b/viewer-frontend/app/api/search/route.ts index aa52627..e35cfeb 100644 --- a/viewer-frontend/app/api/search/route.ts +++ b/viewer-frontend/app/api/search/route.ts @@ -32,7 +32,7 @@ export async function GET(request: NextRequest) { where: { userId }, select: { photoId: true }, }); - favoritePhotoIds = favorites.map(f => f.photoId); + favoritePhotoIds = favorites.map((f: { photoId: number }) => f.photoId); // If user has no favorites, return empty result if (favoritePhotoIds.length === 0) { diff --git a/viewer-frontend/app/api/users/[id]/route.ts b/viewer-frontend/app/api/users/[id]/route.ts index 68025c1..47e5092 100644 --- a/viewer-frontend/app/api/users/[id]/route.ts +++ b/viewer-frontend/app/api/users/[id]/route.ts @@ -279,7 +279,7 @@ export async function DELETE( prismaAuth.photoFavorite.count({ where: { userId } }), ]); - const finalHasRelatedRecords = finalCheck.some(count => count > 0); + const finalHasRelatedRecords = finalCheck.some((count: number) => count > 0); if (finalHasRelatedRecords) { console.log(`[DELETE User ${userId}] Final check found related records, deactivating instead`); diff --git a/viewer-frontend/tsconfig.json b/viewer-frontend/tsconfig.json index e8263c5..6f82382 100644 --- a/viewer-frontend/tsconfig.json +++ b/viewer-frontend/tsconfig.json @@ -28,7 +28,8 @@ "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts", - "**/*.mts" + "**/*.mts", + "types/**/*.d.ts" ], "exclude": ["node_modules", "scripts"] } diff --git a/viewer-frontend/types/prisma-client-auth.d.ts b/viewer-frontend/types/prisma-client-auth.d.ts new file mode 100644 index 0000000..3442ccf --- /dev/null +++ b/viewer-frontend/types/prisma-client-auth.d.ts @@ -0,0 +1,6 @@ +// Type declaration for Prisma client-auth +// This module is generated at build time by Prisma +declare module '../node_modules/.prisma/client-auth' { + export * from '@prisma/client'; +} +