Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions modules/module-01/REFLECTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

# Module 1 — Reflection

**Team name**: **\*\***\_\_\_**\*\***
**Branch**: `module-01/<team-name>`
**Team name**: Bahjat
**Branch**: `module-01/<bahjat>`
**Submitted**: before Module 2 lesson

---
Expand All @@ -22,7 +22,7 @@ You started from a painful monolith. Now you're splitting it into separate servi

Think about it from three angles: the developer who has to change code, the team that has to deploy it, and the user who has to live with its failures. You don't need to cover all three, pick the one that felt most real to you today.

> _Your answer:_
> Splitting the app solves the problem of deployment crashes and tight coupling. From a user's perspective, if the Game Library goes offline because of a bug or an update, the whole platform doesn't crash. They can still log in, view their profile, and chat with friends because the Identity and Activity services are running independently.

---

Expand All @@ -34,7 +34,7 @@ Look at your service map. Every arrow between two services is a decision someone

What would break, slow down, or become harder to manage if you merged those two services back together?

> _Your answer:_
>I separated the Activity service from the Notification service. In the monolith, these were tightly coupled, meaning when a user logged a game, the system paused to write notifications for all their friends before finishing the request. By separating them and using an async event, logging an activity is instant, and notifications are processed safely in the background.

---

Expand All @@ -46,7 +46,7 @@ Microservices solve the monolith's problems. But they create new ones.

No need to solve it: just name it honestly. This is exactly the tension the rest of the course is about.

> _Your answer:_
>Data querying is much harder now. In the monolith, if I wanted to show an activity feed, I could just write a single SQL JOIN to get the user's name, the game title, and the activity. Now, that data is locked in three different databases, requiring multiple network calls between services just to render one page.

---

Expand Down
47 changes: 41 additions & 6 deletions modules/module-01/exercise.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Module 1 — Service Decomposition

**Duration**: 2h in class
**Branch to submit**: `module-01/<team-name>`
**Branch to submit**: `module-01/<bahjat>`

---

Expand All @@ -26,11 +26,13 @@ A bounded context is a part of the system that has a clear responsibility and ow

For each bounded context you identify, fill in the table:

| Bounded Context | Responsibilities | Owned Entities | Team |
| --------------- | -------------------------------------------------------- | -------------- | ----------- |
| Identity | Manages who users are, handles registration and profiles | User, Session | Platform |
| Game Library | _(fill in)_ | _(fill in)_ | _(fill in)_ |
| _(add more)_ | | | |
| Bounded Context | Responsibilities | Owned Entities | Team |
| Identity | Manages who users are, handles registration and profiles | User, Session | Platform |
| Game Library | Manages the catalog of games, titles, and genres | Game, Category | Content |
| Activity | Manages social feeds, friendships, and logging what people play | Activity, Friendship | Social |
| Notification | Manages delivering alerts and messages to users | Notification, DeviceToken | Communications |
| Logging | Records system events, checks GDPR consent | Log, ConsentRecord | Infra |


There is no single correct answer: what matters is that you can justify each row.

Expand All @@ -56,6 +58,24 @@ Payload: { activity_id, user_id, action, game_id, timestamp }

Focus on the flows that feel non-obvious. You do not need to document every possible pair.

Contract 1:
identity-service → activity-service
Trigger: a user logs in successfully
Protocol: RabbitMQ message (async)
Payload: { user_id, session_id, timestamp }

Contract 2:
activity-service → notification-service
Trigger: a user earns an achievement or milestone
Protocol: RabbitMQ message (async)
Payload: { user_id, achievement_id, message, timestamp }

Contract 3:
gateway → identity-service
Trigger: a client sends a login or registration request
Protocol: REST (sync)
Payload: { username, email, password_hash }

---

## Task 3 — Draw the service map _(~20 min)_
Expand All @@ -69,15 +89,30 @@ Draw the full GameHub service map:

This can be a sketch on paper, a whiteboard photo, or ASCII art committed to your branch.

[Client]
|
[Gateway]
_____|__|__|__|_____
| | | | |
[identity][game][activity][notification][logging]
|_async__| |___async___|___async___|


---

## Discussion _(~15 min)_

Three questions to discuss as a team before you leave:

1. Why does `notification-service` use Node.js instead of Python like the rest? What does that tell you about microservices and technology choices?
Because node handles lots of simultaneous I/O better. Each service can use whatever language fits its job.

2. What is the risk of `activity-service` calling `logging-service` synchronously — why might you prefer an async event instead?
if logging-service crashes, activity-service crashes too. Async decouples them.

3. Why does `logging-service` need a GDPR consent check before recording any activity?
you can't store personal data without consent. Logging is the last gate before data is written.


You do not need to write these answers down — they are warm-up for your REFLECTION.md.

Expand Down