codeflash-internal/js/cf-api/endpoints/verify-existing-optimizations.ts

377 lines
12 KiB
TypeScript
Raw Normal View History

import { getInstallationOctokitByOwner, isUserCollaborator } from "../github/github-utils.js"
Pricing Setup V1 (#1504) ### **User description** Screenshots: ![image](https://github.com/user-attachments/assets/7e96678d-5f1f-466d-a2f7-e040adf70e3e) ![image](https://github.com/user-attachments/assets/d826551e-22a6-4c45-8a3c-f652ca69c742) ![image](https://github.com/user-attachments/assets/4defc919-eeae-40ab-ac93-ef76b4806db2) ToDO: Dedupe the code for cf-api and cf-webapp and move it to common Currently user can upgrade from free to monthly only, need to add logic to give choice to update to yearly as well from Billing page. ### **PR Type** - Enhancement ___ ### **Description** - Add Stripe client initialization and pricing config - Implement Stripe webhooks and subscription endpoints - Integrate usage tracking middleware and billing UI - Update Prisma schema and dependency versions ___ ### **Changes walkthrough** 📝 <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>14 files</summary><table> <tr> <td><strong>stripe-client.ts</strong><dd><code>Initialize Stripe client with API version setting</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-133526b16a4d7cf5fe0440be27d479000b85c6714b0a98b1bcc29864fbd59e68">+9/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>stripe.ts</strong><dd><code>Add pricing tiers and plan configurations</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-50e78686f5d8e699a8f0e7bec0151082fb80887cc8d303e8e54f1bf9fae666b6">+20/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>stripe-webhook.ts</strong><dd><code>Introduce Stripe webhook handler for events</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-77cb44047d6530f044469983d43fa5051bcc968add3b298c82cee11646312b2b">+135/-0</a>&nbsp; </td> </tr> <tr> <td><strong>subscription-management.ts</strong><dd><code>Add endpoints for subscription get, checkout, cancel</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-a8e2aca1f0313219f56d75c5d57f36d869fada2292457444f50843b304c26c99">+91/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>index.ts</strong><dd><code>Update routing; add Stripe and usage tracking routes</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-c3e60be1461b6e80f9181080342927fd9df095197e8784ae0ff51daaec8d71d5">+50/-16</a>&nbsp; </td> </tr> <tr> <td><strong>track-endpoint-calls.ts</strong><dd><code>Fix analytics import to .js extension</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-28e52f52b5f5ed621618a985f95d3636974f2a2c2281abe0d7c03ec2a5936537">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>track-usage.ts</strong><dd><code>Add middleware to track subscription usage limits</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-9248228a33147544ca9b58ff8b9c737b33763dd3e29717c82c38808bb7e34db3">+78/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>setup-stripe.ts</strong><dd><code>Add script for Stripe products and pricing setup</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-fde1de99bb4325e0352a86fad382424a2a890d68c0ccfd8790796371bae1324f">+85/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>subscription-utils.ts</strong><dd><code>Create helper functions for subscription checkout and limits</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-846af69dc1c830de7e6d0c1f73a01e75d60d3e3788b0b60d907d8a161140c679">+122/-0</a>&nbsp; </td> </tr> <tr> <td><strong>page.tsx</strong><dd><code>Add billing page UI displaying subscription status</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-86ac324c6a48fe59d742a236c9abad3998b7c571534ba8b4a757a89f5ad3ef83">+54/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>environment.ts</strong><dd><code>Add utilities for environment mode detection</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-0f860026005bc9b93926c42b04923ad589ad88fcde9aa7190bcefe8695aaa263">+7/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration.sql</strong><dd><code>Add migration for new subscriptions table creation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-8c1b31527c409128ba8d71ade36064c4b57bdfa8ec85acdf9a5db1118026f5b4">+26/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration.sql</strong><dd><code>Add foreign key constraint for API keys relation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-b07dd458b6c11384532557e84d1c5bda168806cc96e117f545ba7b261b6b0a3e">+2/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>schema.prisma</strong><dd><code>Update Prisma schema to include subscriptions relation</code>&nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-b30267f4306ab8d4d39c41394218b2aa428a35de686b88ca3a8c1f6b62453832">+24/-4</a>&nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Formatting</strong></td><td><details><summary>2 files</summary><table> <tr> <td><strong>create-pr.ts</strong><dd><code>Update import paths and minor formatting fixes</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-728a794bb81f944ae7db030f5e6ae1c1ba6888aa46e4be6846ebc5bd1ce12c2c">+10/-10</a>&nbsp; </td> </tr> <tr> <td><strong>verify-existing-optimizations.ts</strong><dd><code>Correct import extensions to .js for consistency</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-27bad39c963ec01481b7bdcff482e9d57ca39b99ee4ed0344a74d760092fb387">+4/-4</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>3 files</summary><table> <tr> <td><strong>prisma-client.ts</strong><dd><code>Document and update Prisma client instantiation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-2961161048a21c0e00e92d799ccbe21870c5638af2aab0670c963c3d5dd929b0">+15/-1</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>.env.example</strong><dd><code>Add example Stripe environment variables</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-ab5d181c31c59dbee1bfd63202d1471ab27276a59ceee617e5b46988935db773">+11/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration_lock.toml</strong><dd><code>Minor update to migration lock file documentation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-44423d32fecc24a69cc5d2d075987e28b6ab13da9730940621da28c0786b37e0">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Dependencies</strong></td><td><details><summary>2 files</summary><table> <tr> <td><strong>package-lock.json</strong><dd><code>Update dependency versions for dotenv and stripe</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-75446c74353509ca0232d6a1350aef075ced8f72bd568e9bafa09cf255683142">+15/-1</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>package.json</strong><dd><code>Bump dotenv and stripe versions in dependencies</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-53ddfb1f8a02f1231d3d15a2e694ffe1407d2cc01d3e685de5653b67fec571c7">+2/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Additional files</strong></td><td><details><summary>1 files</summary><table> <tr> <td><strong>installed-repositories.ts</strong></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-86bc38f589fc8426f2ae4cc8bfaa79a4652064344591bccd524c0f996cfc5abd">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr></tr></tbody></table> ___ > <details> <summary> Need help?</summary><li>Type <code>/help how to ...</code> in the comments thread for any questions about PR-Agent usage.</li><li>Check out the <a href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a> for more information.</li></details> ___ ### **PR Type** Enhancement ___ ### **Description** - Add Stripe client & pricing configuration. - Implement Stripe webhook & subscription endpoints. - Integrate usage tracking middleware & billing UI. - Update Prisma schema and dependency versions. ___ ### **Changes walkthrough** 📝 <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>18 files</summary><table> <tr> <td><strong>stripe-client.ts</strong><dd><code>Initialize Stripe client with API version and error handling</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-133526b16a4d7cf5fe0440be27d479000b85c6714b0a98b1bcc29864fbd59e68">+9/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>stripe.ts</strong><dd><code>Add Stripe pricing tiers configuration object</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-50e78686f5d8e699a8f0e7bec0151082fb80887cc8d303e8e54f1bf9fae666b6">+20/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>stripe-webhook.ts</strong><dd><code>Implement comprehensive Stripe webhook handler with multiple cases</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-77cb44047d6530f044469983d43fa5051bcc968add3b298c82cee11646312b2b">+209/-0</a>&nbsp; </td> </tr> <tr> <td><strong>subscription-management.ts</strong><dd><code>Add subscription management endpoints for retrieval and checkout</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-a8e2aca1f0313219f56d75c5d57f36d869fada2292457444f50843b304c26c99">+91/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>index.ts</strong><dd><code>Integrate Stripe webhook, subscription endpoints and tracking </code><br><code>middleware</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-c3e60be1461b6e80f9181080342927fd9df095197e8784ae0ff51daaec8d71d5">+50/-16</a>&nbsp; </td> </tr> <tr> <td><strong>track-usage.ts</strong><dd><code>Implement usage tracking middleware for subscription limits</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-9248228a33147544ca9b58ff8b9c737b33763dd3e29717c82c38808bb7e34db3">+78/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>setup-stripe.ts</strong><dd><code>Script for setting up Stripe products and prices</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-fde1de99bb4325e0352a86fad382424a2a890d68c0ccfd8790796371bae1324f">+85/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>subscription-utils.ts</strong><dd><code>Add utilities for subscription limits and checkout session creation</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-846af69dc1c830de7e6d0c1f73a01e75d60d3e3788b0b60d907d8a161140c679">+122/-0</a>&nbsp; </td> </tr> <tr> <td><strong>actions.ts</strong><dd><code>Add billing actions for subscription upgrade and cancellation</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-483bd280b775abd99ae9bbbbcbee9cdcd7407a5c8f09e97591143ea7a460a349">+96/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>billing-view.tsx</strong><dd><code>Create billing view with subscription usage and action UI</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-4b7dc7632b66abfc90fcb72aaca8222a6f72b2cd65386f5cdf3d6affec187565">+82/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>page.tsx</strong><dd><code>Implement server-side billing page with session and subscription fetch</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-86ac324c6a48fe59d742a236c9abad3998b7c571534ba8b4a757a89f5ad3ef83">+37/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>sidebar.tsx</strong><dd><code>Add billing link to sidebar navigation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-a3069b9cc39bb2210f37074c90af1f24894834cef38ca2794c312cf13a299aae">+9/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>progress.tsx</strong><dd><code>Create custom progress component for displaying usage</code>&nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-9437c33457680b4b21714c401e3ba3307a38187bc452ab57759ab5e354c8a74c">+25/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>environment.ts</strong><dd><code>Add helper functions for environment detection</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-0f860026005bc9b93926c42b04923ad589ad88fcde9aa7190bcefe8695aaa263">+7/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration.sql</strong><dd><code>Add subscriptions table with indices and foreign key constraints</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-8c1b31527c409128ba8d71ade36064c4b57bdfa8ec85acdf9a5db1118026f5b4">+26/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration.sql</strong><dd><code>Add foreign key constraint linking API keys to users</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-b07dd458b6c11384532557e84d1c5bda168806cc96e117f545ba7b261b6b0a3e">+2/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration.sql</strong><dd><code>Insert free tier subscriptions for users missing subscription records</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-c508ef69e6af2c10282872c39559bf10fcd0886fe5000ea507360c53feae5509">+28/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>schema.prisma</strong><dd><code>Update Prisma schema to include subscriptions model and relations</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-b30267f4306ab8d4d39c41394218b2aa428a35de686b88ca3a8c1f6b62453832">+24/-4</a>&nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Miscellaneous</strong></td><td><details><summary>4 files</summary><table> <tr> <td><strong>installed-repositories.ts</strong><dd><code>Correct GitHub app import by appending .js extension</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-86bc38f589fc8426f2ae4cc8bfaa79a4652064344591bccd524c0f996cfc5abd">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>verify-existing-optimizations.ts</strong><dd><code>Update import paths for consistency in optimizations endpoint</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-27bad39c963ec01481b7bdcff482e9d57ca39b99ee4ed0344a74d760092fb387">+4/-4</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>track-endpoint-calls.ts</strong><dd><code>Update import references in endpoint call tracking middleware</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-28e52f52b5f5ed621618a985f95d3636974f2a2c2281abe0d7c03ec2a5936537">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>prisma-client.ts</strong><dd><code>Update Prisma client initialization with additional comments</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-2961161048a21c0e00e92d799ccbe21870c5638af2aab0670c963c3d5dd929b0">+15/-1</a>&nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Dependencies</strong></td><td><details><summary>3 files</summary><table> <tr> <td><strong>package-lock.json</strong><dd><code>Update package lock with newer versions for dotenv and stripe</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-75446c74353509ca0232d6a1350aef075ced8f72bd568e9bafa09cf255683142">+15/-1</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>package.json</strong><dd><code>Update package dependencies: bump dotenv and add stripe version</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-53ddfb1f8a02f1231d3d15a2e694ffe1407d2cc01d3e685de5653b67fec571c7">+2/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>package.json</strong><dd><code>Update webapp package with stripe dependency and minor adjustments</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-4edec169b0f8d3312edaf35b5cc8521fe1edfa163ce174f60eff51906896601f">+2/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>3 files</summary><table> <tr> <td><strong>.env.example</strong><dd><code>Add sample environment variables for webapp configuration</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-2b720c1841e0bd5022a4a9c3fe68e8a52bba9115e2569e7d7af5b780f1da7b0c">+10/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>.env.example</strong><dd><code>Add Stripe environment variables in common example file</code>&nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-ab5d181c31c59dbee1bfd63202d1471ab27276a59ceee617e5b46988935db773">+11/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration_lock.toml</strong><dd><code>Minor update to migration lock file comment formatting</code>&nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-44423d32fecc24a69cc5d2d075987e28b6ab13da9730940621da28c0786b37e0">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr></tr></tbody></table> ___ > <details> <summary> Need help?</summary><li>Type <code>/help how to ...</code> in the comments thread for any questions about PR-Agent usage.</li><li>Check out the <a href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a> for more information.</li></details>
2025-03-10 16:24:51 +00:00
import { githubApp } from "../github/github-app.js"
import { Request, Response } from "express"
Pricing Setup V1 (#1504) ### **User description** Screenshots: ![image](https://github.com/user-attachments/assets/7e96678d-5f1f-466d-a2f7-e040adf70e3e) ![image](https://github.com/user-attachments/assets/d826551e-22a6-4c45-8a3c-f652ca69c742) ![image](https://github.com/user-attachments/assets/4defc919-eeae-40ab-ac93-ef76b4806db2) ToDO: Dedupe the code for cf-api and cf-webapp and move it to common Currently user can upgrade from free to monthly only, need to add logic to give choice to update to yearly as well from Billing page. ### **PR Type** - Enhancement ___ ### **Description** - Add Stripe client initialization and pricing config - Implement Stripe webhooks and subscription endpoints - Integrate usage tracking middleware and billing UI - Update Prisma schema and dependency versions ___ ### **Changes walkthrough** 📝 <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>14 files</summary><table> <tr> <td><strong>stripe-client.ts</strong><dd><code>Initialize Stripe client with API version setting</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-133526b16a4d7cf5fe0440be27d479000b85c6714b0a98b1bcc29864fbd59e68">+9/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>stripe.ts</strong><dd><code>Add pricing tiers and plan configurations</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-50e78686f5d8e699a8f0e7bec0151082fb80887cc8d303e8e54f1bf9fae666b6">+20/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>stripe-webhook.ts</strong><dd><code>Introduce Stripe webhook handler for events</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-77cb44047d6530f044469983d43fa5051bcc968add3b298c82cee11646312b2b">+135/-0</a>&nbsp; </td> </tr> <tr> <td><strong>subscription-management.ts</strong><dd><code>Add endpoints for subscription get, checkout, cancel</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-a8e2aca1f0313219f56d75c5d57f36d869fada2292457444f50843b304c26c99">+91/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>index.ts</strong><dd><code>Update routing; add Stripe and usage tracking routes</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-c3e60be1461b6e80f9181080342927fd9df095197e8784ae0ff51daaec8d71d5">+50/-16</a>&nbsp; </td> </tr> <tr> <td><strong>track-endpoint-calls.ts</strong><dd><code>Fix analytics import to .js extension</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-28e52f52b5f5ed621618a985f95d3636974f2a2c2281abe0d7c03ec2a5936537">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>track-usage.ts</strong><dd><code>Add middleware to track subscription usage limits</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-9248228a33147544ca9b58ff8b9c737b33763dd3e29717c82c38808bb7e34db3">+78/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>setup-stripe.ts</strong><dd><code>Add script for Stripe products and pricing setup</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-fde1de99bb4325e0352a86fad382424a2a890d68c0ccfd8790796371bae1324f">+85/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>subscription-utils.ts</strong><dd><code>Create helper functions for subscription checkout and limits</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-846af69dc1c830de7e6d0c1f73a01e75d60d3e3788b0b60d907d8a161140c679">+122/-0</a>&nbsp; </td> </tr> <tr> <td><strong>page.tsx</strong><dd><code>Add billing page UI displaying subscription status</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-86ac324c6a48fe59d742a236c9abad3998b7c571534ba8b4a757a89f5ad3ef83">+54/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>environment.ts</strong><dd><code>Add utilities for environment mode detection</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-0f860026005bc9b93926c42b04923ad589ad88fcde9aa7190bcefe8695aaa263">+7/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration.sql</strong><dd><code>Add migration for new subscriptions table creation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-8c1b31527c409128ba8d71ade36064c4b57bdfa8ec85acdf9a5db1118026f5b4">+26/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration.sql</strong><dd><code>Add foreign key constraint for API keys relation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-b07dd458b6c11384532557e84d1c5bda168806cc96e117f545ba7b261b6b0a3e">+2/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>schema.prisma</strong><dd><code>Update Prisma schema to include subscriptions relation</code>&nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-b30267f4306ab8d4d39c41394218b2aa428a35de686b88ca3a8c1f6b62453832">+24/-4</a>&nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Formatting</strong></td><td><details><summary>2 files</summary><table> <tr> <td><strong>create-pr.ts</strong><dd><code>Update import paths and minor formatting fixes</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-728a794bb81f944ae7db030f5e6ae1c1ba6888aa46e4be6846ebc5bd1ce12c2c">+10/-10</a>&nbsp; </td> </tr> <tr> <td><strong>verify-existing-optimizations.ts</strong><dd><code>Correct import extensions to .js for consistency</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-27bad39c963ec01481b7bdcff482e9d57ca39b99ee4ed0344a74d760092fb387">+4/-4</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>3 files</summary><table> <tr> <td><strong>prisma-client.ts</strong><dd><code>Document and update Prisma client instantiation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-2961161048a21c0e00e92d799ccbe21870c5638af2aab0670c963c3d5dd929b0">+15/-1</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>.env.example</strong><dd><code>Add example Stripe environment variables</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-ab5d181c31c59dbee1bfd63202d1471ab27276a59ceee617e5b46988935db773">+11/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration_lock.toml</strong><dd><code>Minor update to migration lock file documentation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-44423d32fecc24a69cc5d2d075987e28b6ab13da9730940621da28c0786b37e0">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Dependencies</strong></td><td><details><summary>2 files</summary><table> <tr> <td><strong>package-lock.json</strong><dd><code>Update dependency versions for dotenv and stripe</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-75446c74353509ca0232d6a1350aef075ced8f72bd568e9bafa09cf255683142">+15/-1</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>package.json</strong><dd><code>Bump dotenv and stripe versions in dependencies</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-53ddfb1f8a02f1231d3d15a2e694ffe1407d2cc01d3e685de5653b67fec571c7">+2/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Additional files</strong></td><td><details><summary>1 files</summary><table> <tr> <td><strong>installed-repositories.ts</strong></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-86bc38f589fc8426f2ae4cc8bfaa79a4652064344591bccd524c0f996cfc5abd">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr></tr></tbody></table> ___ > <details> <summary> Need help?</summary><li>Type <code>/help how to ...</code> in the comments thread for any questions about PR-Agent usage.</li><li>Check out the <a href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a> for more information.</li></details> ___ ### **PR Type** Enhancement ___ ### **Description** - Add Stripe client & pricing configuration. - Implement Stripe webhook & subscription endpoints. - Integrate usage tracking middleware & billing UI. - Update Prisma schema and dependency versions. ___ ### **Changes walkthrough** 📝 <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>18 files</summary><table> <tr> <td><strong>stripe-client.ts</strong><dd><code>Initialize Stripe client with API version and error handling</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-133526b16a4d7cf5fe0440be27d479000b85c6714b0a98b1bcc29864fbd59e68">+9/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>stripe.ts</strong><dd><code>Add Stripe pricing tiers configuration object</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-50e78686f5d8e699a8f0e7bec0151082fb80887cc8d303e8e54f1bf9fae666b6">+20/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>stripe-webhook.ts</strong><dd><code>Implement comprehensive Stripe webhook handler with multiple cases</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-77cb44047d6530f044469983d43fa5051bcc968add3b298c82cee11646312b2b">+209/-0</a>&nbsp; </td> </tr> <tr> <td><strong>subscription-management.ts</strong><dd><code>Add subscription management endpoints for retrieval and checkout</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-a8e2aca1f0313219f56d75c5d57f36d869fada2292457444f50843b304c26c99">+91/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>index.ts</strong><dd><code>Integrate Stripe webhook, subscription endpoints and tracking </code><br><code>middleware</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-c3e60be1461b6e80f9181080342927fd9df095197e8784ae0ff51daaec8d71d5">+50/-16</a>&nbsp; </td> </tr> <tr> <td><strong>track-usage.ts</strong><dd><code>Implement usage tracking middleware for subscription limits</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-9248228a33147544ca9b58ff8b9c737b33763dd3e29717c82c38808bb7e34db3">+78/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>setup-stripe.ts</strong><dd><code>Script for setting up Stripe products and prices</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-fde1de99bb4325e0352a86fad382424a2a890d68c0ccfd8790796371bae1324f">+85/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>subscription-utils.ts</strong><dd><code>Add utilities for subscription limits and checkout session creation</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-846af69dc1c830de7e6d0c1f73a01e75d60d3e3788b0b60d907d8a161140c679">+122/-0</a>&nbsp; </td> </tr> <tr> <td><strong>actions.ts</strong><dd><code>Add billing actions for subscription upgrade and cancellation</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-483bd280b775abd99ae9bbbbcbee9cdcd7407a5c8f09e97591143ea7a460a349">+96/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>billing-view.tsx</strong><dd><code>Create billing view with subscription usage and action UI</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-4b7dc7632b66abfc90fcb72aaca8222a6f72b2cd65386f5cdf3d6affec187565">+82/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>page.tsx</strong><dd><code>Implement server-side billing page with session and subscription fetch</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-86ac324c6a48fe59d742a236c9abad3998b7c571534ba8b4a757a89f5ad3ef83">+37/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>sidebar.tsx</strong><dd><code>Add billing link to sidebar navigation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-a3069b9cc39bb2210f37074c90af1f24894834cef38ca2794c312cf13a299aae">+9/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>progress.tsx</strong><dd><code>Create custom progress component for displaying usage</code>&nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-9437c33457680b4b21714c401e3ba3307a38187bc452ab57759ab5e354c8a74c">+25/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>environment.ts</strong><dd><code>Add helper functions for environment detection</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-0f860026005bc9b93926c42b04923ad589ad88fcde9aa7190bcefe8695aaa263">+7/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration.sql</strong><dd><code>Add subscriptions table with indices and foreign key constraints</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-8c1b31527c409128ba8d71ade36064c4b57bdfa8ec85acdf9a5db1118026f5b4">+26/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration.sql</strong><dd><code>Add foreign key constraint linking API keys to users</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-b07dd458b6c11384532557e84d1c5bda168806cc96e117f545ba7b261b6b0a3e">+2/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration.sql</strong><dd><code>Insert free tier subscriptions for users missing subscription records</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-c508ef69e6af2c10282872c39559bf10fcd0886fe5000ea507360c53feae5509">+28/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>schema.prisma</strong><dd><code>Update Prisma schema to include subscriptions model and relations</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-b30267f4306ab8d4d39c41394218b2aa428a35de686b88ca3a8c1f6b62453832">+24/-4</a>&nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Miscellaneous</strong></td><td><details><summary>4 files</summary><table> <tr> <td><strong>installed-repositories.ts</strong><dd><code>Correct GitHub app import by appending .js extension</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-86bc38f589fc8426f2ae4cc8bfaa79a4652064344591bccd524c0f996cfc5abd">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>verify-existing-optimizations.ts</strong><dd><code>Update import paths for consistency in optimizations endpoint</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-27bad39c963ec01481b7bdcff482e9d57ca39b99ee4ed0344a74d760092fb387">+4/-4</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>track-endpoint-calls.ts</strong><dd><code>Update import references in endpoint call tracking middleware</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-28e52f52b5f5ed621618a985f95d3636974f2a2c2281abe0d7c03ec2a5936537">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>prisma-client.ts</strong><dd><code>Update Prisma client initialization with additional comments</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-2961161048a21c0e00e92d799ccbe21870c5638af2aab0670c963c3d5dd929b0">+15/-1</a>&nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Dependencies</strong></td><td><details><summary>3 files</summary><table> <tr> <td><strong>package-lock.json</strong><dd><code>Update package lock with newer versions for dotenv and stripe</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-75446c74353509ca0232d6a1350aef075ced8f72bd568e9bafa09cf255683142">+15/-1</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>package.json</strong><dd><code>Update package dependencies: bump dotenv and add stripe version</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-53ddfb1f8a02f1231d3d15a2e694ffe1407d2cc01d3e685de5653b67fec571c7">+2/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>package.json</strong><dd><code>Update webapp package with stripe dependency and minor adjustments</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-4edec169b0f8d3312edaf35b5cc8521fe1edfa163ce174f60eff51906896601f">+2/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>3 files</summary><table> <tr> <td><strong>.env.example</strong><dd><code>Add sample environment variables for webapp configuration</code></dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-2b720c1841e0bd5022a4a9c3fe68e8a52bba9115e2569e7d7af5b780f1da7b0c">+10/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>.env.example</strong><dd><code>Add Stripe environment variables in common example file</code>&nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-ab5d181c31c59dbee1bfd63202d1471ab27276a59ceee617e5b46988935db773">+11/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>migration_lock.toml</strong><dd><code>Minor update to migration lock file comment formatting</code>&nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://github.com/codeflash-ai/codeflash-internal/pull/1504/files#diff-44423d32fecc24a69cc5d2d075987e28b6ab13da9730940621da28c0786b37e0">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr></tr></tbody></table> ___ > <details> <summary> Need help?</summary><li>Type <code>/help how to ...</code> in the comments thread for any questions about PR-Agent usage.</li><li>Check out the <a href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a> for more information.</li></details>
2025-03-10 16:24:51 +00:00
import { parseAndCreateOptimizationsDict } from "../github/pr-changes-utils.js"
import { posthog } from "../analytics.js"
import { userNickname } from "../auth0-mgmt.js"
import { logger } from "../utils/logger.js"
2026-01-19 17:33:57 +00:00
import {
missingRequiredFields,
unauthorized,
githubInstallationError,
githubNotCollaborator,
githubPrNotFound,
internalServerError,
} from "../exceptions/index.js"
// Dependencies interface for easier testing
export interface VerifyExistingOptimizationsDependencies {
getInstallationOctokitByOwner: typeof getInstallationOctokitByOwner
githubApp: typeof githubApp
parseAndCreateOptimizationsDict: typeof parseAndCreateOptimizationsDict
posthog: typeof posthog
userNickname: typeof userNickname
isUserCollaborator: typeof isUserCollaborator
}
// Default dependencies
let dependencies: VerifyExistingOptimizationsDependencies = {
getInstallationOctokitByOwner,
githubApp,
parseAndCreateOptimizationsDict,
posthog,
userNickname,
isUserCollaborator,
}
// For testing - allow dependency injection
export function setVerifyExistingOptimizationsDependencies(
deps: Partial<VerifyExistingOptimizationsDependencies>,
) {
dependencies = { ...dependencies, ...deps }
}
export function resetVerifyExistingOptimizationsDependencies() {
dependencies = {
getInstallationOctokitByOwner,
githubApp,
parseAndCreateOptimizationsDict,
posthog,
userNickname,
isUserCollaborator,
}
}
export async function verifyExistingOptimizations(req: Request, res: Response) {
try {
const { repo_owner, repo_name, pr_number } = req.body
const userId = (req as any).userId
logger.debug("Processing verify-existing-optimizations request", {
requestId: (req as any).requestId,
userId,
endpoint: "/cfapi/verify-existing-optimizations",
operation: "request_start",
repo_owner,
repo_name,
pr_number,
})
if (!repo_name || !repo_owner || !pr_number) {
2026-01-19 17:33:57 +00:00
throw missingRequiredFields("repo_name, repo_owner, pr_number")
}
const nickname: string | null = await dependencies.userNickname(userId)
if (nickname == null) {
2026-01-19 17:33:57 +00:00
throw unauthorized("")
2024-09-16 15:48:26 +00:00
}
const octokit = await dependencies.getInstallationOctokitByOwner(
dependencies.githubApp,
repo_owner,
repo_name,
userId,
)
if (octokit instanceof Error) {
2026-01-19 17:33:57 +00:00
throw githubInstallationError(octokit.message)
}
logger.info("Got installation Octokit for repository", {
requestId: (req as any).requestId,
userId,
endpoint: "/cfapi/verify-existing-optimizations",
operation: "octokit_installation",
repo_owner,
repo_name,
})
// Check collaborator status with error handling
try {
const isCollaborator = await dependencies.isUserCollaborator(
octokit,
repo_owner,
repo_name,
nickname,
)
if (!isCollaborator) {
// Emit human-readable console message for tests (using info for console.log output)
// Don't include userId in context to avoid logger appending " for user ..."
logger.info(`${nickname} is not a collaborator on ${repo_owner}/${repo_name}`, {
requestId: (req as any).requestId,
endpoint: "/cfapi/verify-existing-optimizations",
operation: "collaborator_verification",
repo_owner,
repo_name,
nickname,
})
2026-01-19 17:33:57 +00:00
throw githubNotCollaborator(`${repo_owner}/${repo_name}`)
}
} catch (error) {
2026-01-19 17:33:57 +00:00
if (error && typeof error === "object" && "getHttpStatus" in error) {
throw error
}
// Concatenate error in message for tests
logger.error(`Error checking collaborator status: ${error}`, {
requestId: (req as any).requestId,
userId,
endpoint: "/cfapi/verify-existing-optimizations",
operation: "collaborator_verification",
repo_owner,
repo_name,
nickname,
})
2026-01-19 17:33:57 +00:00
throw internalServerError("Failed to verify collaborator status")
}
// Get PR with specific 404 handling
// Note: GitHub returns 404 for both non-existent PRs and PRs the installation cannot access
let pr
try {
pr = await octokit.rest.pulls.get({
owner: repo_owner,
repo: repo_name,
pull_number: pr_number,
})
} catch (error: any) {
if (error.status === 404) {
// Log additional context to help diagnose permission vs not-found issues
logger.warn(
`PR #${pr_number} returned 404 in ${repo_owner}/${repo_name}. This could mean the PR doesn't exist, or the GitHub App installation doesn't have access to it.`,
{
requestId: (req as any).requestId,
userId,
endpoint: "/cfapi/verify-existing-optimizations",
operation: "pr_not_found_or_no_access",
repo_owner,
repo_name,
pr_number,
nickname,
errorMessage: error.message,
errorResponse: error.response?.data,
},
)
throw githubPrNotFound(
`#${pr_number} in ${repo_owner}/${repo_name}. If the PR exists, ensure the GitHub App installation has access to this repository.`,
)
}
// Handle 403 (Forbidden) as a permissions issue
if (error.status === 403) {
logger.warn(
`Access forbidden to PR #${pr_number} in ${repo_owner}/${repo_name}. The GitHub App installation may not have sufficient permissions.`,
{
requestId: (req as any).requestId,
userId,
endpoint: "/cfapi/verify-existing-optimizations",
operation: "pr_access_forbidden",
repo_owner,
repo_name,
pr_number,
nickname,
errorMessage: error.message,
},
)
throw githubInstallationError(
`Access forbidden to PR #${pr_number} in ${repo_owner}/${repo_name}. Please ensure the GitHub App has the necessary permissions.`,
)
}
throw error // Re-throw to be caught by global handler
}
// Get PR comments with error handling
let pr_messages
try {
pr_messages = await octokit.rest.issues.listComments({
owner: repo_owner,
repo: repo_name,
issue_number: pr_number,
})
} catch (error) {
// Pass error object for tests
logger.error(
"Error getting PR messages:",
{
requestId: (req as any).requestId,
userId,
endpoint: "/cfapi/verify-existing-optimizations",
operation: "get_pr_messages",
repo_owner,
repo_name,
pr_number,
},
undefined,
error as Error,
)
2026-01-19 17:33:57 +00:00
throw internalServerError(`Failed to retrieve PR comments for ${repo_owner}/${repo_name}`)
}
// Get PR reviews with error handling
let pr_reviews
try {
pr_reviews = await octokit.rest.pulls.listReviews({
owner: repo_owner,
repo: repo_name,
pull_number: pr_number,
})
} catch (error) {
// Pass error object for tests
logger.error(
"Error getting PR reviews:",
{
requestId: (req as any).requestId,
userId,
endpoint: "/cfapi/verify-existing-optimizations",
operation: "get_pr_reviews",
repo_owner,
repo_name,
pr_number,
},
undefined,
error as Error,
)
2026-01-19 17:33:57 +00:00
throw internalServerError(`Failed to retrieve PR reviews for ${repo_owner}/${repo_name}`)
}
const reviewBodies: Array<{ body: string }> = []
for (const review of pr_reviews.data) {
// Add the main review body if it exists
if (review.body) {
reviewBodies.push({ body: review.body })
}
// Get review comments for this specific review
try {
const reviewComments = await octokit.rest.pulls.listCommentsForReview({
owner: repo_owner,
repo: repo_name,
pull_number: pr_number,
review_id: review.id,
})
// Add each review comment body
for (const comment of reviewComments.data) {
if (comment.body) {
reviewBodies.push({ body: comment.body })
}
}
} catch (error) {
// Emit explicit console message for tests
logger.error(
`Error getting review comments for review ${review.id}:`,
{
requestId: (req as any).requestId,
userId,
endpoint: "/cfapi/verify-existing-optimizations",
operation: "get_review_comments",
repo_owner,
repo_name,
pr_number,
reviewId: review.id,
},
undefined,
error as Error,
)
// Continue with other reviews even if one fails
}
}
// Also get all review comments (not tied to a specific review)
try {
const allReviewComments = await octokit.rest.pulls.listReviewComments({
owner: repo_owner,
repo: repo_name,
pull_number: pr_number,
})
for (const comment of allReviewComments.data) {
if (comment.body) {
reviewBodies.push({ body: comment.body })
}
}
} catch (error) {
// Emit explicit console message for tests
logger.error(
"Error getting all review comments:",
{
requestId: (req as any).requestId,
userId,
endpoint: "/cfapi/verify-existing-optimizations",
operation: "get_all_review_comments",
repo_owner,
repo_name,
pr_number,
},
undefined,
error as Error,
)
// Continue even if this fails
}
const prBody = pr.data.body || ""
const validComments = pr_messages.data.filter(
(comment: { body?: string }) => comment.body !== undefined,
) as Array<{ body: string }>
const allComments = [...validComments, ...reviewBodies]
const optimizations_dict = dependencies.parseAndCreateOptimizationsDict(prBody, allComments)
if (Object.keys(optimizations_dict).length === 0) {
return res.status(200).json({ error: "No optimizations found for this PR" })
}
const response_dict: Record<string, string[]> = {}
for (const key in optimizations_dict) {
response_dict[key] = Array.from(optimizations_dict[key])
}
add posthog github pr event for analytics (#1421) ### **User description** <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added user tracking for GitHub pull request optimization interactions using PostHog analytics. - **Chores** - Improved code formatting for comment filtering logic. <!-- end of auto-generated comment: release notes by coderabbit.ai --> ___ ### **PR Type** Enhancement ___ ### **Description** - Added telemetry tracking for GitHub pull request optimization. - Integrated PostHog event tracking in the CLI. ___ ### **Changes walkthrough** 📝 <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table> <tr> <td> <details> <summary><strong>cfapi.py</strong><dd><code>Add PostHog event for telemetry tracking</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary> <hr> cli/codeflash/api/cfapi.py <li>Imported <code>ph</code> function from <code>posthog_cf</code> module.<br> <li> Added a PostHog event <code>cli-github-pr-optimization</code> for telemetry <br>tracking. </details> </td> <td><a href="https://github.com/codeflash-ai/codeflash/pull/1421/files#diff-0615684f0153a74b94ca6b9a3a85c7f8af244b661cd66f361eb81e45d610a8fd">+2/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></td></tr></tr></tbody></table> ___ > 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull request to receive relevant information --------- Co-authored-by: Sarthak Agarwal <sarthak.saga@gmail.com>
2025-01-28 17:20:28 +00:00
dependencies.posthog?.capture({
distinctId: userId,
event: `cfapi-github-pr-optimization`,
properties: {
repo_owner,
repo_name,
pr_number,
},
})
return res.status(200).json(response_dict)
} catch (error) {
2026-01-19 17:33:57 +00:00
// Re-throw AppExceptions to be handled by GlobalExceptionHandler
if (error && typeof error === "object" && "getHttpStatus" in error) {
throw error
}
// Emit specific console message expected by tests (stringified for single-arg output)
// Note: Error object is still passed for Sentry, but test mode outputs stringified version
// Use String(error) to match test expectation of ${error} format
const errorStr = String(error)
logger.errorWithSentry(
`Error in /cfapi/verify-existing-optimizations: ${errorStr}`,
{
requestId: (req as any).requestId,
userId: (req as any).userId,
endpoint: "/cfapi/verify-existing-optimizations",
operation: "verify_existing_optimizations",
},
{
repo_owner: req.body?.repo_owner,
repo_name: req.body?.repo_name,
pr_number: req.body?.pr_number,
},
error as Error,
)
if (error instanceof Error) {
2026-01-19 17:33:57 +00:00
throw internalServerError(`Error verifying existing optimizations: ${error.message}`)
} else {
2026-01-19 17:33:57 +00:00
throw internalServerError("Error verifying existing optimizations")
}
}
add posthog github pr event for analytics (#1421) ### **User description** <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added user tracking for GitHub pull request optimization interactions using PostHog analytics. - **Chores** - Improved code formatting for comment filtering logic. <!-- end of auto-generated comment: release notes by coderabbit.ai --> ___ ### **PR Type** Enhancement ___ ### **Description** - Added telemetry tracking for GitHub pull request optimization. - Integrated PostHog event tracking in the CLI. ___ ### **Changes walkthrough** 📝 <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table> <tr> <td> <details> <summary><strong>cfapi.py</strong><dd><code>Add PostHog event for telemetry tracking</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary> <hr> cli/codeflash/api/cfapi.py <li>Imported <code>ph</code> function from <code>posthog_cf</code> module.<br> <li> Added a PostHog event <code>cli-github-pr-optimization</code> for telemetry <br>tracking. </details> </td> <td><a href="https://github.com/codeflash-ai/codeflash/pull/1421/files#diff-0615684f0153a74b94ca6b9a3a85c7f8af244b661cd66f361eb81e45d610a8fd">+2/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></td></tr></tr></tbody></table> ___ > 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull request to receive relevant information --------- Co-authored-by: Sarthak Agarwal <sarthak.saga@gmail.com>
2025-01-28 17:20:28 +00:00
}