Visitar URL original
chore: improve codebase type safety, error handling, and API validation by cwchanap · Pull Request #13 · cwchanap/cetus · GitHub
Skip to content

chore: improve codebase type safety, error handling, and API validation - #13

Merged
cwchanap merged 4 commits into
mainfrom
chore/codebase-improvements
Dec 21, 2025
Merged

cwchanap merged 4 commits into
mainfrom
chore/codebase-improvements

Conversation

@cwchanap

@cwchanap cwchanap commented Dec 20, 2025 •

Copy link
Copy Markdown
Owner
  • Remove any types and create proper interfaces for game data
  • Add shared game types in src/lib/games/shared/types.ts
  • Add error logging to all database query catch blocks
  • Consolidate duplicate getUserBestScore functions
  • Remove dead code (unused checkConsecutiveObjectType)
  • Create jsonResponse helper for consistent API responses
  • Add Zod for runtime API validation with schemas
  • Fix Google OAuth env validation (conditionally enabled)
  • Update tests to match new validation behavior

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Implemented validation system for score submissions and profile updates with clearer error messages.
    • Standardized API response formatting across endpoints.
  • Bug Fixes

    • Added Google OAuth configuration safety guard to prevent startup failures.
    • Enhanced error handling and logging for better debugging visibility.
  • Tests

    • Updated test suite to reflect new validation-first request handling.

✏️ Tip: You can customize this high-level summary in your review settings.

- Remove `any` types and create proper interfaces for game data
- Add shared game types in src/lib/games/shared/types.ts
- Add error logging to all database query catch blocks
- Consolidate duplicate getUserBestScore functions
- Remove dead code (unused checkConsecutiveObjectType)
- Create jsonResponse helper for consistent API responses
- Add Zod for runtime API validation with schemas
- Fix Google OAuth env validation (conditionally enabled)
- Update tests to match new validation behavior

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings December 20, 2025 08:15
@vercel

vercel Bot commented Dec 20, 2025 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
cetus Ready Ready Preview, Comment Dec 21, 2025 7:48pm

@coderabbitai

coderabbitai Bot commented Dec 20, 2025 •

Copy link
Copy Markdown

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This pull request strengthens type safety and API infrastructure across the codebase. It introduces shared type definitions for games and stats, adds Zod-based request validation and standardized API response helpers, improves authentication configuration, enhances error handling in database queries, and updates services and endpoints to use the new type-safe patterns.

Changes

Cohort / File(s) Summary
Configuration & Dependencies
.claude/settings.local.json, package.json
Updated Claude settings to allow Bash cat commands; added zod ^4.2.1 to dependencies for runtime validation.
Type System & Data Models
src/lib/games/shared/types.ts, src/lib/games/{tetris,bubble-shooter}/types.ts, src/lib/achievements.ts
Created canonical shared types module with per-game data interfaces (GameHistoryEntry, TetrisGameData, BubbleShooterGameData, etc.), GameData union, stats interfaces, and PixiJS color utilities; introduced AchievementCheckData union type and tightened achievement condition signatures; added BubbleShooterEndGameStats and TetrisEndGameStats interfaces for end-game callbacks.
Authentication Configuration
src/lib/auth.ts
Added conditional Google OAuth configuration; provider only included when googleClientId and googleClientSecret are set.
Server Infrastructure
src/lib/server/api-utils.ts, src/lib/server/validations.ts, src/lib/server/db/queries.ts
Introduced API response helpers (jsonResponse, errorResponse, unauthorizedResponse, badRequestResponse, notFoundResponse, successResponse); added Zod validation schemas for score submission, profile updates, leaderboard, and pagination queries with helper validators (validateBody, validateQuery); enhanced database query error logging and added backward-compatible getUserBestScoreByGame alias.
Services
src/lib/services/{achievementService.ts, scoreService.ts}
Updated checkInGameAchievements to accept typed AchievementCheckData; widened scoreService ScoreData and saveGameScore to accept GameData | Record<string, unknown>.
Score API
src/pages/api/scores.ts, src/pages/api/scores.test.ts
Refactored scores endpoint to use scoreSubmissionSchema validation and standardized response helpers; updated tests to verify validation-first error flow (expects 400 "Invalid JSON body" for malformed JSON instead of 500); removed direct reliance on getGameById after validation.
User Profile API
src/pages/api/user/profile.ts
Added UserUpdate type import and cast updates argument as UserUpdate instead of any.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

  • Key areas requiring attention:
    • src/lib/achievements.ts: Review the AchievementCheckData union type definition and verify all achievement check functions align with the new signature
    • src/lib/server/validations.ts: Validate Zod schemas (especially profileUpdateSchema refinement and enum generation from GameID)
    • src/pages/api/scores.ts and test updates: Confirm validation-first error handling flow and response helper usage are consistent
    • src/lib/server/db/queries.ts: Review error logging additions to ensure no sensitive data leaks in console output
    • src/lib/games/shared/types.ts: Check that all per-game data interfaces accurately reflect their respective game state requirements

Possibly related PRs

  • 001 2048 game #10: Adds 2048 achievement entries to src/lib/achievements.ts, which will need to align with the AchievementCheckData type constraints introduced in this PR.

Poem

🐰 With types we dance and schemas play,
Validation guards the API way,
From Tetris blocks to bubble pops,
Type safety never, ever stops! ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objectives of the changeset: improving type safety, error handling, and API validation across multiple modules.
Docstring Coverage ✅ Passed Docstring coverage is 95.24% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/codebase-improvements

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov-commenter

codecov-commenter commented Dec 20, 2025 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 57.75578% with 128 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/lib/server/db/queries.ts 35.65% 74 Missing ⚠️
src/lib/server/validations.ts 84.11% 17 Missing ⚠️
src/lib/auth.ts 0.00% 14 Missing ⚠️
src/lib/games/shared/types.ts 6.66% 14 Missing ⚠️
src/lib/server/api-utils.ts 76.00% 6 Missing ⚠️
src/lib/achievements.ts 66.66% 1 Missing ⚠️
src/lib/services/achievementService.ts 0.00% 1 Missing ⚠️
src/pages/api/scores.ts 95.23% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR improves codebase type safety, error handling, and API validation by replacing any types with proper interfaces, adding runtime validation with Zod, consolidating duplicate database functions, and improving error logging throughout the database layer.

  • Introduces shared game type definitions in a centralized location
  • Adds Zod-based runtime validation for API endpoints with reusable validation schemas
  • Replaces manual JSON response construction with helper utilities for consistency
  • Enhances database error handling with logging across all query functions

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
package.json Adds Zod dependency for runtime validation
bun.lock Updates lock file with Zod package and dependencies
src/lib/server/validations.ts New file containing Zod schemas for score submission, profile updates, leaderboard queries, and pagination
src/lib/server/api-utils.ts New file with response helper functions for consistent API responses
src/lib/games/shared/types.ts New file consolidating game-specific data types and common interfaces across all games
src/pages/api/scores.ts Refactors to use Zod validation and response helpers, removing manual validation and response construction
src/pages/api/scores.test.ts Updates tests to match new validation behavior (malformed JSON now returns 400 instead of 500)
src/pages/api/user/profile.ts Replaces any cast with proper UserUpdate type
src/lib/services/scoreService.ts Updates gameData parameter type from any to GameData | Record<string, unknown>
src/lib/services/achievementService.ts Adds AchievementCheckData type and removes duplicate checkConsecutiveObjectType helper function
src/lib/achievements.ts Imports game-specific types and updates achievement check function signatures with proper types
src/lib/games/tetris/types.ts Adds TetrisEndGameStats interface for properly typed game-over callback
src/lib/games/bubble-shooter/types.ts Adds BubbleShooterEndGameStats interface for properly typed game-over callback
src/lib/server/db/queries.ts Adds error logging to all catch blocks and consolidates duplicate getUserBestScore functions
src/lib/auth.ts Conditionally enables Google OAuth only when environment variables are properly configured

Comment thread src/pages/api/scores.test.ts
cwchanap and others added 3 commits December 21, 2025 11:47
- Remove `any` types and create proper interfaces for game data
- Add shared game types in src/lib/games/shared/types.ts
- Add error logging to all database query catch blocks
- Consolidate duplicate getUserBestScore functions
- Remove dead code (unused checkConsecutiveObjectType)
- Create jsonResponse helper for consistent API responses
- Add Zod for runtime API validation with schemas
- Fix Google OAuth env validation (conditionally enabled)
- Update tests to match new validation behavior

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (7)
src/lib/auth.ts (4)

36-36: Critical: Set secure: true for production cookie security.

The secure: false setting allows cookies to be transmitted over unencrypted HTTP connections, exposing session tokens to interception. This violates secure session requirements.

🔎 Proposed fix to enable secure cookies in production
-            secure: false,
+            secure: import.meta.env.PROD,

Based on coding guidelines and learnings: secure sessions are required for authentication.


40-40: Make trustedOrigins environment-specific to support production deployments.

Hardcoding localhost prevents the application from working correctly when deployed to staging or production environments.

🔎 Proposed fix to use environment-based origins
-    trustedOrigins: ['http://localhost:4325'],
+    trustedOrigins: [
+        import.meta.env.BETTER_AUTH_URL || 'http://localhost:4325',
+        ...(import.meta.env.PROD ? [] : ['http://localhost:4325'])
+    ],

41-42: Add runtime validation for required authentication secrets.

The non-null assertion on BETTER_AUTH_SECRET will cause a runtime error if the variable is undefined, and the empty string fallback for BETTER_AUTH_URL may cause authentication failures.

🔎 Proposed fix to validate secrets at startup
+const authSecret = import.meta.env.BETTER_AUTH_SECRET
+const authBaseURL = import.meta.env.BETTER_AUTH_URL
+
+if (!authSecret || authSecret.trim() === '') {
+    throw new Error('BETTER_AUTH_SECRET is required but not configured')
+}
+if (!authBaseURL || authBaseURL.trim() === '') {
+    throw new Error('BETTER_AUTH_URL is required but not configured')
+}
+
 export const auth = betterAuth({
     database: {
         dialect,
         type: 'sqlite',
     },
     emailAndPassword: {
         enabled: true,
         requireEmailVerification: false, // Set to true in production
     },
     // Only enable Google OAuth if properly configured
     ...(isGoogleOAuthConfigured && {
         socialProviders: {
             google: {
                 clientId: googleClientId,
                 clientSecret: googleClientSecret,
             },
         },
     }),
     session: {
         expiresIn: 60 * 60 * 24 * 7, // 7 days
         updateAge: 60 * 60 * 24, // 1 day
         cookie: {
             sameSite: 'lax',
             secure: false,
             httpOnly: true,
         },
     },
     trustedOrigins: ['http://localhost:4325'],
-    secret: import.meta.env.BETTER_AUTH_SECRET!,
-    baseURL: import.meta.env.BETTER_AUTH_URL || '',
+    secret: authSecret,
+    baseURL: authBaseURL,
 })

4-42: Critical: Add test coverage for authentication configuration.

The Codecov report shows 0% coverage for this file with 14 missing lines. Authentication is security-critical and requires comprehensive testing, especially for the new conditional OAuth configuration logic.

Recommended test scenarios:

  • OAuth enabled with valid credentials
  • OAuth disabled when credentials are missing or placeholders
  • OAuth disabled when credentials are empty strings
  • Session configuration validation
  • Secret validation errors

Do you want me to generate test cases for the authentication configuration?

src/lib/services/achievementService.ts (3)

56-58: Add error logging to catch block.

The PR description mentions adding error logging to all database query catch blocks, but this catch block silently returns an empty array without logging. This makes debugging difficult when achievement checks fail.

🔎 Proposed fix
     } catch (error) {
+        console.error('Error checking and awarding achievements:', error)
         return []
     }

85-87: Add error logging to catch block.

Similar to the previous function, this catch block should log errors for debugging purposes as mentioned in the PR description.

🔎 Proposed fix
     } catch (error) {
+        console.error('Error awarding global achievement:', error)
         return false
     }

134-136: Add error logging to catch block.

This catch block also needs error logging for consistency with the PR's stated improvements.

🔎 Proposed fix
     } catch (error) {
+        console.error('Error getting user game achievement progress:', error)
         return []
     }
🧹 Nitpick comments (5)
src/pages/api/user/profile.ts (1)

5-162: Consider refactoring to use the new API response helpers.

This endpoint manually constructs JSON responses while the new src/lib/server/api-utils.ts provides standardized helpers (unauthorizedResponse, badRequestResponse, successResponse, etc.) that are used in src/pages/api/scores.ts. Adopting these helpers would improve consistency across API routes.

Example refactor using API helpers

Add the import at the top:

+import { unauthorizedResponse, badRequestResponse, successResponse } from '@/lib/server/api-utils'

Then replace manual response constructions:

-        return new Response(JSON.stringify({ error: 'Unauthorized' }), {
-            status: 401,
-            headers: { 'Content-Type': 'application/json' },
-        })
+        return unauthorizedResponse()
-                return new Response(
-                    JSON.stringify({
-                        error: 'Name must be a non-empty string when provided',
-                    }),
-                    {
-                        status: 400,
-                        headers: { 'Content-Type': 'application/json' },
-                    }
-                )
+                return badRequestResponse('Name must be a non-empty string when provided')
-        return new Response(
-            JSON.stringify({
-                success: true,
-                message: 'Profile updated successfully',
-            }),
-            { status: 200, headers: { 'Content-Type': 'application/json' } }
-        )
+        return successResponse({ message: 'Profile updated successfully' })
src/pages/api/scores.ts (1)

64-64: Prefix unused error variable with underscore.

The caught error is unused. Per coding guidelines for TypeScript, prefix unused variables with _ to comply with ESLint rules.

Suggested fix
-    } catch (_error) {
+    } catch (_) {

Or if you plan to log it:

-    } catch (_error) {
+    } catch (error) {
+        console.error('[POST /api/scores] Unexpected error:', error)
         return errorResponse('Internal server error')
     }

As per coding guidelines: "Prefix unused variables with _ to comply with ESLint rules."

src/pages/api/scores.test.ts (1)

147-147: Consider asserting specific error messages for better test clarity.

The tests now check result.error is defined rather than asserting specific error messages. While this makes tests more resilient to error message changes, it reduces test specificity. Consider asserting expected error messages to catch unintended validation message changes.

Example with specific assertions
-        expect(result.error).toBeDefined()
+        expect(result.error).toBe('Invalid game ID')

For missing fields, you might expect Zod's default messages like:

-        expect(result.error).toBeDefined()
+        expect(result.error).toContain('Required')

Also applies to: 172-172, 198-198, 225-225

src/lib/achievements.ts (1)

21-29: Consider narrowing the fallback type for stricter validation.

The Record<string, unknown> fallback allows any object to pass as valid AchievementCheckData, which somewhat reduces the type safety benefits. While this provides extensibility for games without specific types, you might consider either:

  1. Removing the fallback to enforce explicit types for all games
  2. Using a more constrained fallback like { [key: string]: never } or a marker interface

However, if you need this flexibility for future game additions, the current approach is reasonable.

src/lib/server/validations.ts (1)

108-128: Validation helper with type-safe return structure!

The discriminated union return type provides excellent type safety for callers. The catch block appropriately handles JSON parsing errors.

Consider adding an error parameter to the catch block for better visibility (even if unused):

-    } catch {
+    } catch (error) {
+        // JSON parsing failed
         return { success: false, error: 'Invalid JSON body' }
     }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb2a2ae and 00afa7a.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • .claude/settings.local.json (1 hunks)
  • package.json (1 hunks)
  • src/lib/achievements.ts (6 hunks)
  • src/lib/auth.ts (2 hunks)
  • src/lib/games/bubble-shooter/types.ts (2 hunks)
  • src/lib/games/shared/types.ts (1 hunks)
  • src/lib/games/tetris/types.ts (2 hunks)
  • src/lib/server/api-utils.ts (1 hunks)
  • src/lib/server/db/queries.ts (29 hunks)
  • src/lib/server/validations.ts (1 hunks)
  • src/lib/services/achievementService.ts (2 hunks)
  • src/lib/services/scoreService.ts (3 hunks)
  • src/pages/api/scores.test.ts (6 hunks)
  • src/pages/api/scores.ts (3 hunks)
  • src/pages/api/user/profile.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (21)
src/{components,pages}/**/*.{ts,tsx,astro}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/{components,pages}/**/*.{ts,tsx,astro}: Always use the established sci-fi theme classes for styling consistency
Apply mobile-first responsive design with responsive breakpoints
Use Button component with variants (primary, outline, destructive) and proper sizing (sm, md, lg)
Apply Card component with glass-morphism using variant="sci-fi" or variant="glass"
Use Badge component with color-coded variants (success, warning, error, outline)
Implement Avatar component with gradient backgrounds and proper sizing
Use text-holographic, bg-sci-fi-dark, border-neon-cyan, shadow-glow-purple, animate-float sci-fi theme classes
Ensure link styling with text-white no-underline class
Use CSS animations over JavaScript when possible for better performance
Maintain sci-fi aesthetic while ensuring accessibility with proper ARIA labels
Ensure sufficient color contrast for readability in sci-fi theme

Implement responsive design with mobile-first approach in UI components

Files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/pages/api/user/profile.ts
src/pages/api/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Validate sessions on all protected API endpoints

src/pages/api/**/*.ts: Use file-based routing in src/pages/api/ for API endpoints
Implement proper error handling with consistent error patterns across API routes

Files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/pages/api/user/profile.ts
src/{lib/games,pages}/**/*.{ts,astro}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Implement keyboard navigation for games

Files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/pages/api/user/profile.ts
  • src/lib/games/bubble-shooter/types.ts
  • src/lib/games/shared/types.ts
  • src/lib/games/tetris/types.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.test.{ts,tsx}: Verify responsive behavior of game interfaces and canvas elements in tests
Use Vitest 3.2.4 with jsdom environment for component and service testing

Files:

  • src/pages/api/scores.test.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use single quotes for strings in JavaScript/TypeScript
Always include error handling in async operations

Files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/lib/auth.ts
  • src/pages/api/user/profile.ts
  • src/lib/games/bubble-shooter/types.ts
  • src/lib/server/api-utils.ts
  • src/lib/services/achievementService.ts
  • src/lib/services/scoreService.ts
  • src/lib/achievements.ts
  • src/lib/games/shared/types.ts
  • src/lib/server/validations.ts
  • src/lib/server/db/queries.ts
  • src/lib/games/tetris/types.ts
**/*.{js,ts,jsx,tsx,py,java,go}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx,py,java,go}: Write clear variable names that describe their purpose
Document complex algorithms with comments

Files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/lib/auth.ts
  • src/pages/api/user/profile.ts
  • src/lib/games/bubble-shooter/types.ts
  • src/lib/server/api-utils.ts
  • src/lib/services/achievementService.ts
  • src/lib/services/scoreService.ts
  • src/lib/achievements.ts
  • src/lib/games/shared/types.ts
  • src/lib/server/validations.ts
  • src/lib/server/db/queries.ts
  • src/lib/games/tetris/types.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use type annotations for function parameters in TypeScript

**/*.{ts,tsx}: Prefix unused variables with _ to comply with ESLint rules
Use strict TypeScript with explicit any warnings

Files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/lib/auth.ts
  • src/pages/api/user/profile.ts
  • src/lib/games/bubble-shooter/types.ts
  • src/lib/server/api-utils.ts
  • src/lib/services/achievementService.ts
  • src/lib/services/scoreService.ts
  • src/lib/achievements.ts
  • src/lib/games/shared/types.ts
  • src/lib/server/validations.ts
  • src/lib/server/db/queries.ts
  • src/lib/games/tetris/types.ts
src/pages/api/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Test API endpoints with request/response mocking

Files:

  • src/pages/api/scores.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use co-located *.test.ts files in the same directory as source code for unit tests

Files:

  • src/pages/api/scores.test.ts
src/{pages/api/scores,lib/services/scoreService}.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Score submissions should include automatic achievement checking

Files:

  • src/pages/api/scores.ts
  • src/lib/services/scoreService.ts
src/lib/auth*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Implement 7-day sessions with 1-day update intervals for session management

Files:

  • src/lib/auth.ts
src/{lib/auth.ts,pages/api/auth/**/*.ts}

📄 CodeRabbit inference engine (CLAUDE.md)

Use CSRF protection and secure sessions for authentication

Files:

  • src/lib/auth.ts
src/lib/games/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/lib/games/**/*.ts: Use PixiJS for canvas-based game rendering and interactive gameplay
Implement proper touch and mouse event handling for mobile/desktop compatibility
Handle responsive canvas sizing with proper scaling across devices
Query for existing Astro elements in TypeScript - never overwrite parent HTML with innerHTML
Clear children safely using removeChild instead of innerHTML
Game Container Pattern: Never use innerHTML for creating structure, Astro provides all necessary DOM structure upfront
Submit scores with POST to /api/scores endpoint including gameId, score, and optional gameData for achievement checking
Handle achievement notifications by calling window.showAchievementAward() when result.newAchievements is present
Support in-game events for achievements (Tetris line clears, Reflex coin streaks) via gameData parameter
Optimize PixiJS applications for mobile devices
Implement proper game state management with TypeScript types
Include timer and scoring systems with real-time updates
Add progress tracking and comprehensive achievement integration

Files:

  • src/lib/games/bubble-shooter/types.ts
  • src/lib/games/shared/types.ts
  • src/lib/games/tetris/types.ts
src/lib/games/*/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/lib/games/*/*.ts: Use PixiJS for canvas-based games, DOM manipulation for others
Implement proper game state transitions and button state management
Add score tracking with database integration via /api/scores endpoint
Integrate with achievement system for automatic progress tracking
Query for existing Astro elements rather than using innerHTML to create DOM structure
Use GameEventEmitter for type-safe event system in games
Use GameTimer for countdown timers with pause/resume support and time-based callbacks
Use ScoreManager for centralized score tracking with bonus/penalty calculations and multipliers
Use game debug objects (window.gameNameGame.getGame()) for game debugging

Files:

  • src/lib/games/bubble-shooter/types.ts
  • src/lib/games/shared/types.ts
  • src/lib/games/tetris/types.ts
src/lib/server/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Kysely for type-safe database queries instead of raw SQL

Use Kysely for all database queries

Files:

  • src/lib/server/api-utils.ts
  • src/lib/server/validations.ts
  • src/lib/server/db/queries.ts
src/lib/services/achievementService.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Achievement system should be code-based with 4 rarity tiers and automatic checking on score submission

Files:

  • src/lib/services/achievementService.ts
src/lib/achievements.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/lib/achievements.ts: Define all achievements in src/lib/achievements.ts with rarity levels
Use score-based (score_threshold) and custom event-based achievement types

Files:

  • src/lib/achievements.ts
src/lib/server/db/queries.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Integrate achievements automatically via saveGameScoreWithAchievements() function

Files:

  • src/lib/server/db/queries.ts
src/lib/server/db/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Handle database operations with proper TypeScript types for new entities

Files:

  • src/lib/server/db/queries.ts
src/lib/server/db/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Follow established patterns in src/lib/server/db/queries.ts when adding database queries

Files:

  • src/lib/server/db/queries.ts
src/lib/games/{tetris,reflex}/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Tetris and Reflex use PixiJS canvas rendering with container/graphics system

Files:

  • src/lib/games/tetris/types.ts
🧠 Learnings (39)
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/games/**/*.test.ts : Ensure proper game state transitions and score submissions in tests

Applied to files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/lib/games/bubble-shooter/types.ts
  • src/lib/services/scoreService.ts
  • src/lib/server/validations.ts
  • src/lib/server/db/queries.ts
  • src/lib/games/tetris/types.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/**/*.test.ts : Test achievement score thresholds and in-game event achievements

Applied to files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/lib/games/bubble-shooter/types.ts
  • src/lib/services/achievementService.ts
  • src/lib/services/scoreService.ts
  • src/lib/achievements.ts
  • src/lib/server/validations.ts
  • src/lib/server/db/queries.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/games/*/*.ts : Add score tracking with database integration via `/api/scores` endpoint

Applied to files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/lib/games/bubble-shooter/types.ts
  • src/lib/services/scoreService.ts
  • src/lib/server/validations.ts
  • src/lib/server/db/queries.ts
  • src/lib/games/tetris/types.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/{pages/api/scores,lib/services/scoreService}.ts : Score submissions should include automatic achievement checking

Applied to files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/lib/services/achievementService.ts
  • src/lib/services/scoreService.ts
  • src/lib/achievements.ts
  • src/lib/server/validations.ts
  • src/lib/server/db/queries.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/games/**/*.ts : Submit scores with POST to `/api/scores` endpoint including gameId, score, and optional gameData for achievement checking

Applied to files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/lib/services/achievementService.ts
  • src/lib/services/scoreService.ts
  • src/lib/achievements.ts
  • src/lib/server/validations.ts
  • src/lib/server/db/queries.ts
  • src/lib/games/tetris/types.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/games/**/*.test.ts : Test game logic with unit tests for core mechanics

Applied to files:

  • src/pages/api/scores.test.ts
  • src/lib/games/shared/types.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/pages/api/**/*.test.ts : Test API endpoints with request/response mocking

Applied to files:

  • src/pages/api/scores.test.ts
  • src/lib/server/api-utils.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to **/*.test.{ts,tsx} : Verify responsive behavior of game interfaces and canvas elements in tests

Applied to files:

  • src/pages/api/scores.test.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/games/**/*.ts : Add progress tracking and comprehensive achievement integration

Applied to files:

  • src/pages/api/scores.test.ts
  • src/lib/games/bubble-shooter/types.ts
  • src/lib/services/achievementService.ts
  • src/lib/services/scoreService.ts
  • src/lib/achievements.ts
  • src/lib/games/shared/types.ts
  • src/lib/server/validations.ts
  • src/lib/server/db/queries.ts
  • src/lib/games/tetris/types.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/games/*/*.ts : Use ScoreManager for centralized score tracking with bonus/penalty calculations and multipliers

Applied to files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/lib/services/scoreService.ts
  • src/lib/server/validations.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/server/db/queries.ts : Integrate achievements automatically via `saveGameScoreWithAchievements()` function

Applied to files:

  • src/pages/api/scores.test.ts
  • src/pages/api/scores.ts
  • src/lib/services/achievementService.ts
  • src/lib/services/scoreService.ts
  • src/lib/achievements.ts
  • src/lib/server/validations.ts
  • src/lib/server/db/queries.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/services/achievementService.ts : Achievement system should be code-based with 4 rarity tiers and automatic checking on score submission

Applied to files:

  • src/pages/api/scores.ts
  • src/lib/services/achievementService.ts
  • src/lib/services/scoreService.ts
  • src/lib/achievements.ts
  • src/lib/server/db/queries.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/pages/api/**/*.ts : Implement proper error handling with consistent error patterns across API routes

Applied to files:

  • src/pages/api/scores.ts
  • src/lib/server/api-utils.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/achievements.ts : Use score-based (`score_threshold`) and custom event-based achievement types

Applied to files:

  • src/pages/api/scores.ts
  • src/lib/services/achievementService.ts
  • src/lib/services/scoreService.ts
  • src/lib/achievements.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/games/**/*.ts : Handle achievement notifications by calling `window.showAchievementAward()` when `result.newAchievements` is present

Applied to files:

  • src/pages/api/scores.ts
  • src/lib/games/bubble-shooter/types.ts
  • src/lib/services/achievementService.ts
  • src/lib/achievements.ts
  • src/lib/server/db/queries.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/games/**/*.ts : Support in-game events for achievements (Tetris line clears, Reflex coin streaks) via gameData parameter

Applied to files:

  • src/pages/api/scores.ts
  • src/lib/games/bubble-shooter/types.ts
  • src/lib/services/achievementService.ts
  • src/lib/services/scoreService.ts
  • src/lib/achievements.ts
  • src/lib/games/shared/types.ts
  • src/lib/server/db/queries.ts
  • src/lib/games/tetris/types.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/auth*.ts : Implement 7-day sessions with 1-day update intervals for session management

Applied to files:

  • src/lib/auth.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/{lib/auth.ts,pages/api/auth/**/*.ts} : Use CSRF protection and secure sessions for authentication

Applied to files:

  • src/lib/auth.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Use Better Auth for production-ready authentication with email/password and OAuth

Applied to files:

  • src/lib/auth.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/pages/**/*.astro : Check `Astro.locals.user` for authentication on protected routes

Applied to files:

  • src/pages/api/user/profile.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/games/**/*.ts : Implement proper game state management with TypeScript types

Applied to files:

  • src/lib/games/bubble-shooter/types.ts
  • src/lib/services/scoreService.ts
  • src/lib/games/shared/types.ts
  • src/lib/games/tetris/types.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/games/core/*.ts : Use BaseGame abstract class for game logic with state management, scoring, and event emission

Applied to files:

  • src/lib/games/bubble-shooter/types.ts
  • src/lib/games/shared/types.ts
  • src/lib/games/tetris/types.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/games/*/*.ts : Use GameEventEmitter for type-safe event system in games

Applied to files:

  • src/lib/games/bubble-shooter/types.ts
  • src/lib/games/shared/types.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/games/**/*.ts : Include timer and scoring systems with real-time updates

Applied to files:

  • src/lib/games/bubble-shooter/types.ts
  • src/lib/server/validations.ts
  • src/lib/games/tetris/types.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/server/db/**/*.ts : Handle database operations with proper TypeScript types for new entities

Applied to files:

  • src/lib/server/api-utils.ts
  • src/lib/server/db/queries.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/games/*/*.ts : Integrate with achievement system for automatic progress tracking

Applied to files:

  • src/lib/services/achievementService.ts
  • src/lib/achievements.ts
  • src/lib/server/db/queries.ts
  • src/lib/games/tetris/types.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/achievements.ts : Define all achievements in `src/lib/achievements.ts` with rarity levels

Applied to files:

  • src/lib/services/achievementService.ts
  • src/lib/services/scoreService.ts
  • src/lib/achievements.ts
  • src/lib/server/db/queries.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/games/*/[!core]/**/*.ts : Follow modular game architecture pattern with consistent file structure (types.ts → game.ts → renderer.ts → utils.ts)

Applied to files:

  • src/lib/games/shared/types.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/games/{tetris,reflex}/**/*.ts : Tetris and Reflex use PixiJS canvas rendering with container/graphics system

Applied to files:

  • src/lib/games/shared/types.ts
  • src/lib/games/tetris/types.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/games/**/*.ts : Use PixiJS for canvas-based game rendering and interactive gameplay

Applied to files:

  • src/lib/games/shared/types.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/games/**/init.ts : Export debug objects for games: `window.memoryMatrixGame.getGame()`, `window.tetrisGame.getGame()` for development

Applied to files:

  • src/lib/games/shared/types.ts
  • src/lib/games/tetris/types.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/games/*/*.ts : Use PixiJS for canvas-based games, DOM manipulation for others

Applied to files:

  • src/lib/games/shared/types.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/games/**/*.ts : Optimize PixiJS applications for mobile devices

Applied to files:

  • src/lib/games/shared/types.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/games/*/*.ts : Use game debug objects (window.gameNameGame.getGame()) for game debugging

Applied to files:

  • src/lib/games/shared/types.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/server/db/*.ts : Follow established patterns in `src/lib/server/db/queries.ts` when adding database queries

Applied to files:

  • src/lib/server/db/queries.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/lib/server/**/*.ts : Use Kysely for type-safe database queries instead of raw SQL

Applied to files:

  • src/lib/server/db/queries.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/server/**/*.ts : Use Kysely for all database queries

Applied to files:

  • src/lib/server/db/queries.ts
📚 Learning: 2025-11-25T03:26:35.629Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Store user achievements as records with dynamic progress calculation for score-based achievements

Applied to files:

  • src/lib/server/db/queries.ts
📚 Learning: 2025-12-16T07:58:40.459Z
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/games/*/*.ts : Implement proper game state transitions and button state management

Applied to files:

  • src/lib/games/tetris/types.ts
🧬 Code graph analysis (8)
src/pages/api/scores.test.ts (1)
src/lib/games.ts (1)
  • getGameById (177-179)
src/pages/api/scores.ts (4)
src/lib/server/api-utils.ts (4)
  • unauthorizedResponse (25-29)
  • badRequestResponse (34-36)
  • errorResponse (18-20)
  • jsonResponse (8-13)
src/lib/server/validations.ts (2)
  • validateBody (108-128)
  • scoreSubmissionSchema (14-20)
src/lib/games.ts (1)
  • getGameById (177-179)
src/lib/services/achievementService.ts (1)
  • getAchievementNotifications (142-159)
src/pages/api/user/profile.ts (2)
src/lib/server/db/queries.ts (1)
  • updateUser (631-652)
src/lib/server/db/types.ts (1)
  • UserUpdate (105-115)
src/lib/services/achievementService.ts (2)
src/lib/server/db/types.ts (1)
  • GameType (66-66)
src/lib/achievements.ts (1)
  • AchievementCheckData (22-29)
src/lib/services/scoreService.ts (1)
src/lib/games/shared/types.ts (1)
  • GameData (104-116)
src/lib/achievements.ts (2)
src/lib/games/shared/types.ts (7)
  • TetrisGameData (15-22)
  • BejeweledGameData (32-37)
  • ReflexGameData (54-58)
  • QuickMathGameData (61-68)
  • Game2048Data (91-95)
  • WordScrambleGameData (47-51)
  • GameHistoryEntry (6-12)
src/lib/services/scoreService.ts (1)
  • GameHistoryEntry (27-32)
src/lib/games/shared/types.ts (1)
src/lib/games/tetris/types.ts (1)
  • GameStats (15-22)
src/lib/server/db/queries.ts (1)
src/lib/services/scoreService.ts (1)
  • getUserBestScore (136-153)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: 🎭 End-to-End Tests
🔇 Additional comments (29)
.claude/settings.local.json (1)

13-14: LGTM! Reasonable addition of read-only command permission.

Adding cat permission is consistent with other read-only bash commands (grep, find, ls) already allowed. This enables useful file reading capabilities for Claude Code while maintaining appropriate security boundaries.

src/lib/server/db/queries.ts (3)

15-17: LGTM! Excellent defensive error handling helper.

The sanitizeError helper provides type-safe error normalization, preventing crashes from unexpected error types while ensuring consistent string output for logging.


46-47: Excellent enhancement: comprehensive error logging improves observability.

The consistent error logging pattern across all database operations significantly improves debugging and monitoring capabilities. Key strengths:

  • Function name prefixes (e.g., [getUserStats]) enable quick error source identification
  • The sanitizeError helper ensures safe error message formatting
  • Migration operations appropriately use console.warn instead of console.error
  • All functions maintain their existing error recovery behavior (returning null/false/empty arrays)

This is a model implementation of defensive logging that balances observability with operational safety.

Also applies to: 87-88, 149-153, 183-186, 208-212, 261-265, 305-309, 351-355, 377-381, 404-408, 441-442, 488-492, 534-538, 607-611, 648-650, 669-673, 722-726, 753-757, 790-794, 817-821, 840-842, 853-855, 875-879, 893-897, 909-911, 1068-1072


624-626: LGTM! Clean deprecation strategy.

The deprecation alias maintains backward compatibility while providing a clear migration path. The JSDoc notice will help consumers update their code at their own pace.

src/lib/auth.ts (2)

7-11: Strengthen OAuth credential validation to reject empty strings.

The current validation checks for truthy values and rejects 'placeholder', but empty strings would pass the truthy check and cause OAuth failures at runtime.

🔎 Proposed fix to add empty string validation
 const isGoogleOAuthConfigured =
     googleClientId &&
     googleClientSecret &&
+    googleClientId.trim() !== '' &&
+    googleClientSecret.trim() !== '' &&
     googleClientId !== 'placeholder' &&
     googleClientSecret !== 'placeholder'
⛔ Skipped due to learnings
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/{lib/auth.ts,pages/api/auth/**/*.ts} : Use CSRF protection and secure sessions for authentication
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Applies to src/lib/auth*.ts : Implement 7-day sessions with 1-day update intervals for session management
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T03:26:35.629Z
Learning: Applies to src/pages/api/**/*.ts : Validate sessions on all protected API endpoints
Learnt from: CR
Repo: cwchanap/cetus PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T07:58:40.459Z
Learning: Use Better Auth for production-ready authentication with email/password and OAuth

23-30: Type narrowing in the conditional OAuth provider spread is properly handled.

The googleClientId and googleClientSecret variables are explicitly checked for truthiness and non-placeholder values before being used in the conditional spread (lines 7-11). The isGoogleOAuthConfigured guard ensures these variables are narrowed from string | undefined to string before the spread operator at lines 23-30, which satisfies TypeScript strict mode requirements.

src/lib/server/api-utils.ts (1)

1-52: LGTM! Well-structured API response utilities.

The implementation provides consistent response formatting with proper type safety, default parameters, and clear separation of concerns. The helpers centralize error handling patterns across API routes as intended.

src/pages/api/user/profile.ts (1)

141-141: LGTM! Safe type assertion.

The cast to UserUpdate is safe given the preceding validation logic ensures only valid fields are present in the updates object.

src/lib/games/bubble-shooter/types.ts (2)

27-33: LGTM! Strong type definition for end-game stats.

The new BubbleShooterEndGameStats interface provides clear, well-structured typing for game completion data.


50-50: Excellent type safety improvement.

Replacing any with BubbleShooterEndGameStats in the onGameOver callback signature eliminates type ambiguity and provides IDE autocomplete support.

src/pages/api/scores.ts (1)

24-36: Excellent validation-first flow with proper error handling.

The Zod validation and centralized error responses create a clean, type-safe request handling pattern.

src/pages/api/scores.test.ts (2)

222-227: Clear documentation of validation-first behavior.

The updated comments correctly explain that Zod validation catches invalid game IDs before getGameById is invoked, and the assertion on line 226 confirms this expectation.


295-314: Appropriate validation of malformed JSON handling.

The test correctly verifies that malformed JSON is caught by the validation layer and returns the expected "Invalid JSON body" error message.

src/lib/games/tetris/types.ts (2)

24-34: LGTM! Comprehensive end-game statistics interface.

The TetrisEndGameStats interface captures all relevant game completion metrics with clear, descriptive field names.


50-50: Excellent type safety improvement.

Replacing any with TetrisEndGameStats eliminates type ambiguity and provides compile-time type checking for the callback parameter.

src/lib/services/scoreService.ts (2)

24-24: Strong type safety improvement.

Replacing any with GameData | Record<string, unknown> provides type-safe game data handling while maintaining flexibility for edge cases.


83-83: Consistent type refinement.

The updated parameter type aligns with the ScoreData interface and eliminates the use of any, improving overall type safety.

package.json (1)

53-53: Zod version 4.2.1 is confirmed to exist and is production-ready.

The version was published to npm on December 16, 2025 (5 days ago) as a stable release. Zod 4 does indeed introduce significant breaking changes including unified error customization, new standalone string schemas (moved from z.string().foo() to top-level z.foo() helpers), default value behavior changes, object/structural API changes, and ZodError shape modifications. The dependency specification in package.json is valid.

src/lib/services/achievementService.ts (1)

5-5: Excellent type safety improvement!

Replacing any with AchievementCheckData provides better type checking and aligns with the PR's goal of removing any types from the codebase.

Also applies to: 176-176

src/lib/achievements.ts (2)

940-941: Type-safe achievement checks look good!

The inline type annotations for gameData provide clear expectations for what data these achievements need, improving both type safety and code readability.

Also applies to: 953-954


1113-1137: Helper function properly typed!

The checkConsecutiveObjectType function now uses GameHistoryEntry[] instead of a loosely-typed array, improving type safety while maintaining the correct logic for streak detection.

src/lib/server/validations.ts (5)

14-22: Score submission schema looks good!

The schema properly validates game IDs against the enum, enforces non-negative integer scores, and allows flexible game data. This aligns well with the achievement system's needs.


27-66: Profile update schema with proper validation!

The preprocessing for displayName and username ensures clean data (trimming, lowercasing), and the refinement requiring at least one field prevents empty update requests. The combination of .nullable().optional() correctly allows fields to be omitted or set to null.


71-83: Leaderboard query schema properly structured!

The transform-then-pipe pattern correctly parses string query parameters to integers and validates the range. The default of '10' appropriately matches the pre-transform type.


88-103: Pagination query schema follows the same solid pattern!

Consistent with the leaderboard schema, properly handling string-to-number transformation with sensible defaults and constraints.


133-149: Query validation helper looks good!

Clean synchronous validation for URL search parameters with the same type-safe return pattern as validateBody.

src/lib/games/shared/types.ts (3)

6-101: Comprehensive game data type definitions!

The interfaces cover all game-specific data needed for achievement tracking and scoring. The GameHistoryEntry base type is particularly well-designed for tracking click events across games.


152-160: Color conversion function with proper validation!

The function correctly validates hex color format and throws meaningful errors for invalid input. The regex ensures exactly 6 hex digits, preventing out-of-range values.


169-178: Robust reverse color conversion!

The function defensively handles invalid inputs (non-numbers, NaN, Infinity) and gracefully clamps out-of-range values to valid color boundaries. The padding ensures consistent 6-digit hex output.

This branch was successfully deployed

1 active deployment
Preview — 00afa7ae Deployed Dec 21, 2025 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants