feat: infinite scroll, HEIC support, likes fix, security & backup

- Fix liked hearts not showing after page reload (sync useEffect in CatCard)
- Replace pagination with infinite scroll (useInfiniteQuery + IntersectionObserver)
- Add HEIC/HEIF/AVIF image support with sharp conversion to JPEG on upload
- Validate MIME type alongside file extension to prevent spoofing
- Limit caption to 500 chars; increase upload size limit to 20MB
- Delete physical file from uploads/ when post is removed (cats + admin routes)
- Add WAL journal mode and graceful shutdown (SIGTERM/SIGINT) to db
- Add rate limiter for upload endpoint (10 req / 15 min)
- Add pre-deploy backup of data.db and uploads/ to deploy.sh (keeps last 10)
- Add plan_modernization.md with ideas for future improvements

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-26 00:18:46 +03:00
parent 81c9bba56f
commit 94fff09a41
11 changed files with 290 additions and 65 deletions

View File

@@ -1,10 +1,13 @@
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useInfiniteQuery, useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { getCats, getUserCats, getCat, uploadCat, deleteCat } from '@/api/endpoints';
export function useCats(page: number) {
return useQuery({
queryKey: ['cats', page],
queryFn: () => getCats(page).then((r) => r.data),
export function useCats() {
return useInfiniteQuery({
queryKey: ['cats'],
queryFn: ({ pageParam }) => getCats(pageParam as number).then((r) => r.data),
initialPageParam: 1,
getNextPageParam: (lastPage) =>
lastPage.page < lastPage.totalPages ? lastPage.page + 1 : undefined,
});
}