-
-
Notifications
You must be signed in to change notification settings - Fork 853
Add a reference project that showcases the new waitpoint primitive #1908
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Trigger.dev secret key | ||
# https://trigger.dev/docs/apikeys | ||
TRIGGER_SECRET_KEY= | ||
TRIGGER_API_URL= | ||
NEXT_PUBLIC_TRIGGER_API_URL= | ||
|
||
# OpenAI API key for generating article summaries. | ||
# https://platform.openai.com | ||
OPENAI_API_KEY= | ||
|
||
# ElevenLabs API key for converting text to speech. | ||
# https://elevenlabs.io/docs/quickstart#create-an-api-key | ||
ELEVENLABS_API_KEY= | ||
|
||
# Credentials for writing audio streams to an S3-compatible bucket. | ||
# Does not necessarily need to be AWS S3 bucket, as long as it is compatible to the S3 SDK, e.g., https://www.tigrisdata.com/ | ||
# https://docs.aws.amazon.com/sdkref/latest/guide/environment-variables.html | ||
AWS_ACCESS_KEY_ID= | ||
AWS_SECRET_ACCESS_KEY= | ||
AWS_ENDPOINT_URL_S3= | ||
AWS_ENDPOINT_URL_IAM= | ||
AWS_S3_BUCKET= | ||
AWS_REGION= | ||
|
||
# Slack webhook URL for sending messages to a Slack channel. | ||
# Follow the guide in https://api.slack.com/messaging/webhooks to generate a webhook URL. | ||
SLACK_WEBHOOK_URL= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.* | ||
.yarn/* | ||
!.yarn/patches | ||
!.yarn/plugins | ||
!.yarn/releases | ||
!.yarn/versions | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
.pnpm-debug.log* | ||
|
||
# env files (can opt-in for committing if needed) | ||
.env* | ||
!.env.example | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts | ||
|
||
.trigger |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# An AI workflow with a human-in-the-loop approval step | ||
|
||
This reference project shows a possible approach to implement workflows using Trigger.dev and [ReactFlow](https://reactflow.dev/). | ||
It makes use of the Trigger.dev Realtime API and the new waitpoint token feature to implement a human-in-the-loop workflow. | ||
|
||
## Getting Started | ||
|
||
This guide assumes that you have followed the [Contributing.md](https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md#setup) instructions to set up a local Trigger.dev instance. If not, please complete the setup before continuing. | ||
|
||
1. Run the main Trigger.dev webapp: | ||
|
||
```bash | ||
pnpm run dev --filter webapp | ||
``` | ||
|
||
2. Optionally, build the CLI and SDK if you are working on them and applying changes: | ||
|
||
```bash | ||
pnpm run dev --filter trigger.dev --filter "@trigger.dev/*" | ||
``` | ||
|
||
3. Login with the CLI: | ||
|
||
```bash | ||
cd references/trigger-flow | ||
pnpm exec trigger login -a http://localhost:3030 | ||
``` | ||
|
||
Optionally, you can use the `profile` flag to create a new profile: | ||
|
||
```bash | ||
pnpm exec trigger login -a http://localhost:3030 --profile local | ||
``` | ||
|
||
Note that you'll need to use this profile for the subsequent commands. | ||
|
||
4. Create an `.env` file by copying [.env.example](.env.example) and fill in the required environment variables. The example file includes a description for each variable. | ||
|
||
5. Run the CLI | ||
|
||
```bash | ||
pnpm exec trigger dev | ||
``` | ||
|
||
You should see now the `dev` command spitting out messages, including that it's started a background worker. | ||
|
||
6. Run the ReactFlow app: | ||
|
||
```bash | ||
pnpm run dev | ||
``` | ||
|
||
Open [http://localhost:3000](http://localhost:3000) on your browser to checkout the workflow. | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Learn More | ||
|
||
To learn more about the technologies used in this project, check out the following resources: | ||
|
||
- [Trigger.dev Docs](https://trigger.dev/docs) - learn about Trigger.dev and its features | ||
- [Trigger.dev Waitpoint Token Docs](https://trigger.dev/docs/wait-for-token) - learn about waitpoint tokens in Trigger.dev and human-in-the-loop flows | ||
- [Trigger.dev Realtime Docs](https://trigger.dev/docs/realtime) - learn about the Realtime feature of Trigger.dev | ||
- [Trigger.dev Realtime Streams](https://trigger.dev/docs/realtime/streams) - learn about the different types of streams available in Trigger.dev | ||
- [ReactFlow Docs](https://reactflow.dev/learn) - learn about building interactive diagrams using ReactFlow | ||
- [React Hooks for Trigger.dev](https://trigger.dev/docs/frontend/react-hooks) - learn about the React hooks provided by Trigger.dev | ||
- [ElevenLabs SDK](https://elevenlabs.io/docs/overview) - learn about ElevenLabs' AI audio capabilities | ||
- [AI SDK Documentation](https://sdk.vercel.ai/docs/introduction) - learn about the AI SDK for working with LLMs |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import type { NextConfig } from "next"; | ||
|
||
const nextConfig: NextConfig = { | ||
/* config options here */ | ||
}; | ||
|
||
export default nextConfig; |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,41 @@ | ||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||
"name": "waitpoint-tokens", | ||||||||||||||||||||||||||||
"version": "0.1.0", | ||||||||||||||||||||||||||||
"private": true, | ||||||||||||||||||||||||||||
"scripts": { | ||||||||||||||||||||||||||||
"dev": "next dev --turbopack", | ||||||||||||||||||||||||||||
"trigger:dev": "trigger dev", | ||||||||||||||||||||||||||||
"build": "next build", | ||||||||||||||||||||||||||||
"start": "next start", | ||||||||||||||||||||||||||||
"lint": "next lint" | ||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||
"dependencies": { | ||||||||||||||||||||||||||||
"@ai-sdk/openai": "^1.3.4", | ||||||||||||||||||||||||||||
"@aws-sdk/client-s3": "^3.777.0", | ||||||||||||||||||||||||||||
"@aws-sdk/s3-request-presigner": "^3.777.0", | ||||||||||||||||||||||||||||
"@trigger.dev/react-hooks": "workspace:*", | ||||||||||||||||||||||||||||
"@trigger.dev/sdk": "workspace:*", | ||||||||||||||||||||||||||||
"@xyflow/react": "^12.4.4", | ||||||||||||||||||||||||||||
"ai": "^4.2.8", | ||||||||||||||||||||||||||||
"clsx": "^2.1.1", | ||||||||||||||||||||||||||||
"elevenlabs": "^1.55.0", | ||||||||||||||||||||||||||||
"html-to-text": "^9.0.5", | ||||||||||||||||||||||||||||
"lucide-react": "^0.484.0", | ||||||||||||||||||||||||||||
"next": "15.2.4", | ||||||||||||||||||||||||||||
"react": "^19.0.0", | ||||||||||||||||||||||||||||
"react-dom": "^19.0.0", | ||||||||||||||||||||||||||||
"react-tippy": "^1.4.0", | ||||||||||||||||||||||||||||
"tailwind-merge": "^3.2.0" | ||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||
"devDependencies": { | ||||||||||||||||||||||||||||
"@tailwindcss/postcss": "^4", | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add PostCSS as a direct dependency You're using "devDependencies": {
"@tailwindcss/postcss": "^4",
"@trigger.dev/build": "workspace:*",
"@types/html-to-text": "^9.0.4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
+ "postcss": "^8",
"tailwindcss": "^4",
"trigger.dev": "workspace:*",
"typescript": "^5"
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||
"@trigger.dev/build": "workspace:*", | ||||||||||||||||||||||||||||
"@types/html-to-text": "^9.0.4", | ||||||||||||||||||||||||||||
"@types/node": "^20", | ||||||||||||||||||||||||||||
"@types/react": "^19", | ||||||||||||||||||||||||||||
"@types/react-dom": "^19", | ||||||||||||||||||||||||||||
"tailwindcss": "^4", | ||||||||||||||||||||||||||||
"trigger.dev": "workspace:*", | ||||||||||||||||||||||||||||
"typescript": "^5" | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
const config = { | ||
plugins: ["@tailwindcss/postcss"], | ||
}; | ||
|
||
export default config; |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,78 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"use server"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import type { articleWorkflow } from "@/trigger/articleWorkflow"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import type { ReviewPayload } from "@/trigger/reviewSummary"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { auth, tasks, wait } from "@trigger.dev/sdk/v3"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const randomStr = (length: number) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[...Array(length)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.map( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
() => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"[ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Math.floor(Math.random() * 62) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.join(""); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export async function triggerArticleWorkflow(prevState: any, formData: FormData) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const articleUrl = formData.get("articleUrl") as string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const workflowTag = `reactflow_${randomStr(20)}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const reviewWaitpointToken = await wait.createToken({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
tags: [workflowTag], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
timeout: "1h", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
idempotencyKey: `review-summary-${workflowTag}`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const [workflowPublicAccessToken] = await Promise.all([ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// We generate a public access token to use the Trigger.dev realtime API and listen to changes in task runs using react hooks. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// This token has access to all runs tagged with the unique workflow tag. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
auth.createPublicToken({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
scopes: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
read: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
tags: [workflowTag], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
tasks.trigger<typeof articleWorkflow>( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"article-workflow", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
articleUrl, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
approvalWaitpointTokenId: reviewWaitpointToken.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
tags: [workflowTag], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+27
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix empty slot in Promise.all array There's an empty slot in the Promise.all array (line 38) which could cause unexpected behavior. Remove the extra comma. const [workflowPublicAccessToken] = await Promise.all([
// We generate a public access token to use the Trigger.dev realtime API and listen to changes in task runs using react hooks.
// This token has access to all runs tagged with the unique workflow tag.
auth.createPublicToken({
scopes: {
read: {
tags: [workflowTag],
},
},
}),
- ,
tasks.trigger<typeof articleWorkflow>(
"article-workflow",
{
articleUrl,
approvalWaitpointTokenId: reviewWaitpointToken.id,
},
{
tags: [workflowTag],
}
),
]); 📝 Committable suggestion
Suggested change
🧰 Tools🪛 Biome (1.9.4)[error] 27-48: This array contains an empty slot. Unsafe fix: Replace hole with undefined (lint/suspicious/noSparseArray) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
articleUrl, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
workflowTag, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
workflowPublicAccessToken, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+17
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add validation for article URL The function doesn't validate the article URL before triggering the workflow. Consider adding basic validation to ensure it's a valid URL. export async function triggerArticleWorkflow(prevState: any, formData: FormData) {
const articleUrl = formData.get("articleUrl") as string;
+
+ // Validate URL
+ try {
+ new URL(articleUrl);
+ } catch (error) {
+ return {
+ error: "Please enter a valid URL",
+ };
+ }
const workflowTag = `reactflow_${randomStr(20)}`;
// Rest of function remains the same 📝 Committable suggestion
Suggested change
🧰 Tools🪛 Biome (1.9.4)[error] 27-48: This array contains an empty slot. Unsafe fix: Replace hole with undefined (lint/suspicious/noSparseArray) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export async function approveArticleSummary(tokenId: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await wait.completeToken<ReviewPayload>( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ id: tokenId }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
approved: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
approvedAt: new Date(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
approvedBy: "Alice", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+57
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Make approver name a parameter instead of hardcoding Currently, the approver name is hardcoded as "Alice". Consider making it a parameter to allow different users to approve summaries. -export async function approveArticleSummary(tokenId: string) {
+export async function approveArticleSummary(tokenId: string, approverName: string = "Alice") {
await wait.completeToken<ReviewPayload>(
{ id: tokenId },
{
approved: true,
approvedAt: new Date(),
- approvedBy: "Alice",
+ approvedBy: approverName,
}
);
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export async function rejectArticleSummary(tokenId: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await wait.completeToken<ReviewPayload>( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ id: tokenId }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
approved: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
rejectedAt: new Date(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
rejectedBy: "Alice", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
reason: "It's no good", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+68
to
+78
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Make rejection parameters configurable Similar to the approve function, the rejection function has hardcoded values for the rejector name and reason. Make these configurable parameters. -export async function rejectArticleSummary(tokenId: string) {
+export async function rejectArticleSummary(
+ tokenId: string,
+ rejectorName: string = "Alice",
+ reason: string = "It's no good"
+) {
await wait.completeToken<ReviewPayload>(
{ id: tokenId },
{
approved: false,
rejectedAt: new Date(),
- rejectedBy: "Alice",
- reason: "It's no good",
+ rejectedBy: rejectorName,
+ reason: reason,
}
);
} 📝 Committable suggestion
Suggested change
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,29 @@ | ||||||||||||||||||
@import "tailwindcss"; | ||||||||||||||||||
@import "react-tippy/dist/tippy.css"; | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
:root { | ||||||||||||||||||
--background: #ffffff; | ||||||||||||||||||
--foreground: #171717; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
@theme inline { | ||||||||||||||||||
--color-background: var(--background); | ||||||||||||||||||
--color-foreground: var(--foreground); | ||||||||||||||||||
--font-sans: var(--font-geist-sans); | ||||||||||||||||||
--font-mono: var(--font-geist-mono); | ||||||||||||||||||
Comment on lines
+14
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Font variables reference undefined fonts. The CSS variables @theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
- --font-sans: var(--font-geist-sans);
- --font-mono: var(--font-geist-mono);
+ --font-sans: Arial, Helvetica, sans-serif;
+ --font-mono: monospace;
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
@media (prefers-color-scheme: dark) { | ||||||||||||||||||
:root { | ||||||||||||||||||
--background: #0a0a0a; | ||||||||||||||||||
--foreground: #ededed; | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
body { | ||||||||||||||||||
background: var(--background); | ||||||||||||||||||
color: var(--foreground); | ||||||||||||||||||
font-family: Arial, Helvetica, sans-serif; | ||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import type { Metadata } from "next"; | ||
import { Geist, Geist_Mono } from "next/font/google"; | ||
import "./globals.css"; | ||
|
||
const geistSans = Geist({ | ||
variable: "--font-geist-sans", | ||
subsets: ["latin"], | ||
}); | ||
|
||
const geistMono = Geist_Mono({ | ||
variable: "--font-geist-mono", | ||
subsets: ["latin"], | ||
}); | ||
|
||
export const metadata: Metadata = { | ||
title: "Trigger Flow", | ||
description: "Trigger.dev reference project with ReactFlow", | ||
}; | ||
|
||
export default function RootLayout({ | ||
children, | ||
}: Readonly<{ | ||
children: React.ReactNode; | ||
}>) { | ||
return ( | ||
<html lang="en"> | ||
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>{children}</body> | ||
</html> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Directory path inconsistency.
The README instructs users to navigate to "references/trigger-flow", but based on the PR and file structure, the project appears to be in "references/waitpoint-tokens".
📝 Committable suggestion