Analysis
Business requirements
These goals explain why Gotion is being built instead of adopting an existing tool.
-
BR-01 — Keep data in-house: Company policies or regulatory obligations may restrict where meeting notes, specifications, and customer data can be stored. Gotion therefore runs on infrastructure controlled by the adopting organization and makes no calls to external services at runtime.
-
BR-02 — Keep costs independent of team size: Per-user pricing becomes expensive as a team grows, especially when many members only need read access. With Gotion, the organization pays for its infrastructure, not for each user it adds.
-
BR-03 — Avoid vendor lock-in: Gotion stores content as Markdown, an open plain-text format, so that the content stays readable without Gotion. Using a proprietary format would recreate the dependency the project is intended to remove.
-
BR-04 — Minimize administrative work: Gotion is intended for small companies and research groups without a dedicated system administrator. Installation, upgrades, and backups must be manageable by one part-time administrator.
-
BR-05 — Make migration familiar: Teams already using Notion should not have to learn an entirely new way of working. Gotion must support familiar features such as nested pages, collaborative editing, and comments.
-
BR-06 — Make the system auditable and adaptable: Gotion is released under the GNU General Public License v3. Organizations can inspect how it handles their data, modify it to meet their needs, and verify the privacy guarantees behind BR-01.
Event Storming
The domain was explored with an Event Storming session, following the ten steps taught in the course, after Alberto Brandolini and chapter 12 of Khononov. The process is iterative: the model is enriched one step at a time, and every step is shown below.
The board is on Miro: Gotion Event Storming. Each section below links to the frame holding the wall at that step.
The colour of a sticky is its meaning, not decoration. The legend is kept on the board.
The grammar reads read model → actor + command → aggregate → domain event for a human-driven slice, and domain event → policy → command → aggregate → domain event for an automated one. By the end of step 8 every command must be executed by an actor, triggered by a policy, or called by an external system. Actor and aggregate are both yellow and are told apart by size: the actor is the small sticky on its command, the aggregate the large one. Pain points are pink diamonds, and pivotal events are vertical bars rather than stickies.
Steps
1. Unstructured Exploration
Each team member wrote the domain events that can happen in the system on orange stickies, in the past tense, and put them on the board without any order and without worrying about duplicates.
2. Timeline
The domain events were organised in the order in which they occur in the business domain, starting from the happy path and branching out from there.
3. Pain Points
We went back over the timeline to spot the points that need attention: bottlenecks, manual steps, missing domain knowledge. They are pink diamonds placed on the event they concern, so that a debate never stalls the session.
4. Pivotal Points
The events where the context or the phase changes are marked with a vertical bar dividing the events before and after. They are the first indicator of bounded context boundaries.
5. Commands
The command that triggers each event or flow of events: light blue, written in the imperative, and placed before the event it produces. Where a person in a role issues it, a small yellow actor sits on the command.
6. Policies
The commands left without an actor are executed by an automation policy: an event triggers the command. Purple, worded when X then Y, between the event and the command it fires.
7. Read Models
The view over the data that an actor reads before deciding to execute a command: a screen, a report, a notification. Green, placed before the command.
8. External Systems
Pink: anything that is not part of the domain being explored, and that either issues a command in or is notified of an event out through a policy. No external system is in scope for Gotion. This step is also the completeness check of the method: by the end of it every command is executed by an actor or triggered by a policy.
9. Aggregates
Commands and events were regrouped into transactional consistency boundaries. Each aggregate is a large yellow sticky that receives commands on its left and produces events on its right. Eight emerged: User, Workspace, Workspace Membership, Page, Page Block Tree, Real-time Editing Session, Notification, Comment Thread.
10. Bounded Contexts
Finally the aggregates that belong together functionally were grouped, and a boundary was drawn around each group. Those groups are the candidate bounded contexts, and the candidate microservices.
The identified bounded contexts are:
Account: who the user is, and the workspaces they work in (User,Workspace).Membership: who belongs to each workspace and with which role (Workspace Membership).Editing: the pages, their content and the real-time editing of a page (Page,Page Block Tree,Real-time Editing Session).Notification: what reaches the user (Notification).Discussion: the conversation attached to the content (Comment Thread).
They are candidates: the design weighs them against the subdomains and settles the bounded contexts in Strategic Design.
Open pain points
The pain points still open at the end of the session, each traced to the user story or quality attribute scenario it puts at risk. The architectural ones are settled in an Architecture Decision Record, the others in the domain model.
| Pain point | Context | Traces to |
|---|---|---|
| PP-01 — Where concurrent edits are ordered and merged: a central sequencer in the Editing service, or replicas that merge on their own | Editing | US-08, QA-02, QA-05 |
| PP-02 — Whether an invitation expires, and what happens when it is refused | Membership | US-03 |
| PP-03 — How a member leaves a workspace, given that the last Admin cannot | Membership | US-03 |
| PP-04 — How Editing and Discussion enforce the roles held by Membership: no policy on the board carries them out of Membership | Membership, Editing, Discussion | US-03, QA-06 |
| PP-05 — What happens to the comment threads of a deleted page, block or workspace, and to the Workspace Membership of a deleted workspace: no policy removes them | Discussion, Membership | US-02, US-04, US-09 |
Ubiquitous language
Each word below has exactly one meaning, in this report, in the code, and in the API: a block is a Block in the source, never a Node or an Item.
This glossary records the ubiquitous language of Gotion. Following DDD, the language is split by bounded context: a term is precise only inside the context where it is defined, and the same person or thing can take a different name in each context. The terms come from the Event Storming board, where the sticky wording is the language, and from the user stories.
Account
| Term | Definition | Not to be confused with |
|---|---|---|
| User | A person registered in Gotion with an email address and a password (US-01). The identity that signs in. | Member, which is a user seen inside one workspace. |
| Workspace | A separate space that contains pages, used to keep different projects or teams apart (US-02). A user’s first workspace is created when the user registers. | Workspace Membership, which holds who belongs to the workspace. |
| Main workspace | The workspace a user has chosen as the default one. By default it is the first workspace created when the user registers, until the user chooses another. | Active workspace. |
| Active workspace | The workspace the user is currently working in; switching workspace changes it. | Main workspace. |
Membership
| Term | Definition | Not to be confused with |
|---|---|---|
| Workspace Membership | The set of members of one workspace, each with a role. A workspace always keeps at least one Admin, so the last Admin cannot leave it. | Workspace, which lives in the Account context. |
| Member | A user who belongs to a workspace. Every member has exactly one role: Admin, Editor or Viewer. | User, the identity in the Account context. |
| Role | What a member may do in the workspace: Admin, Editor or Viewer (US-03). | — |
| Admin | The role that can do everything an Editor can, and also invite members, remove them and change their role (US-03). The creator of a workspace becomes its first Admin. | — |
| Editor | The role that can create, change and delete the pages and blocks of the workspace. | — |
| Viewer | The role that can only read the pages of the workspace. | — |
| Invitation | The request an Admin sends to a person to join a workspace. Accepting it turns the invitee into a member. | Notification, which only delivers the invitation. |
| Invitee | The person an invitation is addressed to, until they accept it. | Member. |
Editing
| Term | Definition | Not to be confused with |
|---|---|---|
| Page | A document of a workspace, with its metadata and its place in the page tree (US-04). Every page except the root page is also a block of its parent page. | Page Block Tree, the content of the page. |
| Root page | The only page of a workspace that has no parent, created together with the workspace. It holds content like any other page, and it is where new pages start: every other page is created inside it or inside one of its sub-pages, so every page of the workspace descends from it. A workspace has exactly one root page: no other can be created, and it is deleted only together with its workspace. | Main workspace. |
| Sub-page | Any page other than the root page: a page whose page block lives inside another page, its parent. | — |
| Page tree | The hierarchy of the pages of a workspace, rooted at the root page and given by the parent of each page. | Page Block Tree. |
| Page metadata | The title, icon and cover of a page (US-05). | Page content. |
| Block | The unit of content of a page: formatted text, heading, bulleted, numbered or to-do list, code (US-06, US-07). Blocks are ordered and can be nested. | — |
| Page block | The block that stands for a sub-page. Inserting, moving, deleting or updating it creates, moves, deletes or updates the metadata of that sub-page. | Page, which the page block points to. |
| Page Block Tree | The ordered, nestable tree of the blocks of one page: the page content. There is one per page, and it is deleted as a whole when its page is deleted. | Page tree, which is made of pages. |
| Real-time Editing Session | The shared editing of one page by the collaborators who have it open (US-08). Their edits are merged and then applied to the Page Block Tree. The session is closed when its page is deleted. | Workspace: a session belongs to a single page. |
| Collaborator | A user who has joined the editing session of a page, or who takes part in a discussion. | Member, which is about belonging to the workspace. |
| Presence | The collaborators currently in the editing session of a page (US-08). | — |
| Edit | A change to the content of a page submitted by a collaborator during a session. | Block: an edit is applied to blocks. |
| Merge | The combination of concurrent edits into one consistent result, applied to the Page Block Tree. | — |
Notification
| Term | Definition | Not to be confused with |
|---|---|---|
| Notification | A message that informs a user of something relevant to them, such as an invitation or a mention, shown in-app (US-10). It is raised, delivered on a best-effort basis, and marked as read by the user. | Comment. |
| Recipient | The user a notification is addressed to. | — |
Discussion
| Term | Definition | Not to be confused with |
|---|---|---|
| Comment Thread | A conversation attached to a page or to a single block (US-09). It can be resolved when the discussion is over. | Notification. |
| Comment | A message posted in a comment thread. | — |
| Mention | A reference to a member of the workspace written in a comment (US-09). It makes that member receive a notification. | — |
One person, many names
The same person takes a different name in each context, and each name carries only what that context needs.
| Context | Name | What the context knows about them |
|---|---|---|
| Account | User | Email address, credentials, workspaces |
| Membership | Member (Admin, Editor or Viewer), Invitee | Role in one workspace |
| Editing | Collaborator | Presence in the editing session of one page |
| Notification | Recipient | Where and how to reach them |
| Discussion | Collaborator, mentioned user | The comments they write and the mentions they receive |
Functional requirements
Expressed as user stories and grouped by the bounded contexts found with the Event Storming. Non-functional constraints on these behaviours are specified separately as Non functional requirements. Stories outside the current scope are kept aside, without an identifier, in Out of scope.
Account
- US-01 — Sign up and sign in: As a user, I want to register and authenticate with my email address and password so that I can access Gotion.
- US-02 — Manage workspaces: As a user, I want to create, rename, delete, and switch between multiple workspaces, and choose my main one, so that I can keep different projects or teams separate.
Membership
- US-03 — Manage workspace members: As a workspace Admin, I want to invite people to the workspace, remove members, and assign them the Admin, Editor, or Viewer role so that I can control who can read and who can change its content. A workspace always keeps at least one Admin.
Editing
- US-04 — Manage pages and blocks: As an Editor, I want to create, read, update, and delete pages and organize them and their blocks in a tree so that I can structure content hierarchically. Each workspace has exactly one root page, created with the workspace: it holds content like any other page, every new page is created inside it or inside one of its sub-pages, and it is deleted only together with the workspace.
- US-05 — Customize page metadata: As an Editor, I want to set a page title, icon, and cover so that pages are easy to recognize and personalize.
- US-06 — Edit Markdown blocks: As an Editor, I want to work with an ordered, nestable list of blocks so that content remains modular and structured.
- US-07 — Use native Markdown block types: As an Editor, I want to create formatted text, headings, bulleted, numbered, and to-do lists, and code blocks so that I can write rich content with Markdown.
- US-08 — Collaborate in real time: As a collaborator, I want to see the avatars of the other connected users and co-edit the same page so that we can work together.
Discussion
- US-09 — Discuss content in context: As a collaborator, I want to add comment threads to pages or individual blocks, resolve them, and mention a member of the workspace in a comment so that conversations stay connected to the relevant content.
Notification
- US-10 — Receive in-app notifications: As a user, I want to receive in-app notifications about invitations and mentions so that I can stay informed.
Out of scope for now
Stories written before the Event Storming and left out of the current scope, kept here so that the history of the analysis stays traceable.
| Story | Reason |
|---|---|
| Restore deleted pages (trash area, restore, permanent delete) | Deleting a page is permanent: it removes the page content and its sub-pages at once. |
| Review page history (revisions and their authors) | Not needed by the prototype. |
| Reuse synchronized content (synced blocks) | Not needed by the prototype. |
| Apply granular permissions (per-page permissions inherited from the workspace) | Replaced by the workspace roles of US-03. |
| Search the workspace (full-text search) | Planned as a future extension: it can be added as a new service that listens to the events Editing already publishes. |
Non functional requirements
Non-functional requirements, expressed as six-part scenarios (source, stimulus, artifact, environment, response, response measure). Each scenario is testable: the response measure is the acceptance criterion.
The reference deployment for every scenario is a single self-hosted node with 4 vCPU and 8 GB RAM, serving a workspace of 50 members, 10 000 pages and 1 000 000 blocks, unless a scenario states otherwise.
Performance
QA-01 — Editor input latency (constrains US-06, US-07)
| Part | Value |
|---|---|
| Source | User typing in the editor |
| Stimulus | Inserts a character into a block |
| Artifact | Editor client and block persistence path |
| Environment | Normal operation, page containing 500 blocks |
| Response | Character is rendered locally and durably persisted |
| Response measure | Local render ≤ 50 ms (p95); server acknowledgement ≤ 500 ms (p95) |
QA-02 — Real-time propagation latency (constrains US-08)
| Part | Value |
|---|---|
| Source | Remote collaborator |
| Stimulus | Edits a block on a page open in other clients |
| Artifact | Synchronization channel |
| Environment | Normal operation, 5 concurrent editors on the same page |
| Response | Change is applied and rendered in every other connected client |
| Response measure | ≤ 300 ms (p95), ≤ 1 s (p99) from acknowledgement to remote render |
QA-03 — Page open time (constrains US-04)
| Part | Value |
|---|---|
| Source | User |
| Stimulus | Opens a page from the sidebar |
| Artifact | Page loading and rendering path |
| Environment | Cold client cache, page containing 500 blocks |
| Response | Page is rendered and accepts input |
| Response measure | Interactive within 1.5 s (p95) |
Availability
QA-04 — Process crash without data loss (constrains US-04, US-06)
| Part | Value |
|---|---|
| Source | Infrastructure fault |
| Stimulus | The server process terminates abnormally |
| Artifact | Persistence layer |
| Environment | Normal operation, edits in flight |
| Response | The service restarts; every acknowledged edit survives |
| Response measure | Zero loss of acknowledged edits; service available again within 60 s |
Data Consistency
QA-05 — Concurrent edit convergence (constrains US-08)
| Part | Value |
|---|---|
| Source | Multiple collaborators |
| Stimulus | 10 users edit the same block simultaneously |
| Artifact | Synchronization engine |
| Environment | Normal operation, client-server round-trip up to 500 ms |
| Response | All replicas converge to an identical document state; no acknowledged edit is silently discarded |
| Response measure | 100 % convergence within 2 s of the last edit, verified by an automated test over 1 000 randomized operation interleavings |
Security
QA-06 — Unauthorized page access (constrains US-03)
| Part | Value |
|---|---|
| Source | Authenticated user who is not a member of the workspace, or a Viewer of it |
| Stimulus | Requests a page directly by identifier, or submits a change to it, bypassing the UI |
| Artifact | Authorization layer |
| Environment | Normal operation |
| Response | The request is denied |
| Response measure | 100 % of such requests denied; for a non-member, responses for “forbidden” and “non-existent” are indistinguishable, leaking no title or metadata |
QA-07 — Brute-force login (constrains US-01)
| Part | Value |
|---|---|
| Source | Attacker |
| Stimulus | Attempts repeated logins against one account, guessing its password |
| Artifact | Authentication subsystem |
| Environment | Normal operation |
| Response | Repeated failed attempts are throttled |
| Response measure | More than 5 failed attempts per account per 15 minutes triggers rate limiting |
Deployability
QA-08 — Fresh self-hosted installation
| Part | Value |
|---|---|
| Source | System administrator |
| Stimulus | Deploys Gotion on a clean Linux host |
| Artifact | The whole system |
| Environment | No pre-existing dependencies beyond a container runtime |
| Response | A running instance with an initial administrator account |
| Response measure | Reachable within 10 minutes using one documented command; schema migrations run automatically, with no manual database step |
Modifiability
QA-09 — Adding a block type (constrains US-07)
| Part | Value |
|---|---|
| Source | Developer |
| Stimulus | Adds a new block type, for example a table |
| Artifact | Block model, editor, renderer |
| Environment | Development time |
| Response | The type is available end to end: creation, persistence, rendering |
| Response measure | Changes confined to the definition and the rendering of the new type; no change to real-time synchronization or to the persistence schema |
Accessibility
QA-10 — Keyboard-only and assistive-technology editing (constrains US-06, US-07)
| Part | Value |
|---|---|
| Source | User relying on a keyboard or a screen reader |
| Stimulus | Creates, reorders, nests, and deletes blocks without a pointing device |
| Artifact | Editor user interface |
| Environment | Normal operation, screen reader active |
| Response | Every block operation is reachable and announced |
| Response measure | 100 % of block operations keyboard-accessible; editor and navigation conform to WCAG 2.1 level AA |
Out of scope for now
| Scenario | Reason |
|---|---|
| Search response time | Search left the scope together with the search story. |
| Editing during network interruption (offline editing, reconciled on reconnect) | Not covered: editing a page requires a connection to the server. |