1. Introduction and Goals

Participating in partner dances offers numerous benefits:

  • It brings people together (social perspective)

  • Dancing is a good full-body workout (physical health perspective)

  • Dancing relieves stress (mental health perspective)

  • In general, people who dance seem to be less interested in starting wars (society’s perspective)

  • Last but not least, you can find a partner for life (mankind’s survival perspective)

HOWEVER

There is often one barrier for individuals wanting to beging with partner dances — they need to find a dance partner.

Dancier is here to help all those people!

1.1. Functional Requirements

Dancier aims to be the go-to platform for dance enthusiasts of all types, regardless of their preferred dance style, be it Tango, Salsa, or any other.

In its initial stage, our primary focus with our list of requirements will center around partner dances, encompassing a wide array of styles where two individuals dance together. As Dancier evolves into a platform where people can find dance partners, we will consider adding more features, such as enabling dance schools to provide information about their courses and dance events.

Based on that, we provide details on what is required for our Minimum Viable Product (MVP) and what can be considered optional in the following table.

ID Requirement Description

M1

Each dancer can provide information about themselves

Dancier aims to facilitate good matches between its users. Therefore, it requires information such as the dancer’s location and the dance styles they can perform.

M2

Match dancers

Dancier should recommend potential dance partners based on their likeliness of being a great dancing couple.

M3

Dancers should be able to communicate with each other

Matched dancers (M2) should have the capability to communicate with their matches, to arrange a dance.

O1

Schools/Event-Organisers can provide information

Dancier should match dance courses, and dance events in general to its main users.

O2

Match dance classes with dancers

Dancers should easily find courses that suit their skill level.

O3

Find/match dancing events

Dancers should be able to discover dancing events that align with their preferences.

O4

Match dance holidays

Organizers of dance holidays should have an efficient way to present their offerings to interested dancers.

(M=mandatory, O=Optional) for the MVP.

1.2. Quality Goals

Nr Prio Quality Goal Description

QG1

1

Easy to use

Dancers should find features that are easy to use and almost self-explanatory.

QG2

1

Good recommendations

Recommendations should be relevant and not feel like advertisements; they should resemble helpful tips for schools, workshops, shoes, and other recommended items.

QG5

2

Reliable

The user should have a system that is available when he needs it, produces the results he expects and does not lose information eg. messages he sends to other users.

QG3

2

Attractive Project/Team

The entire project should be perceived by users as a collaborative effort by a friendly team with a strong commitment to making a positive impact in the world ;-)

QG4

2

Be a valuable learning project

While our primary focus is bringing people together through dancing, we also aim to provide team members with opportunities for professional growth. This includes areas such as engineering, design, and more. Therefore, we may occasionally take approaches that could be seen as over-engineering.

(got inspiration from https://quality.arc42.org)

1.3. Stakeholders

Role/Name Expectations from this project Expectations from this documentation

Dancer

Seeks an easy way to connect with other dancers, schools, etc.

None

School

Wishes to use Dancier as a channel to promote its dance classes and events.

None

Event Organiser

Aims to use Dancier as a platform to promote their events.

None

Developer

Wants to have a holistic learning experience while working on a complete product. Also, looks forward to making friends and having a great time.

Expect this documentation to serve as a central reference, providing an overview of project goals and functionality, explaining the building blocks and their interactions, and offering insights into decision-making processes.

2. Architecture/Technical Constraints

The only constraints we have is to obey our architectural principles. Find them here.

2.1. Organizational Constraints

Id Constraint Description

OC1

Founder is Marc

Is a dancer, who wants a platform to connect Dancers. Wants to learn how to drive a product holistically. Have a reference project. May find potential for future earnings.

OC2

Team’s Motivation

Wants to learn how to drive a product holistically. Have a great time working together. Have a reference project. No intention to earn anything with it.

OC3

Work-mode: startup

Only do things that immediately pay off within the next 6 months. For everything that slows us down and pays off later: do not do this.

OC4

Licence

All source code will be released under an open-source license. Everyone can fork the project and start a dancier on their own (with a different name, of course)

2.2. Conventional Constraints

Id Convention Description

C1

Be polite

being aggressive or rude…​ will never do anything good.

C2

Listen first, judge less

When confronted with a different point of view, give your colleague the chance to explain themselves.

C3

Name Convention Database names

SQL key words in UPPERCASE, identifiers (database names, tables, colums) in snake_case

C4

Name Convention (Kafka-)Topic names

use hyphens and all lower case: profile-updated

3. Context

3.1. Business Context

functional context.drawio

Neighbor Description

Dancer

Individuals who engage in dancing, seeking fellow dancers and dance-related information. The system is designed to accommodate at least 10,000 dancers.

School

Institutions providing dance courses, workshops, and other dance-related activities. They utilize Dancier as a platform to connect with dancers and promote their activities.

Event Organisers

Organizers of various dance-related events use Dancier as a means to connect with potential participants.

3.2. Technical Context

technical context.drawio

Neighbor Description

SMTP-Server

Used to send emails to stakeholders

Web-Client

Each Stakeholder will access Dancier through a dedicated web application via a web client (web browser).

4. Solution Strategy

Dancier will leverage best-of-breed technology and best practices to achieve its functional goals:

  • By developing a web application with responsive web design, we enable all users on all devices (Phone, Tablet, Desktop) to access Dancier.

  • By using well established technology based on Python/Spark, we support well-working recommendation algorithms to give dancers the best-fitting counterparts for other dancers, events, courses, and workshops.

  • By using Java, Spring-Boot, and PostgreSQL, we leverage established technology for our backend services.

  • By using Kafka, we decouple services where appropriate, e.g. to achieve a higher resilience.

  • By developing everything as K8s-ready as possible, we aim to be able to scale with our certainly growing user base.

5. Building Block View

5.1. Whitebox Overall System

whitebox overall system.drawio

See the following sections for a brief description of each black box.

5.2. Blackbox SPA/Show-Dancer

Purpose

Single Page Application, written in Angular, that contains the UI for all parts of our system (Dancers, Schools,…​)

Interface

Web interface designed for use with standard web browsers. Utilizing responsive web design methods ensures Dancier’s accessibility on nearly any device with a web browser.

Connects to the "Dancer" (our [BFF]).

Risks

Could evolve into a frontend monolith that is hard to maintain. We have to be careful to keep the codebase clean and modular while we add new features to the UI.

Repo

https://github.com/dancier/show-dancer

5.3. Blackbox Dancer

Purpose

[BFF] to Dancier. All calls from the internet are handled by this component. Additionally, it’s also responsible for user/account/profile management. We started with a monolithic approach for Dancer, putting everything in one modular monolith. Having the mentioned functionalities included in Dancer gave us no issues so far, so we continue with this approach.

Interface

Dancer provides a REST API, giving our Angular Single Page Application (SPA) an entrypoint to communicate with the entire Dancier System.

Refer to the whitebox overall system to identify the services used by Dancer directly.

Additionally, Dancer emits [BusinessEvent]s for every interesting use case it’s primarily responsible for. Particularly the handling of accounts and user profiles. These events are sent to an S3 Bucket and Kafka to be consumed by other services requiring this information.

Note
As the SPA runs in the browser of our customer, they normally could not (directly) write [BusinessEvent]s to our Kafka Broker. For this reason, the dancer has a certain endpoint (see REST API), to enable the SPA to publish events on our Kafka-Broker. Those will also be persisted in our S3-Bucket.

Risks/Smells

The Dancer is something in between a pure backend for frontend and a small modulith, as it also contains some modules with business logic. This hybrid design stems from the initial preference for a modulith over numerous microservices. The current setup may introduce some testing complexities, and if found too cumbersome over time, refactoring may be necessary.

Repo

https://github.com/dancier/dancer

5.4. Blackbox Recommendation

Purpose

Identify all pairs of dancers that are likely to form a good dancing couple and compute a [score] for them.

Interface

The Recommendation System reads all profile update events once a day, computes new scores, and offers them via a REST endpoint.

Risks

Computing scores only once a day could turn out to be insufficient to satify our customer’s needs for receiving good recommendations. Because of this, we may need to refactor to a degree that could be considered more of a rewrite.

Repo

https://github.com/dancier/recommendation

5.5. Blackbox Chat-Dancer

Purpose

This is the backend for all chat-related functionality.

Interface

It’s invoked by the Dancer via its REST API to create/maintain chats. It writes [BusinessEvent]s to Kafka that might be interesting for other services to consume, like ChatCreated or MessageReceived. Once use case for it could be for another services to determine if an email should be sent to inform the customer about a new chat message.

Risks

Choosing an open-source chat backend might have been an option. However, we opted against it, considering that the effort to integrate a third-party tool could be comparable to implementing the basic functionality we need ourselves. If this assumption holds true, our solution would be more flexible. However, this decision was mostly grounded in assumptions.

Repo

https://github.com/dancier/chat-dancer

5.6. Blackbox Kikeriki

Purpose

This component determines when to send specific emails to our stakeholders.

Interface

It consumes business events from all other systems, such as:

  • a user logging in

  • a user being active on the platform

  • a user updating their profile

  • the recommendation system computing new scores

  • a user sending a message to another user

  • …​

It then applies certain rules to decide whether to send an email to the user or not.

Repo

https://github.com/dancier/kikeriki

5.7. Blackbox School

Purpose

Handle school-related functionality

Status

Not Implemented

5.8. Blackbox Events

Purpose

Handle events-related functionality

Status

Not Implemented

5.9. Blackbox SMTP-Server

Purpose

Third-party SMTP-Server for outgoing emails.

6. Runtime View

6.1. E-Mail Sending (not the [Info-Mail])

We are describing how some System can send an arbitrary mail to some arbitrary recipient.

From a high level perspective it looks like:

send mail
  1. The E-Mail Command that some system sends…​
    contains the complete Mail (as Text) and its recipients

  2. Kikeriki send the E-Mail via the SMTP-Server to the recipients

6.1.1. More detailed look on how kikeriki send the E-Mail

send mail kikeriki
  1. send mail command reaches kikeriki

  2. command is being mapped
    Kikeriki uses Spring Application Events to decouple it’s distinct modules. The incoming Mail-Command from Kafka is being mapped into an Application Event, that is being thrown.

  3. The Mail Command is stored into an outbox
    The Mail Command ist handled by storing it into on outbox table. (when this fails, also the Kafka-Adapter will try to reconsume the event until this is successfull)

  4. A Job polls the outbox
    Every two seconds the Job looks for more Mails to be send.

6.2. [Info-Mail] Sending

Currently we are sending out mails, to inform the customer about new chat-message that he has. For this to happen we have three processes in place.

6.2.1. Maintaining the state per dancer

state dancer

6.2.2. Sending out the Mail to the dancer

check and send
  1. The InfoMailCheckJob is checking for scheduled Checks from the ScheduleInfoMailCheck, and hand the scheduled jobs over to the CheckAndSendService

  2. For a scheduled check, the CheckAndSendService loads the State for the dancer

  3. In case thate the state should lead to an info mail the corresponding E-Mail-Adress is loaded

  4. The Mail content is being build (something like: You have 2 unread chat messages…​)

  5. a new mail command is being created and thrown to Springs Application Event mechanism.

6.2.3. Maintaining a dancer to email-address mapping

kikeriki mail addresses
  1. whenever a dancer changes his profile, the dancer-service send an profile_updated event.

  2. this is being picked up by Kikeriki’s Kafka-Adapter, that maps it to an Application Event that is being trown

  3. The ApplicationEventListener updates the E-Mail-Adress with the UserInfoService

6.3. Process how Recommendations are being computed

When a user changes his profile, this is likey to invalidate all score he has in relation to other dancers.

It starts with a change of the profile…​

change profile

Now it is time for the recommendation to compute all new recommendations. This is implemented as a batch job, that runs once a night.

compute recommendations

Now the recommendation service can return for each dancer, a list of all dancers within a distance of 200km together with the computed [score].

7. Deployment View

Everything we are deploying is inside of a Docker Container…​

7.1. We are using/building thoose images

deployment components.drawio

7.2. We are deploying our images in these environments

deployment.drawio

8. Cross-cutting Concepts

find our Cross Cutting Concepts here

9. Design Decisions

find our Architecural Decision Records here

10. Quality Requirements

10.1. Quality Tree

quality tree

The leaves in this tree refer to the Quality-Scenarios from the following section…​

10.2. Quality Scenarios

Szenario Prio Goal(s) Description

QS1
High

Recommandations (QG2)

A dancer reads the list of his recommendations and writes messages to recommended dancers with a probability that correlates positively to the [score].

QS2
High

Recommandations (QG2)

A Dancer receiving the first message of another dancer, is replying with a probability that correlates positively to the [score].

QS3
High

Recommandations (QG2), Reliable (QG5)

When a dancer changes his personal information in his [profile], his feed is updated with new recommendations after no more than 24 hours.

QS4
High

Easy (QG1)

A dancer without an account at Dancier can get one and fill out the [profile] in one hour.

QS5
High

Team (QG3), Reliable (QG5)

In case our user base is doubling, it is easy to adapt the whole system to remain stable and performant.

QS6
High

Team (QG3), Reliable (QG5)

In case some components of Dancier are crashing, the rest keep running and serve user requests. (Graceful degradation)

QS7
Middle

Easy (QG1)

A school that wants to present itself on Dancier can get an account and provide basic information about itself in no more than one hour.

QS8
Middle

Team (QG3), Reliable (QG5)

When using Dancier, every (technical) request of our users is answered so timely, that the system is perceived as fast.

QS9
Middle

Team (QG3), Reliable (QG5)

In case of an exceptional situation where we lose (parts) of our data we can recover to a state that is not older than one day.

QS10
Middle

Team (QG3), Reliable (QG5)

A dancer rarely receives emails/chat messages that he perceives as Spam.

QS11
Low

Team (QG3)

When performing a sentiment analysis against common social networks, we see that Dancier is perceived well.

QS12
Low

Team (QG3)

Being asked how likely it is that they would recommend Dancier to another dancer, our customers answer with an average of 70.

QS13
Middle

Learning (QG4)

A new engineer starting at Dancier, can understand the system as a whole by reading this documentation, to be able to participate in architectural discussions after 8 hours.

QS14
Middle

Learning (QG4)

A new engineer starting at Dancier, can understand each technical building block fast, as it follows a clear and common code structure.

11. Risks and Technical Debts

11.1. Potential Overengineering

By trying to be an attractive learning project for developers, we are at risk of over-engineering. One example that falls into this category is that we split the system into more individual microservices as probably needed. A modular monolith would be likely to be easier to maintain and operate.

It is also questionable if Kafka would be a good fit for our messaging requirements.

But we want a project that is a distributed system and uses those technologies that are quite dominant (at least in the companies we have worked).

We should have a close eye on this, not introduce arbitrary more examples of things like this, to not risk the project as a whole.

11.2. Spam could be a severe problem

Providing a platform where individuals can chat with each other, could lead to problems with spamming people. As of now, we are not implementing anything against this problem, to get our MVP faster done. This could put us under pressure to react fast in case that turns out to be a problem.

12. Glossary

Term Definition

BFF

Backend For Frontend

Business Event

An Event that is being sent out to Kafka, exactly after something interesting has happened. Like:

  • AccountValidated

  • ProfileUpdated

  • RecommendationComputed

  • ChatMessageReceived

Info-Mail

in this context we mean the mail that inform the dancers about new chat-messages, new recommendations…​

Profile

All the information that the dancer provides about himself. Those are things like:

  • age

  • Gender

  • Location

  • what he can dance

  • what he is looking for

School

A school that offers dance courses, organises dance evenings…​

Score

Number between 0 and 100 indicating how likely it is that two dancers will like to dance with each other. A higher value indicates a better fit.