Deonté Vanterpool

Student - BS Computer Science

I attend the University of Pittsburgh, and am currently pursuing a Bachelor’s degree in Computer Science. My expected graduation date is May 2027. I am looking for Software Engineering roles. I have past software engineering experience as an intern at Google.

# Projects

Noladoro — Minimalist Pomodoro

A minimalist Pomodoro timer where each session is tied to a specific task. Built with Kotlin and Jetpack Compose.
Github

Overview

Noladoro is a minimalist Pomodoro timer application designed for focused work sessions. Unlike traditional timers, each Pomodoro session is explicitly linked to a specific task, providing clarity and intentionality to your work. Built with modern Android development practices and optimized for AMOLED displays.

Features

Architecture and Implementation

The application follows modern Android architecture patterns with a clear separation of concerns:

MVVM Architecture: The app is structured using Model-View-ViewModel pattern, ensuring clean separation between UI logic and business logic. The ViewModel manages UI-related data and survives configuration changes.

Reactive UI with Jetpack Compose: The entire UI is built using declarative Jetpack Compose, with Mutable State Flows in the ViewModel driving all UI updates. This enables efficient, reactive rendering of state changes without the boilerplate of traditional Android views.

Dependency Injection with Hilt: Hilt provides dependency injection throughout the app, making components testable and loosely coupled. This simplifies management of ViewModels and other dependencies.

Navigation Component: Multi-screen navigation is handled seamlessly with Compose Navigation, allowing smooth transitions between the task list and timer screens while maintaining back stack integrity.

Builder Pattern for Data Models: Task data is structured using model classes with Builder pattern support, enabling type-safe construction of task objects with pomodoro completion counters and other metadata.

Takeaways

First Takeaway: Jetpack Compose significantly accelerates UI development compared to traditional XML layouts. The declarative approach reduces boilerplate code and makes the UI more predictable. However, there's a learning curve in thinking reactively and managing state properly within the Compose ecosystem.

Second Takeaway: The MVVM architecture with State Flows proved highly effective for managing UI state reactively. The clear separation allowed for easier testing and maintenance. Future enhancements could include persisting state across app restarts using DataStore or Room database.

Third Takeaway: Building for AMOLED displays with a true black theme not only provides visual appeal but also practical battery benefits. The minimalist approach aligned well with the Pomodoro technique's philosophy of focused work sessions without distractions.

Future Enhancements

Tech Stack


Domain Specific Language (DSL)

A Domain Specific Language (DSL) transpiler for SQL queries.
Github

Overview

This project is a Domain Specific Language (DSL) transpiler that converts a custom query language int o SQL queries. The DSL is designed to be more user-friendly and easier to read than traditional SQL, making it accessible to users who may not be familiar with SQL syntax.

I initially had no experience with language parsing or compilers, so I opened up the "Crafting Interpreters" book to learn how parsers are built. I then adapted the concepts learned from the book to create my own DSL that transpiles to SQL.

I designed the language in a way that would make predicting the next token easier, which is essential for building an autocompletion engine. The autocompletion engine suggests possible keywords based on the current state of the input, making it easier for users to write valid queries.

Below is an example of a DSL query: !tag.equals(hello) OR (date.before(2021-01-01) AND title.startswith("bar" OR "c\"\\runch"))

You can find more details about the syntax in the GitHub repository README.

Features

Architecture and Implementation

The transpiler was separated into three main components: the scanner, lexer, and parser.

The reason for the separation of the scanner and lexer is to make the code more modular. This way, the completion engine can use the scanner to get the current token without having to parse the entire input. The scanner is responsible for breaking the input into tokens, while the lexer is responsible for converting those tokens into a more meaningful classes. The lexer also saves the possible expected next token classes for the autocompletion engine to use.

The parser is responsible for taking the tokens from the lexer and building an Abstract Syntax Tree (AST) that represents the structure of the query. The AST is then traversed to generate the corresponding SQL query.

The autocompletion engine uses the lexer to get the current token and the possible expected next token classes. It then suggests keywords based on the current state of the input.

Tech Stack


NolaTabs: Git Based Tab Manager

Version controlled tab manager with functionality based on Git, and commands based on UNIX commands
Github

Overview

This project is a Chrome extension that allows users to manage their browser tabs using Git-like version control. It provides a unique way to organize and version control browser tabs, making it easy to save, restore, and manage tab sessions. It was initially developed as a learning exercise to understand Git better, and as well as a proof of concept for if Git's concepts could be applied to other domains.

Features

Architecture and Implementation

The extension is built using TypeScript and the Chrome Extensions API. It uses the Web Crypto API for encryption and decryption of tab data, ensuring that sensitive information is protected. The argon2-browser library is used for hashing passwords securely.

The architecture is based on a design pattern called "functional core, imperative shell". The core logic of the extension is implemented in a functional programming style, while the interaction with the Chrome Extensions API, and databases is handled in an imperative manner. This separation of concerns makes the codebase more testable, since the core deals with concrete data.

Future Improvements

Tech Stack


Full Stack Inventory Manager

Inventory manager built with Full Stack web technologies.

Github

Overview

This inventory manager is a full-featured application designed to help users manage their inventory efficiently. It includes user authentication, and reporting dashboards. I had pretty much self taught all the technologies used in this project, and it was a great learning experience!

Features

Architecture and Implementation

I used database migrations in order to keep track of changes to the database schema.

The frontend was built using Tauri, which allows you to create desktop applications using web technologies. The main benefit of using web technologies is that it is very portable and can run on multiple platforms, including Windows, macOS, and Linux (since browsers are mainly universal). This way, my development environment would not be significantly different from the production environment.

Tauri also allows you to call Rust functions from JavaScript without calling the backend, which is very useful for performance-intensive tasks like database queries and data processing.

Not only this, but Rust enforces strong type safety compared to Typescript, which keeps the application secure and predictable. The Rust data types are automatically synced with typescript using Tauri. Therefore, the model classes are the same in both the frontend and backend, which reduces the chances of bugs and makes the code more maintainable.

Asyncronous programming is used extensively in this project to ensure that the application remains responsive while performing database operations or network requests.

Database pooling is implemented to manage database connections efficiently, allowing multiple requests to be handled concurrently using the same database connection. This improves performance and reduces the overhead of establishing new connections for each request.

models.rs contains the data models for the all items stored in the database, such as Product, User, and PendingOrder. Each model is built using a Builder pattern, which allows for easy and consistent construction of complex objects. Not only this, but all the operations are consistent, since the models have their own methods for the common operations.

Authorization is handled using an AuthGuard, which is middleware that checks if the user is authenticated before allowing access to certain routes. It does this by checking the password hash in the request headers and verifying it against the database. If the username/password combination is valid, the user is allowed to access the route.

Takeaways

First Takeaway: Although I learned a lot trying to implement my own secure authentication system, in the future it would be more practical to use an existing solution like Firebase or Auth0. This would save time and effort, and make the authentication more maintainable.

For example, because I didn't implement both refresh tokens and access tokens, it does pose a slight security risk, since the client has to continuously send their password in the request headers to access protected routes. This is debatably less secure than only logging in once, and using a temporary token to continuously authorize the client.

The second issue is that it is much slower, since hashing and salting passwords is meant to be a slow operation. Having a refresh token would allow the client to get a new temporary access token without having to send their password again, which would improve performance and security.

Second Takeaway: Tauri was a very smooth development experience, and I would recommend it to anyone looking to build a desktop application using Rust. When I initially started this project, I was looking at Slint because it was fully native. However, I quickly switched to Tauri because at the time, Slint did not have a stable release and was still in beta. I actually was able to report this compiler bug here. Super proud of that one! Because Tauri uses web technologies, you can easily borrow a lot of th stability of tried and tested UI technlogies such as HTML, CSS, and JavaScript.

Third Takeaway: An improvement to increase reliability would be to use GraphQL or gRPC instead of REST for the API. This would allow for more efficient data fetching and reduce the number of requests needed to get the data. It would also allow for more flexibility in the data structure, since GraphQL allows you to specify exactly what data you want in the response. The data models would also be more consistent, since the same schema would be used for both the frontend and backend. This works well with Tauri, since it allows you to call Rust functions from JavaScript without calling the backend. Since REST uses JSON, it does not provide much benefit over GraphQL or gRPC, since the frontend no longer has to make HTTP requests using Javascript/TypeScript, but can call Rust functions directly.

Tech Stack