Skip to content

Design Document

Soyoung Yoon edited this page Nov 2, 2025 · 48 revisions

Document Revision History

Date Version Details
2025/10/05 v1.0 Initial Documentation
2025/10/10 v1.1 Update API Specification
2025/10/14 v1.2 Remove API Specification
2025/10/19 v2.0 Separate PoC page, update diagrams
2025/10/19 v3.0 Update testing plan & diagrams

System Design

System Architecture

system-architecture

The figure above illustrates overall architecture of MomenTag. MomenTag consists of 3 layers; android frontend, DRF backend and cloud-based resources.

The frontend, built with Android and jetpack compose communicates with the backend using Retrofit as HTTP client, to handle user interactions such as uploading photos, tagging images, and retrieving semantic search results.

On the backend, the application runs on containerized environment within Google Cloud Platform compute engine, using the Django REST Framework to process client requests, manage user data, and coordinate external services. When a text query or an image is uploaded, the backend utilizes a Vision Transformer model from HuggingFace for generating an embedding vector. Work distribution is performed using Celery as task queue, with redis container as broker.

MomenTag uses two kinds of database. Image embeddings and their metadata are saved on Qdrant, a vector database optimized for similarity search, enabling fast and accurate retrieval of contextually related images. Meanwhile, user profiles, authentication data, and metadata are maintained in Cloud SQL, ensuring reliability and scalability. This modular architecture allows efficient communication between components and supports both high-performance vector search and flexible backend management for future expansion.

Class Diagrams and Data Models

Android Class Diagram

frontend

This is a class diagram of an Android application designed based on the MVVM (Model-View-ViewModel) architecture. It is structured as follows:

  • View

    • MainActivity: App's entry point
    • AppNavigation: Manages navigation between screens using navigation component
    • Screens (HomeScreen, SearchResultScreen, etc.): Composable functions that compose each UI screen. These screens are updated based on ui state changes
  • ViewModel

    • LocalViewModel: Manages local data; original user images
    • AuthViewModel: Manages authentication state
    • SearchViewModel: Manages search results
    • ImageDetailViewModel: Manages detailed info of images
    • PhotoViewModel: Manages photos to upload
    • HomeViewModel: Managees home screen
    • AlbumViewModel: Manages tag albums
    • AddTagViewModel: Manages tag creation with recommendation
    • SelectImageViewModel: Manages image selecting
    • StoryViewModel: Manages story(moment) feature
  • Model

    • Repository (LocalRepository, SearchRepository, etc.): Abstracts the data source and separates it from the ViewModel
    • Data Source: Implements APIService using Retrofit as HTTP client and communicates with the backend
    • Data Class (Tag, Photo, etc.): Representation of data

Backend Class Diagram

backend_models backend_api_1 backend_api_2

The diagrams above represent the models and APIs of the gallery and search apps, which serve as the core components of the backend. The backend consists of the User, Tags, Captions, RepVec, and Photos databases, along with Photo_Tag and Photo_Caption tables that connect these entities.

The backend is organized into two main applications:

the gallery app, which provides methods to add, delete, and modify data used for searching, and

the search app, which handles the actual search functionality.

The search app supports personalized tag-based search, understanding the semantic meaning of the user-created tags and using them to perform image searches tailored to each user.

The gallery app allows users to upload their photos, thereby adding them to the searchable dataset, or remove photos from search results. Users can also add or remove tags associated with each photo.

When a user uploads a photo, the system generates a caption for it using an LLM, storing descriptive information that helps analyze the photo’s content.

To enhance user convenience, the system can recommend tag names for photos or suggest relevant photos for existing tags.

Finally, to support efficient search, the backend processes tag and caption data to create, update, or delete auxiliary structures such as graphs and representative vectors—the latter serving as embedding vectors that represent each tag.

ER Diagram

erd

MomenTag stores the User, Tags, Photo_Tag, Captions, and Photo_Caption tables in MySQL as an RDB, while the Photos and RepVec collections are stored in Qdrant DB.

The User table contains the information (username, password, and email) for each user. id is the primary key. The Tags table stores semantic labels, enabling flexible search and association with photos. The Photo_Tag table serves as a junction entity, allowing many-to-many relationships between photos and tags, which captures the rich, dynamic connections between visual content and its conceptual meanings. The Captions table stores captions for photos, which are generated by an LLM and split word by word. The Photo_Caption table serves as a junction entity, allowing many-to-many relationships between photos and tags, which captures the rich, dynamic connections between visual content and its conceptual meanings.

Additionally, metadata related to each image is stored in the vector DB along with the image's embedding. photo_id is the primary key, and id is a foreign key that indicates who posted the photo. photo_path_id is the photo ID for using the MediaStore URL, which allows for the reconstruction of the URL to access and load the photo via the MediaStore API. The embedding field stores the photo’s semantic representation vector, while created_at, location_lat, and location_lng are metadata for the photo.

Finally, the RepVec collection stores representative vectors for each tag. For each tag, representative vectors are calculated based on the average value of vectors within $k$ groups generated through K-means clustering. Furthermore, representative vectors are also generated for outliers (특이값) if they exist.

Since two different databases are used, MomenTag has to take extra care for maintaining data integrity. However, by combining vector DB and traditional RDB, MomenTag achieves the best of both worlds: efficient semantic retrieval through vector similarity search and reliable relational integrity for user and metadata management.

Testing Plan

Unit Testing & Integration Testing

Method

  • Who
    • Tests for the existing code are conducted by one coder
    • Tests for future code will be conducted by each coder
  • When
    • At every PR

Android Frontend

  • Unit Test: JUnit
  • Integration Test: JUnit + Compose UI Test
  • Architecture: MVVM
    • Model: test coverage for all business logic
    • ViewModel: test coverage for state and data handling

The Android application follows the MVVM architecture. Therefore the logic is concentrated in the Repository and ViewModel layers. For unit testing, we employ JUnit to validate core logic and synchronization between the local and remote repositories. Mock objects and MockWebServer are used for simulating network responses without depending on actual backend communication.

Since we use Jetpack Compose in our project, and composable functions are declarative without business logic, they are not a direct subject of unit test. Instead, integration tests using JUnit and Compose UI Test are performed to ensure that user interactions trigger the expected ViewModel updates and UI state changes correctly. The Compose UI Test enables simulation of user activities such as pressing the button and navigating through pages.

  • Results {photo}

Backend

  • Unit Test: unittest + DRF APITestCase
  • Integration Test: DRF APIClient

For backend testing, we use Python’s unittest framework and Django REST Framework’s APITestCase to perform unit tests on models, serializers, and views. For integration test, we use the DRF APIClient to simulate API requests and responses. These tests simulates interactions between models, serializers, and views.

By combining these tests, we ensure data consistency between our relational database and Qdrant, and verify that both systems work properly under realistic client actions.

  • Results

frontend

frontend_test

backend

backend_test

Acceptance Testing

These are the five user stories for user acceptance testing.

Natural language photo search

As an user with a large photo collection,
I can search photos using natural language,
so that I can quickly find the images I want.

Personalized tag aware natural language photo search

As a user who has photos with personalized tags,
I can search photos based on my personalized tags,
so that I can easily perform searches related to my personalized tags.

Photo recommendation

As an user who wants to add tags to my photos,
I can receive recommendations of similar images even if I tag only a few photos,
so that I can easily make tags with many related photos.

Tag recommendation

As an user enjoying room escape,
I can accept automatically generated tag "room escape" for my new escape room photos,
so that I can add tag to images effortlessly.

Story feature

As a photo-heavy user,
I can skim through recommended images,
so that I can find forgotten photos and add tags to them.

Clone this wiki locally