Skip to content

Conversation

@leslyclopez11
Copy link
Contributor

✨ Codu Pull Request 💻

Fixes #1009

Pull Request details

  • I added code to _client.tsx modifying slideThree (including the dropdown)
  • Defined yearsOfExperience in additionalUserDetails.tsx
  • Defined yearsOfExperience in page.tsx
  • Defined yearsOfExperience in schema.ts
  • I added validation based on coderabbitai suggestions
  • Attempted to create the Drizzle migration
  • I cherry-picked from the develop branch the commits, but I'm confused if I'm doing this right.

Any Breaking changes

  • I don't believe I have anything that would break the code

Associated Screenshots

  • None

@leslyclopez11 leslyclopez11 requested a review from a team as a code owner October 14, 2024 13:25
@vercel
Copy link

vercel bot commented Oct 14, 2024

@leslycatota1 is attempting to deploy a commit to the Codú Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 14, 2024

Walkthrough

The changes in this pull request introduce a new field, yearsOfExperience, to the onboarding form's AdditionalSignUpDetails component. This includes the addition of a dropdown for users to select their years of experience, updates to the user schema, and modifications to the database to accommodate this new field. The changes also incorporate validation using Zod for the new field and ensure that the data is correctly handled throughout the application.

Changes

File Path Change Summary
app/(app)/alpha/additional-details/_client.tsx Added yearsOfExperienceOptions constant and YearsOfExperience type. Updated UserDetails type to include yearsOfExperience. Modified AdditionalSignUpDetails and SlideThree functions to handle the new field.
app/(app)/alpha/additional-details/page.tsx Updated Page function to include yearsOfExperience in the database query and object construction.
drizzle/0010-yearsOfExperiece Added a migration script to include yearsOfExperience column in the "User" table with validation constraints.
schema/additionalUserDetails.ts Added optional yearsOfExperience field to slideThreeSchema with validation checks.
server/db/schema.ts Introduced yearsOfExperience field in the user table with a default value of "0-1" and marked as not nullable.

Assessment against linked issues

Objective Addressed Explanation
Add "Years of experience" field to onboarding form (#1009)
Include Zod schema for validation of the new field (#1009)
Add new field to the user table (#1009)

Possibly related PRs

  • Fix/date to string #990: This PR modifies the UserDetails type in the _client.tsx file, similar to the main PR's updates to the UserDetails type to include yearsOfExperience. Both PRs involve changes to the same type, indicating a related focus on user details management.

Poem

🐰 In the land of forms, so bright and clear,
A dropdown appears, bringing cheer!
With years of experience, users can share,
Their journey of work, with love and care.
So hop along, fill it out with glee,
For every detail counts, you see! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@leslyclopez11
Copy link
Contributor Author

leslyclopez11 commented Oct 14, 2024

I don't know how to take these commits out: Added Drizzle to README.md, Merge branch 'develop' into develop. I thought I cherry-picked but maybe that was not the case. I'll try to do it again but any tips?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (5)
drizzle/0010-yearsOfExperiece (2)

1-5: Consider NOT NULL constraint and use migration versioning.

The new "yearsOfExperience" column allows NULL values by default. Consider if this is the intended behavior. If not, you may want to add a NOT NULL constraint.

Also, it's a good practice to include the migration version in the SQL file for better traceability. Consider renaming the file to something like 0010_add_years_of_experience.sql.

You can modify the ALTER TABLE statement like this:

ALTER TABLE "User" ADD COLUMN "yearsOfExperience" text NOT NULL DEFAULT '0-1';

This assumes '0-1' is a valid default value. Adjust as needed based on your requirements.


7-12: Approved with a minor optimization suggestion.

The CHECK constraint implementation looks good. It correctly limits the "yearsOfExperience" values to the specified range and uses proper error handling.

For a minor optimization, you could combine both ALTER TABLE statements into a single DO block:

DO $$ 
BEGIN
    ALTER TABLE "User" 
    ADD COLUMN "yearsOfExperience" text,
    ADD CONSTRAINT "User_yearsOfExperience_check"
    CHECK ("yearsOfExperience" IN ('0-1', '1-3', '3-5', '5-8', '8-12', '12+'));
EXCEPTION
    WHEN duplicate_column THEN 
        -- Column already exists, try to add just the constraint
        ALTER TABLE "User" 
        ADD CONSTRAINT "User_yearsOfExperience_check"
        CHECK ("yearsOfExperience" IN ('0-1', '1-3', '3-5', '5-8', '8-12', '12+'));
    WHEN duplicate_object THEN null;
END $$;

This approach reduces the number of separate operations and handles cases where the column might exist but the constraint doesn't.

schema/additionalUserDetails.ts (1)

33-38: Approve changes with a suggestion for improved type safety.

The implementation of the yearsOfExperience field looks good and aligns well with the PR objectives. It's correctly defined as optional and includes proper validation against the yearsOfExperienceOptions.

For improved type safety, consider using z.enum() instead of z.string(). This will ensure that the type is inferred correctly and provide better autocomplete support. Here's how you can modify the field:

yearsOfExperience: z
  .enum(yearsOfExperienceOptions as [YearsOfExperience, ...YearsOfExperience[]])
  .optional(),

This change eliminates the need for the custom refinement while still ensuring type safety and validation.

app/(app)/alpha/additional-details/_client.tsx (2)

Line range hint 435-446: Correct the variable naming and logic in form validation

The variable isError is used to store the result of trigger(), which returns true when the validation passes. This can be misleading and might cause logic errors. Consider renaming isError to isValid and adjusting the conditional logic accordingly.

Apply this diff to fix the variable naming and logic:

-let isError = await trigger(["professionalOrStudent"]);
+let isValid = await trigger(["professionalOrStudent"]);

-if (isError && professionalOrStudent === "Working professional") {
-  isError = await trigger(["workplace", "jobTitle", "yearsOfExperience"]);
+if (isValid && professionalOrStudent === "Working professional") {
+  isValid = await trigger(["workplace", "jobTitle", "yearsOfExperience"]);
}

-if (isError && professionalOrStudent === "Current student") {
-  isError = await trigger(["levelOfStudy", "course"]);
+if (isValid && professionalOrStudent === "Current student") {
+  isValid = await trigger(["levelOfStudy", "course"]);
}

-if (isError) {
+if (isValid) {
  try {
    const isSuccess = await slideThreeSubmitAction(data);
    // ...

530-536: Reuse yearsOfExperienceOptions for consistency

Instead of hardcoding the options in the select input, consider mapping over the yearsOfExperienceOptions array. This promotes consistency and simplifies future updates.

Apply this diff:

- <option value="0-1">0-1 years</option>
- <option value="1-3">1-3 years</option>
- <option value="3-5">3-5 years</option>
- <option value="5-8">5-8 years</option>
- <option value="8-12">8-12 years</option>
- <option value="12+">12+ years</option>
+ {yearsOfExperienceOptions.map((experience) => (
+   <option key={experience} value={experience}>
+     {experience} years
+   </option>
+ ))}

This ensures the options remain in sync with the defined constants.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between cbd9a06 and 94cefec.

📒 Files selected for processing (5)
  • app/(app)/alpha/additional-details/_client.tsx (7 hunks)
  • app/(app)/alpha/additional-details/page.tsx (3 hunks)
  • drizzle/0010-yearsOfExperiece (1 hunks)
  • schema/additionalUserDetails.ts (2 hunks)
  • server/db/schema.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (10)
drizzle/0010-yearsOfExperiece (1)

1-12: Overall, the migration script looks good with room for minor improvements.

The script successfully adds the "yearsOfExperience" column to the User table and implements the required constraint. The error handling makes the migration idempotent, which is a good practice.

To ensure the changes are correctly reflected in the database schema, please run the following script:

This script will help verify that the column and constraint are properly added to the database schema and that the constraint is working as expected.

schema/additionalUserDetails.ts (1)

Line range hint 1-38: Summary: Implementation meets requirements with minor suggestions for improvement

The changes successfully implement the "Years of experience" field in the onboarding form, meeting the requirements outlined in the PR objectives and linked issue. The implementation is consistent with the existing code structure and includes proper validation using Zod schema.

Key points:

  1. The new field is correctly added to the slideThreeSchema.
  2. Proper validation is implemented to ensure only valid options are accepted.
  3. The changes do not introduce any breaking changes.

Suggestions for improvement:

  1. Consider moving shared constants to a common file to avoid potential server-side rendering issues.
  2. Use z.enum() for improved type safety in the yearsOfExperience field definition.

Overall, the implementation is solid and achieves the desired functionality. Addressing the minor suggestions will further enhance the code quality and maintainability.

server/db/schema.ts (1)

230-230: Consider data type and migration strategy for yearsOfExperience

The addition of the yearsOfExperience field to the user table is a good implementation of the requested feature. However, there are a few points to consider:

  1. Data type: The varchar type allows for flexibility, but it may complicate numerical comparisons or calculations. Consider using an enum or integer type if strict categories are preferred.

  2. Migration strategy: Ensure there's a migration plan to populate this field for existing user records.

  3. UI consistency: Verify that the options in the UI dropdown match the expected format for this field (e.g., "0-1", "1-3", etc.).

  4. Validation: Implement proper validation to ensure only valid values are stored in this field.

To verify the consistency between the schema and the UI implementation, please run the following script:

This script will help identify where and how the yearsOfExperience field is implemented in the UI, allowing us to verify consistency with the schema definition.

app/(app)/alpha/additional-details/page.tsx (1)

27-27: Include yearsOfExperience in user query

Including yearsOfExperience in the user query is appropriate and aligns with the new feature requirements.

app/(app)/alpha/additional-details/_client.tsx (6)

43-44: LGTM: Addition of yearsOfExperienceOptions and YearsOfExperience

The definition of yearsOfExperienceOptions and the corresponding type YearsOfExperience is clear and follows best practices.


56-56: LGTM: Updating UserDetails type

Including yearsOfExperience in the UserDetails type ensures that the new field is properly tracked and managed.


74-74: LGTM: Destructuring yearsOfExperience from details

Properly destructuring yearsOfExperience allows for its seamless use within the component.


406-406: LGTM: Including yearsOfExperience in SlideThree

Adding yearsOfExperience to the destructured details in SlideThree ensures that the value is accessible within the form.


424-424: LGTM: Setting yearsOfExperience in form default values

Including yearsOfExperience in the defaultValues of the form maintains consistency and supports form state management.


520-542: ⚠️ Potential issue

Use watch instead of getValues for reactive form updates

Using getValues("professionalOrStudent") for conditional rendering does not trigger re-renders when the value changes. This may cause the form not to update the UI as expected when the user changes their selection. Consider using watch("professionalOrStudent") to ensure the UI updates reactively.

Apply this diff:

- const professionalOrStudent = getValues("professionalOrStudent");
+ const professionalOrStudent = watch("professionalOrStudent");

Then, update the conditional rendering:

- {getValues("professionalOrStudent") === "Working professional" && (
+ {professionalOrStudent === "Working professional" && (

Ensure that watch is properly utilized in your component for reactive updates.

Likely invalid or redundant comment.

@@ -1,5 +1,5 @@
import z from "zod";

import { yearsOfExperienceOptions, YearsOfExperience } from "@/app/(app)/alpha/additional-details/_client";
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Consider moving shared constants to a common file.

Importing from a client-side file (@/app/(app)/alpha/additional-details/_client) in a schema definition might lead to issues in server-side rendering or API routes. This could potentially cause errors or unexpected behavior in a server environment where client-side modules are not available.

Consider moving the yearsOfExperienceOptions and YearsOfExperience to a shared constants file that can be safely imported in both client and server environments. For example:

// shared/constants.ts
export const yearsOfExperienceOptions = [...] as const;
export type YearsOfExperience = typeof yearsOfExperienceOptions[number];

Then update the import statement:

import { yearsOfExperienceOptions, YearsOfExperience } from "@/shared/constants";

This approach ensures that these constants are accessible throughout your application without risking server-side rendering issues.

Comment on lines +43 to +46
yearsOfExperience: details?.yearsOfExperience &&
["0-1", "1-3", "3-5", "5-8", "8-12", "12+"].includes(details.yearsOfExperience)
? details.yearsOfExperience as YearsOfExperience // Cast to the union type
: "0-1",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle unexpected yearsOfExperience values appropriately

Defaulting to "0-1" when details.yearsOfExperience contains an unexpected value might not reflect the user's actual experience. Consider handling invalid or unexpected values more explicitly, possibly by prompting the user to re-enter their information or by logging the discrepancy.


🛠️ Refactor suggestion

Simplify the yearsOfExperience assignment for better readability

The current assignment logic can be simplified to enhance readability and maintainability. Checking for details?.yearsOfExperience within the includes method suffices.

Consider applying this diff:

-yearsOfExperience: details?.yearsOfExperience && 
-  ["0-1", "1-3", "3-5", "5-8", "8-12", "12+"].includes(details.yearsOfExperience)
-    ? details.yearsOfExperience as YearsOfExperience // Cast to the union type
-    : "0-1",
+yearsOfExperience: ["0-1", "1-3", "3-5", "5-8", "8-12", "12+"].includes(details?.yearsOfExperience)
+  ? (details.yearsOfExperience as YearsOfExperience) // Cast to the union type
+  : "0-1",
📝 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
yearsOfExperience: details?.yearsOfExperience &&
["0-1", "1-3", "3-5", "5-8", "8-12", "12+"].includes(details.yearsOfExperience)
? details.yearsOfExperience as YearsOfExperience // Cast to the union type
: "0-1",
yearsOfExperience: ["0-1", "1-3", "3-5", "5-8", "8-12", "12+"].includes(details?.yearsOfExperience)
? (details.yearsOfExperience as YearsOfExperience) // Cast to the union type
: "0-1",

import Content from "./_client";
import { getServerAuthSession } from "@/server/auth";
import { db } from "@/server/db";
import {YearsOfExperience} from "./_client";
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consolidate imports from the same module

To improve code clarity and organization, consider combining the imports from "./_client" into a single statement.

Apply this diff:

-import Content from "./_client";
-import {YearsOfExperience} from "./_client";
+import Content, { YearsOfExperience } from "./_client";

Committable suggestion was skipped due to low confidence.

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.

Add "Years of experience" field to onboarding form

4 participants