Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: background tasks #1160

Merged
merged 17 commits into from
Jun 21, 2024
Merged

feat: background tasks #1160

merged 17 commits into from
Jun 21, 2024

Conversation

Mythie
Copy link
Collaborator

@Mythie Mythie commented May 15, 2024

Description

Currently a work in progress but this adds background tasks to Documenso for handling tasks that take a little longer and aren't part of the overall critical path.

Related Issue

N/A

Changes Made

Added a pluggable jobs provider supporting both a local provider and a Trigger.dev provider.

Testing Performed

  • Verified job level retries work
  • Verified task level retries work without incrementing job retries

image
image

This will still have a lot of rough edges but is a perfect MVP for local durable compute which may accept more providers later on

Summary by CodeRabbit

  • New Features

    • Added background job management functionalities to handle email sending and job processing.
    • Introduced support for triggering and managing jobs using various providers.
  • Chores

    • Updated environment configuration files to support new job management features.
    • Added and updated scripts and dependencies for job management and CLI commands.
  • Refactor

    • Refactored email sending functionalities to utilize the new job queue mechanism.
  • Documentation

    • Updated documentation to reflect the new environment variables and configurations related to background jobs.
  • Configuration

    • Updated Docker configurations to support new services for job management.
    • Updated VSCode settings for improved development experience with new dependencies and formatting rules.
  • Database

    • Added new database schemas and migrations to support background job management and tracking.

Copy link

vercel bot commented May 15, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
prd-app 🔄 Building (Inspect) Visit Preview 💬 Add feedback Jun 21, 2024 4:33am
stg-app ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 21, 2024 4:33am
stg-docs ❌ Failed (Inspect) Jun 21, 2024 4:33am
stg-marketing ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 21, 2024 4:33am
1 Ignored Deployment
Name Status Preview Comments Updated (UTC)
prd-marketing ⬜️ Ignored (Inspect) Jun 21, 2024 4:33am

Copy link
Contributor

coderabbitai bot commented May 15, 2024

Walkthrough

The recent changes primarily focus on enhancing job management by integrating a new job provider with configurations, refining email dispatching through job queues, and updating various dependencies and scripts. Configuration settings were added across multiple files for the seamless functioning of background jobs, reflecting a solid move towards streamlining job executions within the system.

Changes

File/Directory Summary
.env.example Added environment settings for job provider and trigger API keys.
.vscode/settings.json Updated ESLint validation settings, tab configuration, added Prisma.
apps/marketing/package.json Minor formatting adjustments.
apps/web/package.json Minor modification in package.json.
apps/web/src/pages/api/jobs/[[...handler]].ts Added configuration settings for jobs API.
docker/development/compose.yml Configurations for database, triggerdotdev, triggerdotdev_database
package.json Added/updated scripts and dependencies for new job management tools.
packages/ee/package.json Updated version of the ts-pattern package.
packages/lib/jobs/.../client.ts Introduced jobsClient for email job management.
packages/lib/jobs/.../client/_internal/job.ts Added types and interfaces for job configurations and execution.
packages/lib/jobs/.../client/_internal/json.ts Introduced type definitions for JSON structures.
packages/lib/jobs/.../client/base.ts Introduced BaseJobProvider class with job methods.
packages/lib/jobs/.../client/client.ts Added JobClient class for job management.
packages/lib/jobs/.../client/inngest.ts Added InngestJobProvider class for job definitions and triggers.
packages/lib/jobs/.../client/local.ts Added LocalJobProvider class for job management.
packages/lib/jobs/.../client/trigger.ts Added TriggerJobProvider class for job handling.
packages/lib/jobs/.../definitions/send-confirmation-email.ts Defined job schema for sending confirmation emails.
packages/lib/jobs/.../definitions/send-signing-email.ts Defined job for sending signing emails.
packages/lib/next-auth/auth-options.ts Refactored email sending to use job queue.
packages/lib/package.json Updated dependencies for jobs functionality.
packages/lib/server-only/document/send-document.tsx Significant changes for job triggering mechanisms.
packages/lib/server-only/user/verify-email.ts Replaced email sending with jobsClient.triggerJob.
packages/lib/universal/extract-request-metadata.ts Refactored to use Zod schema for RequestMetadata.
packages/prisma/migrations/.../migration.sql Introduced schema for background jobs and tasks in multiple steps.
packages/prisma/schema.prisma Models and enums for background jobs and tasks.
packages/trpc/server/auth-router/router.ts Integrated jobsClient for signup confirmation emails.
packages/trpc/server/profile-router/router.ts Replaced email logic with job trigger method.
packages/tsconfig/process-env.d.ts Added new environment variable declarations.
turbo.json Updated job provider keys and trigger API settings.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant App
  participant JobHandler
  participant EmailService

  User->>App: Signup Request
  App->>JobHandler: Trigger Confirmation Job
  JobHandler->>EmailService: Send Confirmation Email
  EmailService-->>User: Receive Confirmation Email

  User->>App: Request Email Verification
  App->>JobHandler: Trigger Email Verification Job
  JobHandler->>EmailService: Send Verification Email
  EmailService-->>User: Receive Verification Email
Loading

Poem

In our code realm, where changes sprawl,
A bunny hops with joy, standing tall. 🐇
Jobs and triggers, neatly defined,
Emails now, precisely timed. ✉️
With scripts and config, we march on,
A brighter dawn, with each new spawn. 🌅
Hurrah to progress, let’s celebrate,
For in our code, we innovate! 🎉


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>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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 as 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.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration 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.

@github-actions github-actions bot added apps: web Issues related to the webapp version bump 👀 apps: marketing Issues related to website or marketing app pkg: ee changes labels May 15, 2024
Copy link

github-actions bot commented May 15, 2024

Thank you for following the naming conventions for pull request titles! 💚🚀

packages/lib/jobs/client/local.ts Fixed Show fixed Hide fixed
packages/lib/jobs/client/local.ts Fixed Show fixed Hide fixed
packages/lib/jobs/client/local.ts Dismissed Show dismissed Hide dismissed
Copy link
Collaborator

@dguyen dguyen left a comment

Choose a reason for hiding this comment

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

Implementation looks good so far!

I assume migrations will be squished and stuff right


public getApiHandler() {
return async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'POST') {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Feels like you should do an early return here for non POST methods to reduce nesting

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

agreed

packages/lib/jobs/client/_internal/job.ts Show resolved Hide resolved
@@ -200,7 +200,12 @@ export const profileRouter = router({
try {
const { email } = input;

return await sendConfirmationToken({ email });
await jobsClient.triggerJob({
name: 'send.confirmation.email',
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we should add one more layer since confirmation email is a little too generic

send.signup.confirmation.email

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

agreed

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: 16

Outside diff range and nitpick comments (1)
packages/lib/jobs/client/inngest.ts (1)

39-65: Optimization in Job Definition

When defining a job, logging is performed which might not be necessary in production environments. Consider adding a conditional check to enable logging only in development mode to avoid cluttering production logs.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between ffb890f and 1ad64b4.

Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
Files selected for processing (32)
  • .env.example (1 hunks)
  • .vscode/settings.json (1 hunks)
  • apps/marketing/package.json (1 hunks)
  • apps/web/package.json (1 hunks)
  • apps/web/src/pages/api/jobs/[[...handler]].ts (1 hunks)
  • docker/development/compose.yml (2 hunks)
  • package.json (3 hunks)
  • packages/ee/package.json (1 hunks)
  • packages/lib/jobs/client.ts (1 hunks)
  • packages/lib/jobs/client/_internal/job.ts (1 hunks)
  • packages/lib/jobs/client/_internal/json.ts (1 hunks)
  • packages/lib/jobs/client/base.ts (1 hunks)
  • packages/lib/jobs/client/client.ts (1 hunks)
  • packages/lib/jobs/client/inngest.ts (1 hunks)
  • packages/lib/jobs/client/local.ts (1 hunks)
  • packages/lib/jobs/client/trigger.ts (1 hunks)
  • packages/lib/jobs/definitions/send-confirmation-email.ts (1 hunks)
  • packages/lib/jobs/definitions/send-signing-email.ts (1 hunks)
  • packages/lib/next-auth/auth-options.ts (2 hunks)
  • packages/lib/package.json (2 hunks)
  • packages/lib/server-only/document/send-document.tsx (3 hunks)
  • packages/lib/server-only/user/verify-email.ts (2 hunks)
  • packages/lib/universal/extract-request-metadata.ts (1 hunks)
  • packages/prisma/migrations/20240516022236_add_background_job_models/migration.sql (1 hunks)
  • packages/prisma/migrations/20240516030441_add_more_timestamp_columns_for_background_jobs/migration.sql (1 hunks)
  • packages/prisma/migrations/20240516032317_capture_payload_for_background_job/migration.sql (1 hunks)
  • packages/prisma/migrations/20240516034546_update_background_job_task_model/migration.sql (1 hunks)
  • packages/prisma/schema.prisma (1 hunks)
  • packages/trpc/server/auth-router/router.ts (3 hunks)
  • packages/trpc/server/profile-router/router.ts (2 hunks)
  • packages/tsconfig/process-env.d.ts (1 hunks)
  • turbo.json (1 hunks)
Files skipped from review due to trivial changes (7)
  • apps/marketing/package.json
  • apps/web/package.json
  • packages/ee/package.json
  • packages/lib/jobs/client/_internal/json.ts
  • packages/prisma/migrations/20240516030441_add_more_timestamp_columns_for_background_jobs/migration.sql
  • packages/prisma/migrations/20240516032317_capture_payload_for_background_job/migration.sql
  • packages/prisma/migrations/20240516034546_update_background_job_task_model/migration.sql
Additional context used
Biome
packages/lib/jobs/client/base.ts

[error] 16-16: void is confusing inside a union type. (lint/suspicious/noConfusingVoidType)

Unsafe fix: Use undefined instead.

packages/lib/jobs/client/_internal/job.ts

[error] 39-39: void is confusing inside a union type. (lint/suspicious/noConfusingVoidType)

Unsafe fix: Use undefined instead.


[error] 44-44: void is confusing inside a union type. (lint/suspicious/noConfusingVoidType)

Unsafe fix: Use undefined instead.

packages/lib/jobs/client/trigger.ts

[error] 20-20: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.


[error] 27-27: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.


[error] 30-30: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.

packages/lib/jobs/client/inngest.ts

[error] 27-27: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.


[error] 33-33: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.


[error] 36-36: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.

packages/lib/jobs/client/local.ts

[error] 31-31: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.


[error] 32-32: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.


[error] 35-35: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.


[error] 260-260: void is confusing inside a union type. (lint/suspicious/noConfusingVoidType)

Unsafe fix: Use undefined instead.

packages/lib/next-auth/auth-options.ts

[error] 348-348: Change to an optional chain. (lint/complexity/useOptionalChain)

Unsafe fix: Change to an optional chain.

Gitleaks
.env.example

74-75: Identified a HashiCorp Terraform password field, risking unauthorized infrastructure configuration and security breaches. (hashicorp-tf-password)


123-124: Identified a HashiCorp Terraform password field, risking unauthorized infrastructure configuration and security breaches. (hashicorp-tf-password)

Additional comments not posted (30)
apps/web/src/pages/api/jobs/[[...handler]].ts (2)

3-8: Ensure appropriate API handler configuration.

The configuration disables the bodyParser and sets a maxDuration of 300 seconds. Ensure that these settings align with the expected load and security considerations.


10-10: LGTM!

The default export of jobsClient.getApiHandler() looks good. Ensure that getApiHandler is robustly implemented to handle API requests correctly.

packages/lib/jobs/client.ts (1)

5-12: LGTM!

The initialization of jobsClient with job definitions using as const ensures type safety and correctness in job handling.

.vscode/settings.json (2)

8-13: Enhanced ESLint validation settings are beneficial.

The inclusion of TypeScript and JavaScript React files in ESLint validation helps maintain high code quality across the project.


19-22: Prisma formatter setting is a good practice.

Setting Prisma as the default formatter for .prisma files ensures consistency in database schema definitions.
[APROVED]

packages/lib/jobs/definitions/send-confirmation-email.ts (3)

1-1: Imports and Constants Review:

All imports and constants are correctly defined and used appropriately in the job definition.

Also applies to: 3-4, 6-6


8-11: Schema Definition:

The use of zod for defining the job schema ensures that the data types and requirements are enforced, promoting robustness in job data handling.


13-30: Job Definition:

The job definition is robust and well-structured, ensuring clarity and maintainability. The handler is appropriately asynchronous, suitable for the operations it performs.

packages/lib/jobs/client/client.ts (3)

1-1: Imports and Class Definition Review:

The imports are appropriate for the functionality, and the JobClient class is well-defined with use of TypeScript generics enhancing type safety.

Also applies to: 3-9


12-21: Constructor Implementation:

The use of pattern matching for provider selection in the constructor is a clean and flexible approach to dependency injection, allowing easy switching between different job providers.


23-29: Method Implementations:

The methods triggerJob and getApiHandler are well-implemented, delegating responsibilities to the provider and keeping the class clean and focused.

packages/lib/universal/extract-request-metadata.ts (2)

8-11: Schema Definition:

The ZRequestMetadataSchema is effectively defined using zod, ensuring optional validation for IP addresses and user agents, which enhances flexibility and robustness in metadata extraction.


13-13: Function Implementations:

The functions for metadata extraction are well-implemented, utilizing the defined zod schema to ensure consistency and reliability.

packages/prisma/migrations/20240516022236_add_background_job_models/migration.sql (2)

1-2: SQL Statements for Enums and Tables:

The SQL statements for creating enums and tables are correctly formatted and logically structured, ensuring data integrity and proper relational setups for background job management.

Also applies to: 4-5, 7-34


36-37: Foreign Key Constraints:

The setup of foreign key constraints using cascading updates and deletes is appropriate, ensuring referential integrity and ease of maintenance.

packages/lib/package.json (2)

35-36: Update to Trigger.dev dependencies

You've updated the versions for @trigger.dev/nextjs and @trigger.dev/sdk to 2.3.18 and added inngest at 3.19.13. These updates align with the PR's objective to introduce a pluggable jobs provider. Ensure that these versions are compatible with the rest of your project dependencies to avoid any potential conflicts.

Also applies to: 39-39


57-59: Addition of type definitions for new dependencies

The addition of type definitions for luxon and pg (@types/luxon and @types/pg) is a good practice to ensure type safety and better development experience in TypeScript. Make sure these versions match with their corresponding main packages to maintain compatibility.

packages/lib/server-only/user/verify-email.ts (2)

5-5: Use of Job Client in Email Verification

Importing and using jobsClient from ../../jobs/client to handle email verification through background tasks aligns well with the PR's objective to manage tasks asynchronously. This should enhance the system's responsiveness and scalability.


43-48: Triggering Email Verification Job

The implementation to trigger a job for sending a signup confirmation email when the most recent token is invalid or expired is a robust way to handle user verification. This should help in managing user experience and system performance effectively.

packages/lib/jobs/client/_internal/job.ts (1)

5-10: Type Definitions and Schema for Job Options

The introduction of SimpleTriggerJobOptions and its validation schema ZSimpleTriggerJobOptionsSchema are crucial for ensuring that job options are correctly validated. The use of Zod for schema validation enhances type safety and error handling.

Also applies to: 12-17

docker/development/compose.yml (1)

7-13: Docker Configuration for Services

The updates to the Docker configuration for the database service and the addition of triggerdotdev and triggerdotdev_database services are crucial for supporting the new background job functionality. The detailed setup including health checks, environment variables, and dependency management should facilitate smooth operation and integration of these services.

Also applies to: 43-56

package.json (2)

27-28: Review newly added script for potential issues.

The trigger:dev script uses npx to run a CLI tool, which is fine, but ensure that the handler path is correctly specified and that the environment is properly configured to use this script.


Line range hint 38-59: Review new dependencies for compatibility and licensing issues.

New dependencies such as @trigger.dev/cli and react have been added. It's important to ensure that these dependencies are compatible with the project's existing dependencies and that their licenses do not conflict with the project's license.

packages/tsconfig/process-env.d.ts (1)

71-83: Validate new environment variable declarations for consistency.

The newly declared environment variables NEXT_PRIVATE_JOBS_PROVIDER, NEXT_PRIVATE_TRIGGER_API_KEY, and NEXT_PRIVATE_TRIGGER_API_URL should be consistently used throughout the application. Also, ensure that their naming follows the existing naming conventions.

Verification successful

The new environment variables NEXT_PRIVATE_JOBS_PROVIDER, NEXT_PRIVATE_TRIGGER_API_KEY, and NEXT_PRIVATE_TRIGGER_API_URL are consistently used in the identified files:

  • turbo.json includes them in the globalEnv section.
  • packages/lib/jobs/client/trigger.ts uses NEXT_PRIVATE_TRIGGER_API_KEY and NEXT_PRIVATE_TRIGGER_API_URL in the TriggerClient initialization.
  • packages/lib/jobs/client/client.ts uses NEXT_PRIVATE_JOBS_PROVIDER to determine the job provider.

No inconsistencies or naming conventions issues were found.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Check for consistent usage of new environment variables across the project.
# Expect: Consistent usage and naming conventions.

rg "NEXT_PRIVATE_JOBS_PROVIDER|NEXT_PRIVATE_TRIGGER_API_KEY|NEXT_PRIVATE_TRIGGER_API_URL" --files-with-matches

Length of output: 229



Script:

#!/bin/bash
# Extract the relevant sections from the identified files to verify the usage of the environment variables.

# Check turbo.json for environment variable usage
echo "Contents of turbo.json:"
cat turbo.json

# Check packages/lib/jobs/client/trigger.ts for environment variable usage
echo -e "\n\nContents of packages/lib/jobs/client/trigger.ts:"
cat packages/lib/jobs/client/trigger.ts

# Check packages/lib/jobs/client/client.ts for environment variable usage
echo -e "\n\nContents of packages/lib/jobs/client/client.ts:"
cat packages/lib/jobs/client/client.ts

Length of output: 7473

turbo.json (1)

118-121: Ensure new global environment variables are necessary and correctly used.

The newly added global environment variables related to job providers and Trigger.dev should be reviewed to ensure they are necessary and correctly used across the project.

Verification successful

The new global environment variables NEXT_PRIVATE_JOBS_PROVIDER, NEXT_PRIVATE_TRIGGER_API_KEY, NEXT_PRIVATE_TRIGGER_API_URL, and NEXT_PRIVATE_INNGEST_EVENT_KEY are indeed used in the codebase:

  • packages/tsconfig/process-env.d.ts: These variables are defined with their expected types.
  • packages/lib/jobs/client/inngest.ts: NEXT_PRIVATE_INNGEST_EVENT_KEY is used.
  • packages/lib/jobs/client/client.ts: NEXT_PRIVATE_JOBS_PROVIDER is used.
  • packages/lib/jobs/client/trigger.ts: NEXT_PRIVATE_TRIGGER_API_KEY and NEXT_PRIVATE_TRIGGER_API_URL are used.

These findings confirm that the variables are necessary and correctly used across the project.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the necessity and correct usage of new global environment variables.
# Expect: Correct and necessary usage.

rg "NEXT_PRIVATE_JOBS_PROVIDER|NEXT_PRIVATE_TRIGGER_API_KEY|NEXT_PRIVATE_TRIGGER_API_URL|NEXT_PRIVATE_INNGEST_EVENT_KEY" --files-with-matches

Length of output: 296



Script:

#!/bin/bash
# Description: Inspect the usage of new global environment variables in the identified files.

# Check usage in packages/tsconfig/process-env.d.ts
echo "Usage in packages/tsconfig/process-env.d.ts:"
rg "NEXT_PRIVATE_JOBS_PROVIDER|NEXT_PRIVATE_TRIGGER_API_KEY|NEXT_PRIVATE_TRIGGER_API_URL|NEXT_PRIVATE_INNGEST_EVENT_KEY" packages/tsconfig/process-env.d.ts

# Check usage in packages/lib/jobs/client/inngest.ts
echo "Usage in packages/lib/jobs/client/inngest.ts:"
rg "NEXT_PRIVATE_JOBS_PROVIDER|NEXT_PRIVATE_TRIGGER_API_KEY|NEXT_PRIVATE_TRIGGER_API_URL|NEXT_PRIVATE_INNGEST_EVENT_KEY" packages/lib/jobs/client/inngest.ts

# Check usage in packages/lib/jobs/client/client.ts
echo "Usage in packages/lib/jobs/client/client.ts:"
rg "NEXT_PRIVATE_JOBS_PROVIDER|NEXT_PRIVATE_TRIGGER_API_KEY|NEXT_PRIVATE_TRIGGER_API_URL|NEXT_PRIVATE_INNGEST_EVENT_KEY" packages/lib/jobs/client/client.ts

# Check usage in packages/lib/jobs/client/trigger.ts
echo "Usage in packages/lib/jobs/client/trigger.ts:"
rg "NEXT_PRIVATE_JOBS_PROVIDER|NEXT_PRIVATE_TRIGGER_API_KEY|NEXT_PRIVATE_TRIGGER_API_URL|NEXT_PRIVATE_INNGEST_EVENT_KEY" packages/lib/jobs/client/trigger.ts

Length of output: 1475

packages/lib/server-only/document/send-document.tsx (1)

129-137: Use of Jobs Client for Email Sending

The implementation uses jobsClient to trigger email sending jobs. This is a good use of background tasks for non-critical operations. Ensure that the job definitions and the payload structure are correctly aligned with what the job expects.

.env.example (1)

106-111: Security Risk in API Key Management

The environment variables related to API keys (NEXT_PRIVATE_TRIGGER_API_KEY, NEXT_PRIVATE_INNGEST_EVENT_KEY) are set but not provided values in the .env.example. Ensure that these keys are managed securely and not exposed in version control.

packages/lib/jobs/definitions/send-signing-email.ts (1)

37-167: Comprehensive Email Sending Job Definition

The job definition for sending signing emails is comprehensive and well-structured. It uses various utilities and services to prepare and send the email. Ensure all used services like mailer and prisma are robust and handle errors appropriately.

packages/prisma/schema.prisma (2)

616-621: Enum definition for BackgroundJobStatus looks good.

The enum values appropriately cover the typical states of a background job lifecycle.


643-647: Enum definition for BackgroundJobTaskStatus looks good.

The enum values are consistent and clearly denote the status of tasks within a background job.

Comment on lines +203 to +208
await jobsClient.triggerJob({
name: 'send.signup.confirmation.email',
payload: {
email,
},
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor: Use enhanced job name for clarity and consistency.

The job name send.signup.confirmation.email could be more descriptive and aligned with the application's naming conventions. Based on previous discussions, consider renaming it to enhance clarity and consistency across the codebase.

-          name: 'send.signup.confirmation.email',
+          name: 'send.user.signup.confirmation.email',
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
await jobsClient.triggerJob({
name: 'send.signup.confirmation.email',
payload: {
email,
},
});
await jobsClient.triggerJob({
name: 'send.user.signup.confirmation.email',
payload: {
email,
},
});

Comment on lines +55 to +60
await jobsClient.triggerJob({
name: 'send.signup.confirmation.email',
payload: {
email: user.email,
},
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor: Use enhanced job name for clarity and consistency.

Similar to the previous file, consider using a more descriptive job name for the email sending job. This helps in maintaining a consistent naming convention throughout your application.

-        name: 'send.signup.confirmation.email',
+        name: 'send.user.signup.confirmation.email',
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
await jobsClient.triggerJob({
name: 'send.signup.confirmation.email',
payload: {
email: user.email,
},
});
await jobsClient.triggerJob({
name: 'send.user.signup.confirmation.email',
payload: {
email: user.email,
},
});

Comment on lines +30 to +36
static getInstance() {
if (!this._instance) {
this._instance = new LocalJobProvider();
}

return this._instance;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Clarification: Use class name instead of this in static context.

Using this in static methods can lead to confusion as it does not behave as it might in non-static contexts. Consider using the class name directly for clarity.

-    if (!this._instance) {
-      this._instance = new LocalJobProvider();
-    }
-    return this._instance;
+    if (!LocalJobProvider._instance) {
+      LocalJobProvider._instance = new LocalJobProvider();
+    }
+    return LocalJobProvider._instance;
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
static getInstance() {
if (!this._instance) {
this._instance = new LocalJobProvider();
}
return this._instance;
}
static getInstance() {
if (!LocalJobProvider._instance) {
LocalJobProvider._instance = new LocalJobProvider();
}
return LocalJobProvider._instance;
}
Tools
Biome

[error] 31-31: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.


[error] 32-32: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.


[error] 35-35: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.


private createJobRunIO(jobId: string): JobRunIO {
return {
runTask: async <T extends void | Json>(cacheKey: string, callback: () => Promise<T>) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor: Replace void with undefined in union type.

Using void in union types can be confusing and misleading. Replace it with undefined for better clarity and to avoid potential issues in type checking.

- runTask: async <T extends void | Json>(cacheKey: string, callback: () => Promise<T>) => {
+ runTask: async <T extends undefined | Json>(cacheKey: string, callback: () => Promise<T>) => {
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
runTask: async <T extends void | Json>(cacheKey: string, callback: () => Promise<T>) => {
runTask: async <T extends undefined | Json>(cacheKey: string, callback: () => Promise<T>) => {
Tools
Biome

[error] 260-260: void is confusing inside a union type. (lint/suspicious/noConfusingVoidType)

Unsafe fix: Use undefined instead.

name: Name;
schema?: z.ZodType<Schema>;
};
handler: (options: { payload: Schema; io: JobRunIO }) => Promise<Json | void>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Void Type in Union Warning

The static analysis tool flagged the use of void in a union type as potentially confusing. Consider replacing void with undefined to clarify the intent and avoid any ambiguity.

-  handler: (options: { payload: Schema; io: JobRunIO }) => Promise<Json | void>;
+  handler: (options: { payload: Schema; io: JobRunIO }) => Promise<Json | undefined>;

Also applies to: 44-44

Tools
Biome

[error] 39-39: void is confusing inside a union type. (lint/suspicious/noConfusingVoidType)

Unsafe fix: Use undefined instead.

Comment on lines +46 to +53
public async triggerJob(options: SimpleTriggerJobOptions): Promise<void> {
await this._client.sendEvent({
id: options.id,
name: options.name,
payload: options.payload,
timestamp: options.timestamp ? new Date(options.timestamp) : undefined,
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider handling errors in triggerJob.

The method triggerJob does not handle errors that might occur during sendEvent. It's good practice to catch such errors to prevent them from crashing the application.

- await this._client.sendEvent({
+ try {
+   await this._client.sendEvent({
    id: options.id,
    name: options.name,
    payload: options.payload,
    timestamp: options.timestamp ? new Date(options.timestamp) : undefined,
  });
+ } catch (error) {
+   // Handle error appropriately
+ }
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
public async triggerJob(options: SimpleTriggerJobOptions): Promise<void> {
await this._client.sendEvent({
id: options.id,
name: options.name,
payload: options.payload,
timestamp: options.timestamp ? new Date(options.timestamp) : undefined,
});
}
public async triggerJob(options: SimpleTriggerJobOptions): Promise<void> {
try {
await this._client.sendEvent({
id: options.id,
name: options.name,
payload: options.payload,
timestamp: options.timestamp ? new Date(options.timestamp) : undefined,
});
} catch (error) {
// Handle error appropriately
}
}

Comment on lines +20 to +30
if (!this._instance) {
const client = new TriggerClient({
id: 'documenso-app',
apiKey: process.env.NEXT_PRIVATE_TRIGGER_API_KEY,
apiUrl: process.env.NEXT_PRIVATE_TRIGGER_API_URL,
});

this._instance = new TriggerJobProvider({ client });
}

return this._instance;
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor static method to avoid confusion with this.

Static methods should not use this to refer to the class instance as it can lead to confusion and bugs if the class is subclassed. Use the class name TriggerJobProvider instead.

- if (!this._instance) {
+ if (!TriggerJobProvider._instance) {
- this._instance = new TriggerJobProvider({ client });
+ TriggerJobProvider._instance = new TriggerJobProvider({ client });
- return this._instance;
+ return TriggerJobProvider._instance;
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 (!this._instance) {
const client = new TriggerClient({
id: 'documenso-app',
apiKey: process.env.NEXT_PRIVATE_TRIGGER_API_KEY,
apiUrl: process.env.NEXT_PRIVATE_TRIGGER_API_URL,
});
this._instance = new TriggerJobProvider({ client });
}
return this._instance;
if (!TriggerJobProvider._instance) {
const client = new TriggerClient({
id: 'documenso-app',
apiKey: process.env.NEXT_PRIVATE_TRIGGER_API_KEY,
apiUrl: process.env.NEXT_PRIVATE_TRIGGER_API_URL,
});
TriggerJobProvider._instance = new TriggerJobProvider({ client });
}
return TriggerJobProvider._instance;
Tools
Biome

[error] 20-20: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.


[error] 27-27: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.


[error] 30-30: Using this in a static context can be confusing. (lint/complexity/noThisInStatic)

this refers to the class.
Unsafe fix: Use the class name instead.

Comment on lines +33 to +44
public defineJob<N extends string, T>(job: JobDefinition<N, T>): void {
this._client.defineJob({
id: job.id,
name: job.name,
version: job.version,
trigger: eventTrigger({
name: job.trigger.name,
schema: job.trigger.schema,
}),
run: async (payload, io) => job.handler({ payload, io: this.convertTriggerIoToJobRunIo(io) }),
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Tip

Codebase Verification

The inspection of the surrounding code in both trigger.ts and inngest.ts shows that there are no error handling mechanisms (like try-catch blocks) around the job.handler invocations.

  • packages/lib/jobs/client/trigger.ts: The job.handler is invoked without any error handling.
  • packages/lib/jobs/client/inngest.ts: Similarly, the job.handler is invoked without any error handling.

This confirms the review comment's concern about the lack of error handling in the defineJob method.

  • trigger.ts: Line 44
  • inngest.ts: Line 44
Analysis chain

Ensure proper error handling in asynchronous job definition.

The method defineJob uses an asynchronous callback but does not handle potential exceptions that might be thrown by job.handler. Consider adding try-catch blocks or error handling mechanisms.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify if error handling is implemented in other parts of the codebase for job handlers.
# Expect: Error handling mechanisms around job handler invocations.

rg --type ts "job.handler" --files-with-matches

Length of output: 119



Script:

#!/bin/bash
# Inspect the usage of job.handler in trigger.ts for error handling mechanisms

# Extract the lines around job.handler in trigger.ts
rg --type ts --context 5 "job.handler" packages/lib/jobs/client/trigger.ts

# Extract the lines around job.handler in inngest.ts
rg --type ts --context 5 "job.handler" packages/lib/jobs/client/inngest.ts

Length of output: 707

Comment on lines +55 to +59
public getApiHandler() {
const { handler } = createPagesRoute(this._client);

return handler;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Tip

Codebase Verification

The getApiHandler method is used across several files with varying levels of error handling and customization. Notably:

  • local.ts: Includes error handling for HTTP methods.
  • client.ts: Delegates to the provider's getApiHandler.
  • base.ts: Throws a "Not implemented" error.
  • [[...handler]].ts: Used as a default export without additional customization or error handling.
  • trigger.ts and inngest.ts: Lack error handling and customization.

To ensure consistency and robustness, consider adding error handling and customization options in trigger.ts and inngest.ts.

  • packages/lib/jobs/client/trigger.ts
  • packages/lib/jobs/client/inngest.ts
Analysis chain

Review API handler generation logic.

The method getApiHandler retrieves an API handler but does not provide any customization or error handling capabilities. Consider whether customization options or error handling might be necessary based on the usage context.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Check how `getApiHandler` is used in the application to determine if additional customization or error handling is needed.
# Expect: Usage patterns of `getApiHandler`.

rg "getApiHandler" --files-with-matches

Length of output: 259



Script:

#!/bin/bash
# Extract lines where `getApiHandler` is used in each of the identified files.

files=(
  "packages/lib/jobs/client/trigger.ts"
  "packages/lib/jobs/client/local.ts"
  "packages/lib/jobs/client/inngest.ts"
  "packages/lib/jobs/client/client.ts"
  "packages/lib/jobs/client/base.ts"
  "apps/web/src/pages/api/jobs/[[...handler]].ts"
)

for file in "${files[@]}"; do
  echo "File: $file"
  rg "getApiHandler" "$file" -A 5 -B 5
done

Length of output: 2635

Comment on lines +16 to +18
public getApiHandler(): (req: NextApiRequest, res: NextApiResponse) => Promise<Response | void> {
throw new Error('Not implemented');
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Clarify the return type of getApiHandler.

The method getApiHandler has a return type that includes void, which can be confusing. Consider using undefined instead to improve clarity.

- public getApiHandler(): (req: NextApiRequest, res: NextApiResponse) => Promise<Response | void> {
+ public getApiHandler(): (req: NextApiRequest, res: NextApiResponse) => Promise<Response | undefined> {
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
public getApiHandler(): (req: NextApiRequest, res: NextApiResponse) => Promise<Response | void> {
throw new Error('Not implemented');
}
public getApiHandler(): (req: NextApiRequest, res: NextApiResponse) => Promise<Response | undefined> {
throw new Error('Not implemented');
}
Tools
Biome

[error] 16-16: void is confusing inside a union type. (lint/suspicious/noConfusingVoidType)

Unsafe fix: Use undefined instead.

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: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 1ad64b4 and 2c3c067.

Files selected for processing (1)
  • package.json (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • package.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants