Code Review Instructions
There are 3 categories that you should pay attention to in your code:
- Code Readability
- Repository Friendliness
- Console, TypeScript, and ESLint
1. Code Readability
Prettier
- all code should be formatted using
- you are advised to use editor extension to format on save - see the Download VS Code section for VS Code instructions
React Components
- components and props should have good meaningful names
- there should be no "mega-components" (component with >~250 lines of code)
- you can find big files using: (works on Linux/macOS)
- you can find big files using: (works on Linux/macOS)
- avoid components with a lot of UI and a lot of logic at the same time
- e.g. put logic into React hook(s),
- or separate UI to UI-only component
- duplication of code should be avoided
- use arrow functions for component definitions (unless you need hoisting, e.g., for TanStack Router route definitions)
Frontend Architecture
- Forms: Use with validation for form handling
- State Management: Use Apollo Client for GraphQL queries and mutations
- Routing: Use React Router (or TanStack Router) for navigation
- Component Library: Use Chakra UI as the base component library
- build custom components on top of Chakra UI primitives
- follow Atomic Design principles for component organization
Design System
- there should be some design system in the project
- at least basic "atoms" used across the app (buttons, inputs, icons, ...)
- components should be built on top of Chakra UI primitives
- it may follow Atomic Design
- if you don't use Atomic Design, it has to be structured in a consistent way at least
- design system components should be located in
Backend Architecture
- Proper Layer Separation: Follow the repository/services/resolvers pattern
- Resolvers (): Handle GraphQL-specific concerns (input/output types, decorators)
- Services (): Contain business logic, authorization checks using Ability Factory
- Repositories (): Handle data access and database operations
- Mappers (): Transform data between Prisma models and domain objects
- resolvers should be thin and delegate to services
- resolvers handle GraphQL type conversion and input validation
- services contain the actual business logic
- Authorization: Use the Ability Factory pattern for permission checks
- inject into services
- check permissions in service methods, not in resolvers
- use methods for authorization checks
- Better Auth: Use Better Auth plugins where appropriate
- leverage Better Auth's built-in features (email verification, password reset, etc.)
- extend with plugins when needed (social login, MFA, etc.)
- all logic steps are properly handled -> error handling, logs, value passing and returns
- data layers are properly separated using mappers between Prisma models and domain objects
Good Structure Overall
- Frontend: app should be grouped to modules (like: , , , ...)
- each module should have consistent structure: (atoms, molecules, organisms), , , ,
- Backend: app should be grouped to modules (like: , , , ...)
- each module should have consistent structure: , (resolvers, types), ,
- naming should be consistent across the app (or at least across the module)
- structure in each module should be similar
2. Repository Friendliness
Repository is Friendly for New Team Members
- there are at least basic files for frontend and backend
- should contain:
- system requirements (Node.js version, package manager, database, ...)
- how to install dependencies and run local dev server
- some info about advanced variables (e.g. email service token) and where to get it
- there should be with default/dummy values for all environment variables
- this serves also as "documentation" of all supported env variables
- should not contain any real production secrets (like passwords, API keys, JWT secret, ...)
- all real secrets should be in which is ignored by Git
One Package Manager
- project should use only one package manager (Yarn, NPM, PNPM)
- so the repo should contain only one type of lock files: , , or
3. Console, TypeScript, ESLint, and Dead Code
Console on Frontend
- no debugging console logs on frontend
- there could be few s for some error cases
- but most errors should be displayed to user using React
TypeScript
- TypeScript should return no errors
- there should be no overuse of and in the code
ESLint
- there should be no ESLint errors
- <10 errors/warnings is still tolerable
- but >150 errors/warnings not
- meaningful rules should not be disabled in or in code using
- except of few cases where it makes sense to disable them
Dead Code
- there should not be significant amount of dead code (unused code, commented out code, ...)