diff --git a/.env.example b/.env.example index fb329150..abd0167b 100644 --- a/.env.example +++ b/.env.example @@ -1,27 +1,60 @@ -# Used by `prisma` commands -NX_DATABASE_URL=postgresql://maybe:maybe@localhost:5433/maybe_local -NX_DATABASE_SECRET= - -# Market data API keys (https://polygon.io) -NX_POLYGON_API_KEY= - -# If using free ngrok account for webhooks -NGROK_AUTH_TOKEN= +######################################################################## +# AUTHENTICATION +######################################################################## # Generate a new secret using openssl rand -base64 32 NEXTAUTH_SECRET= NEXTAUTH_URL=http://localhost:4200 NX_NEXTAUTH_URL=http://localhost:4200 -NX_PLAID_SECRET= -NX_FINICITY_APP_KEY= -NX_FINICITY_PARTNER_SECRET= +######################################################################## +# WEBHOOKS +######################################################################## -# Teller API keys (https://teller.io) +# We use ngrok to expose a local development environment to the internet +# You can sign up for a free account and get an API key at https://ngrok.com +NGROK_AUTH_TOKEN= + +######################################################################## +# DATABASE +######################################################################## + +NX_DATABASE_URL=postgresql://maybe:maybe@localhost:5433/maybe_local +NX_DATABASE_SECRET= + +######################################################################## +# FINANICAL DATA SOURCES +######################################################################## + +# Market Data +# We use Polygon.io for market data. You can sign up for a free account +# and get an API key for individual use at https://polygon.io +NX_POLYGON_API_KEY= + +# Automated banking data +# We use Teller.io for automated banking data. You can sign up for a free +# account and get a free API key at https://teller.io NX_TELLER_SIGNING_SECRET= NX_TELLER_APP_ID= +NX_TELLER_ENV=sandbox -# Email credentials +######################################################################## +# EMAIL +######################################################################## + +# We use Postmark for transactional emails. You can sign up for a free account +# and get a free API key at https://postmarkapp.com NX_POSTMARK_FROM_ADDRESS=account@example.com NX_POSTMARK_REPLY_TO_ADDRESS=support@example.com NX_POSTMARK_API_TOKEN= + + +######################################################################## +# DEPRECATING +# We're in the process of removing code that requires the following +# environment variables. They will be removed in a future release, but +# for now, they are still required. +######################################################################## +NX_PLAID_SECRET= +NX_FINICITY_APP_KEY= +NX_FINICITY_PARTNER_SECRET= \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 67e8d549..c133fbea 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -4,6 +4,7 @@ about: Create a report to help us improve title: '' labels: bug assignees: '' + --- **Describe the bug** diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature-request-or-improvement.md similarity index 76% rename from .github/ISSUE_TEMPLATE/feature_request.md rename to .github/ISSUE_TEMPLATE/feature-request-or-improvement.md index 2f28cead..3fb9fcaf 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature-request-or-improvement.md @@ -1,12 +1,13 @@ --- -name: Feature request -about: Suggest an idea for this project +name: Feature request or improvement +about: Suggest a new feature or improvement title: '' labels: '' assignees: '' + --- -**Is your feature request related to a problem? Please describe.** +**Is your request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** diff --git a/README.md b/README.md index 396cf5b1..a3c8eca8 100644 --- a/README.md +++ b/README.md @@ -57,13 +57,14 @@ Then run the following yarn commands: ``` yarn install -yarn run dev:services +yarn run dev:services:all yarn prisma:migrate:dev yarn prisma:seed yarn dev ``` ## Contributing + To contribute, please see our [contribution guide](https://github.com/maybe-finance/maybe/blob/main/CONTRIBUTING.md). ## High-priority issues @@ -91,9 +92,9 @@ To pull market data in (for investments), you'll need a Polygon.io API key. You - [Handling money](https://github.com/maybe-finance/maybe/wiki/Handling-Money) - [REST API](https://github.com/maybe-finance/maybe/wiki/REST-API) - ## Repo Activity -![Repo Activity](https://repobeats.axiom.co/api/embed/7866c9790deba0baf63ca1688b209130b306ea4e.svg "Repobeats analytics image") + +![Repo Activity](https://repobeats.axiom.co/api/embed/7866c9790deba0baf63ca1688b209130b306ea4e.svg 'Repobeats analytics image') ## Credits diff --git a/apps/client/pages/upgrade.tsx b/apps/client/pages/upgrade.tsx index a0edd511..05ca2feb 100644 --- a/apps/client/pages/upgrade.tsx +++ b/apps/client/pages/upgrade.tsx @@ -1,20 +1,23 @@ -import { Button } from '@maybe-finance/design-system' -import Link from 'next/link' +import { UpgradeTakeover } from '@maybe-finance/client/features' +import { useUserApi } from '@maybe-finance/client/shared' +import { useRouter } from 'next/router' export default function UpgradePage() { + const router = useRouter() + + const { useSubscription } = useUserApi() + const subscription = useSubscription() + return ( -
-

Signups have been disabled.

-

- Maybe will be shutting down on July 31.{' '} - - Details and FAQ - -

- -
+ + router.push( + !subscription.data || subscription.data?.subscribed + ? '/' + : '/settings?tab=billing' + ) + } + /> ) } diff --git a/apps/server/src/app/lib/endpoint.ts b/apps/server/src/app/lib/endpoint.ts index 01856bc3..8e01b00d 100644 --- a/apps/server/src/app/lib/endpoint.ts +++ b/apps/server/src/app/lib/endpoint.ts @@ -43,6 +43,7 @@ import { FinicityWebhookHandler, PlaidWebhookHandler, TellerService, + TellerETL, TellerWebhookHandler, InsightService, SecurityPricingService, @@ -53,7 +54,6 @@ import { ProjectionCalculator, StripeWebhookHandler, } from '@maybe-finance/server/features' -import { SharedType } from '@maybe-finance/shared' import prisma from './prisma' import plaid, { getPlaidWebhookUrl } from './plaid' import finicity, { getFinicityTxPushUrl, getFinicityWebhookUrl } from './finicity' @@ -149,8 +149,10 @@ const tellerService = new TellerService( logger.child({ service: 'TellerService' }), prisma, teller, + new TellerETL(logger.child({ service: 'TellerETL' }), prisma, teller, cryptoService), + cryptoService, getTellerWebhookUrl(), - true + env.NX_TELLER_ENV === 'sandbox' ) // account-connection @@ -158,6 +160,7 @@ const tellerService = new TellerService( const accountConnectionProviderFactory = new AccountConnectionProviderFactory({ plaid: plaidService, finicity: finicityService, + teller: tellerService, }) const transactionStrategy = new TransactionBalanceSyncStrategy( diff --git a/apps/server/src/app/lib/postmark.ts b/apps/server/src/app/lib/postmark.ts index 48eddf1b..ff0e87c6 100644 --- a/apps/server/src/app/lib/postmark.ts +++ b/apps/server/src/app/lib/postmark.ts @@ -1,6 +1,6 @@ import { ServerClient } from 'postmark' import env from '../../env' -const postmark = new ServerClient(env.NX_POSTMARK_API_TOKEN) +const postmark = env.NX_POSTMARK_API_TOKEN ? new ServerClient(env.NX_POSTMARK_API_TOKEN) : undefined export default postmark diff --git a/apps/server/src/env.ts b/apps/server/src/env.ts index e69f5f4d..11fd2f76 100644 --- a/apps/server/src/env.ts +++ b/apps/server/src/env.ts @@ -43,6 +43,7 @@ const envSchema = z.object({ NX_TELLER_SIGNING_SECRET: z.string().default('REPLACE_THIS'), NX_TELLER_APP_ID: z.string().default('REPLACE_THIS'), + NX_TELLER_ENV: z.string().default('sandbox'), NX_SENTRY_DSN: z.string().optional(), NX_SENTRY_ENV: z.string().optional(), @@ -74,7 +75,7 @@ const envSchema = z.object({ NX_POSTMARK_FROM_ADDRESS: z.string().default('account@maybe.co'), NX_POSTMARK_REPLY_TO_ADDRESS: z.string().default('support@maybe.co'), - NX_POSTMARK_API_TOKEN: z.string().default('REPLACE_THIS'), + NX_POSTMARK_API_TOKEN: z.string().optional(), }) const env = envSchema.parse(process.env) diff --git a/apps/workers/src/app/lib/di.ts b/apps/workers/src/app/lib/di.ts index 55f3341a..987ebedd 100644 --- a/apps/workers/src/app/lib/di.ts +++ b/apps/workers/src/app/lib/di.ts @@ -28,6 +28,8 @@ import { LoanBalanceSyncStrategy, PlaidETL, PlaidService, + TellerETL, + TellerService, SecurityPricingProcessor, SecurityPricingService, TransactionBalanceSyncStrategy, @@ -55,6 +57,7 @@ import logger from './logger' import prisma from './prisma' import plaid from './plaid' import finicity from './finicity' +import teller from './teller' import postmark from './postmark' import stripe from './stripe' import env from '../../env' @@ -124,11 +127,22 @@ const finicityService = new FinicityService( env.NX_FINICITY_ENV === 'sandbox' ) +const tellerService = new TellerService( + logger.child({ service: 'TellerService' }), + prisma, + teller, + new TellerETL(logger.child({ service: 'TellerETL' }), prisma, teller, cryptoService), + cryptoService, + '', + env.NX_TELLER_ENV === 'sandbox' +) + // account-connection const accountConnectionProviderFactory = new AccountConnectionProviderFactory({ plaid: plaidService, finicity: finicityService, + teller: tellerService, }) const transactionStrategy = new TransactionBalanceSyncStrategy( diff --git a/apps/workers/src/app/lib/postmark.ts b/apps/workers/src/app/lib/postmark.ts index 48eddf1b..ff0e87c6 100644 --- a/apps/workers/src/app/lib/postmark.ts +++ b/apps/workers/src/app/lib/postmark.ts @@ -1,6 +1,6 @@ import { ServerClient } from 'postmark' import env from '../../env' -const postmark = new ServerClient(env.NX_POSTMARK_API_TOKEN) +const postmark = env.NX_POSTMARK_API_TOKEN ? new ServerClient(env.NX_POSTMARK_API_TOKEN) : undefined export default postmark diff --git a/apps/workers/src/app/lib/teller.ts b/apps/workers/src/app/lib/teller.ts new file mode 100644 index 00000000..00a7beb1 --- /dev/null +++ b/apps/workers/src/app/lib/teller.ts @@ -0,0 +1,5 @@ +import { TellerApi } from '@maybe-finance/teller-api' + +const teller = new TellerApi() + +export default teller diff --git a/apps/workers/src/env.ts b/apps/workers/src/env.ts index c41d9692..f58963bf 100644 --- a/apps/workers/src/env.ts +++ b/apps/workers/src/env.ts @@ -17,6 +17,7 @@ const envSchema = z.object({ NX_TELLER_SIGNING_SECRET: z.string().default('REPLACE_THIS'), NX_TELLER_APP_ID: z.string().default('REPLACE_THIS'), + NX_TELLER_ENV: z.string().default('sandbox'), NX_SENTRY_DSN: z.string().optional(), NX_SENTRY_ENV: z.string().optional(), @@ -29,7 +30,7 @@ const envSchema = z.object({ NX_POSTMARK_FROM_ADDRESS: z.string().default('account@maybe.co'), NX_POSTMARK_REPLY_TO_ADDRESS: z.string().default('support@maybe.co'), - NX_POSTMARK_API_TOKEN: z.string().default('REPLACE_THIS'), + NX_POSTMARK_API_TOKEN: z.string().optional(), NX_STRIPE_SECRET_KEY: z.string().default('sk_test_REPLACE_THIS'), NX_CDN_PRIVATE_BUCKET: z.string().default('REPLACE_THIS'), diff --git a/libs/client/features/src/layout/DesktopLayout.tsx b/libs/client/features/src/layout/DesktopLayout.tsx index e61fbdac..21023d6b 100644 --- a/libs/client/features/src/layout/DesktopLayout.tsx +++ b/libs/client/features/src/layout/DesktopLayout.tsx @@ -23,6 +23,7 @@ import { } from 'react-icons/ri' import { Button, Tooltip } from '@maybe-finance/design-system' import { MenuPopover } from './MenuPopover' +import { UpgradePrompt } from '../user-billing' import { SidebarOnboarding } from '../onboarding' import { useSession } from 'next-auth/react' @@ -227,7 +228,7 @@ export function DesktopLayout({ children, sidebar }: DesktopLayoutProps) { className="p-3 text-base bg-gray-700 rounded-lg cursor-pointer hover:bg-gray-600" onClick={() => setOnboardingExpanded(true)} > -
+

Getting started

{onboarding.data.isComplete && ( @@ -337,6 +338,8 @@ function DefaultContent({ {onboarding && onboarding} + +

{name ?? ''}

diff --git a/libs/client/features/src/layout/MobileLayout.tsx b/libs/client/features/src/layout/MobileLayout.tsx index 206df618..585af1dd 100644 --- a/libs/client/features/src/layout/MobileLayout.tsx +++ b/libs/client/features/src/layout/MobileLayout.tsx @@ -12,6 +12,7 @@ import { Button } from '@maybe-finance/design-system' import { MenuPopover } from './MenuPopover' import Link from 'next/link' import { useRouter } from 'next/router' +import { UpgradePrompt } from '../user-billing' import { ProfileCircle } from '@maybe-finance/client/shared' import { usePopoutContext, LayoutContextProvider } from '@maybe-finance/client/shared' import classNames from 'classnames' @@ -90,10 +91,10 @@ function NavItem({ className="absolute inset-0" transition={{ duration: 0.3 }} > -
+
)} - + {label}
@@ -138,7 +139,7 @@ export function MobileLayout({ children, sidebar }: MobileLayoutProps) { >