| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
chore: typos (#2595) ## Describe your changes - Fix typos | 2 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(database): [nan-1063] migrate to database package (#2236) ## Describe your changes As part of another ticket related to webhooks, I want to make a specific webhook package. I don't want the webhook package to depend on shared but shared contained the database as of now. This PR moves the database connection logic to its own package freeing it from shared and making it easier to use freely in other packages now. Note that the seeders have to stay due to the usage of services. ## Issue ticket number and link Contributes to NAN-1063 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
feat(webhooks): [nan-1142] migrate to the external webhooks table (#2302) ## Describe your changes Move settings to an external table for webhook management. Script can be run more than once to not force an immediate release. ## Issue ticket number and link NAN-1142 ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix: eslint pass (#3406) ## Changes - Fix more rules | 1 年前 | |
fix(db): add models_json_schema to sync_configs (#2369) ## Describe your changes Contributes to https://linear.app/nango/issue/NAN-1155/upload-json-schema-when-deploying - Add `models_json_schema` to sync_configs table After I upload the json_schema when deploying, each sync_configs will hold its json schema to be able to validate input/output at runtime | 2 年前 | |
fix(activeLogs): drop v1 activity_log_id (#2390) ## Describe your changes Contributes to https://linear.app/nango/issue/NAN-585/stop-writing-from-v1 When I removed v1 from hooks I didn't realized active_logs had a foreign key attached to the table, so the value `-1` wasn't really cutting it. - Drop column `activity_log_id` from table `_nango_active_logs` | 2 年前 | |
feat(logs.v1): drop data (#2414) ## Describe your changes Fixes https://linear.app/nango/issue/NAN-586/drop-v1-data - Drop data - Remove cron and leftovers - Fix documentation | 2 年前 | |
chore: cleaning up legacy records tables (#2432) Those tables have not been in used for months now. I am currently slowly deleting records so the migration will just drop the empty tables ## Issue ticket number and link https://linear.app/nango/issue/NAN-852/cleanup-nango-sync-data-records-and-nango-sync-data-records-deletes ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
fix(db): add index for invited_users (#2522) ## Describe your changes Fixes https://linear.app/nango/issue/NAN-1445/missing-unique-column-on-invite-table - Add unique index for token This can be problematic if we select the wrong token (very unlikely but still) - Add index for querying | 2 年前 | |
chore: refactor runner and run.service (#2547) ## Describe your changes First I would like to apologize for the size of the PR. The goal of this big PR is to make the communication between `jobs` and `runner` asynchronous, instead of relying on a long running request that can fail and depends on `jobs` in-memory state. The cancellation/aborting mechanism had to be refactored also since it was also relying on an in-memory state in `jobs` The `run.service` logic has been split into one file per script type. It is not the most DRY solution but it avoids the current situation where it is very hard to follow what part of run.service applies to which script type. They all differ slightly from each other and unless we have a good abstraction around them it is better imho to have a bit of duplication. Let me know what you think. Notes: - server/runner/orchestrator must be deployed first before jobs ## Issue ticket number and link https://linear.app/nango/issue/NAN-1421/refactor-runservice ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
chore(migration): add sync_config_id column to sync_config table (#2711) linking sync_config from sync currently requires to check the connection table and match on connectionId, environmentId and syncName. Adding a sync_config_id foreign key to the sync table for more performant queries and easier debugging Following PR is using this new column: https://github.com/NangoHQ/nango/pull/2712 There were actually a bug a couple of month ago that was caused by a missing join where fetching syncs: https://github.com/NangoHQ/nango/pull/2518/files. This change should make such bug less likely to happen. ## Issue ticket number and link https://linear.app/nango/issue/NAN-1442/add-foreign-key-nango-syncs-nango-sync-configs | 2 年前 | |
chore: upgrade eslint (+ plugins) (#3262) ## Changes Fixes https://linear.app/nango/issue/NAN-2473/upgrade-eslint - Upgrade to eslint 9 and all plugins It's a non-trivial upgrade since eslint chose to have a massive breaking change for their config format. Plus we were behind many months of updates for the plugins. I haven't added/deleted rules, the lines that are changed in this PR are either: previous rules catching more stuff or new rules inside recommended plugins. The only big diff is that I enabled Typescript rules only on ts files which removes some false negative (and makes it slightly faster) | 1 年前 | |
fix(syncs table): sync_config_id must be updated when new deploy (#2736) I introduced a bug last week when adding the `sync_config_id` column to the `syncs` table. The value is set when a sync is created and never changes. However each time a sync definition is deployed (or prebuild templates are upgraded) a new version of the `sync_config` is added but the `sync.sync_config_id` is currently not updated and keep pointing to the same `sync_config` that is now inactive. Impact: This new `sync_config_id` is only used by the patch frequency endpoint and demo auto idle feature for now but the bug should be fixed asap This commit is ensuring that sync_config_id in syncs table is updated on deploy/upgrade as well as fixing the drift of `sync_config_id` values in the db | 2 年前 | |
feat: add POST /connect/sessions endpoint (#2769) ## Describe your changes Adding the `POST /connect/sessions` endpoint as well as the `end_users` and `connect_sessions` tables. Happy to discuss the naming 😺 Spec: ``` POST /connect/sessions -H "Authorization: Bearer PRIVATE_KEY" { "end_user": { "id": "1jkhfz2FEuihojhfsdkjh29842", // Required "email": "a@a.com", // Required but for domain "display_name": "Mr A." // Optional }, "organization": { // Optional "if": "foi", // Optional "display_name": "My org.", // Optional } "allowed_integrations": ['hubspot', 'github'] // Optional "integrations_config_defaults": { // Optional "hubspot": { "connection_config": { "extension": "fr", } }, }, } // Response { "token": "nango_connect_session_dfkjdfkdjflksjfoizrjfozijfzoijfz", "expires_at": Date } ``` `GET /connect/session` will come in next PR. Split them so PR are smaller ## Issue ticket number and link https://linear.app/nango/issue/NAN-1775/%5Bserver%5D-api-endpoints-to-getpost-sessions ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(db): add missing index for active_logs (#2823) ## Describe your changes - Add missing index for active_logs We mostly query like this `SELECT * FROM type, connection_id` We also sometimes filter `WHERE active = true`, I could have doubled the index with a prefiltered one, let's see if that is enough otherwise we could improve | 2 年前 | |
fix: out of sync between task state and sync_job status (#2829) When user currently cancels a task we only update the sync_job entry if the abort task is successfully processed by jobs. However if jobs for some reason is having issue, the customer is left with seeing the task still running in the dashboard. With this commit the sync job is always updated when cancellation is clicked and doesn't depend on Job actually aborting the task. Even if jobs is misbehaving the scheduler will eventually recover by cancelling/timing out the task ## Issue ticket number and link https://linear.app/nango/issue/NAN-1865/fix-sync-status-out-of-sync-on-connections-page ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 2 年前 | |
fix(connections): add FK to end users (#2883) ## Describe your changes Contributes to https://linear.app/nango/issue/NAN-1944/connect-end-users-to-connections - Add Foreign Key from connections to end_users Implementation will come after - Add Foreign Key from oauth_session to connect_session to be able to get back the session on the callback Implementation will come after | 1 年前 | |
feat: add migration for otlp settings (#2891) ## Describe your changes Adding column otlp_settings to environment table. Will be used in my next PR It will contains info about where to send the openTelemetry data. ex: ``` { 'endpoint': 'http://otlp.agent:4318/v1', 'headers': { 'x-api-key': 'xxx'} } ``` ## Issue ticket number and link https://linear.app/nango/issue/NAN-1782/opentelemetry-export ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 1 年前 | |
feat(endpoints): store and use "group“ (#2966) ## Describe your changes Fixes https://linear.app/nango/issue/NAN-1934/specify-script-endpoint-section-in-nangoyaml - Store entity - Use it in the UI to categorize endpoints *cf my own nango.yaml* <img width="1147" alt="Screenshot 2024-11-08 at 15 06 34" src="https://github.com/user-attachments/assets/3b3b506e-95c0-4c17-9f08-d28c1d666a9a"> | 1 年前 | |
feat: rename post-connection-scripts table to on-event-scripts (#2990) ## Describe your changes See Linear ticket for more context Nango currently allows users to define a custom script that is executed when a connection is created. We want to extend this feature to also make it possible to execute a custom script when a connection is deleted. In order to do so we are going to implement a generic solution where a custom script can be executed based on a Nango event like connection creation or deletion This first PR is not introducing any new behaviour but rename the `post-connection-scripts table` to `on-event-scripts` and adding an event column where the type of event associated with the script is being stored. The PR is also renaming things related to the deployment, making sure the old `postConnectionScriptsByProvider` param sent by old CLI is still supported for backward compatibility In next PRs I will: - rename all things related to postConnnection in the orchestrator/scheduler - add support for ON_CONNECTION_DELETED event - refactor CLI to allow definition of both events/scripts ## Issue ticket number and link https://linear.app/nango/issue/NAN-1962/connect-lifecycle-scripts ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 1 年前 | |
feat: add support for on-events syntax in nango.yaml (#3021) We want to be able to support custom scripts for more than just post-connection event. This commit is adding support for the following syntax in nango.yaml: ``` my-integration: on-events: post-connection-creation: - script1 - script2 pre-connection-deletion: - script1 syncs: ... ``` Events currently supported are `post-connection-creation` and `pre-connection-deletion` The change is backward compatible and still support the old `post-connection-scripts` even though I don't think it is currently being used. I will add in next PR the logic to trigger the script when connection is deleted ## Issue ticket number and link https://linear.app/nango/issue/NAN-1962/connect-lifecycle-scripts ## Checklist before requesting a review (skip if just adding/editing APIs & templates) - [ ] I added tests, otherwise the reason is: - [ ] I added observability, otherwise the reason is: - [ ] I added analytics, otherwise the reason is: | 1 年前 | |
feat: getting started (#3001) ## Describe your changes Fixes https://linear.app/nango/issue/NAN-2122/implement-getting-started-tab Fixes https://linear.app/nango/issue/NAN-2123/track-events-video-started-and-ended - Replace Interactive Demo by Getting Started I dropped all the codebase related to the interactive demo - Add missing unique index for `user_id` - Add new endpoint `PATCH /onboarding` Only used to set onboarding as done  | 1 年前 | |
feat(server): Add missing fields column for integrations to db (#3045) <!-- Describe the problem and your solution --> We need a stored set of issues on integrations so that we can show those issues in the UI. This will add the new column and ensure that it's handled appropriately in the app. - [x] Add new column - [x] Set up validation function for integrations - [x] Update creating integrations to fill in fields - [x] Update updating integrations to fill in fields A future PR will migrate existing providers to note their missing fields correctly since, and then we'll be able to utilize those in the dashboard. <!-- Issue ticket number and link (if applicable) --> https://linear.app/nango/issue/NAN-2168/surface-integrationsconnections-errors-in-nango-ui <!-- Testing instructions (skip if just adding/editing providers) --> ## How I Tested It - Run the tests - Click through adding a new oauth based integration - Note that missing_fields is set for it in the DB - Update that integration - Note that missing_fields has been updated accordingly | 1 年前 | |
feat(providers): use new package (#3322) ## Changes Contributes to https://linear.app/nango/issue/NAN-2265/remove-shared-from-cli Split of #3297 - Use new package for providers Figured we can actually use it straight away since we publish it the CLI can use it without packing. | 1 年前 | |
feat: reconnect (#3119) ## Changes Fixes https://linear.app/nango/issue/NAN-2302/connect-refuse-connectionid-when-auth-is-session-token Fixes https://linear.app/nango/issue/NAN-2249/connect-reconnect - Ability to create a session token to reconnect a `connection_id` After debate with the team, we settled with a new endpoint dedicated to creating a reconnect token. - Refuse `connection_id` has a query params if a session token is used - Update all endpoints to add the reconnect ability - Add SDK, doc, openapi ## 🧪 How to test? There is no built-in way to reconnect from the UI so it's a bit manual - Use your favorite curl/api tool to create a token from ```sh curl --request POST \ --url http://localhost:3003/connect/sessions/reconnect \ --header 'Authorization: _PRIVATE_KEY_' \ --header 'Content-Type: application/json' \ --data '{ "connection_id": "test-connection-id", "integration_id": "google-mail", "end_user": { "id": "test_insomnia", "email": "samuel@nango.dev" }, }' ``` - Access Connect UI directly with the token `http://localhost:3009/?session_token=SESSION_TOKEN` - Connect - Check that no connection has been created and the selected `connection_id` has been updated | 1 年前 | |
fix(endUser): make email optional (#3159) ## Changes All according to plan 🫣 Fixes https://linear.app/nango/issue/NAN-2371/end-user-change-email-to-be-optional - Make email optional Some customers do not have email in their system and even if they could put garbage it's confusing enough. | 1 年前 | |
fix(db): sync_type casing (#3456) ## Changes Contributes to https://linear.app/nango/issue/NAN-2547/fix-old-casing-of-sync-type - Fix old casing type in Database Will change the associated types after it's been deployed | 1 年前 | |
feat: introduce sync variant (#3521) Adding the 'variant' column to the syncs table with a default 'base'value and add variant parameters to sync related function so we can pass a different value later. This commit doesn't change any behavior. There is still no way to create a variant and cardinality of sync_config:sync is still 1:1 Next steps: - modify existing public function/api (trigger, pause, status, ...) to accept a sync name + variant - expose variant into the script - modify runner-sdk to save variant records and modify getRecords to handle variants - add new functions/api to be able to create a variant - update docs | 1 年前 | |
feat: add API endpoints and functions to create/delete sync variants (#3600) Create API endpoints and node client functions to create and delete a sync variant How to test: ``` // creation curl --request POST --header 'Authorization: SECRET' \ --url http://localhost:3003/sync/SYNC_NAME/variant/NEW_VARIANT \ --header 'Content-Type: application/json' \ --data '{ "provider_config_key": "PROVIDER_CONFIG_KEY", "connection_id": "CONNECTION_ID" }' // deletion curl --request DELETE --header 'Authorization: YOUR_SECRET' \ --url http://localhost:3003/sync/SYNC_NAME/variant/VARIANT \ --header 'Content-Type: application/json' \ --data '{ "provider_config_key": "PROVIDER_CONFIG_KEY", "connection_id": "CONNECTION_ID" }' ``` | 1 年前 | |
fix(syncConfig): runs is nullable, not models (#3636) ## Changes - Fix runs is nullable Unfortunately, this is a limitation zod type and ts type are compatible because `string` is a subset of `string | null` ([playground](https://www.typescriptlang.org/play/?#code/JYOwLgpgTgZghgYwgAgMIHsCuyDeBYAKGWOSkxAGcAuZCsKUAcwG5CBfQ0SWRFAIThRchEqXLVa9JsgA+yEJgA2i1gQ4FCCdJTDJIdAIw0BQgLy4xlGguXJ1WnXoh0ATDQzZz+sAdWFN2nROdADM7ljI5jiWEgDkdAwgjLF2AY7eACzGgpHBYCHMQA)). I played around with IsEqual<> from type-fest but it's basically impossible since we have object like json_schema - Fix models is not nullable | 1 年前 | |
fix(jobs): add index without deleted (#3651) ## Changes Contributes to https://linear.app/nango/issue/NAN-2884/remove-soft-delete-from-jobs - Add index without `deleted` Soft delete is not used on this table, but we need a 3 three steps deployment to avoid issues. Next PR will remove usage | 1 年前 | |
fix(connection): store metadata for refresh (#3653) ## Changes Fixes https://linear.app/nango/issue/NAN-2852/store-more-metadata Contributes to https://linear.app/nango/issue/NAN-2850/investigate-refresh-connections - Store connection metadata for refresh | 1 年前 | |
feat(connect): store operation_id in DB (#3661) ## Changes Fixes https://linear.app/nango/issue/NAN-2889/store-operation-id-in-db We want to log events before we actually save a connection's credentials. To do that, we will create a new public endpoint that receives events from the Connect UI. We need to either pre-create an operation or create the operation at the first event. - Prepare connect_sessions table to receive an operation_id | 1 年前 | |
fix(jobs): drop where deleted index (#3681) ## Changes Fixes https://linear.app/nango/issue/NAN-2884/remove-soft-delete-from-jobs - Drop where deleted index I'll drop the column in a couple of months maybe, to wait for enterprise to migrate In the last 48hours those 2 index have now used  | 1 年前 | |
fix(db): drop unused table schedules (#3692) ## Changes Fixes https://linear.app/nango/issue/NAN-2899/drop-sync-schedules - Drop sync-schedules table and migration script It's been 9months | 1 年前 | |
feat(plans): table migration (#3807) ## Changes Fixes https://linear.app/nango/issue/NAN-2980/modify-db-to-store-trial-information Split of #3803 - Migration: create plans table and types | 1 年前 | |
fix(plan): use plan for tracer (#3848) ## Changes Fixes https://linear.app/nango/issue/NAN-3020/update-tracer-with-plan Contributes to https://linear.app/nango/issue/NAN-3019/store-ratelimit-configuration-in-plan - Use plan for tracer It's only partially used, in jobs we don't really need it for the moment. - Added new column to store api rate limit I have a big question here, rate-limit-flexible does not allow points to be changed dynamically. What we currently do is increase/decrease the consumption based on some condition but it's not really precise. I have looked for ways to do it natively but there is no way. What I have done in the past is to create one class per customers, but not sure with our scale it would fit. ```ts const limiters = new Map(); function getLimiterForCustomer(customerId, points, duration = 60) { if (!limiters.has(customerId)) { const limiter = new RateLimiterMemory({ points, duration }); limiters.set(customerId, limiter); } return limiters.get(customerId); } ``` @TBonnin | 1 年前 | |
feat(ui, api, db): allow editing integration name via new field (#3882) ## Issue When multiple integrations use the same provider (e.g. Salesforce), their names in the dashboard UI appear identical, making them hard to distinguish. This creates confusion when managing or selecting between them. While a temporary solution was explored, the preferred long-term fix is to allow users to customize the display name of each integration manually. ## Fix Introduces a new `custom_display_name` field on integrations, allowing users to rename integrations directly from the dashboard UI. This new name is shown prominently as the integration’s title and in the integrations list, falling back to the default provider name if unset. Users can click a pencil icon next to the integration title to open an inline input and update the name. Changes are saved via API and reflected immediately across the UI. This replaces the integration ID in the page header (which is already shown below) to avoid redundancy and keep the layout clean. Includes: - New `custom_display_name` field added via migration - UI to edit the name from the integration detail page - Updated integrations list (Connect UI) to display the custom name when available - Fallback to provider display name if custom one is not set - Inline edit with cancel/save buttons, enter key support, and loading state ## Testing 1. If needed, create a new integration from the dashboard. 2. Go to the integration detail page (`/integrations/:providerConfigKey`). 3. Click the pencil icon next to the integration name. 4. Edit the name, then either press **Enter** or click **Save**. 5. The new name should be updated immediately in the UI. 6. Navigate to the **Integrations** list and confirm: - The edited name is shown under the new **Name** column. - The integration ID is shown in a separate **ID** column. 7. Try clicking **Cancel** to ensure the name remains unchanged. 8. Make sure empty input is not accepted and that the loading state appears during save. ## Preview <img width="1423" alt="Screenshot 2025-04-06 at 10 58 35 PM" src="https://github.com/user-attachments/assets/3a3af4b9-666c-4eff-a438-15ef54dd7691" /> <img width="1439" alt="Screenshot 2025-04-06 at 11 02 28 PM" src="https://github.com/user-attachments/assets/633d740c-c1eb-4cc2-8169-93b900192b28" /> ## Notes Let me know if you have any feedback or changes you’d like me to make. I’ll be happy to adjust things accordingly! --------- Co-authored-by: Samuel Bodin <1637651+bodinsamuel@users.noreply.github.com> | 1 年前 | |
feat(plan): trial (#3803) ## Changes Fixes https://linear.app/nango/issue/NAN-2981/show-banner-in-ui Figma https://www.figma.com/design/aR5Pjn4JHJWsYxJ3s4iD3D/Free-Trial?node-id=64-1276&t=9lU4gkM197KZudiB-0 - Added: trial banner in UI - Added: API to extend trial - Added: tooltip next to script toggles - Added: Send email 3 days before trial expire - Changed: expired trial do not have the ability to enable scripts anymore - Changed: increase free plan to 50 (checked with @bastienbeurier) - Changed: pause all scripts after trial is over ### Missing > The PR is big so it's missing a few things - Email at the end of the trial - Small leftover for is_capped ## 🧪 Tests - Launch your local dev `npm run dev:watch:web` - Modify your plan in DB, set "free" and some date from the trial - Go to integrations   | 1 年前 | |
fix(plans): follow-up (#3866) ## Changes - Remove is_capped - Remove endpoint to edit plan - Fix cron running on init, not useful - Set `has_sync_variants` to true - Set `sync_frequency_secs_min` to 30 - Change email to upgrade plan - Fix icon being displayed after the end of the trial | 1 年前 | |
fix(plans): add connections_max flag (#3931) ## Changes Contributes to https://linear.app/nango/issue/NAN-3124/enfore-max-1000-connections-for-free-users - Add flag without use | 1 年前 | |
fix(plans): add connections_max flag (#3931) ## Changes Contributes to https://linear.app/nango/issue/NAN-3124/enfore-max-1000-connections-for-free-users - Add flag without use | 1 年前 | |
feat: add on_async_action_completion column to webhook table (#4062) We want to send webhook when async actions complete. Adding a column in the db to store the setting value <!-- Summary by @propel-code-bot --> --- This PR adds a new boolean column `on_async_action_completion` to the `_nango_external_webhooks` table with a default value of true. This change enables the system to track whether webhooks should be sent when asynchronous actions are completed. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat(syncConfig): store sdk version along syncConfigs, onevents (#4106) ## Changes Fixes https://linear.app/nango/issue/NAN-3311/store-sdk-version-in-db - Store sdk version along syncConfigs, onEvents To be able to know which sdk the scripts are using, and also determines if it's a yaml or not. This will help refine some logic of the code without having to load the actual code. Also in general it will give us the ability to know what's the lowest version we can support. NB: it's only types and default value, it's not used yet <!-- Summary by @propel-code-bot --> --- This PR adds support for persisting the SDK version (sdk_version) used during deployments of sync configurations and on-event scripts. These changes introduce new database columns, update relevant TypeScript types, validation schemas, service logic, API endpoints, and test/seed logic to accept and store the SDK version as a first-class, optional property. The version value is currently only captured, stored, and exposed, but not yet actively used for any runtime logic or compatibility decisions. **Key Changes:** • Database migration adds `sdk_version` columns to `_nango_sync_configs` and `on_event_scripts` tables. • TypeScript types/interfaces for sync configs and on-event scripts extended to include `sdk_version`. • API types, endpoints (`/sync/deploy`, `/sync/deploy/confirmation`, `/sync/deploy/internal`), and validation updated to support and validate the `sdkVersion` property (with regex constraint). • Service layers (deployment, on-event script service) refactored to propagate and persist the new field. • Seeder utilities, unit and integration tests updated to set and check `sdkVersion`. • SDK version is defaulted to `null` if unset; no behavioral change yet. **Affected Areas:** • Database schema and migrations • Sync config and on-event script types, validation and service layers • All sync deployment API routes and controllers • Seeders and test suites across CLI, server, jobs, and types packages *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
fix: add missing index for sync endpoint table (#4135) We are joining on sync_config_id here: https://github.com/NangoHQ/nango/blob/a093baae68861bce97b7ede53074eb9ab710c9da/packages/shared/lib/services/sync/config/config.service.ts#L707 but there were no index <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This PR introduces a database migration to add a btree index on the sync_config_id column of the nango._nango_sync_endpoints table. The index is intended to optimize join queries involving sync_config_id, as highlighted in the referenced code location. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat: database changes for webhook forwarding enabled (#4171) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This PR introduces a database migration that adds a new boolean column, 'forward_webhooks', to the '_nango_configs' table with a default value of true. The migration is implemented via a new Knex migration script. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
fix(db): add fields in plans for self-serve billing (#4227) ## Changes - add fields in plans for self-serve billing - `stripe_customer_id` -> to link in orb - `stripe_payment_id` -> to link in orb - `orb_customer_id` -> to know which customer has been linked to orb - `orb_subscription_id` -> to know which subscription a customer has - `orb_future_plan` -> future (when we downgrade the next plan is kickin at the start of the next billing period) - `orb_future_plan_at` -> handy to not have to compute or if an admin choose a different start period <!-- Summary by @propel-code-bot --> --- This PR introduces new columns to the 'plans' table to support self-serve billing. Specifically, it adds Stripe and Orb identifiers, as well as fields to manage future plan changes and their effective dates. The migration is implemented through a Knex migration script. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
fix: migration to fix json schema in public flows (#4268) <!-- Describe the problem and your solution --> ### Describe A migration to update the `models_json_schema` for all our public flows. It uses either the `legacySyncModelsToJsonSchema` or `nangoModelsToJsonSchema` I have been developing to convert the `model_schema`, which is expected to be the trustworthy source of truth. We do it for EVERY public flow, because their json schema was incorrectly saved until recently. I add a tag to the resulting schema to show that it was generated by this migration, in case we need to apply it again with some tweak, we have something to filter for. <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This PR implements a database migration that recalculates and updates the `models_json_schema` for all public, non-deleted sync configs in `_nango_sync_configs`. It ensures the JSON schema is derived from the trusted `model_schema` using either the legacy or new schema conversion logic, adds version tagging for traceability, improves schema conversion robustness for legacy edge cases (such as empty arrays), and enhances unit test coverage to reflect real-world data anomalies. <details> <summary><strong>Key Changes</strong></summary> • Introduces migration (20250618140753_fix_json_schemas.cjs) to update `models_json_schema` for all public, non-deleted sync configs. • Migrated schemas receive a `` marker for identification. • Handles empty/invalid `model_schema` by setting `models_json_schema` to null and logging errors. • Extends `legacySyncModelsToJsonSchema` logic to support empty array types, with matching unit tests/snapshots. • Adds JSDoc type annotations and ensures migration script consistency. </details> <details> <summary><strong>Affected Areas</strong></summary> • _nango_sync_configs (models_json_schema field) • Database migration scripts • Schema conversion utilities (legacy & new) • Test suite and snapshots </details> *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
fix(plans): add auto_idle flag (#4234) ## Changes Fixes https://linear.app/nango/issue/NAN-3456/make-auto-idling-a-feature-flag - add auto_idle flag Not used yet but we'll replace most of the trial flag <!-- Summary by @propel-code-bot --> --- This PR introduces an 'auto_idle' boolean flag to the 'plans' table, updates the corresponding type definitions, and ensures the new field is reflected in seeded test data. The field is added with a default value of true and is not yet used in business logic, but will later replace most uses of the trial flag. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
chore: add last_execution_at column to connection table (#4266) we want to add a new metric to automate the billing of some of the legacy scale plan. The metric is "number of connections with at least a script execution during the period". There is currently no source of truth in the db regarding script executions (actions for example are not tracked). In order to avoid sending an event for every single execution, this commit is adding a last_execution_at column to the connection table that will be updated every time a script execution starts <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This PR adds a new 'last_execution_at' timestamp column to the '_nango_connections' table, along with an index for efficient querying. These changes enable tracking the last script execution per connection to support billing automation for legacy scale plans. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
fix: add primary key to oauth_sessions without unique index (#4275) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This PR updates a database migration to correctly add a primary key on the `id` column of the `_nango_oauth_sessions` table, replacing the previous attempt that used a non-existent unique index. The migration for `_nango_db_config` remains unchanged. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
fix: add index to sync_jobs (#4280) query to check if sync is running must filter on status=RUNNING adding a partial index to speed up the query query plan before: ``` Limit (cost=0.57..1343.49 rows=1 width=320) -> Index Scan using idx_jobs_syncid_createdat on _nango_sync_jobs (cost=0.57..9401.02 rows=7 width=320) Index Cond: (sync_id = '02a49f20-a5df-4c81-8404-b96806d2a08e'::uuid) Filter: (status = 'RUNNING'::text) ``` query plan after ``` Limit (cost=0.42..1.69 rows=1 width=320) -> Index Scan using idx_jobs_syncid_running_createdat on _nango_sync_jobs (cost=0.42..9.34 rows=7 width=320) Index Cond: (sync_id = '02a49f20-a5df-4c81-8404-b96806d2a08e'::uuid) ``` <!-- Summary by @propel-code-bot --> --- This PR introduces a database migration that adds a partial index on the nango._nango_sync_jobs table, targeting (sync_id, created_at DESC) rows where status = 'RUNNING'. The intent is to speed up filtering queries that check for jobs with status RUNNING, resulting in a more efficient query plan. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat: remove connection_with_scripts_max cap (#4329) <!-- Describe the problem and your solution --> Contributes to https://linear.app/nango/issue/NAN-3610/create-new-caps and bigger goal https://linear.app/nango/issue/NAN-3382/explicit-caps-for-free-plans <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This PR removes the 'connection_with_scripts_max' cap, which previously limited the number of connections with active scripts per plan. It eliminates related code, types, checks, and database fields, streamlining cap logic to focus on total connection limits. <details> <summary><strong>Key Changes</strong></summary> • Removed 'connection_with_scripts_max' column from the database (new migration added). • Deleted all code checks, logic, and tracking tied to 'connection_with_scripts_max' in backend services, controllers, hooks, and tests. • Updated plan definitions, types, and seed data to remove references to the scripts cap. • Refactored affected API controllers, deployment logic, and plan objects to only use the total connections cap. • Modified tests and test helpers for compatibility with new cap logic. </details> <details> <summary><strong>Affected Areas</strong></summary> • Database (plans table, migration) • Plans/type definitions and seeders • Sync deployment, enable/disable, and deploy template controllers (backend APIs) • Connection and plan logic/services • Test suites for deployment and plans </details> *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat: create new free-plan caps (#4334) <!-- Describe the problem and your solution --> Not used anywhere yet. <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This PR adds two new capability fields, `monthly_actions_max` and `monthly_active_records_max`, to all plan definitions, assigns default values to the 'free' plan, and sets them to null for others. It updates the database schema by introducing corresponding fields with defaults through a migration, and extends TypeScript interfaces and seeders to include/document these fields; however, this logic is not yet used in application flows. <details> <summary><strong>Key Changes</strong></summary> • Added `monthly_actions_max` and `monthly_active_records_max` (default 1000 and 5000 on 'free', null for others) to all plan definitions • Introduced a migration that adds `monthly_actions_max` and `monthly_active_records_max` columns to the 'plans' table (with defaults) • Updated the DBPlan TypeScript interface and seeder utility to include/document the new fields </details> <details> <summary><strong>Affected Areas</strong></summary> • Plan definitions (packages/shared/lib/services/plans/definitions.ts) • Database schema and migrations • TypeScript DBPlan interface (packages/types/lib/plans/db.ts) • Test plan seeder </details> *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat: usage table migration (#4342) <!-- Describe the problem and your solution --> Separating the migration into a different PR for simpler regression <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This PR introduces a new Knex migration creating an 'accounts_usage' table to track monthly usage statistics per account, including unique constraints to prevent duplicate records. It also adds TypeScript interfaces for usage DTOs and DB representations, and exports these types for broader use across the codebase. <details> <summary><strong>Key Changes</strong></summary> • Created 'accounts_usage' table with fields: id, account_id (FK), month, actions, active_records, created_at, updated_at • Added unique constraint on (account_id, month) for data integrity • Added TypeScript types: DBAccountUsage, CreateAccountUsageDto, UpdateAccountUsageDto • Exported new usage types in types index </details> <details> <summary><strong>Affected Areas</strong></summary> • Database migrations (accounts_usage table) • TypeScript type definitions (usage/dto.ts, usage/db.ts) • Type exports (types/lib/index.ts) </details> *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
fix(endUser): add free-form tagging (#4395) ## Changes Fixes https://linear.app/nango/issue/NAN-3701/add-metadata-to-end-users - Add free-form tagging This will allow customers to store whatever they want in a simpler format. Ultimately, this will probably kill orgId that's not working for a lot of our customers. The column is used but not advertised yet, the goal is to first rework the way we upsert endUser before making that accessible (see main linear issue) <!-- Summary by @propel-code-bot --> --- **Add Free-Form Metadata/Tags Support to End Users and Docs** This PR introduces a new free-form `tags` (metadata) field to the end user model, including database schema changes, API validation, and related documentation updates. The addition enables storing arbitrary key-value metadata for end users, intended to ultimately replace the non-functional orgId approach. Changes also include a new database migration, controller schema updates, and numerous documentation corrections involving formatting and improved clarity. <details> <summary><strong>Key Changes</strong></summary> • Database migration adds a `tags` (``JSON``) column to the ``end_users`` table. • ``API`` controller (``postSessions`.ts`): request body schema expanded to support `tags` (as Record<string, string> with up to 64 keys) for end users. • Relevant ``API`` validation logic updated to validate the new tags field. • Documentation across many `.mdx` files corrected to improve formatting (newline/spacing) and minor copy, especially in integration setup guides. • No other business logic or service function changes outside validation and schema. </details> <details> <summary><strong>Affected Areas</strong></summary> • Database schema (`end_users` table - new tags ``JSON`` column) • ``API``: Connect Session body validation/schema (`postSessions`.ts) • ``API`` docs and integration guides for many providers (formatting and copy) • Migration scripts (new migration file) </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
fix(plans): add webhooks flags (#4374) ## Changes - Add webhooks flags not used <!-- Summary by @propel-code-bot --> --- This PR introduces two new feature flags, has_webhooks_script and has_webhooks_forward, to the plan definitions. The changes propagate these flags through type definitions, the plan seeder utility, and database schema via a migration. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat(providers): add migrations for pre-provisioning provider credentials (#4389) ## Describe the problem and your solution - This PR introduces the initial database migrations and types required to support pre-provisioning of provider credentials. <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This PR implements the foundational support for pre-provisioning provider credentials by introducing a new `providers_shared_credentials` table with a unique constraint, JSON credential storage, and proper timestamping. It extends the `_nango_configs` integration configs table and related TypeScript types with an optional, indexed `shared_credentials_id` foreign key, ensuring integration configs can now reference shared credentials. The changes are thoroughly propagated through the service layer, controller logic, seeder utilities, and all relevant test suites, defaulting the new linkage field to `null` (not yet exposed via outward APIs). <details> <summary><strong>Key Changes</strong></summary> • Adds `providers_shared_credentials` table with unique `name`, JSON credentials, indexed PK, and enforced constraints. • Extends `_nango_configs` with nullable, FK-indexed `shared_credentials_id` for referencing shared credentials. • Propagates new shared credentials field to all relevant TypeScript types (IntegrationConfig, Provider), DB models, and interfaces. • Updates service logic, seeder helpers, and endpoints to set and handle `shared_credentials_id` (defaults to null). • Amends and validates all affected test suites to ensure the field is present in integration config objects. • Adjusts API DTOs to explicitly omit `shared_credentials_id`, keeping internal field hidden from public responses. </details> <details> <summary><strong>Affected Areas</strong></summary> • Database schema and migrations • Integration config models and types (shared, provider, DB) • Integration config service layer and controllers • Seeder utilities • Persist, webhook, and config service tests • API response shaping/types </details> *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat(providers): add migrations for pre-provisioning provider credentials (#4389) ## Describe the problem and your solution - This PR introduces the initial database migrations and types required to support pre-provisioning of provider credentials. <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This PR implements the foundational support for pre-provisioning provider credentials by introducing a new `providers_shared_credentials` table with a unique constraint, JSON credential storage, and proper timestamping. It extends the `_nango_configs` integration configs table and related TypeScript types with an optional, indexed `shared_credentials_id` foreign key, ensuring integration configs can now reference shared credentials. The changes are thoroughly propagated through the service layer, controller logic, seeder utilities, and all relevant test suites, defaulting the new linkage field to `null` (not yet exposed via outward APIs). <details> <summary><strong>Key Changes</strong></summary> • Adds `providers_shared_credentials` table with unique `name`, JSON credentials, indexed PK, and enforced constraints. • Extends `_nango_configs` with nullable, FK-indexed `shared_credentials_id` for referencing shared credentials. • Propagates new shared credentials field to all relevant TypeScript types (IntegrationConfig, Provider), DB models, and interfaces. • Updates service logic, seeder helpers, and endpoints to set and handle `shared_credentials_id` (defaults to null). • Amends and validates all affected test suites to ensure the field is present in integration config objects. • Adjusts API DTOs to explicitly omit `shared_credentials_id`, keeping internal field hidden from public responses. </details> <details> <summary><strong>Affected Areas</strong></summary> • Database schema and migrations • Integration config models and types (shared, provider, DB) • Integration config service layer and controllers • Seeder utilities • Persist, webhook, and config service tests • API response shaping/types </details> *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat(db): connect_sessions overrides (#4426) Review https://github.com/NangoHQ/nango/pull/4427 to understand this. Adds `overrides` column to `connect_sessions`. Isolated PR with migration. > Why not use `integration_config_defaults`? That's clearly meant to set defaults for fields that shouldn't be shown to the end-user, while `overrides` is for overriding settings. <!-- Summary by @propel-code-bot --> --- This pull request introduces two database schema migrations and associated code changes to support session-specific configuration overrides and a plan-level feature flag. Specifically, it adds an `overrides` (nullable JSONB) column to the `connect_sessions` table for per-session override storage, and a `can_override_docs_connect_url` (boolean, default false) column to the `plans` table to control plans' ability to override the connect URL. The plan type definition and related seeder utility are updated to include this new property, ensuring type safety and test coverage. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat(db): connect_sessions overrides (#4426) Review https://github.com/NangoHQ/nango/pull/4427 to understand this. Adds `overrides` column to `connect_sessions`. Isolated PR with migration. > Why not use `integration_config_defaults`? That's clearly meant to set defaults for fields that shouldn't be shown to the end-user, while `overrides` is for overriding settings. <!-- Summary by @propel-code-bot --> --- This pull request introduces two database schema migrations and associated code changes to support session-specific configuration overrides and a plan-level feature flag. Specifically, it adds an `overrides` (nullable JSONB) column to the `connect_sessions` table for per-session override storage, and a `can_override_docs_connect_url` (boolean, default false) column to the `plans` table to control plans' ability to override the connect URL. The plan type definition and related seeder utility are updated to include this new property, ensuring type safety and test coverage. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat(signup): add found us string to an account (#4475) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- **Add 'Found Us' Field to Account Signup Flow** This PR introduces a new 'found_us' field into the account creation and signup process. Changes span the database schema, web UI, backend API, business logic, related TypeScript types, and associated tests to consistently handle, store, validate, and expose this additional signup information. <details> <summary><strong>Key Changes</strong></summary> • Database migration adds a nullable text ``found_us`` column to the _nango_accounts table. • Signup web form (`SignupForm`.tsx) updated with a required input for `How did you hear about Nango?`. • Backend signup ``API`` now accepts, validates, and persists ``foundUs``. • Account creation service modified to accept and store the new field. • `TypeScript` types for both ``API`` and database models updated to include the new field. • Integration, unit, and seeder tests updated to handle and assert the presence of ``found_us``. </details> <details> <summary><strong>Affected Areas</strong></summary> • Database schema (accounts table) • Web ``UI`` (signup form) • ``API`` endpoint for account signup • Account service logic • `TypeScript` types (``API`` and `DBTeam`) • Integration/unit/seed data tests </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat: getting started table migration (#4487) Creating 2 new tables for the new Getting Started flow: - `getting_started_meta` (1 per account) used to store the environment and integration that the account will use for the getting started flow. Necessary because each account needs one integration, and every user going through the getting started will go through the same one. - `getting_started_progress` (1 per user) used to store user specific progress on the getting started flow, and the connection he created within the getting started. > I am aware of `onboarding_progress`, and it is pretty similar to what I needed, but I decided to avoid fixing up existing things and going from scratch. Will come back to delete `onboarding` left-overs later. <!-- Summary by @propel-code-bot --> --- **Add Two New Tables and Types for 'Getting Started' Onboarding Flow** This PR establishes the foundational database structures and corresponding TypeScript types to support a new 'Getting Started' onboarding flow distinct from the existing onboarding logic. It introduces two new tables: `getting_started_meta` (to record the integration and environment an account uses for onboarding) and `getting_started_progress` (to track each user's progress and created connections during the flow). These changes set the stage for a more structured and account-customized onboarding experience, ensuring clear separation of global (per-account) and user-specific data. <details> <summary><strong>Key Changes</strong></summary> • Created migration for ``getting_started_meta`` table: stores one record per account with references to environment and integration; enforces uniqueness on ``account_id``. • Created migration for ``getting_started_progress`` table: stores individual user progress with references to users, the account meta record, and optionally a connection; ensures one progress row per user; includes step tracking. • Established foreign key constraints with ``ON`` ``DELETE`` ``CASCADE`` and ``SET`` ``NULL`` semantics for relevant relationships. • Added corresponding `TypeScript` interfaces (`DBGettingStartedMeta`, `DBGettingStartedProgress`) to represent these tables in code. • Removed the obsolete `complete` property from onboarding progress type. • Migration and type definitions are isolated to avoid disturbing legacy onboarding structures (per author intent). </details> <details> <summary><strong>Affected Areas</strong></summary> • Database schema: new migration files for onboarding tables • `TypeScript` type definitions in `packages/types/lib/`gettingStarted`/db.ts` </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat: getting started table migration (#4487) Creating 2 new tables for the new Getting Started flow: - `getting_started_meta` (1 per account) used to store the environment and integration that the account will use for the getting started flow. Necessary because each account needs one integration, and every user going through the getting started will go through the same one. - `getting_started_progress` (1 per user) used to store user specific progress on the getting started flow, and the connection he created within the getting started. > I am aware of `onboarding_progress`, and it is pretty similar to what I needed, but I decided to avoid fixing up existing things and going from scratch. Will come back to delete `onboarding` left-overs later. <!-- Summary by @propel-code-bot --> --- **Add Two New Tables and Types for 'Getting Started' Onboarding Flow** This PR establishes the foundational database structures and corresponding TypeScript types to support a new 'Getting Started' onboarding flow distinct from the existing onboarding logic. It introduces two new tables: `getting_started_meta` (to record the integration and environment an account uses for onboarding) and `getting_started_progress` (to track each user's progress and created connections during the flow). These changes set the stage for a more structured and account-customized onboarding experience, ensuring clear separation of global (per-account) and user-specific data. <details> <summary><strong>Key Changes</strong></summary> • Created migration for ``getting_started_meta`` table: stores one record per account with references to environment and integration; enforces uniqueness on ``account_id``. • Created migration for ``getting_started_progress`` table: stores individual user progress with references to users, the account meta record, and optionally a connection; ensures one progress row per user; includes step tracking. • Established foreign key constraints with ``ON`` ``DELETE`` ``CASCADE`` and ``SET`` ``NULL`` semantics for relevant relationships. • Added corresponding `TypeScript` interfaces (`DBGettingStartedMeta`, `DBGettingStartedProgress`) to represent these tables in code. • Removed the obsolete `complete` property from onboarding progress type. • Migration and type definitions are isolated to avoid disturbing legacy onboarding structures (per author intent). </details> <details> <summary><strong>Affected Areas</strong></summary> • Database schema: new migration files for onboarding tables • `TypeScript` type definitions in `packages/types/lib/`gettingStarted`/db.ts` </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
fix(db): drop deleted columns (#4519) ## Changes Fixes https://linear.app/nango/issue/NAN-2904/drop-jobs-column-deleted - drop deleted columns It's been 6months <!-- Summary by @propel-code-bot --> --- This PR introduces a database migration to drop the 'deleted' and 'deleted_at' columns from the '_nango_sync_jobs' table. The columns have been unused for six months, and their removal is tracked in Linear issue NAN-2904. The migration includes an 'up' script to drop the fields, but the 'down' migration is intentionally left empty. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat: getting started closed state (#4525) I was removing all references to `onboarding` and I realized we still depend on it's `completed` state to handle the ability to "close" the getting started in the UI, which is a detail I've missed. <img width="242" height="57" alt="image" src="https://github.com/user-attachments/assets/ec95820d-3e63-40f5-8db8-1d30178ba962" /> So I'm adding a `closed` state to the progress. Chose `closed` because going through all the getting started steps won't trigger it automatically. It will only be hidden if the user explicitly closes it by clicking the little `x` button. Next PR will remove everything related to the old `onboarding`. <!-- Summary by @propel-code-bot --> --- **Add Explicit 'Closed' State for Getting Started UI Flow** This PR replaces the use of the legacy 'onboardingComplete' logic with a dedicated 'closed' boolean state for the Getting Started user flow. The new 'closed' state allows the Getting Started feature to be dismissed only by explicit user action (e.g., clicking the close 'x'), and no longer depends on completion of all onboarding steps. The change involves database schema updates, backend API adjustments, new and modified TypeScript types, webapp UI and logic changes, and updates to tests and data contracts to consistently utilize the new 'closed' property throughout the stack. <details> <summary><strong>Key Changes</strong></summary> • Introduces a migration adding a `closed` ``BOOLEAN`` ``NOT`` ``NULL`` ``DEFAULT`` ``FALSE`` column to the ``getting_started_progress`` table. • Extends backend logic and `TypeScript` types (``DTO``, ``DB`` types) to include the new `closed` property. • Updates backend ``GET``/``PATCH`` endpoints for Getting Started to support reading and writing the `closed` flag. • Refactors Meta ``API`` and client-side data structures to expose ``gettingStartedClosed`` instead of ``onboardingComplete``. • Updates frontend webapp logic (sidebar menu, root redirect) to use ``gettingStartedClosed`` for controlling Getting Started visibility and behavior. • Replaces legacy onboarding code paths with logic built around the new `closed` state. • Modifies and extends relevant tests to verify correct handling of the new `closed` property and overall endpoint behavior. </details> <details> <summary><strong>Affected Areas</strong></summary> • Database schema/migrations • Backend controllers/handlers for getting started and meta (``API`` v1) • Backend & shared `TypeScript` types (db, `DTOs`, ``API`` contracts) • Getting started service functions • Frontend React webapp navigation and components • Integration and unit test suites for getting started endpoints </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
chore: remove `onboarding_demo_progress` and it's references (#4526) This has now been replaced by `getting_started_progress`. Since we switched, it does mean that users that have already gone through the getting started will initially have the getting started being visible again. <!-- Summary by @propel-code-bot --> --- **Remove Deprecated Onboarding Demo Progress and Its References** This PR comprehensively removes the deprecated `onboarding_demo_progress` functionality from the codebase, now fully superseded by `getting_started_progress`. All backend, shared, and frontend code related to the old onboarding progress feature is deleted, including API endpoints, services, database models, types, and associated frontend hooks. A database migration is included to drop the obsolete `_nango_onboarding_demo_progress` table. The changes update the type exports and API endpoint lists to ensure `onboarding_demo_progress` is no longer referenced anywhere in the system. <details> <summary><strong>Key Changes</strong></summary> • Deleted backend controller (``patchOnboarding`.ts`) and service (`onboarding.service.ts`) handling onboarding demo progress. • Removed `TypeScript` types, model definitions, and ``API`` endpoint specifications for onboarding demo. • Dropped `_nango_onboarding_demo_progress` database table via new migration. • Deleted frontend onboarding hook (``useOnboarding`.tsx`) related to the old flow. • Updated routing (`routes.private.ts`) and ``API`` endpoint definitions to remove onboarding endpoints. • Removed onboarding demo type exports from shared and types packages. </details> <details> <summary><strong>Affected Areas</strong></summary> • Backend controllers and routing • Shared services and `TypeScript` types • Frontend onboarding hooks • Database schema and migration scripts • ``API`` endpoint/type definitions and exports </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
fix: incorrect migration name (#4551) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This pull request corrects an incorrect migration file name within the database migrations folder. No code or logic within the migration was changed; only the filename was updated to conform to expected conventions. *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat(connect): stop normalizing endUser (#4564) ## Changes Fixes https://linear.app/nango/issue/NAN-3747/remove-normalization-of-userorg-id > [!NOTE] > This is a proposal. I have struggled more than anticipated, and I'm not satisfied with the current result. But the only other alternatives are even more unsatisfying - Connect: stop normalizing endUser **Before**, we were creating an end user directly when requesting a Connect Session. Most of the time the `endUser` would already be known, ending up just updating some values. So if a connect session end up not being used, there would be very little churn. **After**, if we create an end user directly, we will end up with thousands and thousands of unused rows in the DB. > I have decided not to do it because that would require an immediate need for a new cron to clean up the data. > NB: we do have churn right now, but less intense --- In an ideal world, `endUser` is now just a column in `connections`, there is no reason to have a dedicated table anymore, and it would simplify operations a lot. > I have also decided not to do that, because that would require modifying a lot of code depending/updating/creating connections. --- **So I took an intermediate step:** - Add a column endUser to `connect_sessions`, this allows us to store the future endUser - When we create a connection, we store the `endUser` - When we update a connection, we update the `endUser` <!-- Summary by @propel-code-bot --> --- **Refactor Connect Session: Defer End User Normalization** This PR changes how end-user data is handled in the Connect (OAuth) flow by deferring normalization (database insertion/update) until a connection is actually established or updated, rather than at Connect Session creation. The end-user payload is now stored as a JSON column on the `connect_sessions` table (added via migration), reducing unnecessary database churn and large numbers of unused end user rows. All controller logic, service functions, and TypeScript types related to Connect Sessions and end users have been updated accordingly, and a broad set of test cases and endpoint handlers are refactored to support this new approach. <details> <summary><strong>Key Changes</strong></summary> • Introduced a new ``end_user`` ``JSON`` column to the ``connect_sessions`` table via migration. • Connect Session creation now stores the end user payload as ``JSON``; no end user is created in the database at this stage. • Normalization (creation/update) of the end user occurs only when a connection is created or updated. • Refactored service, controller, and middleware logic to accommodate in-memory payload and defer ``DB`` writes. • Updated all relevant `TypeScript` types and interface contracts for Connect Sessions and end users. • Rewrote/adjusted relevant integration and unit tests to match the new lifecycle. • Refactored downstream flows to propagate new end user format, and updated ``API``: connect/reconnect, patch, `OAuth`, etc. </details> <details> <summary><strong>Affected Areas</strong></summary> • Connect Session and `EndUser` service logic • Database schema (migrations) for `connect_sessions` • Controllers related to all Connect flows (`getSession`, `postSession`, reconnect, `OAuth` flows, etc.) • Type definitions in @nangohq/types (`ConnectSession`, `EndUser`, `InternalEndUser`) • Middleware and Express request/response typings • Integration and unit tests for Connect Sessions and end user handling </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat: connect ui settings migration (#4574) Isolated PR with migrations for ConnectUI settings. Feature PR: https://github.com/NangoHQ/nango/pull/4575 <!-- Summary by @propel-code-bot --> --- **Infrastructure for Connect UI Settings and Feature Flag Migrations** This pull request introduces foundational backend infrastructure to support Connect UI customization by adding new database migrations, plan-level feature flags, and associated TypeScript type definitions. The changes create a new 'connect_ui_settings' table for environment-specific UI settings (including theming and watermark controls), extend the 'plans' table and seed logic to include booleans for UI theme and watermark control, and aggregate related types for broader usage. No direct API endpoints or UI features are introduced in this PR; the focus is solely on schema, type, and plan groundwork for future development. <details> <summary><strong>Key Changes</strong></summary> • Add migration to create ``connect_ui_settings`` table with fields for `environment_id`, theme (``JSON``), and `show_watermark` (boolean). • Add migration to extend `plans` table with ``can_customize_connect_ui_theme`` and ``can_disable_connect_ui_watermark`` boolean columns. • Update plan definitions (current and legacy) to set values for the new feature flags. • Update plan seeder to assign defaults for new plan fields. • Introduce `TypeScript` `DTOs` and ``DB`` interfaces for Connect ``UI`` settings and themes. • Aggregate new Connect ``UI`` types into main types index for cross-package compatibility. </details> <details> <summary><strong>Affected Areas</strong></summary> • Database schema (migrations for `connect_ui_settings` and plans tables) • Plan definition files • Plan seeder • `TypeScript` type definitions (``DTO``/db) • Type export aggregation (types/lib/index.ts) </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat: connect ui settings migration (#4574) Isolated PR with migrations for ConnectUI settings. Feature PR: https://github.com/NangoHQ/nango/pull/4575 <!-- Summary by @propel-code-bot --> --- **Infrastructure for Connect UI Settings and Feature Flag Migrations** This pull request introduces foundational backend infrastructure to support Connect UI customization by adding new database migrations, plan-level feature flags, and associated TypeScript type definitions. The changes create a new 'connect_ui_settings' table for environment-specific UI settings (including theming and watermark controls), extend the 'plans' table and seed logic to include booleans for UI theme and watermark control, and aggregate related types for broader usage. No direct API endpoints or UI features are introduced in this PR; the focus is solely on schema, type, and plan groundwork for future development. <details> <summary><strong>Key Changes</strong></summary> • Add migration to create ``connect_ui_settings`` table with fields for `environment_id`, theme (``JSON``), and `show_watermark` (boolean). • Add migration to extend `plans` table with ``can_customize_connect_ui_theme`` and ``can_disable_connect_ui_watermark`` boolean columns. • Update plan definitions (current and legacy) to set values for the new feature flags. • Update plan seeder to assign defaults for new plan fields. • Introduce `TypeScript` `DTOs` and ``DB`` interfaces for Connect ``UI`` settings and themes. • Aggregate new Connect ``UI`` types into main types index for cross-package compatibility. </details> <details> <summary><strong>Affected Areas</strong></summary> • Database schema (migrations for `connect_ui_settings` and plans tables) • Plan definition files • Plan seeder • `TypeScript` type definitions (``DTO``/db) • Type export aggregation (types/lib/index.ts) </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat(custom-validation-script): spec custom verification endpoints as a on events script (#4609) <!-- Describe the problem and your solution --> Add in a `validate-connection` on-event script that kicks off right after the connection is saved. If an error is thrown during the script then the connection errors out and is silently deleted and an auth error is returned during the auth process. <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- **Support 'validate-connection' Event Script for Custom Connection Validation** This PR introduces a new 'validate-connection' event script mechanism within the Nango platform. Integration developers can now define one or more scripts to run immediately after a connection is created, allowing for custom, programmatic validation of the newly established connection/credentials. If any 'validate-connection' script throws an error, the connection is considered invalid, a dedicated 'connection_validation_failed' error is returned (including surfaced failure details), and-if applicable-the connection is hard-deleted with no trace. The feature is implemented consistently across all supported auth modes (API Key, OAuth, Basic, JWT, Signature, App Store, Unauthenticated, Two-Step, TBA), and includes changes to backend controllers, configuration schema, developer experience, logs, error handling, docs, type system, migration logic, CLI/config validation, and UI surfaces. <details> <summary><strong>Key Changes</strong></summary> • Added support for `validate-connection` as an on-event script across all connection auth flows. • Validation scripts run synchronously post-connection creation; errors abort creation and may trigger a hard-delete. • Dedicated ``connection_validation_failed`` error response surfaced to ``API`` clients and displayed in developer logs/``UI``. • Backend controller refactors to inject validate-connection logic into all auth endpoints, with precise sequencing relative to connection insertion and error handling semantics. • Schema, `TypeScript`, and ``CLI``/schema tooling extended for the new event trigger, including migration for ``DB`` enum ``script_trigger_event``. • Documentation and code comment updates across ``YAML``/``JSON`` schema, developer docs, and code-level references. • Developer Connect ``UI`` updated to correctly surface custom validation error messages in the user interface. • Expanded integration and parser tests to accommodate the new trigger type and related config expansions. </details> <details> <summary><strong>Affected Areas</strong></summary> • Authentication backend controllers for all credential modes • On-event script management services, orchestrator, and execution paths • Configuration file parsing, ``CLI``, ``YAML``/``JSON`` schema definitions • Database: enumeration and on-event script migration (type addition) • Error handling, logging, and user-facing operation logs/``UI`` • Integration script `SDKs`/types and documentation • Integration test suites and config snapshots </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat: migration to add `default_theme` (dark/light/system) to `connect_ui_settings` (#4672) PR with migration and updates to satisfy build. Feature in next PR <!-- Summary by @propel-code-bot --> --- **Add `default_theme` (dark/light/system) to `connect_ui_settings` Schema & Services** This PR introduces a new non-nullable `default_theme` property with possible values `light`, `dark`, or `system` to the `connect_ui_settings` domain. The update includes a database schema migration, DTO and type definition extensions, validation schema updates, service method modifications, and expanded test coverage to ensure that the new property is correctly handled end-to-end. <details> <summary><strong>Key Changes</strong></summary> • Created migration `packages/database/lib/migrations/20250915224200_add_default-theme_to_connect-ui-settings.cjs` to add a `default_theme` enum column to the `connect_ui_settings` table (default: `system`). • Extended `ConnectUISettings` and `DBConnectUISettings` interfaces in `packages/types/lib/connectUISettings/dto.ts` and `db.ts` to include `defaultTheme`/`default_theme` properties, with a new `Theme` union type. • Updated `putConnectUISettings.ts` validation to require and strictly validate the `defaultTheme` property. • Modified `connect-ui-settings.service.ts` for correct read/write of the new property in the service layer. • Revised integration tests in `putConnectUISettings.integration.test.ts`, `getConnectUISettings.integration.test.ts`, and `getSession.integration.test.ts` to verify correct handling and validation of `defaultTheme`. </details> <details> <summary><strong>Affected Areas</strong></summary> • `connect_ui_settings` database table and migration logic • `ConnectUISettings` and `DBConnectUISettings` type definitions • `packages/shared/lib/services/connect-ui-settings.service.ts` • `packages/server/lib/controllers/v1/connectUISettings/putConnectUISettings.ts` (validation and write) • Integration and API test suites for `connect_ui_settings` handling </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat: migration to backfill connect-ui settings and flags (#4696) For new customers, the default flags will be applied on upgrade, but for existing customers, we need to backfill: Free plans: ok to show the watermark for past accounts. Can't toggle or edit colors. Starter: can toggle watermark (grandfathering, new customers won't) Growth: can toggle watermark and customize colors <!-- Summary by @propel-code-bot --> --- **Backfill Migration for `connect-ui` Settings and Flags by Customer Plan** This pull request introduces a new database migration (`20250918202800_backfill_connect_ui_settings.cjs`) to backfill `connect-ui` feature flags and settings for all existing customers based on their subscription plans. The migration updates the `plans` table to grant or restrict access to toggling watermarks and theme customization in line with current product rules (grandfathering specific features for legacy subscribers), and inserts default `connect_ui_settings` for all paying customer environments. The migration uses idempotent insertion logic to avoid duplicate key conflicts if rerun. <details> <summary><strong>Key Changes</strong></summary> • Added migration file `packages/database/lib/migrations/20250918202800_backfill_connect_ui_settings.cjs`. • Set `can_disable_connect_ui_watermark` to `true` for all non-`free` entries in `plans`. • Enabled `can_customize_connect_ui_theme` for `growth` and `growth-legacy` plans in the `plans` table. • Identified all environments for paying customers by joining `_nango_environments` and `plans`. • Backfilled `connect_ui_settings` with watermark disabled and default color themes for paying customers (inserts are idempotent via `.onConflict('environment_id').ignore()`). </details> <details> <summary><strong>Affected Areas</strong></summary> • `packages/database/lib/migrations/20250918202800_backfill_connect_ui_settings.cjs` • `plans` table • `connect_ui_settings` table • `_nango_environments` table (read/joins) </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
fix(endUsers): duplicate all relationships (#4712) ## Changes - duplicate all relationships Now that we have something working and people are actively using it, we need to duplicate all `endUsers` that were tied to multiple connections. I ran it locally and it worked. I would appreciate a test on your side, just in case ☺️ <!-- Summary by @propel-code-bot --> --- **Database Migration: One-to-One Mapping for `end_users` and `_nango_connections`** This PR introduces a one-way, irreversible database migration to normalize the relationship between the `end_users` and `_nango_connections` tables. Currently, a single `end_user` can be tied to multiple `_nango_connections`, creating a many-to-many mapping. The migration script iterates through all `end_users` associated with more than one `_nango_connections` record. For each such user, it creates a copy of the `end_user` for every additional connection and updates the corresponding `_nango_connections` to point to these new records. The migration runs non-transactionally, prioritizing simplicity over strict atomicity and is intended to be re-executed as needed. <details> <summary><strong>Key Changes</strong></summary> • Added migration script `packages/database/lib/migrations/20250922111100_end_users_dup.cjs` • Implemented `exports.up` function to duplicate `end_users` for each associated `_nango_connections` record beyond the first • Updated `_nango_connections` to point to newly created `end_users` • Set `exports.config = { transaction: false }`, disabling transaction wrapping for the migration • Provided an empty, non-functional `exports.down` (irreversible migration) • Removed batching timing/wait logic after review discussion </details> <details> <summary><strong>Affected Areas</strong></summary> • `packages/database/lib/migrations/20250922111100_end_users_dup.cjs` • `end_users` table • `_nango_connections` table </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
feat: Add subscription date to plan table (#4778) Desired behavior is: - Add subscription date on transition from free to paid. - Don't update date on upsells or downgrades (eg. starter to growth, growth to starter) - Don't delete date on downgrade to free <!-- Summary by @propel-code-bot --> --- **Add Subscription Date Tracking to Plan Table on Free → Paid Transitions** This pull request introduces the ability to record the date a team transitions from a free to a paid plan in the billing system. The migration adds the new `orb_subscribed_at` column to the `plans` table, updates relevant TypeScript models, and ensures this field is set only when moving from free to paid-never reset on upsell, downgrade, or return to free. The main plan-change logic is consolidated into a new `handlePlanChanged` function, which is now used across both Stripe and Orb webhook controllers to unify plan update handling and maintain consistent subscription date policies throughout the codebase. <details> <summary><strong>Key Changes</strong></summary> • Added new migration `20250930190000_add_subscription_date_to_plans.cjs` to introduce `orb_subscribed_at` nullable datetime column in the `plans` table • Updated TypeScript model `DBPlan` in `packages/types/lib/plans/db.ts` to include the new `orb_subscribed_at` property • Extended `planToApi` in `packages/server/lib/formatters/plan.ts` to serialize `orb_subscribed_at` to API consumers • Added logic in `handlePlanChanged` (in `packages/shared/lib/services/plans/plans.ts`) to set `orb_subscribed_at` only on transitions from free to paid plans, never on upsell, downgrade, or downgrade to free • Refactored both Orb and Stripe webhook controllers (`postWebhooks.ts`) to delegate plan change logic to the new shared `handlePlanChanged` function • Ensured seeds in `packages/shared/lib/seeders/plan.seeder.ts` initialize `orb_subscribed_at` to null • Removed direct plan mutation logic from controllers, improving maintainability </details> <details> <summary><strong>Affected Areas</strong></summary> • `plans` database table and migrations • `DBPlan` type definitions • `planToApi` formatter • Plan update logic and plan transition handling • Webhook controllers for Stripe and Orb • Plan data seeding </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
chore: add usage max columns to plans table (#4857) Values will be used to cap free account <!-- Summary by @propel-code-bot --> --- **Add Usage Cap Columns to `plans` Table for Free Account Limits** This pull request introduces a schema migration that augments the `plans` database table with six new nullable integer columns: `proxy_max`, `function_executions_max`, `function_compute_gbms_max`, `records_max`, `external_webhooks_max`, and `function_logs_max`. The migration also updates all plans named `free` to assign concrete cap values for these new columns, setting the groundwork for resource usage enforcement for free-tier users. <details> <summary><strong>Key Changes</strong></summary> • Added six new nullable integer columns to the `plans` table: `proxy_max`, `function_executions_max`, `function_compute_gbms_max`, `records_max`, `external_webhooks_max`, and `function_logs_max`. • Populated these columns with fixed caps for rows where `name = 'free'`. • Created migration file `packages/database/lib/migrations/20251014191600_plans_usagev2_columns.cjs` to implement schema and data updates. • Corrected a typo in the column name from `function_compute_gmbs_max` to `function_compute_gbms_max` in a follow-up commit. </details> <details> <summary><strong>Affected Areas</strong></summary> • `plans` table schema • Database migration logic in `packages/database/lib/migrations/20251014191600_plans_usagev2_columns.cjs` </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
chore: add plan.webhook_forwards_max column (#4871) I misunderstood one of the capping metric. `external_webhooks` should actually be `webhook_forwards`. Renaming the column in plan. Next PR will modify the code | 1 年前 | |
fix: rename webhook_forwards usage metric (#4872) follow-up of https://github.com/NangoHQ/nango/pull/4871 <!-- Summary by @propel-code-bot --> --- **Refactor Usage Metric Naming: Rename external_webhooks to webhook_forwards Across Codebase** This pull request standardizes the naming of the webhook usage metric across the codebase by renaming all references of `external_webhooks` (and `external_webhooks_max`) to `webhook_forwards` (and `webhook_forwards_max`). The changes cover backend business logic, API types, plan definitions, usage tracking, UI labeling, as well as modifying test and seeder data to match the new terminology. A new database migration is introduced to remove the obsolete `external_webhooks_max` column from the `plans` table, in alignment with the new metric naming convention. These changes continue the transition begun in the referenced prior PR (https://github.com/NangoHQ/nango/pull/4871) and aim to prevent confusion around webhook-related feature limits. <details> <summary><strong>Key Changes</strong></summary> • Renamed all code references of `external_webhooks` and `external_webhooks_max` to `webhook_forwards` and `webhook_forwards_max` in backend, frontend, types, plan seeding, and UI. • Inserted migration file `packages/database/lib/migrations/20251016193500_plans_remove_external_webhook_max_column.cjs` to drop the `external_webhooks_max` column from the `plans` database table. • Updated API response payloads, usage capping logic, metric tracking, and limits checks to use the new metric name. • Modified plan seeding in `packages/shared/lib/seeders/plan.seeder.ts` and plan definitions in `packages/shared/lib/services/plans/definitions.ts` to apply the new metric. • Adjusted UI labels and internal logic in `packages/server/lib/controllers/v1/plans/usage/getUsage.ts` to ensure user-facing consistency. • Revised usage metric typing, enums, and related logic in `packages/account-usage/lib/metrics.ts` and `packages/account-usage/lib/capping.ts`. • Updated webhook capping and tracking logic in `packages/server/lib/webhook/webhook.manager.ts` and `packages/jobs/lib/execution/webhook.ts`. </details> <details> <summary><strong>Affected Areas</strong></summary> • `packages/account-usage/lib/metrics.ts` • `packages/account-usage/lib/capping.ts` • `packages/metering/lib/processors/billing.ts` • `packages/server/lib/controllers/v1/plans/usage/getUsage.ts` • `packages/server/lib/webhook/webhook.manager.ts` • `packages/jobs/lib/execution/webhook.ts` • `packages/types/lib/plans/db.ts` • `packages/shared/lib/services/plans/definitions.ts` • `packages/shared/lib/seeders/plan.seeder.ts` • `packages/database/lib/migrations/20251016193500_plans_remove_external_webhook_max_column.cjs` </details> --- *This summary was automatically generated by @propel-code-bot* | 1 年前 | |
fix: remove legacy usage table (#4949) Code writing to this table has been remove in https://github.com/NangoHQ/nango/pull/4918 <!-- Summary by @propel-code-bot --> --- **Remove legacy `accounts_usage` table via migration** Adds a single database migration that drops the obsolete `accounts_usage` table. No other code changes are introduced, aligning with prior removal of all write paths to this table in PR #4918. <details> <summary><strong>Key Changes</strong></summary> • Added migration `packages/database/lib/migrations/20251031182500_drop_accounts_usage_table.cjs` with `exports.up` that executes `knex.schema.dropTableIfExists('accounts_usage')` • Sets `exports.config.transaction = false`, and leaves `exports.down` empty (non-reversible) </details> <details> <summary><strong>Affected Areas</strong></summary> • Database migration layer (`knex` migrations) </details> --- *This summary was automatically generated by @propel-code-bot* | 11 个月前 | |
fix: allow webhooks for free plans (#5007) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- **Enable webhooks for `free` plan** This PR lifts the webhook restrictions on the `free` pricing tier. It introduces one Knex migration that updates existing `plans` records and aligns the in-memory `freePlan` definition so that new accounts are provisioned with webhook capabilities. <details> <summary><strong>Key Changes</strong></summary> • Added migration `packages/database/lib/migrations/20251110180000_allow_webhooks_on_free_plans.cjs` to set `has_webhooks_script` and `has_webhooks_forward` to `true` where `name = 'free'` • Modified `packages/shared/lib/services/plans/definitions.ts` to set `freePlan.flags.has_webhooks_script` and `freePlan.flags.has_webhooks_forward` to `true` </details> <details> <summary><strong>Affected Areas</strong></summary> • `plans` table data • `packages/shared/lib/services/plans/definitions.ts` • Any logic that checks plan feature flags </details> --- *This summary was automatically generated by @propel-code-bot* | 11 个月前 | |
feat: switch getting started to Github (#4983) Switches getting started from google calendar to github. The script stars nango's repo. <!-- Summary by @propel-code-bot --> --- **Switch Getting-Started Demo from Google Calendar to Github** The onboarding demo has been re-oriented from posting a Google Calendar event to starring Nango’s Github repository. All backend, frontend, tests and seed data that referenced `google-calendar-getting-started` have been migrated to `github-getting-started`. A one-off migration resets existing onboarding metadata so users can rerun the flow with the new provider. <details> <summary><strong>Key Changes</strong></summary> • Frontend: Replaced Google-specific UI, icons and code snippets in `packages/webapp/src/pages/GettingStarted/*Step.tsx` to use Github endpoints (`/user/starred/nangohq/nango`) with `PUT` semantics • Backend service: Refactored `getOrCreateMeta()` and helpers in `packages/shared/lib/services/getting-started.service.ts` to create `github-getting-started` integrations via new helper `getOrCreateGithubIntegration()` • Controller update: `packages/server/lib/controllers/v1/gettingStarted/getGettingStarted.ts` and associated tests now reference Github provider and unique key • Shared credentials service (`shared-credentials.service.ts`): accepts optional `shared_credentials_name` and ensures correct lookup when creating pre-provisioned configs • DB migration `20251110180000_reset_getting_started_progress.cjs`: truncates `getting_started_meta` and `getting_started_progress` to discard Calendar data • Test & seeder updates across server and shared packages to align with new provider keys • Seed helper enhanced to pass `shared_credentials_name` and avoid collisions </details> <details> <summary><strong>Affected Areas</strong></summary> • `webapp` GettingStarted pages • `shared` getting-started service • `shared-credentials` service • REST controller `getGettingStarted` • Integration & unit tests • Database migration & seeders </details> --- *This summary was automatically generated by @propel-code-bot* | 11 个月前 | |
feat(lambda): lambda runtime for function execution (#4998) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- **Add AWS Lambda Runtime and Multi-Fleet Orchestration for Function Execution** Introduces a Lambda-based execution path alongside the existing container runner, with a pluggable runtime selection layer driven by plan metadata and rules. Adds a dedicated `@nangohq/lambda-runner` package, extends fleet supervision to support multiple fleets and Lambda-specific node providers, and updates infrastructure (Redis, plans schema, deployment workflow) to support the new runtime while maintaining backward compatibility. <details> <summary><strong>Key Changes</strong></summary> • Adds Lambda runtime adapter, node provider, and handler (`packages/jobs/lib/runtime/lambda.adapter.ts`, `packages/jobs/lib/runner/lambda.ts`, `packages/lambda-runner/lib/index.ts`) for invoking AWS Lambda functions asynchronously with locking, heartbeat, and abort handling. • Introduces runtime orchestration layer (`packages/jobs/lib/runtime/runtimes.ts`, `packages/jobs/lib/runtime/runtimes.rules.ts`) that selects fleets based on JSON rules and per-plan runtime flags added via migration `20260108145100_add_function_runtime_flags.cjs` and plan schema updates. • Extends fleet management to support multiple fleets and Lambda nodes (new image verifiers, supervisor updates, `fleet_id` persistence, node provider API changes) and separates Redis usage into system/customer boundaries with locking enhancements (`packages/kvstore/lib/index.ts`, `packages/kvstore/lib/Locking.ts`). • Adds new `@nangohq/lambda-runner` package with build pipeline (`Dockerfile.lambda`, tsconfig, schema validations) and updates CI/CD workflow to deploy Lambda images and invoke rollout API with image type. • Updates job execution paths (sync/action/webhook/on-event) to pass runtime context and use new runtime adapter, while ensuring abort propagation through Redis flags and Lambda heartbeat polling. </details> <details> <summary><strong>Affected Areas</strong></summary> • @nangohq/jobs runtime orchestration • @nangohq/fleet supervision and node models • @nangohq/kvstore locking and Redis clients • @nangohq/server fleet rollout API • @nangohq/utils environment parsing and detection • @nangohq/lambda-runner package and deployment workflow • Database schemas for plans and fleet nodes </details> --- *This summary was automatically generated by @propel-code-bot* --------- Co-authored-by: Bastien Beurier <bastienbeurier@gmail.com> Co-authored-by: Thomas Bonnin <233326+TBonnin@users.noreply.github.com> Co-authored-by: Guilherme Bassa <guilhermebassa@gmail.com> Co-authored-by: Daniel Gonzalez <167912055+gonzalde97@users.noreply.github.com> Co-authored-by: Khaliq <khaliq@nango.dev> Co-authored-by: Hassan_Wari <85742599+hassan254-prog@users.noreply.github.com> Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com> | 9 个月前 | |
fix: only create index if not exists (#5231) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- **Make connections index creation idempotent** Updates the migration that creates `idx_connections_env_createdat_not_deleted` so it only attempts to create the index when it does not already exist. This avoids migration failures caused by re-running the migration against databases where the index is present. <details> <summary><strong>Key Changes</strong></summary> • Adds `IF NOT EXISTS` to the `CREATE INDEX CONCURRENTLY` statement in `packages/database/lib/migrations/20260113104700_add_connections_created_at_index.cjs`. </details> <details> <summary><strong>Affected Areas</strong></summary> • `packages/database/lib/migrations/20260113104700_add_connections_created_at_index.cjs` </details> --- *This summary was automatically generated by @propel-code-bot* | 9 个月前 | |
fix(server): Fix constraints around large environment variables (#5259) <!-- Describe the problem and your solution --> Our API allowed for environment variables with keys up-to 256 characters, and values up-to 4000 characters. However, our DB only allowed 255 characters each. This introduces a migration and adds test to match what the API declared constraints. <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- It adds integration coverage at the controller and service layers to confirm that boundary-length payloads are accepted while invalid submissions are rejected, and updates the API type definition so the env query parameter is required. <details> <summary><strong>Affected Areas</strong></summary> • packages/database/lib/migrations/20260116165950_increase_environment_variables_column_sizes.cjs • packages/server/lib/controllers/v1/environment/variables/postVariables.integration.test.ts • packages/shared/lib/services/environment.service.integration.test.ts • packages/types/lib/environment/variable/api.ts </details> --- *This summary was automatically generated by @propel-code-bot* | 9 个月前 | |
feat(multi-api-secret): Create api_secrets table with 1:N relation to environments. (#5271) Every time an environment secret is created or modified, we also create or modify its mirror image in api_secrets. This means that for now, the relation remains 1:1. This lays the foundation for a transition away from a secret-environment correspondence, to a 1 environment N secrets model. In a second step, we will enable multiple keys per environment. <!-- Summary by @propel-code-bot --> --- **Introduce mirrored `api_secrets` store for environment keys** The PR adds an `api_secrets` table and wires environment secret lifecycle events to maintain a mirrored default secret per environment. Secret creation, rotation, activation, and database encryption flows now run transactional updates that keep `_nango_environments` and `api_secrets` in sync, with new helper methods in `encryption.manager` plus integration coverage validating the mirror stays current and decryptable. <details> <summary><strong>Key Changes</strong></summary> • Create migration `packages/database/lib/migrations/20260119161100_add_api_secrets_table.cjs` defining the `api_secrets` table, indexes, default backfill from `_nango_environments`, and cascading deletes. • Add `DBAPISecret` type and new helper methods `decryptAPISecret`, `upsertDefaultAPISecret`, and `getDefaultAPISecret` to `packages/shared/lib/utils/encryption.manager.ts`. • Wrap environment creation and secret activation in transactions that update `_nango_environments` and call `encryptionManager.upsertDefaultAPISecret` in `packages/shared/lib/services/environment.service.ts`. • Invoke `upsertDefaultAPISecret` during `encryptDatabase()` to keep mirrored secrets aligned when encryption gets enabled post-migration. • Extend integration tests in `packages/shared/lib/services/environment.service.integration.test.ts` to assert mirrored default secret hashing and decryptability before and after rotations. </details> <details> <summary><strong>Affected Areas</strong></summary> • packages/database/lib/migrations/20260119161100_add_api_secrets_table.cjs • packages/shared/lib/services/environment.service.ts • packages/shared/lib/utils/encryption.manager.ts • packages/shared/lib/services/environment.service.integration.test.ts • packages/types/lib/environment/db.ts </details> --- *This summary was automatically generated by @propel-code-bot* --------- Co-authored-by: propel-code-bot[bot] <203372662+propel-code-bot[bot]@users.noreply.github.com> | 9 个月前 | |
feat: Add new tags columns to connect and connect sessions (#5297) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- **Add `tags` JSONB columns with GIN indexes to connections tables** Adds a migration that introduces non-null `jsonb` `tags` columns to both `connect_sessions` and `_nango_connections`. The migration also creates GIN indexes on the new columns and drops them on rollback. <details> <summary><strong>Key Changes</strong></summary> • Adds `jsonb` `tags` column with default `'{}'` to `connect_sessions` • Adds `jsonb` `tags` column with default `'{}'` to `_nango_connections` • Creates concurrent GIN indexes on the new `tags` columns and drops them in `exports.down` </details> <details> <summary><strong>Affected Areas</strong></summary> • `packages/database/lib/migrations/20260120193001_connect_sessions_add_tags.cjs` </details> --- *This summary was automatically generated by @propel-code-bot* | 8 个月前 | |
feat(checkpoint): add checkpoint data model (#5316) It will be possible for customers to get/save checkpoint explicitely in function to allow customers to implement "incremental" syncs, track progress, etc... See inlined comments to discuss design decision. Note: code isn't wired anywhere yet. The goal of this PR is to validate the checkpoints data model <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- **Checkpoint persistence model and service layer** Adds a dedicated `checkpoints` persistence layer (migration, types, service helpers) so future function executions can save and resume progress per environment/connection/key with optimistic locking semantics. Includes comprehensive validation plus unit and integration coverage, but the tables/services are not yet wired into runtime flows. <details> <summary><strong>Key Changes</strong></summary> • Created migration `packages/database/lib/migrations/20260127120000_create_checkpoints_table.cjs` for the `checkpoints` table with `(environment_id, connection_id, key)` uniqueness, soft-delete support, version counter, and a concurrent `varchar_pattern_ops` index to accelerate prefix cleanup queries. • Defined checkpoint type contracts in `packages/types/lib/checkpoint/db.ts` and re-exported them so other packages can consume `Checkpoint`, `CheckpointValue`, and `DBCheckpoint`. • Implemented `validateCheckpoint`, `getCheckpoint`, `upsertCheckpoint`, `deleteCheckpoint`, and `hardDeleteCheckpoints` in `packages/shared/lib/services/checkpoints/checkpoints.ts`, enforcing flat payloads, size limits, and optimistic locking/versioning. • Added extensive unit tests for validation rules plus integration tests covering upsert/update/resurrection, soft delete, hard delete (with prefix + escaping), and database interactions. • Re-exported the checkpoint service via `packages/shared/lib/index.ts` to make the helpers available to other modules. </details> <details> <summary><strong>Affected Areas</strong></summary> • `checkpoints` database table and migration • `packages/shared/lib/services/checkpoints` service + tests • `packages/types` exports • `@nangohq/shared` public surface area </details> --- *This summary was automatically generated by @propel-code-bot* | 8 个月前 | |
feat(tags): Add backfill script/migration for end user tags -> connection tags (#5342) <!-- Describe the problem and your solution --> This query will update `114 282` rows in production. I will run it asynchronously using the migrate script in our cloud, and let knex automatically migrate connections for on-prem/self-hosted deployments. There are a few assumptions in this query to make it simpler, but I did run the queries in prod DB to verify we don't have to care about them - It doesn't truncate keys longer than 64 characters or values longer than 250 characters (which would be invalid new tags) because there are no existing keys or values that long - It doesn't validate that it won't create more than 10 tags because there are no end users with that many (max is 4) - It doesn't validate invalid key format because all existing end user tags are valid <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- **Backfill connection tags and harden tag sanitization** Introduces a reusable SQL CTE pipeline and operational tooling to backfill `_nango_connections.tags` from existing end-user metadata while aligning runtime tag generation with the same constraints. Adds a non-transactional Knex migration, an operational `migrate.ts` runner with optional migration marking, a local seeding helper, and an end-to-end integration test that exercises truncation, invalid keys, tag precedence, and connections lacking end users. Updates `buildTagsFromEndUser` to normalize keys/values, enforce length/count limits, emit structured telemetry about dropped or truncated tags, and fall back to base tags when custom data is invalid so online ingestion matches the migration behavior. <details> <summary><strong>Key Changes</strong></summary> • Added SQL helper `packages/database/lib/migration-helpers/backfillConnectionTagsSql.cjs` that normalizes base tags, sanitizes end-user tag entries, enforces 10-key limits, merges with existing connection tags, and returns summary metrics for operational visibility. • Registered non-transactional migration `packages/database/lib/migrations/20260128120000_backfill_connection_tags.cjs` plus `scripts/one-off/connection-tags-migration/migrate.ts` (with `--mark-migration`) and companion README/seed tooling for cloud and self-hosted deployments. • Created integration test `packages/database/lib/backfillConnectionTags.integration.test.ts` with inline seed helpers covering special characters, precedence, truncation, invalid formats, over-limit keys, and connections lacking end users. • Expanded `packages/shared/lib/services/endUser.service.ts` to truncate/validate tags, log structured telemetry, drop custom tags when exceeding limits, and fall back gracefully if custom tags fail schema validation, updating unit tests accordingly. </details> <details> <summary><strong>Affected Areas</strong></summary> • `packages/database/lib/migration-helpers/backfillConnectionTagsSql.cjs` • `packages/database/lib/migrations/20260128120000_backfill_connection_tags.cjs` • `scripts/one-off/connection-tags-migration/*` • `packages/database/lib/backfillConnectionTags.integration.test.ts` • `packages/shared/lib/services/endUser.service.ts` and unit tests </details> --- *This summary was automatically generated by @propel-code-bot* | 8 个月前 | |
feat: add has_records_autopruning to plans table (#5388) We need to be able to disable records autopruning for specific customers. This commit is adding a `has_records_autopruning` column (default true) to the plans table. It won't be exposed to customers. It is for us to be able to control it and disable autopruning for very specific reasons. I thought about having a autopruning threshold duration column so we can set different duration for different customers but it would make the background processing much less efficient. It is currently looking at the records table directly, fetching candidates for pruning based on the records updated_at. Having a dynamic value to evaluate records staleness would make the entire process slower and more complicated. So for now the setting is a on/off switch since we don't need more than that. <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- The migration executes within a transaction but currently provides no rollback implementation, so reverting this schema change would require a separate follow-up. <details> <summary><strong>Affected Areas</strong></summary> • `packages/database/lib/migrations/20260204173100_plan_disable_records_autopruning.cjs` </details> --- *This summary was automatically generated by @propel-code-bot* | 8 个月前 | |
feat: migration to remove the unique name constraint from `providers_shared` (#5387) ## Describe the problem and your solution - Migration to remove the unique name constraint from providers_shared. We now want to allow multiple credentials per provider to support credential rotation in cases where we hit limits. <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- The migration specifically drops the auto-generated providers_shared_credentials_name_key constraint via a non-transactional run and omits a rollback implementation, so reinstating the uniqueness check would require a follow-up migration. <details> <summary><strong>Affected Areas</strong></summary> • `packages/database/lib/migrations/20260204200310_remove_providers_shared_credentials_name_unique.cjs` </details> --- *This summary was automatically generated by @propel-code-bot* | 8 个月前 | |
feat(migrations): Increase `oauth_client_id` size limit (#5573) ## Describe the problem and your solution - Increase `oauth_client_id` size limit to `512`. <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- This adds a database migration that expands the `_nango_configs.oauth_client_id` column to a longer length and includes a reversible down migration back to 255 characters, configured to run without a transaction and using `alterType` for the schema change. <details> <summary><strong>Possible Issues</strong></summary> • Down migration may truncate or fail if existing `oauth_client_id` values exceed 255 characters. </details> --- *This summary was automatically generated by @propel-code-bot* | 7 个月前 | |
feat(db): migrate Slack connection IDs from env name to env id (#5564) <!-- Describe the problem and your solution --> Adds a knex migration that rewrites Slack notification connection IDs in the admin account from the legacy `account-{uuid}-{envName}` format to the new `account-{uuid}-{envId}` format, scoped to environments with `slack_notifications = true`. Includes a preview SQL helper to capture before/after state for manual rollback (the knex down is a no-op since new and migrated connections are indistinguishable after the dual-lookup deploy). ⚠️ This one has to be merged first !!! https://github.com/NangoHQ/nango/pull/5559 <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- The migration is scoped to admin environments via NANGO_ADMIN_UUID and excludes deleted connections, runs within a transaction with logging of updated row counts, and also adds a SQL helper plus an integration test to validate targeted and non-targeted cases. <details> <summary><strong>Possible Issues</strong></summary> • Comment in `packages/database/lib/migration-helpers/migrateSlackConnectionIdSql.cjs` mentions excluding numeric environment names, but the SQL does not implement this filter. </details> --- *This summary was automatically generated by @propel-code-bot* --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> | 7 个月前 | |
refactor(plans): nan 4966 enable sync variants and fast syncing for all accounts (#5608) <!-- Describe the problem and your solution --> Makes plan defaults less restrictive and migrates existing plans to new defaults. Restrictions no longer necessary with usage based pricing. <!-- Issue ticket number and link (if applicable) --> [NAN-4966: Enable sync variants and fast syncing for all accounts](https://linear.app/nango/issue/NAN-4966/enable-sync-variants-and-fast-syncing-for-all-accounts) <!-- Testing instructions (skip if just adding/editing providers) --> Add plan with to DB, run migration <!-- Summary by @propel-code-bot --> --- Specifically lowers the minimum sync frequency to 30 seconds for the free and starter tiers and adds a migration to update existing plan records whose minimum sync frequency is above 30 to match the new defaults. --- *This summary was automatically generated by @propel-code-bot* | 7 个月前 | |
feat: add variants_per_sync_max to plan (#5607) so we can bump the number of allowed variants per customer. The commit also get rid of `has_sync_variants` that can now be controlled by setting `variants_per_sync_max` to 0 in order to disable the feature. Note: we recently agree to open variants to all customers not just paying ones (ie: all get 100/sync by default) Migration to remove the has_sync_variants column will be done in followup PR <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- **Add `variants_per_sync_max` plan flag and enforce per-sync variant limits** This PR introduces a new `variants_per_sync_max` plan flag, adds a database column with a default of 100, and uses it to cap variants per sync in the `postSyncVariant` controller. It also removes the legacy `has_sync_variants` checks and references, relying on `variants_per_sync_max` (including `0` to disable) instead. --- *This summary was automatically generated by @propel-code-bot* | 7 个月前 | |
chore: drop plan has_sync_variants (#5609) its usage was remove in #5607 <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- **Drop `plans.has_sync_variants` column via migration** This PR adds a single Knex migration that drops the `has_sync_variants` column from the `plans` table. The migration runs inside a transaction and leaves the `down` migration empty, aligning with the stated intent to remove a previously unused field. --- *This summary was automatically generated by @propel-code-bot* | 7 个月前 | |
feat(database): add role column to users/invitations and is_production to environments (#5629) Add schema migrations for the permissions system (NAN-2184): - Add `role` column (VARCHAR(50), default 'administrator') to _nango_users - Add `role` column (VARCHAR(50), default 'administrator') to _nango_invited_users - Add `is_production` column (BOOLEAN, default false) to _nango_environments We will doing first this migration which should be a `noop` from the point of view of our application, once this one is in place we will follow up with the following changes - [PR](https://github.com/NangoHQ/nango/pull/5631) for add logic in our app for tagging all new created `prod` environments as `is_production` as `True` - [PR](https://github.com/NangoHQ/nango/pull/5632) for adding a new migration for updating all existing `prod` environments as `is_production` as `True` This will allow us to not have any dat race and keeping the all proper `prod` environments tagged as they should be After that we will proceed with more PRs for supporting the RBAC system <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- It also updates the environment service integration test expectations to include the new default value for `is_production`. --- *This summary was automatically generated by @propel-code-bot* --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> | 7 个月前 | |
feat(database): add role column to users/invitations and is_production to environments (#5629) Add schema migrations for the permissions system (NAN-2184): - Add `role` column (VARCHAR(50), default 'administrator') to _nango_users - Add `role` column (VARCHAR(50), default 'administrator') to _nango_invited_users - Add `is_production` column (BOOLEAN, default false) to _nango_environments We will doing first this migration which should be a `noop` from the point of view of our application, once this one is in place we will follow up with the following changes - [PR](https://github.com/NangoHQ/nango/pull/5631) for add logic in our app for tagging all new created `prod` environments as `is_production` as `True` - [PR](https://github.com/NangoHQ/nango/pull/5632) for adding a new migration for updating all existing `prod` environments as `is_production` as `True` This will allow us to not have any dat race and keeping the all proper `prod` environments tagged as they should be After that we will proceed with more PRs for supporting the RBAC system <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- It also updates the environment service integration test expectations to include the new default value for `is_production`. --- *This summary was automatically generated by @propel-code-bot* --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> | 7 个月前 | |
feat(database): add role column to users/invitations and is_production to environments (#5629) Add schema migrations for the permissions system (NAN-2184): - Add `role` column (VARCHAR(50), default 'administrator') to _nango_users - Add `role` column (VARCHAR(50), default 'administrator') to _nango_invited_users - Add `is_production` column (BOOLEAN, default false) to _nango_environments We will doing first this migration which should be a `noop` from the point of view of our application, once this one is in place we will follow up with the following changes - [PR](https://github.com/NangoHQ/nango/pull/5631) for add logic in our app for tagging all new created `prod` environments as `is_production` as `True` - [PR](https://github.com/NangoHQ/nango/pull/5632) for adding a new migration for updating all existing `prod` environments as `is_production` as `True` This will allow us to not have any dat race and keeping the all proper `prod` environments tagged as they should be After that we will proceed with more PRs for supporting the RBAC system <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- It also updates the environment service integration test expectations to include the new default value for `is_production`. --- *This summary was automatically generated by @propel-code-bot* --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> | 7 个月前 | |
feat: add features to sync config table (#5652) To be used in next PR to store features used by a given function. At first we'll only track use of checkpoints in function. <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- **Add `features` column to sync config table and relax related tests** This PR introduces a database migration that adds a non-null `text[]` `features` column with an empty array default to the `_nango_sync_configs` table. It also updates integration tests to use `toMatchObject` to tolerate the new column and removes explicit empty `properties` assertions in JSON schema expectations. --- *This summary was automatically generated by @propel-code-bot* | 7 个月前 | |
feat(database): backfill is_production for existing prod environments (#5632) Sets is_production = true for all existing environments named 'prod' that were created before the app logic change. This is the final step in the safe rollout sequence for the is_production column. Follow up PR of this [one](https://github.com/NangoHQ/nango/pull/5631). Set in draft for not having it merged until the previous one is <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- Adds a database migration that updates `_nango_environments` rows named `prod` that are currently not marked as production. --- *This summary was automatically generated by @propel-code-bot* --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> | 7 个月前 | |
fix(lambda): node routing overrides (#5649) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- Summary by @propel-code-bot --> --- **Add plan-level Lambda routing overrides and routing context propagation** This PR introduces plan-scoped Lambda routing overrides by adding a `fleet_node_routing_override` column on `plans` and propagating a new `RoutingContext` through job execution, runtime selection, and Lambda invocation. Routing IDs now use a configurable prefix plus a t‑shirt size derived from `LAMBDA_DEFAULT_MEMORY_MB`. It also moves Lambda defaults to environment-driven values, enforces AWS resource caps when creating Lambda functions, relaxes Lambda ARN validation to support custom prefixes, and updates plan typing, seed data, and unit tests to cover the new routing behavior. --- *This summary was automatically generated by @propel-code-bot* | 7 个月前 | |
feat: gate RBAC behind feature flag (#5864) Uses feature flag to gate RBAC. Allows roles to be set to the default ('administrator') but not to other roles. ~Also reverses roles on downgrade and applies default role on invites if RBAC is disabled at time of acceptance.~ When an account doesn't have RBAC permission checking is skipped. If they have users in roles different than 'administrator' they see a warning (screenshot 2). <img width="539" height="359" alt="image" src="https://github.com/user-attachments/assets/f0c8ee89-2326-403f-b3c0-4cd48df67205" /> <img width="1186" height="540" alt="image" src="https://github.com/user-attachments/assets/7ff3293d-abd6-44b4-86b8-45b85a4d6276" /> | 5 个月前 | |
fix(lambda): new plan flag to control lambda rollout (#5858) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> | 6 个月前 | |
feat(server): add remote function public API (#5836) <!-- Describe the problem and your solution --> Adds public /remote-function/compile, /remote-function/dryrun, and /remote-function/deploy endpoints with request validation, endpoint types, and E2B/local runtime clients for running Nango function code. This intentionally keeps the broader agent-session/internal sandbox prompting APIs and UI work out of this PR. <!-- Issue ticket number and link (if applicable) --> N/A <!-- Testing instructions (skip if just adding/editing providers) --> - npm run ts-build - npm run test:unit -- packages/server/lib/services/remote-function/compiler-client.unit.test.ts packages/server/lib/services/remote-function/shell.unit.test.ts - npm run test:integration -- packages/server/lib/controllers/functions/remote-function.integration.test.ts | 6 个月前 | |
feat: add and use `source` for tracking function source (#5899) Replacing `is_public` and `pre_built`, which are booleans used interchangeably (if you know the reason for `is_public` let me know, but as far as I've seen they always have the same value). > [!NOTE] > I'd like to split the migration from the logic but we need the values to be set correctly as soon as the column exists. > For safety, I'm keeping the migration for removing `is_public` and `pre_built` for a second stage | 5 个月前 | |
feat(nan-5088): API key permissions with scoped customer keys (#5911) Version 2 of the original branch https://github.com/NangoHQ/nango/pull/5822 for implementing the new API Key system, where we have added the fix for keep caching all hashed secret keys, also the internal ones (see this [commit](https://github.com/NangoHQ/nango/pull/5911/changes/883d3a90c608399c7069ff5dbf1800b0ba931967)) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> | 6 个月前 | |
feat(nan-5088): API key permissions with scoped customer keys (#5911) Version 2 of the original branch https://github.com/NangoHQ/nango/pull/5822 for implementing the new API Key system, where we have added the fix for keep caching all hashed secret keys, also the internal ones (see this [commit](https://github.com/NangoHQ/nango/pull/5911/changes/883d3a90c608399c7069ff5dbf1800b0ba931967)) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> | 6 个月前 | |
feat(lambda): isolation (#5961) Enable plan-gated Lambda tenant isolation (PER_TENANT) **Summary** - Adds a new plan attribute tenant_isolation (boolean, default false) with a DB migration. - When enabled, routes invocations to a dedicated Lambda fleet pool (routingId suffix -isolated) and creates AWS functions with distinct names (…-{nodeId}-isolated). - Creates isolated Lambdas with AWS TenancyConfig.TenantIsolationMode = PER_TENANT and passes TenantId on invoke as required by AWS tenant isolation. - Disables provisioned concurrency configuration for tenant-isolated Lambda nodes (not supported/assumed incompatible). **Key changes** - Plans - Migration: plans.tenant_isolation default false - Types/definitions/seeding updated to include the new flag mergeFlags treats tenant_isolation as a “sticky enable” flag on upgrade (downgrades reset to new plan defaults) - Routing & naming - Tenant-isolated routing uses -isolated suffix to ensure separate fleet pools - AWS function naming ensures isolated and non-isolated functions never collide - Lambda create/invoke - CreateFunction conditionally sets TenancyConfig for isolated pool - Invoke conditionally sets TenantId for isolated plan - Provisioned concurrency registration/cleanup is conditional (skipped for isolated pool) | 5 个月前 | |
chore: hard delete syncs and associated data after 1 day (#5993) follow-up of https://github.com/NangoHQ/nango/pull/5989 - migration to soft-delete existing syncs when sync config is disabled (or non existing) - hard delete syncs and associated data after 1 day. We currently don't delete syncs and its associated records when a sync config is disabled, causing the records to be billed. With this commit syncs (and records) will be hard deleted after one day as part of the old delete cron job so it is not done inline and prevent deleting data in case of misclick | 5 个月前 | |
chore: migration to drop unused columns replaced by `source` (#6110) This should only be merged after #6109 is released. <!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/NangoHQ/codesmith/nango/pr/6110"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-in-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-in-codesmith-light.svg"><img alt="View in Codesmith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-in-codesmith-dark.svg"></picture></a> <sup>Need help on this PR? Tag <code>@codesmith</code> with what you need.</sup> - [ ] Let Codesmith autofix CI failures and bot reviews <!-- /codesmith:footer --> | 5 个月前 | |
feat: use stateless sandbox tokens for remote functions (#6161) <!-- Describe the problem and your solution --> Adds stateless `nango_sbx_v1_` sandbox tokens for remote-function dryrun/deploy so sandboxes no longer receive the environment's long-lived internal secret. Tokens are signed with a server-only per-parent customer API key secret, inherit the current parent key scopes plus sandbox baseline scopes, and expire without storing child API keys. ## Sandbox token structure Sandbox tokens are prefixed compact JWTs: ```text nango_sbx_v1_<base64url(header)>.<base64url(payload)>.<base64url(signature)> ``` Header: ```json { "typ": "JWT", "alg": "HS256", "kid": "<parentCustomerKeyId>" } ``` Payload: ```json { "iat": 1710000000, "exp": 1710000300 } ``` Signature: - `HS256` over the compact JWT signing input. - Uses the parent customer API key's server-only `sandbox_signing_secret`. - `kid` is decoded before verification only to find the parent key and signing secret; the token is then verified with `jsonwebtoken.verify(..., { algorithms: ['HS256'] })`. - The payload intentionally only carries JWT time claims. The parent key context, environment, and scopes are derived server-side from `kid` after verification. <!-- Issue ticket number and link (if applicable) --> NAN-5445 <!-- Testing instructions (skip if just adding/editing providers) --> | 5 个月前 | |
feat(nan-5088): scopes remap — accept legacy and new scopes, expand existing keys (#6088) ## Summary Add new fine-grained API key scopes alongside the legacy ones. Routes accept either via `withAnyScope`, so existing keys with legacy scopes keep working. A migration adds the new scopes alongside the legacy ones on existing customer keys (idempotent). Legacy scopes are preserved on keys for rollback safety. Follow-up PRs will: - Remove route mappings for legacy scopes - Strip legacy scope strings from the `scopes` arrays via a final migration ## Scope mapping | Legacy | New | |---|---| | `environment:integrations:write` | `environment:integrations:create` / `update` / `delete` | | `environment:connections:write` | `environment:connections:create` / `update` / `delete` | | `environment:syncs:manage` | `environment:syncs:update` / `variant:create` / `variant:delete` | | `environment:config:read` (for `/environment-variables`) | `environment:variables:read` | | `environment:config:read` (for `/scripts/config`) | `environment:integrations:list_functions` | ## What's included - New scope strings in `@nangohq/types` and `@nangohq/utils` - Route mappings in `routes.public.ts` accept legacy + new via `withAnyScope` - Frontend scope picker shows only the new scopes — legacy scopes are hidden from the picker and excluded from the count column - `stripLegacyScopes` runs in the dashboard save handler so any explicit save on a migrated key drops the legacy entries from the payload (closes the transient window where the API would still authorize via the legacy scope after the user thought they revoked it) - Migration `20260428110800_expand_legacy_api_key_scopes.cjs` — thin wrapper around `expandLegacyApiKeyScopes(knex)` helper - 12 integration tests on the helper directly (no migration runner), break-verified - 38 unit tests on frontend scope-logic ## Rollout plan Three-step rollout designed so each step is independently rollback-safe: 1. **Backup the `customer_keys` table** before deploying this PR. Used as a safety net for the unlikely case that a save during step 1 strips legacy scopes from a key that needs to be rolled back. 2. **Deploy this PR.** Existing keys are expanded in-place (legacy + new scopes side by side). Any newly created key uses only the new scopes. Any save on a migrated key strips the legacy entries from the payload. 3. **Deploy follow-up [PR](https://github.com/NangoHQ/nango/pull/6099)** that removes legacy scope acceptance from public route mappings. After this, only the new scopes authorize requests. 4. **Deploy final PR** that strips legacy scope strings from the `scopes` arrays in the database (cleanup migration). ### Rollback Watch for an increase in `403 Forbidden` responses on the affected endpoints after each step. If one shows up: - After step 2: rollback is safe — legacy scopes are still in the DB on migrated keys, and the previous version of the app accepts them. - After step 3: rollback is safe — legacy scopes are still in the DB and step 3's previous version still accepts them. - After step 4: rollback requires restoring from the backup taken in step 1, since the legacy scope strings are no longer in the DB. Time the deploys with enough spacing (at least one business day) to give the 403 metric room to surface a regression before moving to the next step. ## Test plan - [x] Build passes - [x] 12 helper tests pass (`packages/database/lib/expandLegacyApiKeyScopes.integration.test.ts`) - [x] 38 frontend scope-logic unit tests pass - [x] 49 server scope enforcement integration tests pass (legacy keys still work) - [x] End-to-end manually verified locally: create key with legacy scopes on master → switch to PR branch → migration expands → save in dashboard strips legacy from DB 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> | 5 个月前 | |
feat(functions): Production versions of JIT function endpoints (#6214) ## Summary This PR adds the new public Functions API surface for compiling, deploying, and dry-running TypeScript function source code without requiring users to manage a local integration project layout. ### New function endpoints - `POST /functions/compile` - Accepts submitted TypeScript function code and returns bundled JavaScript plus bundle metadata. - Requires the new `environment:functions:compile` API key scope. - `POST /functions/deployments` - Deploys submitted TypeScript function code into an existing integration. - Uses a purpose-bound deploy sandbox token when the sandbox calls back into Nango. - `POST /functions/dryruns` - Starts an asynchronous dry run and returns `202` with an id, status, and `status_url`. - Uses the status values `waiting`, `running`, `success`, and `failed`. - `GET /functions/dryruns/{id}` - Returns the persisted dry run status, output, result, error, duration, and timeout metadata. - `POST /functions/dryruns/{id}/result` - Internal sandbox callback endpoint. - Only accepts purpose-bound sandbox tokens, not customer API keys. The older `/remote-function/*` endpoints remain in place for the existing synchronous compile/deploy/dryrun behavior while sharing the same underlying sandbox clients. ### Async dry run flow `POST /functions/dryruns` creates a `function_dryruns` row, creates a short-lived sandbox API token with dryrun purpose, and starts an E2B sandbox in the background. Inside the sandbox, Nango writes: - the submitted function code - optional input, metadata, checkpoint, and last sync date payloads - a generated Node callback script That callback script compiles the code, runs `nango dryrun`, and posts the final `success` or `failed` payload back to `/functions/dryruns/{id}/result`. The API stores the output/result/error and `GET /functions/dryruns/{id}` exposes the final state. A timeout cron marks stale dry runs as failed if the sandbox never calls back. ### Sandbox package reorganization This moves the sandbox-related business logic out of `server` and `shared` into a new top-level `@nangohq/sandbox` package: - E2B sandbox creation and error mapping - local Docker fallback clients - compile/deploy/dryrun command construction and output parsing - remote function runtime helpers - purpose-bound sandbox API key creation/verification - function dryrun persistence helpers The server package now mostly owns HTTP validation, endpoint orchestration, and response shaping; shared only has enough sandbox key logic required for deserializing it and retrieving the account context from it | 4 个月前 | |
feat(nan-5088): strip legacy scopes from DB + remove dead code (#6179) ## Summary Step 4 (final) of the legacy → fine-grained scope rollout described in #6088. With #6099 in prod, no route accepts the legacy scopes any more, so the strings sitting in \`customer_keys\` are inert. This PR removes them from the DB and rips out every dead code path that existed to deal with them. ## DB - \`20260519120000_strip_legacy_api_key_scopes.cjs\` — single UPDATE that removes the 5 legacy strings from every \`customer_keys.scopes\` array. - Idempotent: \`&&\` overlap filter in the WHERE only touches rows that still carry at least one legacy. - Per the EXPLAIN runs on prod for the expansion migration, this is ~10ms work on ~72K rows. - \`stripLegacyApiKeyScopes\` helper + 10 integration tests covering each legacy scope, idempotency, soft-deleted keys, empty arrays, and unrelated-scope preservation. ## Code - **Types / utils**: removed the 5 legacy entries from the \`ApiKeyScope\` union in \`packages/types\` and \`packages/utils\`. - **Webapp scope picker**: deleted \`LEGACY_SCOPES\` and \`stripLegacyScopes\` from \`scope-logic.ts\`. Removed the 3 call sites in \`ApiKeys.tsx\` (handleSave, countSelectedScopes, hasNoScopes). \`hasNoScopes\` reverts to the plain \`editedScopes.length === 0\` check. - **Tests**: dropped the 3 \`stripLegacyScopes\` unit tests; updated 2 \`scope.middleware.unit.test.ts\` assertions that were probing the wildcard match using legacy strings (the union no longer accepts them). ## Kept - \`expandLegacyApiKeyScopes\` helper + its migration + integration test. They reference legacy strings as plain literals in \`.cjs\` (no type), so they keep working after the union shrinks, and they document what happened on the way through. ## Stack / merge order This PR is stacked on top of #6099 (\`pfreixes/nan-5088-remove-legacy-scopes\`). It must merge after #6099 is deployed and has been live long enough to be confident no rollback is needed (~3–5 days). If a rollback to before #6099 is ever needed after this PR lands, you'd need to restore \`customer_keys\` from the backup taken at step 1 of the rollout — the legacy scope strings will no longer exist on any key. Once #6099 lands on master, retarget the base of this PR to master via the GitHub UI. ## Test plan - [x] 10 helper integration tests pass (\`stripLegacyApiKeyScopes.integration.test.ts\`) - [x] 35 webapp scope-logic unit tests pass (down from 38 after dropping the 3 strip-legacy tests) - [x] 10 server scope.middleware unit tests pass (updated 2 assertions) - [x] \`npm run ts-build\` clean across the workspace - [ ] CI scope enforcement integration tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> | 5 个月前 | |
feat(runner): send runner telemetry to persist (#6209) The TelemetryBag can be silently dropped on runtime errors, making it unsuitable for sensitive telemetry, like billing data. Introduces an alternative: runner collects telemetry events, aggregates by integration/connection, and flushes to persist via HTTP on interval. Balances reliability and complexity without introducing new transports or requiring major SDK refactors. | 4 个月前 | |
feat(functions): Production versions of JIT function endpoints (#6214) ## Summary This PR adds the new public Functions API surface for compiling, deploying, and dry-running TypeScript function source code without requiring users to manage a local integration project layout. ### New function endpoints - `POST /functions/compile` - Accepts submitted TypeScript function code and returns bundled JavaScript plus bundle metadata. - Requires the new `environment:functions:compile` API key scope. - `POST /functions/deployments` - Deploys submitted TypeScript function code into an existing integration. - Uses a purpose-bound deploy sandbox token when the sandbox calls back into Nango. - `POST /functions/dryruns` - Starts an asynchronous dry run and returns `202` with an id, status, and `status_url`. - Uses the status values `waiting`, `running`, `success`, and `failed`. - `GET /functions/dryruns/{id}` - Returns the persisted dry run status, output, result, error, duration, and timeout metadata. - `POST /functions/dryruns/{id}/result` - Internal sandbox callback endpoint. - Only accepts purpose-bound sandbox tokens, not customer API keys. The older `/remote-function/*` endpoints remain in place for the existing synchronous compile/deploy/dryrun behavior while sharing the same underlying sandbox clients. ### Async dry run flow `POST /functions/dryruns` creates a `function_dryruns` row, creates a short-lived sandbox API token with dryrun purpose, and starts an E2B sandbox in the background. Inside the sandbox, Nango writes: - the submitted function code - optional input, metadata, checkpoint, and last sync date payloads - a generated Node callback script That callback script compiles the code, runs `nango dryrun`, and posts the final `success` or `failed` payload back to `/functions/dryruns/{id}/result`. The API stores the output/result/error and `GET /functions/dryruns/{id}` exposes the final state. A timeout cron marks stale dry runs as failed if the sandbox never calls back. ### Sandbox package reorganization This moves the sandbox-related business logic out of `server` and `shared` into a new top-level `@nangohq/sandbox` package: - E2B sandbox creation and error mapping - local Docker fallback clients - compile/deploy/dryrun command construction and output parsing - remote function runtime helpers - purpose-bound sandbox API key creation/verification - function dryrun persistence helpers The server package now mostly owns HTTP validation, endpoint orchestration, and response shaping; shared only has enough sandbox key logic required for deserializing it and retrieving the account context from it | 4 个月前 | |
feat(records): route to secondary store based on plan (#6363) Came up with a middle ground approach, creating a second logical records store but pointing it our for now at the same db instance (as another schema). This way we can have all the code ready (including plan support) but not have to operate another database yet. Let me know what you think. The main design decision being made is `datasets` are pinned to a store. Not accounts, environments, etc... To do so we would need to implement live migration of existing records or limit new 'stores' to new customers, env, etc... This PR: - Adds records_store column to plans (default: 'default') - Adds records_routing table to persist per-connection/model store assignments - Existing connection/model with records always pin to 'default' store - Threads plan through all records operations for routing context - No-op when secondary store is not configured via env vars (not configure yet) Note: `secondary` name is TBD. I am open to suggestion | 4 个月前 | |
fix: Add missing index on api_secrets (hashed) (#6387) One of the most frequent database query that authenticate internal requests (ex: runner -> persist) is missing an index on the api_secrets table query plan before: ``` Limit (cost=1.44..1483.64 rows=1 width=160) (actual time=1.048..1.050 rows=1 loops=1) ... -> Seq Scan on api_secrets (cost=0.00..1473.62 rows=1 width=4) (actual time=0.955..0.955 rows=1 loops=1) Filter: (is_default AND ((hashed)::text = 'REDACTED'::text)) ... ``` query plan after: ``` Limit (cost=1.86..18.44 rows=1 width=160) (actual time=0.169..0.171 rows=1 loops=1) ... -> Index Scan using api_secrets_hashed on api_secrets (cost=0.41..8.43 rows=1 width=4) (actual time=0.014..0.014 rows=1 loops=1) Index Cond: ((hashed)::text = 'REDACTED'::text) ... ``` Note: index has already been created in prod <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> | 4 个月前 | |
chore: Remove experimental /remote-function endpoints (#6390) Removes the legacy `/remote-function` compile, dryrun, and deploy endpoints plus their controllers, schemas, endpoint types, integration coverage, and plan-gating flag. Relocates the reusable sandbox runtime code from `packages/sandbox/lib/remote-function` into `packages/sandbox/lib/functions` and removes the unused synchronous dryrun path. NAN-5568 | 4 个月前 | |
feat: make function deployments async (#6404) <!-- Describe the problem and your solution --> Makes `/functions/deployments` asynchronous so large deployments no longer need to finish inside the request/ALB timeout. This is a stepping stone towards better concurrent deployments as well. Renames the dryrun storage model to `function_async_jobs`, adds deployment polling/result callback endpoints, and runs deployment sandboxes through an id-bound callback script. <!-- Issue ticket number and link (if applicable) --> NAN-5866 | 4 个月前 | |
feat(sync_jobs): shrink retention + add id_big shadow column (NAN-5491 Phase 3a) (#6376) ## Why Prepare `_nango_sync_jobs` for the int4 → bigint PK widening by shrinking the table and starting dual-writes to a shadow `id_big` column. ## How - **Stack:** standalone — first PR of the Phase 3 sequence, can merge directly to master. Reverted by Phase 3g ([#6382](https://github.com/NangoHQ/nango/pull/6382)). - **Migrations:** **run manually** in cloud prod from psql before merging, wrapped in `BEGIN; SET LOCAL lock_timeout = '1s'; … COMMIT;` to keep the brief ACCESS EXCLUSIVE on `_nango_sync_jobs` bounded. Then mark the migration applied by hand so the auto-runner skips it. Self-hosted auto-runs the migration on deploy. ```sql BEGIN; SET LOCAL lock_timeout = '1s'; ALTER TABLE nango._nango_sync_jobs ADD COLUMN IF NOT EXISTS id_big bigint; CREATE OR REPLACE FUNCTION nango._nango_sync_jobs_mirror_id() RETURNS TRIGGER AS $$ BEGIN NEW.id_big := NEW.id; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER _nango_sync_jobs_mirror_id_trigger BEFORE INSERT OR UPDATE ON nango._nango_sync_jobs FOR EACH ROW EXECUTE FUNCTION nango._nango_sync_jobs_mirror_id(); COMMIT; ``` ```sql INSERT INTO nango._nango_auth_migrations (name, batch, migration_time) VALUES ( '20260608120000_sync_jobs_add_id_big.cjs', (SELECT COALESCE(MAX(batch), 0) + 1 FROM nango._nango_auth_migrations), NOW() ); ``` - **Wait after merging:** **~3 days** for `CRON_DELETE_OLD_JOBS` to chew `_nango_sync_jobs` down to its new steady-state under 3-day retention. ## What - Shorten `CRON_DELETE_OLD_JOBS_MAX_DAYS` default from 31 → 3 days to bring `_nango_sync_jobs` down to a workable size ahead of the swap. Restored to 31 in Phase 3g ([#6382](https://github.com/NangoHQ/nango/pull/6382)) once the swap is complete. - Add `id_big bigint` shadow column to `_nango_sync_jobs` plus a `BEFORE INSERT OR UPDATE` trigger that mirrors `id → id_big` on every write. Dual-write starts immediately, paving the way for the backfill (3b — [#6377](https://github.com/NangoHQ/nango/pull/6377)) and atomic PK swap (3e — [#6380](https://github.com/NangoHQ/nango/pull/6380)). Linear: NAN-5491. ## Test plan - [ ] Cloud prod: run the DDL block manually with `SET LOCAL lock_timeout = '1s'` - [ ] `INSERT INTO _nango_auth_migrations` to mark migration applied - [ ] After deploy, `WHERE id_big IS NULL AND created_at > NOW() - INTERVAL '5 minutes'` returns `0` in staging + prod - [ ] `_nango_sync_jobs` row count visibly decreasing day-over-day in prod - [ ] No regression in sync-job creation/update throughput - [ ] Self-hosted auto-runs the migration on next deploy with no operator intervention --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> | 4 个月前 | |
feat(sync_jobs): backfill id_big from id (NAN-5491 Phase 3b) (#6377) ## Why Confirm every row in `_nango_sync_jobs` has `id_big` populated before Phase 3c builds the unique index on it. ## How - **Stack:** depends on Phase 3a ([#6376](https://github.com/NangoHQ/nango/pull/6376)) — `id_big` column + mirror trigger must exist. - **Check before merging:** - `SELECT count(*) FROM nango._nango_sync_jobs WHERE id_big IS NULL` — returns `0`. - **Migrations (cloud): chunked manual UPDATE.** The trigger from 3a populates `id_big` on every new INSERT/UPDATE, but retention couldn't shrink the historical backlog in any reasonable timeframe (default cron limit 1K rows / 10min is ~280× too slow for the ~141M starting NULL count). Instead, the backfill ran out-of-band via a bash loop of chunked UPDATEs (15K rows, 7s sleep) — completed 2026-06-19. Then mark the migration applied by hand so the auto-runner skips its own (now no-op) UPDATE: ```sql -- Pre-merge sanity check (should already be 0): SELECT count(*) FROM nango._nango_sync_jobs WHERE id_big IS NULL; -- Mark the migration applied so the auto-runner skips its bulk UPDATE on next deploy: INSERT INTO nango._nango_auth_migrations (name, batch, migration_time) VALUES ( '20260608120100_sync_jobs_backfill_id_big.cjs', (SELECT COALESCE(MAX(batch), 0) + 1 FROM nango._nango_auth_migrations), NOW() ); ``` - **Migrations (self-hosted):** the migration body's bulk `UPDATE` runs automatically on deploy — small table, completes in seconds, no operator step needed. ## What - Backfill `id_big = id` across any rows in `_nango_sync_jobs` whose `id_big` is still NULL. In cloud the chunked manual loop already did this on 2026-06-19; on self-hosted the migration body handles it on the next upgrade. - Reverts the spurious `CRON_DELETE_OLD_JOBS_MAX_DAYS` default change that lingered in this branch's history (the value was changed 31→3 in Phase 3a, then restored to 31 by #6496 on master). Without this fix the squash-merge would silently revert the default back to 3 again. Linear: NAN-5491. ## Test plan - [x] Cloud: chunked manual backfill complete; `SELECT count(*) WHERE id_big IS NULL` returns `0`. - [ ] Cloud: `INSERT INTO _nango_auth_migrations` to mark applied. - [ ] Self-hosted: auto-runs the migration on next deploy with no operator intervention. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> | 4 个月前 | |
feat(sync_jobs): build unique index on id_big (NAN-5491 Phase 3c) (#6378) ## Why Build the unique index that Phase 3e's atomic PK swap pivots on, without taking a long ACCESS EXCLUSIVE lock in cloud prod. ## How - **Stack:** depends on Phase 3b ([#6377](https://github.com/NangoHQ/nango/pull/6377)) — backfill must be complete; the unique index would fail if any row still has duplicate `id_big` values, and a partial NULL set means the next phase's NOT NULL proof would fail. - **Migrations:** cloud prod runs `CREATE UNIQUE INDEX CONCURRENTLY` **manually** to avoid the ACCESS EXCLUSIVE lock the auto-run (non-CONCURRENTLY) would take. The migration row is inserted into `nango._nango_auth_migrations` afterward so the auto-runner skips it. Self-hosted runs the non-CONCURRENT version on deploy — fast on their small tables. ### Commands (Schema-qualified for the operator runbook — the migration file itself uses unqualified table names and relies on `search_path`.) **1. Pre-flight check** — confirm backfill is still complete: ```sql SELECT count(*) FROM nango._nango_sync_jobs WHERE id_big IS NULL; -- expect: 0 ``` **2. Build the index** — CONCURRENTLY, no transaction wrapper (CONCURRENTLY can't run inside a txn): ```sql CREATE UNIQUE INDEX CONCURRENTLY sync_jobs_id_big_uidx ON nango._nango_sync_jobs (id_big); ``` **3. Monitor progress** (from a separate psql session while the build is running): ```sql SELECT phase, blocks_done, blocks_total, round(100.0 * blocks_done / NULLIF(blocks_total, 0), 1) AS pct FROM pg_stat_progress_create_index; ``` **4. Verify success** — `indisvalid` and `indisready` must both be `t`: ```sql SELECT indisvalid, indisready FROM pg_index WHERE indexrelid = 'nango.sync_jobs_id_big_uidx'::regclass; -- expect: t, t ``` **5. Mark migration applied** — skip the auto-runner on next deploy: ```sql INSERT INTO nango._nango_auth_migrations (name, batch, migration_time) VALUES ( '20260608120200_sync_jobs_id_big_unique_index.cjs', (SELECT COALESCE(MAX(batch), 0) + 1 FROM nango._nango_auth_migrations), NOW() ); ``` ### Emergency stop (if the build needs to be aborted mid-flight) **1. Find the PID** (from a separate psql session): ```sql SELECT pid, now() - query_start AS duration, state FROM pg_stat_activity WHERE query ILIKE '%CREATE UNIQUE INDEX CONCURRENTLY sync_jobs_id_big_uidx%' AND pid <> pg_backend_pid(); ``` **2. Cancel gracefully** (preferred): ```sql SELECT pg_cancel_backend(<pid>); ``` If cancel doesn't take effect within ~30s (some CREATE INDEX phases ignore SIGINT), escalate to terminate (drops the connection): ```sql SELECT pg_terminate_backend(<pid>); ``` **3. Clean up the invalid leftover** — cancelled/terminated builds leave an invalid index in the catalog: ```sql -- Check what's left: SELECT indisvalid FROM pg_index WHERE indexrelid = 'nango.sync_jobs_id_big_uidx'::regclass; -- if 'f': there's an invalid index that needs to be dropped before retrying -- Drop it (CONCURRENTLY so the DROP itself doesn't lock the table): DROP INDEX CONCURRENTLY IF EXISTS nango.sync_jobs_id_big_uidx; ``` After the DROP, the table is back to a clean pre-3c state and the build can be retried. ## What - Build the `sync_jobs_id_big_uidx` UNIQUE index on `_nango_sync_jobs(id_big)`. This is the constraint backbone of Phase 3e ([#6380](https://github.com/NangoHQ/nango/pull/6380))'s `ADD CONSTRAINT _nango_sync_jobs_pkey PRIMARY KEY USING INDEX sync_jobs_id_big_uidx` — 3e cannot run without it. - Schema-qualifier dropped in the migration file (`nango._nango_sync_jobs` → `_nango_sync_jobs`) to match the project convention of relying on `search_path` for table resolution. Linear: NAN-5491. ## Test plan - [ ] Cloud prod: run pre-flight check (NULL count = 0) - [ ] Cloud prod: `CREATE UNIQUE INDEX CONCURRENTLY sync_jobs_id_big_uidx ON nango._nango_sync_jobs (id_big)` - [ ] `indisvalid = t, indisready = t` on the index - [ ] `INSERT INTO nango._nango_auth_migrations` to mark applied - [ ] Self-hosted auto-runs the non-CONCURRENT migration on next deploy --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> | 4 个月前 | |
feat(sync_jobs): validate id_big NOT NULL (NAN-5491 Phase 3d) (#6379) ## Why Prove `id_big` has no NULL rows so Phase 3e's swap stays metadata-only under `ACCESS EXCLUSIVE` — the long scan happens here, in a non-blocking lock mode. ## How - **Stack:** depends on Phase 3c ([#6378](https://github.com/NangoHQ/nango/pull/6378)) — the unique index is in place. - **Migrations: run manually** in cloud prod from psql. Two separate statements (the second is NOT inside a transaction with the first), so the `VALIDATE` step runs under its native `SHARE UPDATE EXCLUSIVE` (non-blocking) instead of inheriting `ACCESS EXCLUSIVE` from the catalog write. The migration row is inserted into `nango._nango_auth_migrations` afterward so the auto-runner skips it. Self-hosted runs the migration automatically (instant + small-table scan, no concern). ### Commands (Schema-qualified for the operator runbook — the migration file itself uses unqualified table names and relies on `search_path`.) **1. Pre-flight check** — backfill is still complete and unique index is in place: ```sql SELECT count(*) FROM nango._nango_sync_jobs WHERE id_big IS NULL; -- expect: 0 SELECT indisvalid, indisready FROM pg_index WHERE indexrelid = 'nango.sync_jobs_id_big_uidx'::regclass; -- expect: t, t ``` **2. Add the CHECK constraint (NOT VALID)** — catalog entry only, wrapped with `lock_timeout = '1s'` so the brief ACCESS EXCLUSIVE can't queue up behind a busy moment: ```sql BEGIN; SET LOCAL lock_timeout = '1s'; ALTER TABLE nango._nango_sync_jobs ADD CONSTRAINT id_big_not_null CHECK (id_big IS NOT NULL) NOT VALID; COMMIT; ``` **3. Validate the constraint** — runs OUTSIDE a transaction so it gets `SHARE UPDATE EXCLUSIVE` (concurrent reads/writes keep flowing). Aborts the whole step if any row has `id_big IS NULL`: ```sql ALTER TABLE nango._nango_sync_jobs VALIDATE CONSTRAINT id_big_not_null; ``` **4. Verify** — `convalidated` must be `t`: ```sql SELECT convalidated FROM pg_constraint WHERE conrelid = 'nango._nango_sync_jobs'::regclass AND conname = 'id_big_not_null'; -- expect: t ``` **5. Mark migration applied** — skip the auto-runner on next deploy: ```sql INSERT INTO nango._nango_auth_migrations (name, batch, migration_time) VALUES ( '20260608120250_sync_jobs_validate_id_big_not_null.cjs', (SELECT COALESCE(MAX(batch), 0) + 1 FROM nango._nango_auth_migrations), NOW() ); ``` ### Emergency stop (if VALIDATE needs to be cancelled mid-flight) The `VALIDATE` scan is interruptible since it runs under `SHARE UPDATE EXCLUSIVE` (no exclusive lock to release). **1. Find the PID** (from a separate psql session): ```sql SELECT pid, now() - query_start AS duration, state FROM pg_stat_activity WHERE query ILIKE '%VALIDATE CONSTRAINT id_big_not_null%' AND pid <> pg_backend_pid(); ``` **2. Cancel**: ```sql SELECT pg_cancel_backend(<pid>); ``` **3. Clean up the unvalidated CHECK** so a retry starts clean: ```sql ALTER TABLE nango._nango_sync_jobs DROP CONSTRAINT id_big_not_null; ``` After the DROP, you're back to a clean pre-3d state and can retry from step 2. ## What - Add a validated `CHECK (id_big IS NOT NULL)` constraint named `id_big_not_null` to `_nango_sync_jobs`. From that point on, every INSERT/UPDATE is also constraint-checked, so the table can't drift back into containing NULLs while we wait to run 3e. - 3e's swap then uses this validated CHECK as proof (PG 12+ optimization): `ALTER COLUMN id SET NOT NULL` becomes metadata-only, and `ADD CONSTRAINT … PRIMARY KEY USING INDEX` no longer has to scan under `ACCESS EXCLUSIVE`. The redundant CHECK is dropped inside the swap right before the PK supersedes it. - Schema-qualifier dropped in the migration file (`nango._nango_sync_jobs` → `_nango_sync_jobs`) to match the project convention of relying on `search_path` for table resolution. Linear: NAN-5491. ## Test plan - [ ] Cloud prod: pre-flight check (NULL count = 0, unique index valid) - [ ] Cloud prod: run `ADD CONSTRAINT … NOT VALID` wrapped with `lock_timeout = '1s'` - [ ] Cloud prod: run `VALIDATE CONSTRAINT` outside a txn - [ ] `convalidated = t` on `id_big_not_null` - [ ] `INSERT INTO nango._nango_auth_migrations` to mark applied - [ ] Self-hosted auto-runs the migration on next deploy --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> | 4 个月前 | |
feat(sync_jobs): atomic PK swap from int4 id to bigint (NAN-5491 Phase 3e) (#6380) ## Why Flip `_nango_sync_jobs.id` from `int4` to `bigint` in a single transaction, taking the table off the int4 exhaustion path — and keep the swap fully metadata-only by leaning on the validated CHECK from Phase 3d. ## How - **Stack:** depends on Phase 3d ([#6379](https://github.com/NangoHQ/nango/pull/6379)) — the `id_big_not_null` CHECK must be validated. - **Migrations: run manually** in cloud prod from psql, wrapped in `BEGIN; SET LOCAL lock_timeout = '1s'; SET LOCAL statement_timeout = '5s'; … COMMIT;`. Two safety nets: - `lock_timeout = '1s'` — bails if we can't acquire ACCESS EXCLUSIVE on the table within 1s (another long query is in the way). - `statement_timeout = '5s'` — every statement should be sub-millisecond catalog-only DDL. If something deviates (e.g., the PG 12+ CHECK-as-NOT-NULL-proof optimization unexpectedly doesn't kick in, causing a 168M-row scan), bail in 5s instead of waiting ~25s. Either timeout aborts the whole transaction atomically — no partial state. Migration row inserted into `nango._nango_auth_migrations` afterward to skip the auto-runner. - **Wait after merging:** **~24 hours** of clean operation before merging Phase 3f ([#6381](https://github.com/NangoHQ/nango/pull/6381)) — gives a rollback window in case the swap surfaces a subtle issue. The rollback procedure is documented below; once 3f lands and the sequence cap is lifted, that rollback becomes data-destructive. ### Commands (Schema-qualified for the operator runbook — the migration file itself uses unqualified table names and relies on `search_path`.) **1. Pre-flight checks** — confirm all 3a-3d preconditions hold: ```sql -- a) backfill complete (uses sync_jobs_id_big_uidx as Index Only Scan, sub-ms) SELECT count(*) FROM nango._nango_sync_jobs WHERE id_big IS NULL; -- expect: 0 -- b) unique index valid + ready SELECT indisvalid, indisready FROM pg_index WHERE indexrelid = 'nango.sync_jobs_id_big_uidx'::regclass; -- expect: t, t -- c) CHECK validated (this is what makes SET NOT NULL skip its scan inside the swap) SELECT convalidated FROM pg_constraint WHERE conrelid = 'nango._nango_sync_jobs'::regclass AND conname = 'id_big_not_null'; -- expect: t -- d) trigger still in place (it gets dropped inside the swap) SELECT tgname FROM pg_trigger WHERE tgrelid = 'nango._nango_sync_jobs'::regclass AND tgname = '_nango_sync_jobs_mirror_id_trigger'; -- expect: one row ``` **2. The swap** — single transaction with both timeouts: ```sql BEGIN; SET LOCAL lock_timeout = '1s'; SET LOCAL statement_timeout = '5s'; ALTER TABLE nango._nango_sync_jobs ALTER COLUMN id DROP DEFAULT; ALTER TABLE nango._nango_sync_jobs DROP CONSTRAINT _nango_sync_jobs_pkey; ALTER TABLE nango._nango_sync_jobs RENAME COLUMN id TO id_old; ALTER TABLE nango._nango_sync_jobs RENAME COLUMN id_big TO id; ALTER TABLE nango._nango_sync_jobs ALTER COLUMN id_old DROP NOT NULL; ALTER TABLE nango._nango_sync_jobs ALTER COLUMN id SET NOT NULL; ALTER TABLE nango._nango_sync_jobs DROP CONSTRAINT IF EXISTS id_big_not_null; ALTER TABLE nango._nango_sync_jobs ADD CONSTRAINT _nango_sync_jobs_pkey PRIMARY KEY USING INDEX sync_jobs_id_big_uidx; ALTER TABLE nango._nango_sync_jobs ALTER COLUMN id SET DEFAULT nextval('nango._nango_sync_jobs_id_seq'); ALTER SEQUENCE nango._nango_sync_jobs_id_seq OWNED BY nango._nango_sync_jobs.id; DROP TRIGGER IF EXISTS _nango_sync_jobs_mirror_id_trigger ON nango._nango_sync_jobs; DROP FUNCTION IF EXISTS nango._nango_sync_jobs_mirror_id(); COMMIT; ``` **3. Verify** — schema reflects the swap: ```sql -- a) New id is bigint NOT NULL with nextval default; id_old is int nullable SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_schema = 'nango' AND table_name = '_nango_sync_jobs' AND column_name IN ('id', 'id_old') ORDER BY column_name; -- expect: -- id | bigint | NO | nextval('nango._nango_sync_jobs_id_seq'::regclass) -- id_old | integer | YES | (null) -- b) PK now uses sync_jobs_id_big_uidx SELECT conname, pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = 'nango._nango_sync_jobs'::regclass AND contype = 'p'; -- expect: _nango_sync_jobs_pkey | PRIMARY KEY (id) -- (PG hides the USING INDEX detail in the constraint def; the underlying index is sync_jobs_id_big_uidx) -- c) id_big_not_null CHECK is gone SELECT conname FROM pg_constraint WHERE conrelid = 'nango._nango_sync_jobs'::regclass AND conname = 'id_big_not_null'; -- expect: 0 rows -- d) Trigger + function are gone SELECT tgname FROM pg_trigger WHERE tgrelid = 'nango._nango_sync_jobs'::regclass AND tgname = '_nango_sync_jobs_mirror_id_trigger'; -- expect: 0 rows SELECT proname FROM pg_proc WHERE proname = '_nango_sync_jobs_mirror_id'; -- expect: 0 rows -- e) Sequence is owned by the new id column SELECT s.relname AS sequence, d.refobjsubid AS owned_by_attnum, a.attname AS owned_by_column FROM pg_class s JOIN pg_depend d ON d.objid = s.oid AND d.classid = 'pg_class'::regclass AND d.deptype = 'a' JOIN pg_attribute a ON a.attrelid = d.refobjid AND a.attnum = d.refobjsubid WHERE s.relname = '_nango_sync_jobs_id_seq'; -- expect: _nango_sync_jobs_id_seq | <attnum> | id ``` **4. Sanity check round-trip** against the live app — insert a sync_job through normal application path and confirm it gets a fresh bigint id from the sequence. **5. Mark migration applied** — skip the auto-runner on next deploy: ```sql INSERT INTO nango._nango_auth_migrations (name, batch, migration_time) VALUES ( '20260608120300_sync_jobs_id_atomic_swap.cjs', (SELECT COALESCE(MAX(batch), 0) + 1 FROM nango._nango_auth_migrations), NOW() ); ``` ### Mid-flight cancel (before COMMIT lands) The swap is a single transaction, so any error (lock_timeout, statement_timeout, constraint violation, manual cancel) **rolls back the whole thing atomically** — no manual cleanup needed. If you need to abort mid-flight from a separate psql session: ```sql -- Find the swap session: SELECT pid, now() - xact_start AS txn_duration, query FROM pg_stat_activity WHERE query ILIKE '%PRIMARY KEY USING INDEX sync_jobs_id_big_uidx%' AND pid <> pg_backend_pid(); -- Cancel it: SELECT pg_cancel_backend(<pid>); ``` After cancel/timeout, the table goes back to the pre-swap state. You can re-run the swap once whatever caused the issue is resolved. ### Last-resort post-commit rollback (only during the 24h bake window before Phase 3f) Once the swap has committed, true rollback requires undoing the column rename + restoring the PK on the int4 column. Two preconditions must hold: 1. **The sequence's `last_value` is still ≤ 2^31-1.** New bigint ids that have already been emitted must fit back into int4. After Phase 3f lifts the cap and a value > 2^31 is emitted, this rollback becomes data-destructive. 2. **Post-swap rows have NULL `id_old`** (the trigger that mirrored `id → id_big` was dropped). Step A below backfills them. ```sql -- ============================================================ -- Step A — backfill id_old for post-swap rows. Chunked, repeat -- until 0 rows match. Errors out if any id > 2^31-1. -- ============================================================ WITH batch AS ( SELECT ctid FROM nango._nango_sync_jobs WHERE id_old IS NULL LIMIT 15000 ) UPDATE nango._nango_sync_jobs s SET id_old = id::int FROM batch WHERE s.ctid = batch.ctid; -- Confirm: SELECT count(*) FROM nango._nango_sync_jobs WHERE id_old IS NULL; -- expect: 0 ``` ```sql -- ============================================================ -- Step B — build a unique index on id_old CONCURRENTLY (~5 min, -- non-blocking). Required because the original _nango_sync_jobs_pkey -- index was dropped during the swap, and the reverse swap needs an -- index to attach as the new PK. -- ============================================================ CREATE UNIQUE INDEX CONCURRENTLY sync_jobs_id_old_uidx ON nango._nango_sync_jobs (id_old); -- Verify: SELECT indisvalid, indisready FROM pg_index WHERE indexrelid = 'nango.sync_jobs_id_old_uidx'::regclass; -- expect: t, t ``` ```sql -- ============================================================ -- Step C — reverse swap (single txn, same timeout safety nets). -- ============================================================ BEGIN; SET LOCAL lock_timeout = '1s'; SET LOCAL statement_timeout = '5s'; ALTER TABLE nango._nango_sync_jobs ALTER COLUMN id DROP DEFAULT; ALTER TABLE nango._nango_sync_jobs DROP CONSTRAINT _nango_sync_jobs_pkey; ALTER TABLE nango._nango_sync_jobs RENAME COLUMN id TO id_big; ALTER TABLE nango._nango_sync_jobs RENAME COLUMN id_old TO id; ALTER TABLE nango._nango_sync_jobs ALTER COLUMN id_big DROP NOT NULL; ALTER TABLE nango._nango_sync_jobs ALTER COLUMN id SET NOT NULL; ALTER TABLE nango._nango_sync_jobs ADD CONSTRAINT _nango_sync_jobs_pkey PRIMARY KEY USING INDEX sync_jobs_id_old_uidx; ALTER TABLE nango._nango_sync_jobs ALTER COLUMN id SET DEFAULT nextval('nango._nango_sync_jobs_id_seq'); ALTER SEQUENCE nango._nango_sync_jobs_id_seq OWNED BY nango._nango_sync_jobs.id; COMMIT; ``` Notes: - The trigger/function are **deliberately not recreated** — at this point `id` is back to int4 and dual-writing isn't needed. `id_big` stays as a nullable orphan column you can `DROP COLUMN` later if desired. - If rolling back the data also requires reverting the merged PR, also remove the migration row so a re-run is clean: `DELETE FROM nango._nango_auth_migrations WHERE name = '20260608120300_sync_jobs_id_atomic_swap.cjs';` ## What - Atomic PK swap of `_nango_sync_jobs.id` from `int4` to `bigint`. All metadata-only DDL inside one transaction: drop default on old `id`, drop the PK, rename `id → id_old`, rename `id_big → id`, drop NOT NULL on `id_old`, SET NOT NULL on the new `id` (uses the validated CHECK as proof — no scan), drop the now-redundant `id_big_not_null` CHECK, attach the PK via `USING INDEX sync_jobs_id_big_uidx`, restore the `nextval` default, reassign sequence ownership to the new `id`, drop the mirror trigger + function. The sequence ceiling stays at `2^31-1` for now (Phase 3f ([#6381](https://github.com/NangoHQ/nango/pull/6381)) lifts it) — that's safe because the bigint column accepts those values without complaint and behavior is unchanged. - Schema-qualifier dropped in the migration file (`nango._nango_sync_jobs` → `_nango_sync_jobs`) to match the project convention of relying on `search_path` for table resolution. Linear: NAN-5491. ## Test plan - [ ] Cloud prod: pre-flight checks (NULL=0, index valid, CHECK validated, trigger present) - [ ] Cloud prod: run the swap block manually with `lock_timeout = '1s'` + `statement_timeout = '5s'` - [ ] Schema verifies (new bigint `id`, `id_old` int nullable, PK on new id, CHECK gone, trigger gone) - [ ] App round-trip insert succeeds - [ ] `INSERT INTO nango._nango_auth_migrations` to mark applied - [ ] Self-hosted auto-runs the migration on next deploy (no manual step needed there) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> | 4 个月前 | |
feat(sync_jobs): drop legacy id_old and lift sequence to bigint (NAN-5491 Phase 3f) (#6381) ## Why Reclaim the int4 ceiling by dropping the dead `id_old` column and lifting the sequence to bigint — the change that actually buys us the new headroom and closes the failure mode permanently. ## How - **Stack:** depends on Phase 3e ([#6380](https://github.com/NangoHQ/nango/pull/6380)) — the bigint swap must be live. - **Migrations: run manually** in cloud prod from psql, wrapped in `BEGIN; SET LOCAL lock_timeout = '1s'; SET LOCAL statement_timeout = '5s'; … COMMIT;`. Same dual-timeout pattern as 3e: both DDLs are pure catalog updates (no scans), so any deviation gets caught fast. Migration row inserted into `nango._nango_auth_migrations` afterward to skip the auto-runner. - **Point of no return:** once this lands and the sequence emits a value > 2^31, the rollback documented in [#6380](https://github.com/NangoHQ/nango/pull/6380) becomes data-destructive (those ids can't fit in the int4 `id_old` column, which is dropped here anyway). Past this PR, the widening is locked in. ### Commands (Schema-qualified for the operator runbook — the migration file itself uses unqualified table names and relies on `search_path`.) **1. Pre-flight checks** — confirm 3e's state holds: ```sql -- a) New id is bigint SELECT data_type FROM information_schema.columns WHERE table_schema='nango' AND table_name='_nango_sync_jobs' AND column_name='id'; -- expect: bigint -- b) id_old still exists (gets dropped here) SELECT data_type FROM information_schema.columns WHERE table_schema='nango' AND table_name='_nango_sync_jobs' AND column_name='id_old'; -- expect: integer -- c) Current sequence cap (still int4 max for now) SELECT seqmax FROM pg_sequence WHERE seqrelid = 'nango._nango_sync_jobs_id_seq'::regclass; -- expect: 2147483647 ``` **2. The migration** — single transaction with both timeouts: ```sql BEGIN; SET LOCAL lock_timeout = '1s'; SET LOCAL statement_timeout = '5s'; ALTER TABLE nango._nango_sync_jobs DROP COLUMN IF EXISTS id_old; ALTER SEQUENCE nango._nango_sync_jobs_id_seq AS bigint MAXVALUE 9223372036854775807; COMMIT; ``` **3. Verify** — both DDLs landed: ```sql -- a) id_old is gone SELECT data_type FROM information_schema.columns WHERE table_schema='nango' AND table_name='_nango_sync_jobs' AND column_name='id_old'; -- expect: 0 rows -- b) Sequence cap is now bigint max SELECT seqmax FROM pg_sequence WHERE seqrelid = 'nango._nango_sync_jobs_id_seq'::regclass; -- expect: 9223372036854775807 ``` **4. Mark migration applied** — skip the auto-runner on next deploy: ```sql INSERT INTO nango._nango_auth_migrations (name, batch, migration_time) VALUES ( '20260608120400_sync_jobs_drop_id_old_lift_sequence.cjs', (SELECT COALESCE(MAX(batch), 0) + 1 FROM nango._nango_auth_migrations), NOW() ); ``` ### Mid-flight cancel Same as 3e — single transaction, any error/cancel rolls back atomically. ```sql -- Find the session: SELECT pid, now() - xact_start AS txn_duration, query FROM pg_stat_activity WHERE query ILIKE '%ALTER SEQUENCE%_nango_sync_jobs_id_seq%AS bigint%' AND pid <> pg_backend_pid(); -- Cancel: SELECT pg_cancel_backend(<pid>); ``` ## What - `DROP COLUMN id_old` — the int4 column has had no writers since Phase 3e's swap. Pure catalog removal; PG marks the column as dropped without rewriting the table. - `ALTER SEQUENCE … AS bigint MAXVALUE 9223372036854775807` — lifts the sequence's data type and ceiling from int4 (2^31-1 ≈ 2.15B) to bigint (2^63-1 ≈ 9.2 quintillion). This is the change that actually closes the original failure mode. - Schema-qualifier dropped in the migration file (`nango._nango_sync_jobs` → `_nango_sync_jobs`) to match the project convention of relying on `search_path` for table resolution. Linear: NAN-5491. ## Test plan - [ ] Cloud prod: pre-flight (id bigint, id_old still int4, seqmax = 2^31-1) - [ ] Cloud prod: run the SQL block manually with `lock_timeout = '1s'` + `statement_timeout = '5s'` - [ ] Verify (id_old gone, seqmax = 2^63-1) - [ ] `INSERT INTO nango._nango_auth_migrations` to mark applied - [ ] Self-hosted auto-runs the migration on next deploy --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> | 4 个月前 | |
fix: end user deletion timeouts (#6409) Each delete from `end_users` caused a full sequential scan on `connections` and `connect_sessions` tables to enforce the FK constraint because there were no index on end_user_id in either table. Making the deletion of some environments time out The seq scan on `end_users` also lacked an index for the environment_id lookups made on deletion. query plan before ``` Delete on end_users (cost=9385.78..12492.59 rows=0 width=0) (actual time=17798.463..17798.465 rows=0 loops=1) Buffers: shared hit=8571 -> Nested Loop (cost=9385.78..12492.59 rows=414 width=34) (actual time=24.061..25.657 rows=496 loops=1) Buffers: shared hit=7575 -> HashAggregate (cost=9385.36..9389.50 rows=414 width=32) (actual time=24.043..24.206 rows=496 loops=1) Group Key: "ANY_subquery".id Batches: 1 Memory Usage: 105kB Buffers: shared hit=5591 -> Subquery Scan on "ANY_subquery" (cost=0.00..9384.33 rows=414 width=32) (actual time=4.015..23.893 rows=496 loops=1) Buffers: shared hit=5591 -> Limit (cost=0.00..9380.19 rows=414 width=4) (actual time=3.983..23.775 rows=496 loops=1) Buffers: shared hit=5591 -> Seq Scan on end_users end_users_1 (cost=0.00..9380.19 rows=414 width=4) (actual time=3.983..23.731 rows=496 loops=1) Filter: (environment_id = 17814) Rows Removed by Filter: 302983 Buffers: shared hit=5591 -> Index Scan using end_users_pkey on end_users (cost=0.42..7.51 rows=1 width=10) (actual time=0.002..0.002 rows=1 loops=496) Index Cond: (id = "ANY_subquery".id) Buffers: shared hit=1984 Planning: Buffers: shared hit=11 Planning Time: 0.159 ms Trigger for constraint _nango_connections_end_user_id_fkey: time=166567.446 calls=496 Trigger for constraint connect_sessions_end_user_id_fkey: time=31793.984 calls=496 Execution Time: 216161.297 ms ``` query plan after ``` Delete on end_users (cost=1297.43..4404.24 rows=0 width=0) (actual time=0.012..0.013 rows=0 loops=1) Buffers: shared hit=3 -> Nested Loop (cost=1297.43..4404.24 rows=414 width=34) (actual time=0.011..0.012 rows=0 loops=1) Buffers: shared hit=3 -> HashAggregate (cost=1297.01..1301.15 rows=414 width=32) (actual time=0.011..0.011 rows=0 loops=1) Group Key: "ANY_subquery".id Batches: 1 Memory Usage: 37kB Buffers: shared hit=3 -> Subquery Scan on "ANY_subquery" (cost=7.63..1295.97 rows=414 width=32) (actual time=0.009..0.009 rows=0 loops=1) Buffers: shared hit=3 -> Limit (cost=7.63..1291.83 rows=414 width=4) (actual time=0.008..0.009 rows=0 loops=1) Buffers: shared hit=3 -> Bitmap Heap Scan on end_users end_users_1 (cost=7.63..1291.83 rows=414 width=4) (actual time=0.008..0.008 rows=0 loops=1) Recheck Cond: (environment_id = 17814) Buffers: shared hit=3 -> Bitmap Index Scan on idx_end_users_environment_id (cost=0.00..7.53 rows=414 width=0) (actual time=0.006..0.006 rows=0 loops=1) Index Cond: (environment_id = 17814) Buffers: shared hit=3 -> Index Scan using end_users_pkey on end_users (cost=0.42..7.51 rows=1 width=10) (never executed) Index Cond: (id = "ANY_subquery".id) Planning: Buffers: shared hit=30 Planning Time: 0.220 ms Execution Time: 0.053 ms ``` | 4 个月前 | |
chore: default export_runner_telemetry to true (#6652) <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/6652?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 4 个月前 | |
feat: enable `can_override_docs_connect_url` for Growth+ (#6730) Adding it to the plan definitions and backfilling existing plans. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/6730?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 3 个月前 | |
fix(auth): make user emails case-insensitive (#6762) Makes emails case-insensitive. > [!Note] > Before merging and deploying this I will do manual deduplication of existing users that registered with variants of the same email. I have conducted investigation and gathered a list of users to delete. The lowercase email version is not always the correct account to keep. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/6762?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 3 个月前 | |
feat(auth): add MFA factor storage (#6792) <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/6792?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 3 个月前 | |
feat: move webhook_url override to top-level field. (#6778) > This is a breaking change with low surface impact After a lot of discussion we believe that `connection_config` was not the right place for `webhook_url`. We are trying to move quick while it's still not massively adopted (currently 2 accounts, using it incorrectly as the main `webhook_url` setting). This moves the setting to a top-level property on the connection called `webhook_url_override`. I also considered moving it to `overrides` on the connect_session, but the `overrides` object is keyed by integration, which doesn't really make sense for `webhook_url`. So I'm proposing this top-level alternative instead. Please look at the docs updates to understand the user-level change. --------- Co-authored-by: Cursor <cursoragent@cursor.com> | 3 个月前 | |
feat(account): add same-domain-account search (#6827) Adds accountService.findAccountWithSameDomain to power a request-invitation feature: on signup, find an existing team sharing the new user's email domain so they can request to join it instead of creating a new team. - Skips public/free email domains via the existing freeEmailDomains list. - Finds eligible teams with an active user on the same domain and at least one active administrator, excluding the signing-up user's own team. - Ranks multiple matches by paid status, then active member count, then account ID for a stable tie-break. - Adds integration coverage: public-domain exclusion, unique matches, paid-team priority, member-count ranking, and ineligible teams. The query's per-candidate checks (administrator lookup, active member count) and the domain match itself would otherwise scan all of _nango_users on every signup, growing with total user count instead of the number of domain matches: - Add nango_users_email_domain_active: partial expression index on LOWER(SPLIT_PART(email, '@', 2)) WHERE suspended = false, so the domain match is a direct index seek. - Add nango_users_account_id_active: partial index on (account_id, role) WHERE suspended = false, covering the administrator whereExists check and the active-member-count lookup below. Also covers existing user.service.ts reads (getUsersByAccountId, countUsers, getAnUserByAccountId). - Compute active member count as a correlated per-candidate subquery instead of a join + group by CTE, so it can use the new index instead of scanning every active user. Verified via EXPLAIN ANALYZE against ~10k accounts / ~30k users (prod-comparable scale): 251ms -> 2ms. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/6827?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 3 个月前 | |
feat(account): add same-domain-account search (#6827) Adds accountService.findAccountWithSameDomain to power a request-invitation feature: on signup, find an existing team sharing the new user's email domain so they can request to join it instead of creating a new team. - Skips public/free email domains via the existing freeEmailDomains list. - Finds eligible teams with an active user on the same domain and at least one active administrator, excluding the signing-up user's own team. - Ranks multiple matches by paid status, then active member count, then account ID for a stable tie-break. - Adds integration coverage: public-domain exclusion, unique matches, paid-team priority, member-count ranking, and ineligible teams. The query's per-candidate checks (administrator lookup, active member count) and the domain match itself would otherwise scan all of _nango_users on every signup, growing with total user count instead of the number of domain matches: - Add nango_users_email_domain_active: partial expression index on LOWER(SPLIT_PART(email, '@', 2)) WHERE suspended = false, so the domain match is a direct index seek. - Add nango_users_account_id_active: partial index on (account_id, role) WHERE suspended = false, covering the administrator whereExists check and the active-member-count lookup below. Also covers existing user.service.ts reads (getUsersByAccountId, countUsers, getAnUserByAccountId). - Compute active member count as a correlated per-candidate subquery instead of a join + group by CTE, so it can use the new index instead of scanning every active user. Verified via EXPLAIN ANALYZE against ~10k accounts / ~30k users (prod-comparable scale): 251ms -> 2ms. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/6827?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 3 个月前 | |
feat(auth): add account invitation requests during onboarding (#6918) Add a one-shot invitation-request flow for users shown a same-domain account recommendation. The server uses the short-lived discovery marker (embedded in the session) to retrieve the recommended account id, records the request atomically, and notifies active team administrators with the requester's verified details. Clear the short-lived discovery marker once the request is consumed, while retaining the user-level marker to prevent retries. Surface request failures in onboarding so users can ask their team administrator for a direct invite. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/6918?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 2 个月前 | |
chore: db migrations and types for functions configs (#6960) Add db tables and types to support `function`. Tables are similar to current `sync_configs`, `syncs` and `sync_jobs` with the following caveat: - function configs are split between `functions_configs` and `functions_config_version` to clearly mark the difference between a function and its different version (note that the plan is to have version managed internally based on definition and/or code change, instead of having an entry every time customer deploys). None of the tables and types are used yet. I will align the types in the runner SDK and CLI in next PR. Then I will work on function deployment. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/6960?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 2 个月前 | |
feat(auth): add account discovery during new-user onboarding (#6879) Add a short-lived, server-side account-discovery marker for newly created password and managed-auth users. The discovery flow finds and caches the best same-domain account recommendation while exposing only its name to the client. Keep marker persistence best-effort so discovery failures never block signup. No-match, rejection, and discovery-error paths fall back to the existing hear-about-us onboarding guard. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/6879?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 2 个月前 | |
fix(mfa): tolerate authenticator clock drift (NAN-6568) (#7097) NAN-6568 `TOTP_WINDOW` was 1, so we accepted T-1, T and T+1 and nothing else. A device running a minute fast has its valid codes rejected every time. Two changes: 1. The login window goes to 2 2. We now record the offset we observe on each successful verification and check around it as well as around our own clock. Activation gets a wider window of 5 steps. The user is already authenticated at that point so leniency costs nothing, and it is the only place we can learn the offset of a device that is already badly out. With a narrow window there the first code is rejected and the offset never gets seeded at all. Checking both centers, rather than only the stored offset, is deliberate. Pure recentering would lock a user out the moment they fixed their clock, because the stored offset would still be pointing at where the device used to be. [RFC 6238, Section 6 (Resynchronization)](https://www.rfc-editor.org/rfc/rfc6238#section-6) ## Test plan - [x] `npm run ts-build` - [x] `npm run test:integration -- packages/shared/lib/services/mfa.service.integration.test.ts` (9 passed) - [x] `npm run test:integration -- packages/server/lib/controllers/v1/account/mfa/ packages/server/lib/controllers/v1/account/signin.integration.test.ts` (18 passed) - [ ] Marcin confirms he can log in on staging without syncing his phone | 2 个月前 | |
feat(server): add agent session persistence (NAN-6593) (#7152) NAN-6593 Adds the persistence foundation for immutable agent sessions. The table stores resolved connection and compiled toolset snapshots, while the service validates account and environment ownership and indexes active expiry. ## Database fields | Field | Type | Purpose | | --- | --- | --- | | `id` | UUID | Database-generated session identifier | | `account_id` | INTEGER | Owning account, deleted with the account | | `environment_id` | INTEGER | Owning environment, deleted with the environment | | `resolved_connections` | JSONB | Connection selected per integration when the session is created | | `compiled_toolset` | JSONB | Complete reachable toolset, including pinned and searchable tools | | `meta_tools` | JSONB | Resolved per-session meta-tool capability flags | | `expires_at` | TIMESTAMPTZ | Time after which the session must be expired | | `ended_at` | TIMESTAMPTZ, nullable | Time the session was first terminated or expired | | `ended_reason` | TEXT, nullable | Terminal reason: `terminated` or `expired` | | `created_at` | TIMESTAMPTZ | Creation time | | `updated_at` | TIMESTAMPTZ | Last persistence update time | <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7152?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 2 个月前 | |
feat(plans): add audit trail entitlement columns (NAN-6483) (#6966) - Adds `has_audit_trail_control_plane` and `has_audit_trail_access` to `plans`, so audit event ingestion and customer-facing visibility can be gated independently — an account can have its events recorded without being able to see them, which is the point of the reframed rollout. `has_audit_trail_access` covers every surface the customer reads their trail through — the dashboard, the internal API **and** export — so NAN-6344 gates on this same column. - Ships the columns only: **no per-plan defaults and no backfill**. Accounts get onboarded manually with a per-account `UPDATE` so we can enable a few customers for testing first. A follow-up PR adds the per-plan defaults plus a backfill for whatever is left. - Nothing reads or writes these columns yet, so this is inert. The gates land in NAN-6484. ## Why no defaults in `definitions.ts` This is what makes manual onboarding safe rather than just less work. `mergeFlags` skips any key no plan definition declares, so the merged object omits these columns and `changePlan`'s `UPDATE` never touches them — a manual flip survives a plan change in **both** directions. With per-plan defaults present instead, an upgrade would silently grant the entitlement and a downgrade would reset a manually-onboarded account back to its plan default, since a downgrade returns the new plan's flags wholesale. A unit test pins the current behaviour. Worth knowing for the follow-up PR: the moment defaults exist, `changePlan` starts writing these columns again and downgrades start resetting them. The backfill has to be correct at that point, not before. ## Notes for review - The columns can't be deferred even though nothing reads them — `createAccountWithoutEnvironments` spreads `freePlan.flags` into the insert and `changePlan` writes the `mergeFlags` output, so a `DBPlan` field without a column breaks signup. - The two `mergeFlags` case arms are compile-mandatory (the exhaustive `never` check) despite being unreachable until defaults land. - A data-plane column was in the original scope and is deliberately not here: every audited event today is control-plane, so the control-plane flag is checked globally rather than per endpoint. It can be added when data-plane events actually exist. - `down()` is empty per the repo convention that knex rollback is unsupported. ## Test plan - [x] `ts-build` clean across the monorepo — the exhaustive check in `mergeFlags` forces every new key to declare its merge semantics - [x] Unit tests pass (32), including a new one asserting `mergeFlags` leaves both columns out of its output on upgrade and downgrade - [x] Every new assertion verified to fail when the behaviour it guards is broken - [x] Migration applied against a throwaway Postgres DB seeded with pre-existing plan rows: columns land `NOT NULL DEFAULT false`, all existing rows stay `false`, re-running is safe, and a manual per-account flip works - [x] `npm run lint` exit 0, prettier clean - [ ] After deploy: confirm the columns exist and enable the first test accounts manually <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/6966?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> | 2 个月前 | |
feat(audit): gate the audit trail on plan entitlements (NAN-6484) (#6968) Stacked on #6966 — review that first; this PR targets its branch and will retarget to `master` once it merges. - Adds the productized gating for the audit trail. The **two gates are now independent**: emission reads `has_audit_trail_control_plane`, while the dashboard and the read endpoint read `has_audit_trail_access`. An account can be recorded without being able to see its own trail, which is the point of the reframed rollout. - **Turns control-plane ingestion on for paid plans**: a per-plan default so it is applied on upgrade, plus a migration that backfills the existing accounts. `has_audit_trail_access` is deliberately declared on no plan, so it stays off everywhere and is switched on per account by hand. - **Gates `GET /api/v1/audit-trail` on the entitlement.** The endpoint was previously reachable by any RBAC-permitted user while the flag only hid the menu entry — visibility was cosmetic, not enforced. An unentitled account now gets `403 feature_disabled`. ## How the gate resolves ``` FLAG_AUDIT_TRAIL_ENABLED || ( audit-trail flag (Unleash) && plan entitlement ) ``` - **`FLAG_AUDIT_TRAIL_ENABLED`** is a deployment **opt-in** that forces the trail on, bypassing the flag and the plan. It exists for deployments with no flag provider to roll out from — local development above all. It is never set in cloud, where the flag is the kill switch. - **The Unleash flag** is the rollout: percentage or allowlist, plus the kill switch. It defaults `false`, so the rollout only ever advances by an explicit change to it. It is **interim** and will be retired. - **The plan entitlement** is honoured on every account the flag lets through, so widening the flag to 100% still excludes accounts that are not entitled. **A deployment without the plans layer is off, not on.** There is no entitlement to read, so there is nothing to grant. This is deliberately the opposite of `hasRbac`, which treats a plan-less deployment as unrestricted — RBAC is something a self-hoster should get, the audit trail is not. It matters because it is what keeps self-hosted off *structurally*: self-hosted never sets `FLAG_PLAN_ENABLED`, so no plan rows exist there at all (`account.service.ts` only creates one when the flag is on). Relying on the Unleash flag instead would leave self-hosted exposed the day that interim flag is retired. **Everything defaults closed**, and the trade-off is deliberate: if Unleash is unreachable the flag resolves to its default and recording stops, rather than fanning out to every entitled account. ## Rollout practice The `audit-trail` flag already exists, so this is a flag change per environment: 1. **Set the flag strategy to an allowlist of the dogfooding accounts.** The flag is evaluated with `targetingKey = accountUuid`, so per-account strategies and stable percentage buckets both work. 2. **Widen the flag gradually** from there. Because bucketing is keyed on the account uuid, an account that is in stays in as the percentage grows. 3. **To let the account read its trail**, set `has_audit_trail_access` on that account's plan. No plan grants it, so it is always a deliberate per-account act. 4. **To stop everything**, switch the flag off. It gates the UI and the read endpoint as well as ingestion, so it takes the whole feature down without touching plans. Ingestion entitlement needs no manual step: the migration backfills every paid plan and upgrades set it going forward. `FLAG_AUDIT_TRAIL_ENABLED` stays unset in cloud throughout. ## Notes for review - The MFA login-verify middleware runs *before* authentication, so it has no `res.locals.plan` and resolves the plan itself via `getPlanSafe`. One extra query on that endpoint, after the two it already does. - Every `res.locals['account']` assignment in `access.middleware.ts` is paired with a `res.locals['plan']` one, so reading the entitlement from locals cannot silently miss an auth path. - The authz suite now rolls the flag out to every account and seeds `has_audit_trail_access`. Without it, its "deny GET audit-trail" case would still pass — but on `feature_disabled` instead of an RBAC denial, i.e. green while testing nothing. - `free` declares `has_audit_trail_control_plane: false` explicitly rather than omitting it, so a downgrade to free resets the column instead of leaving it on. - Integration suites roll the flag out rather than setting the opt-in, so the plan entitlement stays the thing under test. The `auditable()` unit suite is the reverse: a unit run has no plans, so it uses the opt-in to reach the middleware at all. ## Test plan - [x] `ts-build` clean, `npm run lint` exit 0, prettier clean - [x] 16 unit + 64 integration tests pass across the audit, plans, meta, MFA, read-endpoint and authz suites - [x] Backfill migration run against a throwaway Postgres seeded with pre-existing rows for all 12 plans: every paid plan on, `free` off, read access untouched, safely re-runnable - [x] Deliberately broke each branch and confirmed red: the deployment opt-in, the no-plans branch, the flag default, the kill switch, the ingestion entitlement, the `403`, and the meta flag Verified on dev after deploying this branch (dogfooding account, flipping one thing at a time): - [x] Migration applied; backfill correct — every `growth-v2`/`starter-v2` row entitled to ingestion, every `free` row not, read access off everywhere since no plan declares it - [x] Both entitlements off: no menu entry, nothing ingested - [x] Ingestion only: events land in ClickHouse, still no menu entry - [x] Ingestion + access: menu entry appears and the events are visible - [x] Kill switch: with both entitlements on, disabling the flag stopped ingestion *and* hid the menu — the flag gates both, and takes up to one Unleash poll interval to reach a pod - [x] Management MCP, which has its own emitter: a key scoped to `environment:mcp` calling `integrations_create` is denied and audited. Entitlement off → 4 calls, 0 events; on → 3 calls, 3 `denied` events with `interface: mcp`. Nothing mutated - [ ] After deploy: set the flag strategy per environment, then widen <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Audit trail availability is now controlled by plan entitlements and rollout settings. * Audit recording is enabled for eligible paid plans, while free plans remain excluded. * Added an optional `FLAG_AUDIT_TRAIL_ENABLED` configuration toggle. * Accounts without audit-trail access now receive a clear `feature_disabled` response. * **Bug Fixes** * Audit events now correctly respect the relevant account’s plan entitlement across API, MFA, and MCP activity. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> | 2 个月前 | |
feat(billing): let customers set spend alerts (#7180) ## Problem Customers on usage-based pricing can see their current-period spend, but nothing warns them as it climbs. ## Solution Orb's Alerts API fits, so this configures and surfaces it rather than building a threshold pipeline of our own. - Wrap Orb's alerts in `@nangohq/billing` and add `GET`/`PUT`/`DELETE /api/v1/plans/billing/spend-alert`, gated on the monthly-billed plans that get a spend figure - Handle `subscription.cost_exceeded` and email the Orb invoicing addresses plus the account's verified admins — Orb only webhooks, it doesn't mail customers - De-dup on a claim row: one notification per threshold per billing period, released if every send fails - Clear the alert on any plan change (Orb or Stripe) — a threshold set against one plan's pricing means nothing against another's - Add the Spend alerts section between Usage and Plans, with add / edit / remove Fixes [NAN-6222](https://linear.app/nango/issue/NAN-6222) ## Testing Verified end to end against Orb test mode: saving writes a real `cost_exceeded` alert, editing updates the same alert rather than creating a second, and removing disables it. A genuine Orb delivery arrived over a tunnel and produced the email; a redelivery of the same crossing sent nothing. | 2 个月前 | |
feat(usage): export and cap function runtime in started seconds (#7173) Export function_executions events from the new v2 table. This includes all pre-existing telemetry data points (count, durationMs, customLogs, and compute) as well as the new durationSeconds metering, which tracks each function duration in milliseconds rounded up to started seconds. Add function_duration_seconds across ClickHouse queries, billing APIs, Orb metric mapping, and the billing dashboard (not rendered for now, but wired-in). Add the plan storage, API exposure, execution guards, and metering-side Redis tracking needed to cap this metric; its limit remains null until we are ready to enforce it. The rollout plan: 1. Deploy v2 table definition: ensure data is fed into both tables in parallel. This was done on the 21st, and querying the database shows that from the 22nd we have no deltas between the two tables (apart from the new cols). 2. Deploy this PR, which (i) adds capping capabilities (which won't be enforced), (ii) wires all of the plumbing to display the metric in the UI (which won't be rendered yet) and (iii) exports the Orb events from the new table. This PR should only be merged after asserting the tables are equivalent in production for a few days; which has already been verified. 3. Backfill history for the new table: use the daily aggregates for pre-existing columns and use the 90-days-ttl raw events to recompute the aggregates of the new columns. 4. Flip remaining readers over to the new table (function_executions, function_logs and function_compute_gbms). 5. Clean up old table. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7173?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 2 个月前 | |
feat(plans): cap free function runtime instead of legacy metrics (#7315) Update the Free plan’s usage caps to use function runtime seconds. - Keep the 10-connection limit - Cap function runtime at 10 hours per month - Remove caps from legacy usage metrics - Add coverage for the Free plan cap configuration <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7315?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 1 个月前 | |
chore: add function_runtime in plan with default=lambda (#7230) Adding `function_runtime` to plan | 2 个月前 | |
fix(api): use UUIDs for public environment management (#7309) Use UUIDs instead of numeric IDs throughout the public environment-management API. - Add and backfill a non-null, unique UUID on customer API keys. - Move public environment API-key creation under the environment UUID path. - Resolve environment and API-key UUIDs with account-scoped lookups for create/delete operations. - Return UUIDs from environment and API-key creation responses. - Update audit targets, API types, OpenAPI/reference/generated docs, and integration coverage. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7309?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> | 1 个月前 | |
feat(plans): add the growth add-on for pay-as-you-go (#7301) Pay-as-you-go ships with starter-level flags. The growth feature set — RBAC, OTel, connect-UI customisation — is now unlocked by an optional add-on, modelled in Orb as a standalone price on the subscription. Flags stop being a function of the plan alone and become a function of the plan and the add-on. `POST /api/v1/plans/change` takes the desired end state, `{ orbId, withGrowthFeatures }`. Orb's `schedulePlanChange` can't schedule add-on price removals: it only supports removing plan prices, so changing plan and managing the add-on state are done separately. `mergeFlags` merges plan flags as before, then recomputes the add-on's flags based on the presence of `plans.has_growth_features` — merged flags preserve a per-account override, recomputed ones do not, which makes disabling the add-on actually revoke the features. The additional computation only runs for plans that can carry the add-on, so every other plan is unaffected. Both are asserted to agree before a change is resolved: our record is a mirror of Orb's, and we treat that as an invariant. A mismatch answers 409 rather than guessing, with recovery being a possibility via Orb's webhook or manual intervention. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7301?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 1 个月前 | |
feat(plans): cap free function runtime instead of legacy metrics (#7315) Update the Free plan’s usage caps to use function runtime seconds. - Keep the 10-connection limit - Cap function runtime at 10 hours per month - Remove caps from legacy usage metrics - Add coverage for the Free plan cap configuration <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7315?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 1 个月前 | |
feat(usage): cap free-plan data transfer (#7413) Add a 10 GB monthly data-transfer cap for Free plans. - Add an idempotent plans migration for data_transfer_max - Count billable DTO egress toward monthly capped usage - Enforce the cap for proxy, webhook forwarding, functions, and record reads - Expose the limit through the usage API - Add data-transfer-specific cap messaging and coverage <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7413?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 1 个月前 | |
feat: add OAuth authorization server package (#7463) Adds a reusable OAuth authorization-server package for Nango resources, initially configured for Management MCP. It only supports CIMD. It requires setting up env vars for this to work, but as long as NANGO_MANAGEMENT_MCP_OAUTH_ENABLED is not set, it won't try to fail mounting due to missing env vars Browser session bridging and the React consent flow remain scoped to NAN-6924. Hooking it up to Management MCP is scoped to NAN-6925 and NAN-6926 [NAN-6923](https://linear.app/nango/issue/NAN-6923) <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7463?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 1 个月前 | |
feat(oauth): add dashboard login and consent flow (NAN-6924) (#7481) ## Summary Consent screen for our OAuth server. It has the ability to sign up disabled on the consent screen. Contrary to what we discussed on Slack, the cookie will live on `api.nango.dev` instead of `id.nango.dev` so that it can reuse our dashboards session cookie, which also lives on `api.nango.dev`. We'd need to do an awkward cookie cross-domain hand-over otherwise. <img width="665" height="718" alt="image" src="https://github.com/user-attachments/assets/1d429048-f335-4942-9861-96944138dc71" /> | 1 个月前 | |
feat(plans): growth add-on management cron (#7530) Run a locked hourly cron to: - report enabled growth add-ons on plans that do not support them; - activate due add-ons for eligible plans; - terminate add-ons whose end date has passed. Also adds `growth_features_starts_at` to `plans` in order to unlock the enabling of growth add-ons on a schedule. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7530?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 1 个月前 | |
feat(functions): upsert schedules if needed when deploying functions (#7525) Since there is no atomic transaction between function entries in main db and schedules in orchestrator, we commit the main db function entries before upserting the schedules in orchestrator. The consequence is an orchestrator failure might lead to missing schedules. The opposite workflow (upserting schedules before committing the main db) was discarded because it would lead to orphan schedules that exists even though a function deployment failed, which is a worst outcome. The missing schedules problem is minimized by making deployment self-heal schedules. To achieve this the POST /recurring orchestrator endpoints doesn't fail anymore when schedule already exists and behave like an upsert. The PR also refactors some orchestrator endpoints and internal functions to accept array instead of single item in order to minimize the number of requests. The change is backward compatible but requires orchestrator to be deployed first. Note: scheduled functions execution is still not implemented. That's next PR <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7525?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 1 个月前 | |
feat: delete functions as part of the retention deletion logic (#7602) Add logic to delete function configs, versions, instances and schedules when deleting old data. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7602?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 1 个月前 | |
chore: add function uuid (#7662) Add an unique id to function that will be exposed to customers in the function-related endpoints. | 30 天前 | |
perf: add partial index to functions config for http trigger with subscriptions (#7656) Webhook dispatch looks up for functions with at least one subscription by filtering trigger jsonb. This commit is adding a partial index on `function_config_versions` matching the search predicate (http, not deleted, subscriptions array non-empty) instead of materializing the subscriptions array for all matching rows. Verified locally with lots of synthetic function config versions that the search query is using the index <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7656?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 1 个月前 | |
feat: add PATCH /functions/:uuid to enable/disable (#7703) Disabling a function disables all the existing instances and remove all schedules. Enabling a function re-enable the 'base' instance but not each customer variants, since we don't want to re-enable a variant that was paused directly by customers. ie: enabling variants like creating them is managed by the customers, which is the same behavior as legacy syncs This commit is adding a `enabled` column to the function_instances table, which is also gonna be used to 'pause|unpause' a specific scheduled function. Also adding a share lock mechanism to remove race condition between function enabling/deploying/creation. <!-- Describe the problem and your solution --> <!-- Issue ticket number and link (if applicable) --> <!-- Testing instructions (skip if just adding/editing providers) --> <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7703?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 29 天前 | |
feat(webhooks): add allow unverified webhooks integration option (NAN-7312) (#7726) NAN-7312 Adds an "Allow unverified webhooks" option on integrations, off by default and editable from the integration settings. When it is on, webhooks with a missing or unverifiable signature are processed and still flagged as unverified. Invalid signatures are always rejected. GitHub App, GitHub App OAuth, Gmail, Salesforce and Microsoft Teams now respect the option, with their existing feature flags kept as a fallback. DB: adds `allow_unverified_webhooks boolean NOT NULL DEFAULT false` to `_nango_configs`. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7726?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 27 天前 | |
feat(server): hide the overdue invoices banner for Enterprise plans (#7866) ## Context Enterprise customers often pay late because of slow internal processes, so their engineers see the overdue invoices banner and can't do anything about it. ServiceNow raised this twice. Dunning already handles collection for these accounts. ## Changes - New plan flag `has_overdue_invoices_banner`. When it's off, the overdue invoices endpoint reports nothing overdue without calling Orb, which hides the banner in the sidebar and on Billing & Usage. - Off for `enterprise` and `enterprise-cloud-hosted`, on for every other plan. The migration turns it off for existing Enterprise accounts. - A hidden banner stays hidden across upgrades, and a downgrade resets it to the new plan's value. Fixes [NAN-7513](https://linear.app/nango/issue/NAN-7513/hide-the-overdue-invoices-banner-for-enterprise-plans) ## Testing - Tests cover the flag value on every plan, and an account with the flag off that has an overdue invoice in Orb. - Not verifiable on the webapp preview: this is a server change, so it needs a server deploy to dev. ## Follow-ups - Add the flag to the support Retool dashboard once this is merged and deployed. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7866?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="View guided diff" src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 19 天前 | |
feat: add tags column to function table (#7876) Adding a tags field to `function_config_versions` table. I went for a `jsonb_ops` GIN index in order to potentially support query like 'tags exists' or `any tags ...` <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7876?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="View guided diff" src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 15 天前 | |
feat(webapp): turn off session recordings for BAA accounts (#7970) Fixes [NAN-7698](https://linear.app/nango/issue/NAN-7698/turn-off-session-recordings-for-baa-accounts) ## Context Accounts with a signed HIPAA BAA must not end up in PostHog session recordings, because their screens can show PHI and PostHog AI isn't covered by the BAA. Today recording starts on page load for everyone, before the dashboard knows which account it is. This must ship before #7959, which unmasks text in recordings. ## Changes - Add `has_baa` to accounts (default false), returned as `hasBaa` on `/meta` - Keep `has_baa` out of the team API response - Start PostHog with recording off; record signed-out pages once the user request settles - Record signed-in pages only after `/meta` says no BAA and no impersonation - Run analytics opt-in, identify and recording from one hook in App ## Testing Local stack with the PostHog Dev project key, logged in as `test@nango.dev`. The PR preview can't show this: it runs against the dev API, which has no `hasBaa` yet. 1. Sign in, open Connections and Logs → the recording covers all four pages. 2. Set `has_baa = true` on the account, repeat in a new browser profile → the recording stops at the sign-in page. ## Follow-ups - Customer portal toggle for `has_baa`, then mark the BAA accounts and delete their existing recordings <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/NangoHQ/nango/pull/7970?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="View guided diff" src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a> <!-- End of auto-generated description by cubic. --> | 7 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 2 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 1 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 2 年前 | ||
| 1 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 1 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 1 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 11 个月前 | ||
| 11 个月前 | ||
| 11 个月前 | ||
| 9 个月前 | ||
| 9 个月前 | ||
| 9 个月前 | ||
| 9 个月前 | ||
| 8 个月前 | ||
| 8 个月前 | ||
| 8 个月前 | ||
| 8 个月前 | ||
| 8 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 5 个月前 | ||
| 6 个月前 | ||
| 6 个月前 | ||
| 5 个月前 | ||
| 6 个月前 | ||
| 6 个月前 | ||
| 5 个月前 | ||
| 5 个月前 | ||
| 5 个月前 | ||
| 5 个月前 | ||
| 5 个月前 | ||
| 4 个月前 | ||
| 5 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 3 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 30 天前 | ||
| 1 个月前 | ||
| 29 天前 | ||
| 27 天前 | ||
| 19 天前 | ||
| 15 天前 | ||
| 7 天前 |