1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-09 07:25:19 +02:00

remove ld deps and feature flags

This commit is contained in:
Tyler Myracle 2024-01-10 17:47:43 -06:00
parent b5000404ef
commit 435c6c6fad
20 changed files with 5 additions and 165 deletions

View file

@ -1,6 +1,5 @@
import { useAuth0 } from '@auth0/auth0-react' import { useAuth0 } from '@auth0/auth0-react'
import { useIntercom } from '@maybe-finance/client/shared' import { useIntercom } from '@maybe-finance/client/shared'
import { useLDClient } from 'launchdarkly-react-client-sdk'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useEffect } from 'react' import { useEffect } from 'react'
import * as Sentry from '@sentry/react' import * as Sentry from '@sentry/react'
@ -8,7 +7,6 @@ import * as Sentry from '@sentry/react'
export default function APM() { export default function APM() {
const { user } = useAuth0() const { user } = useAuth0()
const router = useRouter() const router = useRouter()
const ld = useLDClient()
const intercom = useIntercom() const intercom = useIntercom()
// Boot intercom // Boot intercom
@ -36,18 +34,5 @@ export default function APM() {
} }
}, [user]) }, [user])
// Identify LaunchDarkly user
useEffect(() => {
if (ld && user) {
ld.waitUntilReady().then(() => {
ld.identify({
key: user.sub,
email: user.email,
name: user.name,
})
})
}
}, [ld, user])
return null return null
} }

View file

@ -10,17 +10,14 @@ import {
UserAccountContextProvider, UserAccountContextProvider,
AuthProvider, AuthProvider,
} from '@maybe-finance/client/shared' } from '@maybe-finance/client/shared'
import type { ClientType } from '@maybe-finance/client/shared'
import { AccountsManager } from '@maybe-finance/client/features' import { AccountsManager } from '@maybe-finance/client/features'
import { AccountContextProvider } from '@maybe-finance/client/shared' import { AccountContextProvider } from '@maybe-finance/client/shared'
import * as Sentry from '@sentry/react' import * as Sentry from '@sentry/react'
import { BrowserTracing } from '@sentry/tracing' import { BrowserTracing } from '@sentry/tracing'
import { useFlags, withLDProvider } from 'launchdarkly-react-client-sdk'
import env from '../env' import env from '../env'
import '../styles.css' import '../styles.css'
import { withAuthenticationRequired } from '@auth0/auth0-react' import { withAuthenticationRequired } from '@auth0/auth0-react'
import ModalManager from '../components/ModalManager' import ModalManager from '../components/ModalManager'
import Maintenance from '../components/Maintenance'
import Meta from '../components/Meta' import Meta from '../components/Meta'
import APM from '../components/APM' import APM from '../components/APM'
@ -51,7 +48,7 @@ const WithAuth = withAuthenticationRequired(function ({ children }: PropsWithChi
) )
}) })
function App({ export default function App({
Component: Page, Component: Page,
pageProps, pageProps,
}: AppProps & { }: AppProps & {
@ -60,15 +57,8 @@ function App({
isPublic?: boolean isPublic?: boolean
} }
}) { }) {
const flags = useFlags() as ClientType.ClientSideFeatureFlag
const getLayout = Page.getLayout ?? ((page) => page) const getLayout = Page.getLayout ?? ((page) => page)
// Maintenance Guard
if (flags.maintenance) {
return <Maintenance />
}
return ( return (
<LogProvider logger={console}> <LogProvider logger={console}>
<ErrorBoundary <ErrorBoundary
@ -98,9 +88,3 @@ function App({
</LogProvider> </LogProvider>
) )
} }
export default withLDProvider<{ Component; pageProps }>({
clientSideID: env.NEXT_PUBLIC_LD_CLIENT_SIDE_ID,
// Prevent a new LD user being registered on each page load by always initializing with the same key
user: { key: 'anonymous-client', anonymous: true },
})(App)

View file

@ -18,7 +18,6 @@ import { resetUser } from './utils/user'
import { createTestInvestmentAccount } from './utils/account' import { createTestInvestmentAccount } from './utils/account'
import { default as _plaid } from '../lib/plaid' import { default as _plaid } from '../lib/plaid'
jest.mock('launchdarkly-node-server-sdk')
jest.mock('../middleware/validate-plaid-jwt.ts') jest.mock('../middleware/validate-plaid-jwt.ts')
jest.mock('bull') jest.mock('bull')
jest.mock('plaid') jest.mock('plaid')

View file

@ -12,7 +12,6 @@ import { default as _plaid } from '../lib/plaid'
import nock from 'nock' import nock from 'nock'
import { resetUser } from './utils/user' import { resetUser } from './utils/user'
jest.mock('launchdarkly-node-server-sdk')
jest.mock('../middleware/validate-plaid-jwt.ts') jest.mock('../middleware/validate-plaid-jwt.ts')
jest.mock('plaid') jest.mock('plaid')

View file

@ -8,8 +8,6 @@ import stripe from '../lib/stripe'
import { PgService } from '@maybe-finance/server/shared' import { PgService } from '@maybe-finance/server/shared'
import { DateTime } from 'luxon' import { DateTime } from 'luxon'
jest.mock('launchdarkly-node-server-sdk')
const prisma = new PrismaClient() const prisma = new PrismaClient()
const logger = createLogger({ transports: new transports.Console() }) const logger = createLogger({ transports: new transports.Console() })

View file

@ -1,4 +1,4 @@
import type { IFeatureFlagService, IMarketDataService } from '@maybe-finance/server/shared' import type { IMarketDataService } from '@maybe-finance/server/shared'
import type { import type {
IAccountQueryService, IAccountQueryService,
IInstitutionService, IInstitutionService,
@ -13,7 +13,6 @@ import {
EndpointFactory, EndpointFactory,
QueueService, QueueService,
PgService, PgService,
LaunchDarklyFeatureFlagService,
PolygonMarketDataService, PolygonMarketDataService,
CacheService, CacheService,
ServerUtil, ServerUtil,
@ -55,7 +54,6 @@ import {
} from '@maybe-finance/server/features' } from '@maybe-finance/server/features'
import { SharedType } from '@maybe-finance/shared' import { SharedType } from '@maybe-finance/shared'
import prisma from './prisma' import prisma from './prisma'
import ldClient from './ldClient'
import plaid, { getPlaidWebhookUrl } from './plaid' import plaid, { getPlaidWebhookUrl } from './plaid'
import finicity, { getFinicityTxPushUrl, getFinicityWebhookUrl } from './finicity' import finicity, { getFinicityTxPushUrl, getFinicityWebhookUrl } from './finicity'
import stripe from './stripe' import stripe from './stripe'
@ -74,8 +72,6 @@ const redis = new Redis(env.NX_REDIS_URL, {
retryStrategy: ServerUtil.redisRetryStrategy({ maxAttempts: 5 }), retryStrategy: ServerUtil.redisRetryStrategy({ maxAttempts: 5 }),
}) })
const featureFlagService: IFeatureFlagService = new LaunchDarklyFeatureFlagService(ldClient)
export const queueService = new QueueService( export const queueService = new QueueService(
logger.child({ service: 'QueueService' }), logger.child({ service: 'QueueService' }),
process.env.NODE_ENV === 'test' process.env.NODE_ENV === 'test'
@ -352,7 +348,6 @@ export async function createContext(req: Request) {
valuationService, valuationService,
institutionService, institutionService,
cryptoService, cryptoService,
featureFlagService,
queueService, queueService,
plaidService, plaidService,
plaidWebhooks, plaidWebhooks,

View file

@ -1,6 +0,0 @@
import { init } from 'launchdarkly-node-server-sdk'
import env from '../../env'
const ldClient = init(env.NX_LD_SDK_KEY, { offline: process.env.NODE_ENV === 'test' })
export default ldClient

View file

@ -1,23 +1,7 @@
import { createLogger } from '@maybe-finance/server/shared' import { createLogger } from '@maybe-finance/server/shared'
import ldClient from './ldClient'
const logger = createLogger({ const logger = createLogger({
level: 'info', level: 'info',
}) })
function setLevel() {
ldClient
.variation('server-log-level', { key: 'anonymous-server', anonymous: true }, 'info')
.then((level) => {
logger.level = level
logger[level](`Server logger using level: ${level}`)
})
}
// Don't configure for Jest
if (process.env.NODE_ENV !== 'test') {
ldClient.waitForInitialization().then(setLevel)
ldClient.on('update:server-log-level', setLevel)
}
export default logger export default logger

View file

@ -1,5 +1,4 @@
import type { Express } from 'express' import type { Express } from 'express'
import ldClient from '../lib/ldClient'
type MaintenanceOptions = { type MaintenanceOptions = {
statusCode?: number statusCode?: number
@ -9,28 +8,9 @@ type MaintenanceOptions = {
export default function maintenance( export default function maintenance(
app: Express, app: Express,
{ statusCode = 503, path = '/maintenance', featureKey = 'maintenance' }: MaintenanceOptions = {} { statusCode = 503, path = '/maintenance' }: MaintenanceOptions = {}
) { ) {
let enabled = false const enabled = false
function loadFeatureFlag() {
ldClient
.waitForInitialization()
.then((ld) => {
ld.variation(featureKey, { key: 'anonymous-server', anonymous: true }, false).then(
(flag) => (enabled = flag)
)
})
.catch((err) => {
console.error(`error loading feature flag`, err)
})
}
loadFeatureFlag()
ldClient.on(`update:${featureKey}`, () => {
loadFeatureFlag()
})
app.get(path, async (req, res) => { app.get(path, async (req, res) => {
res.status(200).json({ enabled }) res.status(200).json({ enabled })

View file

@ -2,7 +2,6 @@ import type { AddressInfo } from 'net'
import env from './env' import env from './env'
import app from './app/app' import app from './app/app'
import logger from './app/lib/logger' import logger from './app/lib/logger'
import ldClient from './app/lib/ldClient'
import * as Sentry from '@sentry/node' import * as Sentry from '@sentry/node'
process.on('uncaughtException', function (error) { process.on('uncaughtException', function (error) {
@ -22,5 +21,4 @@ const server = app.listen(env.NX_PORT, () => {
// Handle SIGTERM coming from ECS Fargate // Handle SIGTERM coming from ECS Fargate
process.on('SIGTERM', () => server.close()) process.on('SIGTERM', () => server.close())
server.on('close', () => ldClient.close())
server.on('error', (err) => logger.error('Server failed to start from main.ts', err)) server.on('error', (err) => logger.error('Server failed to start from main.ts', err))

View file

@ -18,7 +18,6 @@ import '../../main'
import { queueService, securityPricingService } from '../lib/di' import { queueService, securityPricingService } from '../lib/di'
jest.mock('plaid') jest.mock('plaid')
jest.mock('launchdarkly-node-server-sdk')
// For TypeScript support // For TypeScript support
const plaid = jest.mocked(_plaid) const plaid = jest.mocked(_plaid)

View file

@ -40,13 +40,12 @@ import {
EmailProcessor, EmailProcessor,
TransactionService, TransactionService,
} from '@maybe-finance/server/features' } from '@maybe-finance/server/features'
import type { IFeatureFlagService, IMarketDataService } from '@maybe-finance/server/shared' import type { IMarketDataService } from '@maybe-finance/server/shared'
import { import {
BullQueueFactory, BullQueueFactory,
CacheService, CacheService,
CryptoService, CryptoService,
InMemoryQueueFactory, InMemoryQueueFactory,
LaunchDarklyFeatureFlagService,
PgService, PgService,
PolygonMarketDataService, PolygonMarketDataService,
QueueService, QueueService,
@ -58,7 +57,6 @@ import logger from './logger'
import prisma from './prisma' import prisma from './prisma'
import plaid from './plaid' import plaid from './plaid'
import finicity from './finicity' import finicity from './finicity'
import ldClient from './ldClient'
import postmark from './postmark' import postmark from './postmark'
import { managementClient } from './auth0' import { managementClient } from './auth0'
import stripe from './stripe' import stripe from './stripe'
@ -71,7 +69,6 @@ const redis = new Redis(env.NX_REDIS_URL, {
retryStrategy: ServerUtil.redisRetryStrategy({ maxAttempts: 5 }), retryStrategy: ServerUtil.redisRetryStrategy({ maxAttempts: 5 }),
}) })
export const featureFlagService: IFeatureFlagService = new LaunchDarklyFeatureFlagService(ldClient)
export const cryptoService = new CryptoService(env.NX_DATABASE_SECRET) export const cryptoService = new CryptoService(env.NX_DATABASE_SECRET)
export const pgService = new PgService(logger.child({ service: 'PgService' }), env.NX_DATABASE_URL) export const pgService = new PgService(logger.child({ service: 'PgService' }), env.NX_DATABASE_URL)

View file

@ -1,6 +0,0 @@
import { init } from 'launchdarkly-node-server-sdk'
import env from '../../env'
const ldClient = init(env.NX_LD_SDK_KEY, { offline: process.env.NODE_ENV === 'test' })
export default ldClient

View file

@ -1,23 +1,7 @@
import { createLogger } from '@maybe-finance/server/shared' import { createLogger } from '@maybe-finance/server/shared'
import ldClient from './ldClient'
const logger = createLogger({ const logger = createLogger({
level: 'info', level: 'info',
}) })
function setLevel() {
ldClient
.variation('workers-log-level', { key: 'anonymous-server', anonymous: true }, 'info')
.then((level) => {
logger.level = level
logger[level](`Workers logger using level: ${level}`)
})
}
// Don't configure for Jest
if (process.env.NODE_ENV !== 'test') {
ldClient.waitForInitialization().then(setLevel)
ldClient.on('update:workers-log-level', setLevel)
}
export default logger export default logger

View file

@ -170,15 +170,6 @@ export class ServerStack extends Stack {
} }
) )
), ),
NX_LD_SDK_KEY: ECSSecret.fromSsmParameter(
StringParameter.fromSecureStringParameterAttributes(
this,
'LaunchDarklySDKKeyParam',
{
parameterName: '/providers/NX_LD_SDK_KEY',
}
)
),
NX_POLYGON_API_KEY: ECSSecret.fromSsmParameter( NX_POLYGON_API_KEY: ECSSecret.fromSsmParameter(
StringParameter.fromSecureStringParameterAttributes( StringParameter.fromSecureStringParameterAttributes(
this, this,

View file

@ -124,15 +124,6 @@ export class WorkersStack extends Stack {
} }
) )
), ),
NX_LD_SDK_KEY: ECSSecret.fromSsmParameter(
StringParameter.fromSecureStringParameterAttributes(
this,
'LaunchDarklySDKKeyParam',
{
parameterName: '/providers/NX_LD_SDK_KEY',
}
)
),
NX_POLYGON_API_KEY: ECSSecret.fromSsmParameter( NX_POLYGON_API_KEY: ECSSecret.fromSsmParameter(
StringParameter.fromSecureStringParameterAttributes( StringParameter.fromSecureStringParameterAttributes(
this, this,

View file

@ -1,5 +1 @@
export type MetricStatus = 'coming-soon' | 'under-construction' | 'active' export type MetricStatus = 'coming-soon' | 'under-construction' | 'active'
export type ClientSideFeatureFlag = Partial<{
maintenance: boolean
}>

View file

@ -1,25 +0,0 @@
import type { LDClient, LDUser } from 'launchdarkly-node-server-sdk'
export interface IFeatureFlagService {
getFlag<TValue = any>(flagKey: string, defaultValue: TValue, user?: LDUser): Promise<TValue>
}
export class LaunchDarklyFeatureFlagService implements IFeatureFlagService {
constructor(private readonly ldClient: LDClient) {}
async getFlag<TValue = any>(
flagKey: string,
defaultValue: TValue,
user?: LDUser
): Promise<TValue> {
if (!this.ldClient) return defaultValue
await this.ldClient.waitForInitialization()
return await this.ldClient.variation(
flagKey,
user ?? { key: 'anonymous-server', anonymous: true },
defaultValue
)
}
}

View file

@ -1,5 +1,4 @@
export * from './crypto.service' export * from './crypto.service'
export * from './feature-flag.service'
export * from './queue.service' export * from './queue.service'
export * from './queue' export * from './queue'
export * from './cache.service' export * from './cache.service'

View file

@ -121,8 +121,6 @@
"jwk-to-pem": "^2.0.5", "jwk-to-pem": "^2.0.5",
"jwks-rsa": "^3.0.0", "jwks-rsa": "^3.0.0",
"jwt-decode": "^3.1.2", "jwt-decode": "^3.1.2",
"launchdarkly-node-server-sdk": "^6.4.3",
"launchdarkly-react-client-sdk": "^2.25.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"luxon": "^3.1.0", "luxon": "^3.1.0",
"mime-types": "^2.1.35", "mime-types": "^2.1.35",