-
Notifications
You must be signed in to change notification settings - Fork 505
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(web): add budget spend management #1224
Conversation
|
@ubinatus is attempting to deploy a commit to the Unkey Team on Vercel. A member of the Team first needs to authorize it. |
Thank you for following the naming conventions for pull request titles! 🙏 |
@@ -71,7 +71,7 @@ client.defineJob({ | |||
}); | |||
|
|||
const users = await io.runTask(`get users for workspace ${ws.id}`, () => | |||
getUsers(ws.tenantId), | |||
getClerkOrganizationUsers(ws.tenantId), |
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.
Centralized the clerk usage with an util fn. It should handle Clerk's rate limit.
const year = t.getUTCFullYear(); | ||
const month = t.getUTCMonth() + 1; // months are 0 indexed | ||
|
||
// TODO: Find a way to pipe Tinybird for a given set of workspaceIds. |
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.
In case it becomes an expensive op, would be great to have a custom pipe to retrieve the active keys and verifications for a given list of workspaces IDs.
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.
agreed, but it's fine for now
// TODO: Assumming admin users will not change frequently their emails, we could store in in the budget entity to avoid this step. | ||
await io.runTask( | ||
"retrieve workpaces admin emails from Clerk for exceeded budgets", |
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.
Since Unkey is not storing emails but retrieving them directly from Clerk, this job will need to retrieve the involved workspace admin's emails. So either i) retrieve it directly on the job or ii) save it on the budget and assume the admin user email won't change.
/** | ||
* Webhook URL to POST trigger when metered resources reached set amount. | ||
* @dev TODO: Not used currently. | ||
*/ | ||
webhookUrl?: string; |
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.
Just explanatory to showcase future customization of budget notification with webhookUrls, Slack, etc.
@@ -101,4 +102,45 @@ export class Resend { | |||
console.error("Error occurred sending payment issue email ", JSON.stringify(error)); | |||
} | |||
} | |||
|
|||
public async sendBatchBudgetExceeded( |
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.
Adds the batch
feature from Resend in order to send the budget spending limit emails.
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.
This could use the create-budget-button
, as it only adds the enabled
switch form item and interacts with a different mutation.
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
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.
Here I had to remove the "use client" directive.
Idk why but the job was failing when calling resend. (It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.
). Very weird behaviour.
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.
Created this billing util that is currently used in the spend-management workflow and in the ProUsage
web component
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.
Ready for review. By the way, I've noted that the endpoint__ratelimits_by_workspace__v1
pipe is missing in the internals/tinybird
.
So, for the matter of this testing, I assumed the following pipe:
%
SELECT
time
FROM mv__ratelimits_monthly__v1
where
workspaceId = {{ String(workspaceId, required=True) }}
and time = makeDate({{ Int64(year) }}, {{ Int64(month) }}, 1)
group by time
What does this PR do?
Fixes #1223
I've added a Loom so that you can see the feature of interacting with budgets in action:
https://www.loom.com/share/986fc21fb8aa4ed6910494838826780d?sid=0a5fe5cd-c94b-4655-85ba-37afaf085ccc
The email that users will receive is the following:
Type of change
How should this be tested?
Requirements for testing:
Tinybird (to retrieve active keys and verification for usage calculation).
Stripe (basically for creating a paid workspace). Believe you could use dummy env vars for this so that
stripeSchema
doesn't throw when you create a paid workspace.App
Worfklows (trigger.dev)
Test A: Handle a Budget.
Test B: Receive a spending limit notification
lastReachedAt
property set on your budget (see db) and iii) should not receive more emails about that budget for the rest of the month cycle.Checklist
Required
pnpm build
pnpm fmt
console.logs
git pull origin main
Appreciated