These conventions must be followed in all code:
-
Group exports at the end of the file in a single
export {}block -
When designing a module, place the calling function at the top of the file, and the child function(s) below it. This improves readability by showing the main logic first.
// Good: Calling function first function mainTask() { const result = subTask(); console.log(result); } function subTask() { return "Sub-task completed"; } // Bad: Child function first function subTask() { return "Sub-task completed"; } function mainTask() { const result = subTask(); console.log(result); }
-
Destructure props directly in the function signature for components and functions
-
When a function accepts multiple arguments (3 or more), prefer passing them as a single object rather than positional arguments. This improves readability and makes adding/removing arguments less error-prone.
// Good: Single object argument interface UserOptions { id: number; name: string; isAdmin?: boolean; } function createUser({ id, name, isAdmin = false }: UserOptions) { // ... } createUser({ id: 1, name: "Alice" }); // Bad: Multiple positional arguments function createUser(id: number, name: string, isAdmin: boolean = false) { // ... } createUser(1, "Alice"); // What is the third argument? Is it optional?
- Avoid multi-line jsdoc comments when it can fit in a single line
- All comments should be relevant:
- Avoid comments that explain simple lines of code (e.g.,
// Initialize variable x). The code should be self-explanatory. - Avoid "working comments" or comments that merely state what the code is doing (e.g.,
// Updated function call,// Loop through items,// removed xyz from here). These become outdated quickly and add noise. - Comments should primarily clarify why something is done a certain way if it's not obvious, or explain complex logic that cannot be simplified further.
- Avoid comments that explain simple lines of code (e.g.,
- Tests should start with the word "should".
- Tests should be grouped under a
__tests__folder and use the following naming scheme:${filename}.test.ts. - Use
TZDatefrom@date-fns/tzfor creating dates within tests to ensure consistent timezone handling, matching the application logic. - For time-sensitive tests, use
vi.useFakeTimers()andvi.setSystemTime()to control the system clock. Remember to callvi.useRealTimers()inafterEach. - Assert specific log messages using the shared
capturedOutputarray imported from@/utils/createOutputCapture. Clear this array (capturedOutput.length = 0) inbeforeEach. - For tests involving database interactions, ensure the relevant tables are cleaned up in
beforeEach(e.g.,await db.delete(coursesSchema)).
- Use descriptive error messages that explain what went wrong
- Prefer custom error classes for specific error types
- Always log errors with appropriate context