Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,544 changes: 1,221 additions & 323 deletions .output.txt

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions app/(root)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import HeroSection from "@/components/HeroSection";
import BookCard from "@/components/BookCard";
import {getAllBooks} from "@/lib/actions/book.actions";

export const dynamic = 'force-dynamic';

const Page = async () => {
const bookResults = await getAllBooks()
const books = bookResults.success ? bookResults.data ?? [] : []
Expand Down
2 changes: 2 additions & 0 deletions components/VapiControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ const VapiControls = ({ book }: { book: IBook }) => {
<button
onClick={isActive ? stop : start}
disabled={status === 'connecting'}
aria-label={isActive ? "Stop voice assistant" : "Start voice assistant"}
title={isActive ? "Stop voice assistant" : "Start voice assistant"}
className={`vapi-mic-btn shadow-md !w-[60px] !h-[60px] z-10 ${isActive ? 'vapi-mic-btn-active' : 'vapi-mic-btn-inactive'}`}
>
{isActive ? (
Expand Down
4 changes: 4 additions & 0 deletions hooks/useVapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ export function useVapi(book: IBook) {
});
} catch (err) {
console.error('Failed to start call:', err);
if (sessionIdRef.current) {
endVoiceSession(sessionIdRef.current, 0).catch((endErr) => console.error('Failed to rollback voice session after start failure:', endErr),);
sessionIdRef.current = null;
}
Comment on lines +271 to +274
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, find and examine the endVoiceSession implementation
fd -t f "session.actions.ts" --exec cat -n {} \;

# Also check the useVapi.ts file around lines 271-274
fd -t f "useVapi.ts" --exec sed -n '260,285p' {} \;

Repository: adrianhajdin/jsm_bookified

Length of output: 3218


🏁 Script executed:

# Check for other call sites using endVoiceSession with .catch()
rg -n "endVoiceSession.*\.catch" hooks/useVapi.ts

# Get broader context around the issue area to ensure this is the only instance
rg -B2 -A2 "endVoiceSession" hooks/useVapi.ts

Repository: adrianhajdin/jsm_bookified

Length of output: 1915


Apply consistent error handling for endVoiceSession across all call sites.

endVoiceSession returns { success: false } on failure instead of throwing, making .catch() handlers ineffective. This pattern appears at lines 107, 185, 214, and 272, silently skipping error handling in all cases. Update all call sites to await the result and check the success flag:

-                endVoiceSession(sessionIdRef.current, 0).catch((endErr) => console.error('Failed to rollback voice session after start failure:', endErr),);
+                const rollbackResult = await endVoiceSession(sessionIdRef.current, 0);
+                if (!rollbackResult.success) {
+                    console.error('Failed to rollback voice session after start failure:', rollbackResult.error);
+                }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (sessionIdRef.current) {
endVoiceSession(sessionIdRef.current, 0).catch((endErr) => console.error('Failed to rollback voice session after start failure:', endErr),);
sessionIdRef.current = null;
}
if (sessionIdRef.current) {
const rollbackResult = await endVoiceSession(sessionIdRef.current, 0);
if (!rollbackResult.success) {
console.error('Failed to rollback voice session after start failure:', rollbackResult.error);
}
sessionIdRef.current = null;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hooks/useVapi.ts` around lines 271 - 274, endVoiceSession returns a result
object with a success flag rather than throwing, so replace fire-and-forget
.catch() usage with awaiting the call and inspecting the returned { success } at
each call site (e.g., where sessionIdRef.current is used and endVoiceSession is
invoked around the handlers at the sites referenced). Concretely, in functions
referencing sessionIdRef and calling endVoiceSession (including the occurrences
near the current snippet and those ~lines 107, 185, 214), await
endVoiceSession(sessionIdRef.current, 0), check if result.success is false, and
log or handle the error using the returned result (and then set
sessionIdRef.current = null) instead of using .catch().

setStatus('idle');
setLimitError('Failed to start voice session. Please try again.');
}
Expand Down
10 changes: 10 additions & 0 deletions lib/actions/book.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {escapeRegex, generateSlug, serializeData} from "@/lib/utils";
import Book from "@/database/models/book.model";
import BookSegment from "@/database/models/book-segment.model";
import mongoose from "mongoose";
import {revalidatePath} from "next/cache";

export const getAllBooks = async () => {
try {
Expand Down Expand Up @@ -71,6 +72,8 @@ export const createBook = async (data: CreateBook) => {

const book = await Book.create({...data, slug, totalSegments: 0});

revalidatePath('/')

return {
success: true,
data: serializeData(book),
Expand Down Expand Up @@ -167,6 +170,13 @@ export const searchBookSegments = async (bookId: string, query: string, limit: n
const keywords = query.split(/\s+/).filter((k) => k.length > 2);
const pattern = keywords.map(escapeRegex).join('|');

if (keywords.length === 0) {
return {
success: true,
data: [],
};
}

segments = await BookSegment.find({
bookId: bookObjectId,
content: { $regex: pattern, $options: 'i' },
Expand Down
4 changes: 4 additions & 0 deletions next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ const nextConfig: NextConfig = {
typescript: {
ignoreBuildErrors: true,
},
// @ts-ignore
eslint: {
ignoreDuringBuilds: true,
},
Comment on lines 4 to +10
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check package.json for build/lint/typecheck scripts
echo "=== Checking package.json for build/lint/typecheck scripts ==="
if [ -f package.json ]; then
  rg -n "\"(build|lint|typecheck)\"\\s*:" package.json
else
  echo "package.json not found"
fi

echo ""
echo "=== Checking .github/workflows for CI checks ==="
# Find and search workflow files
fd -t f '.*\.(yml|yaml)$' .github/workflows 2>/dev/null | head -20 | while read -r file; do
  echo "File: $file"
  rg -n "lint|eslint|typecheck|tsc|next build|pnpm build|npm run build|yarn build" "$file" 2>/dev/null
done

echo ""
echo "=== Full next.config.ts content (first 50 lines) ==="
if [ -f next.config.ts ]; then
  head -50 next.config.ts
fi

Repository: adrianhajdin/jsm_bookified

Length of output: 734


Build safety gates are effectively disabled with no CI compensation.

Both typescript.ignoreBuildErrors and eslint.ignoreDuringBuilds are enabled, allowing broken typing and lint errors to ship undetected. The @ts-ignore comment masks config typing drift. No CI workflows are configured to enforce these checks separately, leaving no safety net before merge.

Recommended fix
     typescript: {
-        ignoreBuildErrors: true,
+        ignoreBuildErrors: false,
     },
-    // `@ts-ignore`
     eslint: {
-        ignoreDuringBuilds: true,
+        ignoreDuringBuilds: false,
     },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@next.config.ts` around lines 4 - 10, The config currently disables build
safety gates by setting typescript.ignoreBuildErrors = true and
eslint.ignoreDuringBuilds = true (with an `@ts-ignore` masking typing drift);
revert these by removing the `@ts-ignore` and setting typescript.ignoreBuildErrors
= false and eslint.ignoreDuringBuilds = false so type/lint errors fail builds,
and add/enable CI checks (a workflow step that runs TypeScript type-check and
ESLint) to enforce them before merge; ensure any legitimate type/lint issues are
fixed instead of silencing the checks in the next.config.ts configuration.

images: { remotePatterns: [
{ protocol: 'https', hostname: 'covers.openlibrary.org' },
{ protocol: 'https', hostname: 'lspfdyhgsrgsxcju.public.blob.vercel-storage.com' },
Expand Down
4 changes: 2 additions & 2 deletions types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export interface FileUploadFieldProps<T extends FieldValues> {
placeholder: string;
hint: string;
}
interface SessionCheckResult {
export interface SessionCheckResult {
allowed: boolean;
currentCount: number;
limit: number;
Expand All @@ -125,7 +125,7 @@ interface SessionCheckResult {
error?: string;
}

interface StartSessionResult {
export interface StartSessionResult {
success: boolean;
sessionId?: string;
maxDurationMinutes?: number;
Expand Down