Inspiration

Discovering a need often begins with a personal experience. For me, it was after my basic military training when my mom eagerly wanted to see my photos. I subscribed to "WebGuy," our paid photo album, only to find myself sifting through 70,000 photos from the two-month training. A week of endless scrolling yielded just 9 photos of myself. This problem wasn't unique to me; friends and other acquaintances faced the same issue, they expressed the same concerns a year later when we had our big event the "Exemplar Dinner".

With my background in some software development, I initially created a prototype named "FaceGuy" but didn't pursue it further, distracted by other academic and technical endeavors. However, a conversation with my friend Noah reignited my interest. He reminded me of the broader application of this solution – from event organizers to marathon runners and corporate events. "You can be the next Flickr", he said. The real turning point was presenting "FaceGuy" at the Jean Bartik Computing Symposium, where it was received with enthusiasm and won the "People's Choice Award" in the conference, validating the need for such a platform. So I rebranded to a more inclusive and gen-Z friendly name, "gitit". Short for the slang "Let's getit". And started going all in on building "gitit" – a platform tailored to redefine community memories.

What it does

In most events, we take pictures with the sole purpose of preserving these memories—something to come back to later on. However, often these vast amounts of pictures end up in obscure cloud storages or forgotten in digital albums. This is where gitit steps in.

gitit transforms this scattered photographic landscape into an organized, interactive experience. By leveraging cutting-edge facial recognition technology, gitit allows users to quickly locate their photos amidst thousands. It's not just about finding your pictures; it's about reconnecting with those moments.

With gitit, event photos are more than just pixels on a screen. They become a dynamic part of your community's story. Here's what gitit does for you:

  • Effortless Photo Sorting: Say goodbye to endless scrolling. Find your face in seconds, not hours.
  • Community Engagement: Each event gets its own dedicated space, where memories are shared, liked, and commented on.
  • Revolutionized Event Experience: From weddings to marathons, gitit ensures that every participant's moments are highlighted and easily accessible.
  • Inclusivity and Connection: No one feels left out. Our AI ensures that every face in the crowd gets its moment in the spotlight.

gitit isn't just a photo platform; it's a gateway to reliving your most cherished experiences, anytime and anywhere.

How we built it

  • NextJs - Frontend (Won't be the focus of this discussion)
  • AWS Lambdas - Some backend functions (Won't be the focus of this discussion)
  • Convex - Backend functions and Database

Convex Focus

  1. CRUD Operations and Type Safety: I've created different query and mutation functions (createPost, getPost, deletePost, updatePostDescription, etc.), each serving a specific CRUD operation on my posts data. I've used Convex's v validators to ensure the correct types for the function arguments, significantly enhancing the type safety in my application.
  2. Contextual Database Access: In my handlers, I access the database in context (ctx.db). Convex's ctx.db enables me to perform database operations within a specific context, ensuring accurate, efficient, and consistent data manipulations. Each function knows precisely what it needs from the database and operates independently of each other, reducing side effects and potential clashes. The contextual awareness adds to the robustness of Convex, making database manipulations easier and safer.
  3. Creation of a post: In the createPost mutation, ctx.db.insert("posts", args.data) comes into play, which precisely represents the operation of creating a new post. When an event_id is present in the request, ctx.db.get(args.data.event_id) retrieves the event data. Using the information from this event data, I pass the community_id along with the original data to ctx.db.insert to create the post with an associated community. Otherwise, I insert the post without an associated event or community. All this is done within the same operation context, ensuring data consistency.
  4. Post's data retrieval: The getPostData function exemplifies an efficient way to fetch multiple records contextually. Given an array of postIDs args.postIds, I create promises for each of them via ctx.db.get(postId as Id<"posts">) to asynchronously fetch their data from the database. I then wait for all promises to resolve using Promise.all(), which holds the array of posts fetched in parallel within that same context.
  5. Paginated query in a particular context: In the getCommunityFeed query, I first narrow the context to posts within a particular community using withIndex("by_community", q => q.eq("community_id", args.community_id as Id<"communities">)). Next, I apply order("desc") to sort them in descending order, followed by paginate(args.paginationOpts) to apply pagination to the results.
  6. Powerful Querying: I leverage Convex's robust querying capabilities by chaining the ctx.db.query() with withIndex(), order(), and paginate() functions. This gives me the flexibility to query my posts data by different parameters, like getting a feed, or getting community or event-specific feeds.
  7. Retrieving post counts by event: Within the getPostCount query, I deploy Convex's powerful querying features to precisely get the count of posts per event. By using .withIndex("by_event", q => q.eq("event_id", args.eventId)), I'm able to filter posts that are tied to a particular event, and then I use .collect() to gather all these posts in an array. The length of this array gives me the required count. This demonstrates how Convex enables performing index-based filtered queries to retrieve data in a specific context.
  8. Creating a feed: In the getFeed query, I use powerful Convex queries to create a feed of posts. By chaining ctx.db.query("posts").order("desc").paginate(args.paginationOpts), I get the posts in descending order and paginate the results based on pagination options provided. This allows me to control the amount of data fetched optimally, valuable when dealing with potentially large result sets. On the frontend, the pagination query is then used to create an infinite scroll feature.
  9. Community and event specific feed: Queries like getCommunityFeed and getEventFeed are more complex as they utilize multiple features together. First, I narrow down the context to posts within a specific community or event using .withIndex() to filter the posts. Then, I sort them in descending order (.order("desc")), and finally, paginate the results using the provided pagination parameters. This chained querying process demonstrates how powerful and flexible Convex is in designing complex queries.
  10. Retrieve multiple posts: The getPostData function shows how to retrieve multiple records in a single operation. Given an array of postIDs, I "map" each postId to its promise from ctx.db.get(postId as Id<"posts">). This array of promises is then resolved using Promise.all(), which returns an array of posts. This highlights how Convex allows efficient mass retrieval of data.
  11. Realtime: I've used Convex in a React environment, which means my data management is done in real-time on the client-side, ensuring that the data presented is always up-to-date. This works exceptionally well with the reactive nature of React, syncing changes from the database to my user interfaces seamlessly.
  12. I basically used the same principles in handling data in all my other functions.
  13. Community Members: Managed membership controls, determining who can or cannot join.
  14. Community Management: Implemented straightforward CRUD operations for community data.
  15. User Authentication and Access Control: Utilized Firebase's auth.uid for user identification and established access parameters, currently refining user document verification for enhanced security.
  16. Photo Management: Efficiently handled storage of photo IDs and integrated facial recognition features.
  17. FaceSearch Functionality: Developed indexing for search results, enabling quick retrieval in subsequent searches.

Challenges we ran into

  1. Dealing with the query being undefined at first. (Yeah, I didn't read all of the docs before writing code)
  2. Creating Mock Data that fits with my needs to simulate the frontend. (I know, it shouldn't be that hard but I'm working solo and due to the deadline upcoming, I ended up with a dirty way using macros to upload photos rather than the initial python script I made)
  3. I have not wrote any unit tests which sucks but I am about too.

Accomplishments that we're proud of

While there's always room for improvement, I'm proud of several key milestones achieved in this project:

  1. Balancing Act: Successfully developing this platform single-handedly in just two weeks, amidst the challenges of academic responsibilities, capstone research, and military training.
  2. Effective Facial Recognition: Implementing a functional facial recognition feature that stands as the core of this platform.
  3. Database Management and Schema Design: Efficiently managing complex data relationships and designing a robust database schema that underpins the entire application. Also, perfectly aligned for easy modifications, like changing authentication methods or adding new fields, ensuring future scalability and adaptability.

What we learned

  • Adaptability in Development: Tackling unforeseen challenges, particularly in managing undefined queries and creating mock data under tight deadlines, has honed my problem-solving skills.
  • Importance of Documentation: The initial hurdles with Convex queries underscored the significance of thoroughly understanding documentation before diving into code.
  • Efficiency in Solo Projects: Managing a complex project alone taught me the value of efficient time management and prioritization, especially in balancing diverse tasks such as development, testing, and user experience design.
  • Scalability Considerations: The development process highlighted the importance of building a scalable and adaptable architecture, especially when planning for future enhancements and integrations.

What's next for gitit.ai

  • Mobile App Development: A key focus currently is the development of a robust mobile application, aiming to enhance user accessibility and engagement. This development is integral to supporting the forthcoming user influx and ensuring a high-quality user experience across all devices. (Hard Deadline: March 30)
  • User Onboarding and Growth: The immediate objective is to optimize our system for seamlessly handling 4,000 users, with a firm deadline set for April 15. This urgency stems from my business partner, who's been actively engaging with representatives from various class cabinets. Our strategy is to efficiently onboard these 4,000 users by the end of April, ensuring a smooth and successful roll-out within our school. Concurrently, we're also initiating conversations with other universities, aiming to validate our platform's effectiveness with our initial user base. Additionally, a promising opportunity awaits with an external organization, prepared to bring in 50,000 users, contingent upon our platform proving its production readiness and scalability. This phase is crucial not only for immediate growth but also as a stepping stone towards larger-scale adoption and impact.
  • Comprehensive Testing: I'm set to develop and implement unit tests to ensure the reliability and stability of the platform, a crucial step given the anticipated user growth.
  • Scalability Enhancements: Continuous refinement of the database and backend functions to support scalability, particularly in preparation for expanding our user base and adding new features.
  • Expanding Features and Integrations: Long-term plans include adding more functionalities, refining the user interface, and potentially integrating with other platforms to enhance user engagement and experience. (For now, I have to make sure it is fast and bug-free)
  • Exploring Partnerships: We're looking into partnerships with event organizers and educational institutions to broaden gitit.ai's reach and applicability.

Built With

Share this project:

Updates