Narration / Transcript
Building an AI-powered Financial Behavior Analyzer with NodeJS, Python, SvelteKit, and TailwindCSS - Part 4: Frontend and WebSocket
This is what the narrator says, not what the page shows: equations are read as sentences, code blocks are described, and citations are spoken as citations.
- 0:00
Introduction
- 0:02
In this part of the series, we will implement our backend service's WebSocket handler and begin building the frontend. This will enable real-time communication between the backend and frontend, allowing us to display analysis results as they become available.
- 0:19
Prerequisite
- 0:20
The main prerequisite is that you have gone through the previous articles in this series. This ensures you have the necessary context and environment set up.
- 0:31
Source code Sirneij/finance-analyzer
- 0:34
An AI-powered financial behavior analyzer and advisor written in Python (aiohttp) and TypeScript (ExpressJS & SvelteKit with Svelte 5) svelte typescript python javascript css3 html5
- 0:50
Implementation
- 0:52
Step: WebSocket handler
- 0:54
To provide real-time updates for financial data analysis and summaries, we use WebSockets, a bidirectional communication protocol, instead of traditional HTTP requests that require constant refreshing. The Transaction Web Socket Handler function manages WebSocket connections: The TypeScript code below defines Transaction Web Socket Handler and handle Action, 103 lines, from src slash websockets slash transaction dot websocket dot ts.
- 1:22
Using the ws module (installed in the previous article), this function sets up the WebSocket connection and defines handlers for incoming messages, connection close, and errors. As soon as it receives a message, the callback for the message event listener gets fired and it works as follows:
- 1:41
Parses incoming messages as JSON, expecting an array of actions.
- 1:47
Validates the format of each action, ensuring it contains action and user Id.
- 1:53
Validates the user Id to ensure it is a valid Mongoose ObjectId.
- 1:58
Uses a switch statement to handle different actions (analyze and summary), and
- 2:03
Calls the handle Action function to process each valid action.
- 2:08
The handle Action processes specific actions requested by the client by retrieving transactions for the specified user Id using Transaction Service dot find Transactions By User Id static method discussed in the previous article. Any transactions retrieved are sent via the Transaction Service dot connect To Utility Server method to the utility server for analysis or summary.
- 2:34
Let's register this handler with our app: The TypeScript code below defines start Server, 26 lines, from src slash app dot ts.
- 2:44
With that, we conclude the backend service. Now it's time to set SvelteKit up with TailwindCSS.
- 2:51
Step 2: SvelteKit with TailwindCSS
- 2:55
To setup a SvelteKit project with TailwindCSS, we will refer to the official TailwindCSS guide with some modifications from the migration guide I previously wrote.
- 3:07
First, create a new SvelteKit project via the Svelte 5 sv CLI: The shell code below is 1 line.
- 3:15
You will be prompted to install sv which you should accent to. Your interaction with the CLI should look like this: The shell code below is 46 lines.
- 3:25
Feel free to modify any of the steps as you like. You can change directory into the newly created project and install the dependencies.
- 3:34
For some reasons, the tailwindcss installed by sv was version 3.4.17. However, at the time of writting this, TailwindCSS is already at version 4.0.2. So we need to migrate. To incept the migration steps, run this command: The shell code below is 1 line.
- 3:54
You should get something like this: The shell code below is 46 lines.
- 3:59
It will magically modify your src slash app dot css to look like: The CSS code below is 22 lines.
- 4:08
tailwind dot config dot ts will be removed and postcss dot config dot js will be modified. We need to make a slight change to src slash app dot css and vite dot config dot js: The CSS code below is 16 lines, from src slash app dot css.
- 4:28
We need line 6 so that we can leverage classes (and later, prefers color scheme) to dynamically switch themes.
- 4:36
Next is vite dot config dot js: The JavaScript code below is 11 lines, from vite dot config dot js.
- 4:45
That concludes the initial setup.
- 4:47
Step 3: Leverage prefers color scheme in theme toggling
- 4:52
Many modern operating systems (OS) have made dark mode a first-class feature, and tuning your web application to honor the user's OS theme preference provides a better user experience. The CSS prefers color scheme media feature makes this easy to implement. Here's how to leverage it: The HTML code below is 53 lines, from src slash app dot html.
- 5:16
This short HTML code does a lot of things. First, the theme color meta tags adapt the browser's UI (e.g., address bar) to match the theme. prefers color scheme is used to set different colors for light and dark modes. Then, in the script, we first checks if the user has a saved theme preference in local Storage. If not, it checks the OS-level dark mode setting using window dot match Media of prefers-color-scheme: dark. It then applies the appropriate theme by adding or removing the dark class to the less than html greater than element. This class is used to toggle CSS styles (e.g., using dark:bg-gray-900 in the less than body greater than class). Finally, it listens for changes in the OS-level dark mode setting and updates the theme accordingly (but only if the user hasn't explicitly set a preference). We also used the less than body greater than element to set the background and text colors based on the presence of the dark class using Tailwind CSS classes.
- 6:19
Step 4: Theme switching logic with icons
- 6:23
Before we proceed to creating the authentication/login page, let's make a simple Theme Switcher dot svelte component: The HTML code below defines toggle Theme, 26 lines, from src slash lib slash components slash reusables slash Theme Switcher dot svelte.
- 6:42
Since this app will be fully powered by Svelte 5, we are using the dollar props rune to accept any attributes passed to the component as props, and the spread operator helps expand these attributes. We also declared a reactive variable with the dollar state rune, and it gets updated in the dollar effect rune and in the toggle Theme function. The dollar effect rune runs once on component initialization and whenever its dependencies change. In this case, it checks if the dark class is present on the less than html greater than element and updates the is Dark state accordingly. This ensures the component's initial state matches the current theme. As for the toggle Theme function, it gets called when the button is clicked and toggles the is Dark state, saves the selected theme ("dark" or "light") to local Storage, and toggles the dark class on the less than html greater than element. The less than button greater than element calls the toggle Theme function on click and passes any additional props to the button. Inside the button, the hash if is Dark...:else... slash if block conditionally renders either the Sun or Moon component based on the is Dark state. Note: Events are properties in Svelte 5
- 7:54
The on: directive was used in Svelte 4 to attach events to HTML elements. However, Svelte 5 changed that narrative by being more natural with HTML, which sees events as simply properties.
- 8:09
The sun and moon icons are simply svgs that have become svelte components: The HTML code below is 18 lines, from src slash lib slash components slash icons slash Sun dot svelte. The HTML code below is 18 lines, from src slash lib slash components slash icons slash Moon dot svelte.
- 8:31
This is a nifty way to make svgs flexible as you can pass styles are other attributes and they will be reflected.
- 8:40
Step 5: Authentication or login page
- 8:43
Now, let's see what the login page will look like: The HTML code below is 141 lines, from src slash routes slash finanalyzer slash auth slash login slash +page dot svelte.
- 8:58
Though this code seems long, the only really important part is: The HTML code below is 30 lines.
- 9:05
These are just less than a greater than elements whose URLs link directly to the API endpoints (Google yet to be implemented). The BASE API URI is exported by src slash lib slash utils slash constants dot ts: The TypeScript code below is 3 lines, from src slash lib slash utils slash constants dot ts.
- 9:28
It necessitates that you set either VITE BASE API URI DEV or VITE BASE API URI PROD as environment variables pointing to your server's base URL. In development, I set VITE BASE API URI DEV equals http: slash slash localhost:3030 slash api in a dot env file at the root of my SvelteKit project. Tip: Environment Variables in Production
- 9:54
When deploying to a production server, configure the environment variable VITE BASE API URI PROD to point to your backend's production URL, including the slash api path (e.g., https: slash slash your production url dot com slash api). Most deployment platforms offer a way to set these variables.
- 10:17
Back in our plus page dot svelte, we also retrieve the next page, which specifies where a user should be redirected after successful authentication. This is configured on a per-route basis. In addition to these core features, the page includes visual elements such as infinitely animating floating icons. These icons— Ai Node (AI integration), Fin Chart (finance), and Calculator (analysis)—represent the application's key themes. Custom styles are applied to create a continuous vertical translation from 0px to -20px and back, combined with a simultaneous rotation from 0deg to 360deg. We could have used tailwind styles directly.
- 11:01
This article is getting long, so we will defer the user dashboard to the next article. However, there's a little safekeeping that needs to be done. Authenticated users should not be allowed to access this login page since they're already authenticated. To achieve this, we'll have a plus page dot server dot ts file whose aim is to redirect any authenticated user from coming here: The TypeScript code below is 9 lines, from src slash routes slash finanalyzer slash auth slash login slash +page dot server dot ts.
- 11:35
See you in the next one!
- 11:37
Outro
- 11:39
Enjoyed this article? I'm a Software Engineer, Technical Writer and Technical Support Engineer actively seeking new opportunities, particularly in areas related to web security, finance, healthcare, and education. If you think my expertise aligns with your team's needs, let's chat! You can find me on LinkedIn and X. I am also an email away.
- 12:02
If you found this article valuable, consider sharing it with your network to help spread the knowledge!