chore: Update project configuration and enhance code quality
CI / skip-ci-check (push) Successful in 1m27s
CI / skip-ci-check (pull_request) Successful in 1m27s
CI / lint-and-type-check (pull_request) Has been cancelled
CI / python-lint (pull_request) Has been cancelled
CI / test-backend (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
CI / secret-scanning (pull_request) Has been cancelled
CI / dependency-scan (pull_request) Has been cancelled
CI / sast-scan (pull_request) Has been cancelled
CI / workflow-summary (pull_request) Has been cancelled
CI / lint-and-type-check (push) Successful in 2m4s
CI / python-lint (push) Successful in 1m53s
CI / test-backend (push) Successful in 2m37s
CI / build (push) Failing after 2m13s
CI / secret-scanning (push) Successful in 1m40s
CI / dependency-scan (push) Successful in 1m34s
CI / sast-scan (push) Successful in 2m42s
CI / workflow-summary (push) Successful in 1m26s

This commit modifies the `.gitignore` file to exclude Python library directories while ensuring the viewer-frontend's `lib` directory is not ignored. It also updates the `package.json` to activate the virtual environment during backend tests, improving the testing process. Additionally, the CI workflow is enhanced to prevent duplicate runs for branches with open pull requests. Various components in the viewer frontend are updated to ensure consistent naming conventions and improve type safety. These changes contribute to a cleaner codebase and a more efficient development workflow.
This commit is contained in:
Tanya
2026-01-07 12:29:17 -05:00
parent 36b84fc355
commit b6a9765315
26 changed files with 1311 additions and 67 deletions
+2 -2
View File
@@ -248,9 +248,9 @@ export function HomePageContent({ initialPhotos, people, tags }: HomePageContent
// Photo is already loaded, use it directly - no database access!
console.log('[HomePageContent] Using existing photo from photos array:', {
photoId: existingPhoto.id,
hasFaces: !!existingPhoto.faces,
hasFaces: !!(existingPhoto as any).faces,
hasFace: !!(existingPhoto as any).Face,
facesCount: existingPhoto.faces?.length || (existingPhoto as any).Face?.length || 0,
facesCount: (existingPhoto as any).faces?.length || (existingPhoto as any).Face?.length || 0,
photoKeys: Object.keys(existingPhoto),
});
setModalPhoto(existingPhoto);
+21 -2
View File
@@ -1,13 +1,13 @@
'use client';
import { useState } from 'react';
import { useState, Suspense } from 'react';
import { signIn } from 'next-auth/react';
import { useRouter, useSearchParams } from 'next/navigation';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import Link from 'next/link';
export default function LoginPage() {
function LoginForm() {
const router = useRouter();
const searchParams = useSearchParams();
const callbackUrl = searchParams.get('callbackUrl') || '/';
@@ -213,3 +213,22 @@ export default function LoginPage() {
);
}
export default function LoginPage() {
return (
<Suspense fallback={
<div className="flex min-h-screen items-center justify-center bg-gray-50 px-4">
<div className="w-full max-w-md space-y-8">
<div className="text-center">
<h2 className="mt-6 text-center text-3xl font-bold tracking-tight text-secondary">
Sign in to your account
</h2>
<p className="mt-2 text-center text-sm text-gray-600">Loading...</p>
</div>
</div>
</div>
}>
<LoginForm />
</Suspense>
);
}
+10 -1
View File
@@ -1,3 +1,4 @@
import { Suspense } from 'react';
import { prisma } from '@/lib/db';
import { HomePageContent } from './HomePageContent';
import { Photo } from '@prisma/client';
@@ -229,7 +230,15 @@ export default async function HomePage() {
</p>
</div>
) : (
<HomePageContent initialPhotos={serializePhotos(photos)} people={serializePeople(people)} tags={serializeTags(tags)} />
<Suspense fallback={
<div className="flex items-center justify-center py-12">
<div className="text-center">
<p className="text-gray-600 dark:text-gray-400">Loading...</p>
</div>
</div>
}>
<HomePageContent initialPhotos={serializePhotos(photos)} people={serializePeople(people)} tags={serializeTags(tags)} />
</Suspense>
)}
</main>
);
+9 -9
View File
@@ -8,14 +8,14 @@ async function getPhoto(id: number) {
const photo = await prisma.photo.findUnique({
where: { id },
include: {
faces: {
Face: {
include: {
person: true,
Person: true,
},
},
photoTags: {
PhotoTagLinkage: {
include: {
tag: true,
Tag: true,
},
},
},
@@ -36,18 +36,18 @@ async function getPhotosByIds(ids: number[]) {
processed: true,
},
include: {
faces: {
Face: {
include: {
person: true,
Person: true,
},
},
photoTags: {
PhotoTagLinkage: {
include: {
tag: true,
Tag: true,
},
},
},
orderBy: { dateTaken: 'desc' },
orderBy: { date_taken: 'desc' },
});
return serializePhotos(photos);
+21 -2
View File
@@ -1,12 +1,12 @@
'use client';
import { useState, useEffect } from 'react';
import { useState, useEffect, Suspense } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import Link from 'next/link';
export default function ResetPasswordPage() {
function ResetPasswordForm() {
const router = useRouter();
const searchParams = useSearchParams();
const token = searchParams.get('token');
@@ -177,6 +177,25 @@ export default function ResetPasswordPage() {
);
}
export default function ResetPasswordPage() {
return (
<Suspense fallback={
<div className="flex min-h-screen items-center justify-center bg-gray-50 px-4">
<div className="w-full max-w-md space-y-8">
<div className="text-center">
<h2 className="mt-6 text-center text-3xl font-bold tracking-tight text-secondary">
Reset your password
</h2>
<p className="mt-2 text-center text-sm text-gray-600">Loading...</p>
</div>
</div>
</div>
}>
<ResetPasswordForm />
</Suspense>
);
}
+7 -4
View File
@@ -25,13 +25,16 @@ async function getAllPeople() {
if (error?.code === 'P2023' || error?.message?.includes('Conversion failed')) {
console.warn('Corrupted person data detected, attempting fallback query');
try {
// Try with minimal fields first
// Try with minimal fields first, but include all required fields for type compatibility
return await prisma.person.findMany({
select: {
id: true,
first_name: true,
last_name: true,
// Exclude potentially corrupted optional fields
middle_name: true,
maiden_name: true,
date_of_birth: true,
created_date: true,
},
orderBy: [
{ first_name: 'asc' },
@@ -64,12 +67,12 @@ async function getAllTags() {
if (error?.code === 'P2023' || error?.message?.includes('Conversion failed')) {
console.warn('Corrupted tag data detected, attempting fallback query');
try {
// Try with minimal fields
// Try with minimal fields, but include all required fields for type compatibility
return await prisma.tag.findMany({
select: {
id: true,
tag_name: true,
// Exclude potentially corrupted date field
created_date: true,
},
orderBy: { tag_name: 'asc' },
});
+6 -9
View File
@@ -17,10 +17,9 @@ export default function TestImagesPage() {
id: 9991,
path: 'https://picsum.photos/800/600?random=1',
filename: 'test-direct-url-1.jpg',
dateAdded: new Date(),
dateTaken: null,
date_added: new Date(),
date_taken: null,
processed: true,
file_hash: 'test-hash-1',
media_type: 'image',
},
// Test 2: Another direct URL
@@ -28,10 +27,9 @@ export default function TestImagesPage() {
id: 9992,
path: 'https://picsum.photos/800/600?random=2',
filename: 'test-direct-url-2.jpg',
dateAdded: new Date(),
dateTaken: null,
date_added: new Date(),
date_taken: null,
processed: true,
file_hash: 'test-hash-2',
media_type: 'image',
},
// Test 3: File system path (will use API proxy)
@@ -39,10 +37,9 @@ export default function TestImagesPage() {
id: 9993,
path: '/nonexistent/path/test.jpg',
filename: 'test-file-system.jpg',
dateAdded: new Date(),
dateTaken: null,
date_added: new Date(),
date_taken: null,
processed: true,
file_hash: 'test-hash-3',
media_type: 'image',
},
];