Skip to content

Assignment 4: Backend Design & Implementation (beta)

Data modeling

Abstract data model

concept User
    purpose
        provide authentication
    principle
        after registration, returns the object associated with provided credentials if they're right
    state
        // User is a class defined within the User concept
        username, password: User -> one String
    actions
        register(name, pwd: String, out u: User)
        getUserById(id: String, out u: User)
        getUserByUsername(username: String, out u: User)
        // returns usernames of each id provided
        idsToUsernames(ids: set String, out u:)
        // if empty, returns all users
        getUsers(username?: String)
        authenticate(username, password: String)
        update(id: String, update, out u: User)
        delete(id: String)
        userExists(id: string)
        // checks if username and password are adequate for registration
        canCreate(username: String, password: String)
        // checks whether a username already exists
        isUsernameUnique(username: String)
concept User
    purpose
        provide authentication
    principle
        after registration, returns the object associated with provided credentials if they're right
    state
        // User is a class defined within the User concept
        username, password: User -> one String
    actions
        register(name, pwd: String, out u: User)
        getUserById(id: String, out u: User)
        getUserByUsername(username: String, out u: User)
        // returns usernames of each id provided
        idsToUsernames(ids: set String, out u:)
        // if empty, returns all users
        getUsers(username?: String)
        authenticate(username, password: String)
        update(id: String, update, out u: User)
        delete(id: String)
        userExists(id: string)
        // checks if username and password are adequate for registration
        canCreate(username: String, password: String)
        // checks whether a username already exists
        isUsernameUnique(username: String)
concept Session[User]
    purpose
        provide authentication for extended period
    principle
        after a session starts (and before it ends), authentication won't be needed again, until the session is ended.
    state
        // if a session goes inactive, it's removed from
        // the relation
        user: Session -> one User
    actions
        start(u: User, out s: Session)
        getUser(s: Session, out u: User)
        end(s: Session)
        isLoggedIn(s: Session)
        isLoggedOut(s: Session)
concept Session[User]
    purpose
        provide authentication for extended period
    principle
        after a session starts (and before it ends), authentication won't be needed again, until the session is ended.
    state
        // if a session goes inactive, it's removed from
        // the relation
        user: Session -> one User
    actions
        start(u: User, out s: Session)
        getUser(s: Session, out u: User)
        end(s: Session)
        isLoggedIn(s: Session)
        isLoggedOut(s: Session)
concept Tag[Post]
    purpose
        provide systematic classification
    principle
        after associating tags to objects, when given a determined tag, returns 
        all posts with that tag associated
    state
        // Tag is a class defined within the Tag concept
        attachments: Tag -> many Post
    actions
        getAllWithTag(tag: Tag, out u: set Post)
        createAttachment(tag: Tag, post: Post)
        deleteAttachment(tag: Tag, post: Post)
        createTag(name: String, out u: Tag)
        deleteTag(tag: Tag)
        getTagByName(name: String, out u: Tag)
concept Tag[Post]
    purpose
        provide systematic classification
    principle
        after associating tags to objects, when given a determined tag, returns 
        all posts with that tag associated
    state
        // Tag is a class defined within the Tag concept
        attachments: Tag -> many Post
    actions
        getAllWithTag(tag: Tag, out u: set Post)
        createAttachment(tag: Tag, post: Post)
        deleteAttachment(tag: Tag, post: Post)
        createTag(name: String, out u: Tag)
        deleteTag(tag: Tag)
        getTagByName(name: String, out u: Tag)
concept Thumbnail[Post]
    purpose
        create images that convey the tone of a text
    principle
        for every post, there'll be a thumbnail, a visual representation of the tone in the text.
    state
        // Thumbnail is a class defined within the Thumbnail concept
        thumbnails: Thumbnail -> many Post
    actions
        createThumbnail(content: Post, out u: Thumbnail)
concept Thumbnail[Post]
    purpose
        create images that convey the tone of a text
    principle
        for every post, there'll be a thumbnail, a visual representation of the tone in the text.
    state
        // Thumbnail is a class defined within the Thumbnail concept
        thumbnails: Thumbnail -> many Post
    actions
        createThumbnail(content: Post, out u: Thumbnail)
concept Feed[Post, User]
    purpose
        bring together content from multiple sources into a single, centralized location
    principle
        add objects to a feed, that can be retrieved when lookup (sorted differently according to whom it belongs)
    state
        composition: Feed -> set Post
        assignment: Feed -> one User
    actions
        // if feed doesn't exist, creates one
        getFeedByUser(user: User, out u: Feed)
        getFeedById(id: String, out u: Feed)
        removeFromFeed(user: User, post: Post)
        addToFeed(user: User, post: Post)
concept Feed[Post, User]
    purpose
        bring together content from multiple sources into a single, centralized location
    principle
        add objects to a feed, that can be retrieved when lookup (sorted differently according to whom it belongs)
    state
        composition: Feed -> set Post
        assignment: Feed -> one User
    actions
        // if feed doesn't exist, creates one
        getFeedByUser(user: User, out u: Feed)
        getFeedById(id: String, out u: Feed)
        removeFromFeed(user: User, post: Post)
        addToFeed(user: User, post: Post)
concept Post[User]
    purpose
        allow users to contribute to the community
    principle
        after creating content, it is made into an object that allows removing and editing
    state
        // Post is a class defined within the Post concept
        author: posts -> User
        content: posts -> String
    actions
        create(author: User, content: String, out u: Post)
        // Given a series of selections, returns all posts that 
        // satisfy that filter
        getPosts(query, out u: set Post)
        getByAuthor(author: User, out u: set Post)
        update(post: Post, update)
        delete(post: Post)
        isAuthor(user: User, post: Post)
concept Post[User]
    purpose
        allow users to contribute to the community
    principle
        after creating content, it is made into an object that allows removing and editing
    state
        // Post is a class defined within the Post concept
        author: posts -> User
        content: posts -> String
    actions
        create(author: User, content: String, out u: Post)
        // Given a series of selections, returns all posts that 
        // satisfy that filter
        getPosts(query, out u: set Post)
        getByAuthor(author: User, out u: set Post)
        update(post: Post, update)
        delete(post: Post)
        isAuthor(user: User, post: Post)
concept Sort[View, Post, Algorithm]
    purpose
        sorts a set of object by their view using Algorithm as sorting algorithm
    principle
        when asked about highlights, Sort takes in all posts of the specified
        date and sorts them by views (more to less).
    state
       collection: View -> Post
    actions
        // creates a new entry post -> iniVal
        create(post: Post, iniVal: View)        
        sort(posts: set Post, out u: set Post)
        // updates the number of views for post
        update(post: Post, toAdd: View)
        delete(post: Post)
concept Sort[View, Post, Algorithm]
    purpose
        sorts a set of object by their view using Algorithm as sorting algorithm
    principle
        when asked about highlights, Sort takes in all posts of the specified
        date and sorts them by views (more to less).
    state
       collection: View -> Post
    actions
        // creates a new entry post -> iniVal
        create(post: Post, iniVal: View)        
        sort(posts: set Post, out u: set Post)
        // updates the number of views for post
        update(post: Post, toAdd: View)
        delete(post: Post)
app ADDapp
    include User
    include Session
    include Post
    include Feed[Post.Post, User.User]
    include Thumbnail[Post.Post]
    include Tag[Post.Post]
    include Sort[Number, Post.Post, regular sorting of numbers]
app ADDapp
    include User
    include Session
    include Post
    include Feed[Post.Post, User.User]
    include Thumbnail[Post.Post]
    include Tag[Post.Post]
    include Sort[Number, Post.Post, regular sorting of numbers]

Diagram


Design reflection

While implementing the Thumbnail concept, I faced a dilemma: I needed to perform two distinct tasks – generating a prompt from a post and creating an image based on that prompt. Initially, I contemplated splitting these tasks into separate concepts like PromptGenerator and ImageGenerator, as they could have broader applications, such as creating prompts from any text or generating images from any text. However, this approach seemed overly granular, potentially confusing future code readers, including myself. Managing the synchronization between two narrowly defined concepts could also harm modularity. Therefore, I opted to combine both tasks within a single concept, given the low likelihood of needing their individual functionalities in the future.

Another challenge was determining where to implement post filtering by date. While only the Sort feature required post filtering, I questioned whether this should be the exclusive responsibility of Sort. However, to avoid duplicating posts in Sort every time a new post was created and to minimize memory usage, I integrated the date filtering into the Post concept. This decision ensured flexibility for potential future features dependent on date filtering.

In designing the Sort concept, my initial idea was to sort posts based on their views and update view counts by increments. However, I recognized the value of making this concept more versatile. Instead of limiting it to numerical views and ascending sorting, I generalized it. The "view" parameter could be of any type, and the sorting algorithm could follow any criteria. Additionally, the update function for a "view" could accommodate various operations as desired by the user. This versatility allows for future adaptability in diverse scenarios, hence the decision to implement it with a custom link (of type T), a custom sorting algorithm, and a custom update function.

Deployment

Click here!