Categories
Capstone Development Progress

We Made It

Well, here we are—the end of the Alpha development cycle for Foodable. And man, oh man, has it been a journey. In this post, let’s talk about the biggest challenges we faced while developing this awesome application. There were a few, but we’ll stick to the top three.

Fully Utilizing Server-Side Rendering (SSR)


First and foremost, making the most of Server-Side Rendering. For those unfamiliar with SSR, it essentially means that data is fetched and processed before the page is delivered to the user—super helpful. My team and I were still learning the ins and outs of Next.js (one of the most popular SSR frameworks for React) and didn’t implement it correctly at first. The worst part? I didn’t realize our mistake until we were about 75% of the way through development. By that point, we had written a ton of code, and refactoring it to properly leverage SSR was a major headache—but absolutely worth it in the long run.

Mixing Up TanStack Query and Zustand

To clarify, TanStack Query (formerly React Query) is a server-state management library, while Zustand is a lightweight client-state management tool. Unfortunately, we mixed these up in the early stages of development, which led to an absolute mess of a codebase—so chaotic that even Professor Roger would be disappointed. Ironically, I realized this issue at almost the same exact time we caught our SSR mistake. Fixing it took a ton of effort, but once we got it right, everything felt so much smoother and more efficient.

Team Communication Issues

Now, what’s a development cycle without at least one team-related problem? I won’t name names, but one of our teammates barely communicated, and the work they did produce was sloppy and poorly thought out. Both my other teammate and I made ourselves available multiple times throughout the term to offer help, yet they hardly took advantage of it. This meant we couldn’t trust them with complex tasks or longer assignments, which ultimately put more work on our plates. Look, I get it—everyone is busy—but when you commit to something and don’t use the resources available to you, then blame external factors, it just shows a lack of care for the project.

Final Thoughts

Despite these bumps in the road, I learned a ton about different technologies and being in a development team. The development process went well overall, and seeing everything come together was incredibly rewarding. If I had to pick the most challenging problem, it would definitely be the combination of SSR and state management mishaps. The way I solved it was by sitting down, carefully analyzing our mistakes, and refactoring the code piece by piece—painful but necessary. All-in-all though Foodable was chosen because we wanted to build something practical, innovative, and useful for real people. So far, it has met expectations. Sure, there were challenges, but overcoming them only made the project stronger. Now, onto the next phase!

Categories
Uncategorized

Everything Dev

Every software application is a mix of different technologies working together to make something functional. The specific frameworks, languages, and tools depend on what the software is trying to accomplish. Foodable is a full-stack web app, and while it’s easy to split the tech stack into front-end and back-end, there’s a lot more going on under the hood. Instead of writing up another design doc, I’m breaking down some parts of Foodable’s tech stack and my experience working with these technologies.

My Favorite Technology: Next.js

Out of everything we’ve used in this project, Next.js is my favorite. It simplifies routing, enhances performance with server-side rendering (SSR) and static site generation (SSG), and allows for API routes within the same framework, reducing the need for a separate backend. The developer experience is also top-notch, with features like fast refresh and built-in TypeScript support. Plus, its tight integration with Vercel streamlines deployment and continuous integration.

How does it work?

Next.js enhances the standard React experience by allowing both static and dynamic rendering. It determines at build time or request time whether a page should be statically generated (SSG) or rendered on the server (SSR). This flexibility makes it perfect for Foodable, where some pages (like recipes) benefit from static generation for SEO, while user-specific pages (like saved recipes) need real-time data with SSR. With API routes, we can also handle backend logic without needing a separate Express server, keeping everything within the same framework.

Least Favorite Technology: None (But Some Were Annoying to Learn)

I wouldn’t say I have a least favorite technology, but some were definitely frustrating at first. Zustand and TanStack Query required a shift in mindset regarding state management, especially when handling both client-side and server-side state efficiently. However, once I got comfortable with them, they became essential.

Easiest Technology: Tailwind CSS

Tailwind CSS was by far the easiest to pick up and use effectively. It speeds up UI development with its utility-first approach, ensuring that styles remain consistent without writing tons of custom CSS. The ability to rapidly prototype and refine the UI made front-end development much more efficient.

What’s Missing From the Stack?

One thing I wish we had included from the start is WebSockets for real-time updates. While TanStack Query does a great job with caching and re-fetching, real-time features like collaborative shopping lists or live chat would be smoother with WebSockets or something like Pusher.

Overall

Building Foodable has been an insightful experience, and the technologies we chose have played a huge role in shaping how the app functions. While some tools had a steeper learning curve, they ultimately contributed to a more efficient and scalable application.

Categories
Coding Topics

Getting Rid of Stinky Code

If you are a programmer, and have been for even a year, chances are you have seen what you might consider to be messy code; I for sure have. It’s the code that looks like someone’s mind threw up what they were trying to do, but yet it doesn’t quite do it; or if it does, the methods it uses are so ridiculous you just close the page because you can’t stand the sight of it. Luckily, from early on in my learning, I worked in a group with someone who embodies clean code. What he wrote was beautiful. I learned so much from him and, over the last year, have tried to adapt it to my own development workflow.

What to Begin

With that being said, one major takeaway from what I’ve learned from him and from the article about clean code is that writing clean code starts at the very beginning of developing any piece of software [1]. Bjarne Stroustrup put it best: “Clean code does one thing well.” [1]. While a piece of software must accomplish multiple tasks, each component of that software, such as a function, should do one thing—and do it exceptionally well. For example, in web development, a React component should focus on a single responsibility. If it’s handling form input, it shouldn’t also concern itself with data fetching or state management.

Here is an example of a React component that could be considered “Messy Code”:

RecipeSearch.js

Here is an example of the “Messy Code” above becoming “Clean Code”:

SearchForm.js

SearchResults.js

RecipeSearch.js

In the “Messy Code” example, the RecipeSearch React component is doing multiple things at once. It handles state management, user input, API fetching, and rendering the results—all within a single component. While it might perform what it needs to do, reading and understanding it can be challenging, and maintaining or extending it could lead to errors in the future.

The “Clean Code” example separates all the functions of the RecipeSearch into three distinct components, each with a single responsibility:

  • SearchForm: Responsible solely for rendering the search form and handling user input. This makes it easy to understand and reuse if the same form structure is needed elsewhere in the app.
  • SearchResults: Handles the display of search results, ensuring the rendering logic for the results is isolated from the state management and data fetching.
  • RecipeSearch: Manages the overall state, orchestrates the API calls, and connects the SearchForm and SearchResults components. It serves as a higher-level controller, keeping the logic centralized but the presentation decoupled.

By following this approach, the code becomes easier to read, test, and maintain. Each component is focused, making it less likely that changes in one area will accidentally introduce bugs elsewhere. This is something I already do, but need to do from the beginning of writing code, instead of just going back through the “messy” code and refactoring it to become “clean” code.

What to Avoid

On the other hand, from the article about bad code smells, one habit I need to work on avoiding is the Long Method. Long methods are difficult to understand, maintain, and extend. They kind of just happen if you’re not careful. They often try to do too much at once, leading to clutter and confusion [2]. The idea is simple: shorter methods are easier to read and manage because they focus on a single task. Modern object-oriented languages such as TypeScript eliminate much of the overhead of subroutine calls, making it practical to use many small methods instead of one long one.

This thing to avoid ties in very well to the concept of clean code. Long methods often indicate that a function is trying to handle multiple responsibilities, which goes against the principle of “doing one thing well.” Breaking down a long method into smaller, more focused methods not only makes the code easier to read but also improves reusability and testing.

For example, let’s revisit the handleSearch function from the messy RecipeSearch component. In its current form, it does everything: preventing the default form submission behavior, updating the loading state, fetching data from the API, and handling both success and error states. This approach makes the method long and harder to maintain.

Instead, by applying the principle of breaking down long methods, we could refactor it into smaller, more focused functions:

Here, handleSearch delegates specific tasks to smaller, dedicated functions like fetchRecipes, updateResults, and logError. Each function has a single responsibility, making the code easier to follow and less error-prone.

Final Thoughts

The road to writing clean, maintainable code starts with awareness and deliberate practice. By focusing on principles like separation of concerns, avoiding long methods, and prioritizing readability, we can significantly improve the quality of our codebases. While refactoring messy code into clean code is an essential skill, the ultimate goal should be to write clean code from the very beginning. This not only saves time and effort but also creates a foundation for scalable and robust applications.

As developers, it’s our responsibility to strive for clarity and simplicity in our work. After all, clean code doesn’t just make our lives easier—it makes our codebases a joy to work with for everyone.

Sources

[1] R. C. Martin, Clean code a handbook of agile software craftmanship. Upper Saddle River [Etc.] Prentice Hall, 2010.

[2] M. Fowler, Refactoring: Improving the design of existing code. Boston: Addison-Wesley, 2019.

Categories
Capstone Development Progress

Winter is Coming, but so is Foodable

Hello 👋,

First and foremost it is cold here in Oregon, starting to feel it in my bones. Besides that though, lets chat about the the progression of Foodable; the application that will make all of our grocery shopping experiences cheaper and easier.

v0.0.1

For v0.0.1, my team and I were like a well oiled machine. We fully setup our testing and development environment. In short, we are using Docker compose to create two containers, one containing the Frontend, created with Next.js, and the other containing the Database, using the latest mongo instance. This development environment allows for fast local testing, and seamless testing in GitHub actions with Cypress, Jest, and Postman. Additionally, initial Clerk.js verification was integrated. All-in-all, the progression to get the v0.0.1 went really well and set the development team up for seamless future integrations.

v0.0.2

This version was about getting a main feature of the application functional. In this case, the main feature we decided to focus on was the main CRUD operations for the user, groceries, and recipes collections. A large component of this was to get the API structure and state management set. What this entailed was figuring out how we are going to use TanStack Query to call our API layer. As of now, we have setup the application to accomplish that task seamlessly and believe that the overall structure between TanStack and our API layer will not need any major changes in the future. Along with TanStack for managing the server-side state, we implemented an initial client-side state manager: Zustand. This will allow us to store the information that we know we are only going to need to retrieve once or at most twice throughout a users session length on the application. TanStack and Zustand were not in the initial architectural designs, however we believe that it will make the overall data management and UI / UX significantly better.

The Struggles

The team and I have agreed that we want to do this application the right way, not just the easiest. For instance, we could have easily used a simple to use database such as Firebase but we chose to use MongoDB to have the flexibility that the application should have. With this being said though, there have been some struggles. All of us have read through a lot of information and documentation about the technologies that we will use and that is time consuming. We all have jobs and busy lives outside of this project, so it can sometimes be hard to balance everything, but together we have persevered and are developing something I think is super cool.

What’s Next?

I am assuming that the next version will be v0.0.3, but you never know. For whatever the new version is called, the progression takes place over winter break. While myself and the team have agreed to work on the project, it will not be the only thing we do. Seeing family and resetting the brain is highly important for life and development. But I still plan to do a good chunk of stuff. For this next version the main things that need to get developed are:

  • Finishing the Role Based Access Control (RBAC) through Clerk.js and connecting that with the MongoDB user collection.
    • This is going to be a little tricky and take some time, but is highly important for the user roles and differentiation in feature access.
  • Creating navigation component for all user roles and screen types
  • Creating UI for all of the pages
  • Connecting TanStack query with front end components

In short, when this is done, we should be able to have a strong user flow for the application, which will allow us to create interviews with users and get feedback on the design.

Final Thoughts

The development of the Foodable application is going pretty well, all things considered. We have a really strong base and good understanding and design about how this application will be developed. Along with this, the members of the team are all now familiar with each other and a sense of trust has grown among us, allowing for good communication and nice development. I have no doubt that this application will be great and we will all continue learning a lot in the process.

Happy Holidays To Everyone!!!

If you have any questions, please feel free to comment below.

Categories
Capstone RAG

Couple Weeks In…

Hello 👋,

Let’s start off by discussing how my capstone project is going so far. Fortunately, my proposed project, Foodable, got approved, and I was assigned to it with two great teammates. In short, I’ve learned a lot. One of the more challenging aspects has been figuring out how to implement an efficient and highly scalable Retrieval Augmented Generation (RAG) method. Since this is cutting-edge in today’s tech stacks, there are so many ways to implement it, each with its own pros and cons. For our needs, we decided on MongoDB Atlas along with Atlas Vector Search, paired with AWS Bedrock for embeddings and language models. This setup promises high customizability and scalability. It will certainly come with its challenges, but based on research, it should pay off in the end.

As for the capstone course itself, it’s been pretty good. The course is structured in a way that assignments build on each other, which I find very effective. For example, the smaller Preliminary Design Documents, which we did individually, helped my teammates and me brainstorm and figure out the design for our application in the larger, more technical Design Document. However, a recurring issue has been due date extensions. These assignments aren’t small, even the shorter ones, and they’re usually due on Thursdays. But every project so far has had its deadline extended to Sunday. I think setting the due dates for Sundays from the start would align better with development sprint timelines and reduce requests for extensions.

Another exciting development in my life has been the job opportunities that have come my way since attending the OSU STEM Fair. If you haven’t attended that event before, it’s fantastic and packed with opportunities. Thanks to the fair, I’ve had interviews with multiple companies, many of which have progressed to second-round interviews, and I’m preparing for those now. Overall, my career prospects look promising, and I’m excited to see what happens next.

While researching RAG methods, I encountered the term “vector embeddings” frequently. They’re essentially the foundation of how RAG methods function. Creating embeddings relies on linear algebra, and although I like math, I haven’t studied beyond integral calculus since I’ve been focusing on CS classes to graduate. However, I’m genuinely interested in learning more about vector embeddings, semantic similarity, scalars, and related topics. Over winter break, I plan to take a freeCodeCamp course in linear algebra to broaden my understanding of large language models and machine learning. I believe anyone interested in these technologies should have a solid grasp of linear algebra.

Something else I’ve noticed is the use of generative AI for coding. I could talk about this all day, but if you’re interested in learning why it might make you a worse programmer, check out this article.

Lastly, I’d like to share a tip that has significantly improved my collaboration and teamwork. I’ve been part of both good and bad groups, and one area I’m working on is team communication. Sometimes, it can feel like everything rests on your shoulders—let go of that idea. You’d be surprised how much just being honest with your teammates (respectfully) and asking for help can lighten the load.

If you have any questions, please feel free to comment below

Categories
Capstone Uncategorized

Before it Starts

Hello 👋,

I want to start by saying that I’m really excited to begin the Computer Science capstone. I can’t wait to see all the new things I’ll learn and the connections I’ll make along the way. This is something I’ve been looking forward to, and I’m eager to get started and make the most of the experience.

I currently live in Albany with my wife because the rent prices in Corvallis are insane. I really don’t have time for hobbies; everything I’m doing this year is focused on making me a better Software Engineer and ensuring I can pay rent and afford food in this economy. This doesn’t mean I don’t have fun. For example, I’m currently configuring a more advanced Neovim setup and improving my Vim motions on my Arch Linux system, which I personally find very fun and rewarding. Some people might consider my time at the gym a hobby, but for me, the gym is non-negotiable, so I don’t view it as a hobby. If and when I have free time, the hobbies I’d enjoy would be hiking, playing games with friends (the type of game varies), and playing Nintendo Switch with my wife.

My story for getting into computer science is surprising to some, but here it goes. I started college in 2020 during what we all know and love as COVID-19. When I began, I was pursuing a degree in Kinesiology, also known as Exercise Science, with the goal of becoming a physical therapist (PT). I entered college with a lot of credit from being an International Baccalaureate (IB) graduate, which covered a decent portion of my core requirements, though I still had several classes left to take. As a result, the first two years were focused on completing those core credits, with some major-specific courses sprinkled in.

During my second year in Kinesiology, two main things happened:

  1. The course material and difficulty of many classes were no longer as interesting or challenging as they used to be.
  2. I began to love developing Discord bots and learning programming with Python.

Despite this, I continued with Kinesiology and, during the summer of 2022, landed a per-diem job at Good Samaritan as a Physical Therapy Aide. In this role, I worked side-by-side with physical and occupational therapists. Unfortunately, this only confirmed my disinterest in Kinesiology, leading me to take a huge leap of faith and switch to Computer Science. The first few classes completely opened my eyes to the possibilities of software engineering and the rest is history.

When I’m not working on an awesome project, I’m working at Beaver Town Movers as a Job Site Supervisor / Lead Mover. It’s a physically intensive job with flexible hours, and it’s usually fun and pays well. I’m truly grateful I found this job a year ago.

When I’m not working or spending time with my lovely wife, I’m also exploring new technologies. Currently, I find Amazon Web Services (AWS) fascinating. For my CS 406 course, I’m building an AWS project while pursuing my AWS certifications.

I might be a little biased, but my favorite project is one I proposed: Foodable. If we’re not talking about my project, then I’d have to say my two second favorites are the Language Immersion Virtual Environment (LIVE) and Lidar to 3D Sound Application for the Seeing-impaired. These projects fascinate me because they not only sound exciting to create but also have the potential to help people in the real world.