Ver Fonte

add docs

appflowy há 3 anos atrás
pai
commit
126ac20ccc

+ 1 - 2
.gitignore

@@ -9,5 +9,4 @@ Cargo.lock
 # These are backup files generated by rustfmt
 **/*.rs.bk
 
-/rust-lib/flowy-ast
-/rust-lib/flowy-derive
+/rust-lib

+ 14 - 30
README.md

@@ -1,38 +1,22 @@
-# AppFlowy client
+[![Version](https://img.shields.io/badge/rustc-1.46+-ab6000.svg)](https://blog.rust-lang.org/2020/03/12/Rust-1.46.html)
+![Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web.svg)
 
-* The Big Picture
-    * Introduce
-    * Goals
-    * Cross-platform
 
-* Getting started
-    * Build
-    * Running
-    
-* Contributing
-    * First steps
-    * Opening issues
-    * Participating in discussions
-    * Finding something to work on
-    * Open your PR
-    * Review Process
-    * Getting more involved
-        * Organization membership
-        * Contributor
-        * Maintainer
+# what is AppFlowy?
 
-## The Big Picture
+## Features
 
-### Introduce
+## Documentation
 
-### Goals
-
-### Cross-platform
-
-
-## Getting Started
-Read the [architecture doc](doc/architecture.md) before you started.
+* [**Getting Started**](doc/getting_started.md)
+* [**Roadmap**](doc/roadmap.md)
+* [**Deep Dive AppFlowy**](doc/architecture.md)
 
 ## Contributing
-Read the [architecture doc](doc/architecture.md) before you started.
+Read the [Contributing Doc](doc/contribute.md) before you want to contribute.
+
+## Social Media
+* Slack
 
+## License
+AppFlowy is under the Apache 2.0 license. See the [LICENSE](/LICENSE) file for details.

+ 1 - 0
doc/about app flowy.md

@@ -0,0 +1 @@
+[WIP]

+ 13 - 225
doc/architecture.md

@@ -1,231 +1,19 @@
-# AppFlowy Architecture
-This documentation introduces the Domain-Driven Design and the design of AppFlowy. Feel free to skip the first part
-if you know what Domain-Driven Design is.
-* Basic Concepts
-    * Layered architecture
-    * Domain Driven Design
-    
-* AppFlowy Design
-    * Overview
-    * Operation Flow
-    * Create
-    * Read
-    * Update
-    * Delete
-    
-# Basic Concepts
-
-## Layered architecture
-The most common architecture pattern is the layered architecture pattern, known as the n-tier architecture pattern.
-Partition the software into `layers` to reduce the complexity. Each layer of the layered architecture pattern has a
-specific role and responsibility.
+# 🥳 AppFlowy System Design
 
-## Domain Driven Design
-For many architects, the process of data modeling is driven by intuition. However, there are well-formulated methodologies
-for approaching it more formally. I recommend the [Domain-Driven Design](https://en.wikipedia.org/wiki/Domain-driven_design)
-and choose it as AppFlowy architecture. 
+* Goals of the System
+* Some Design Considerations
+* High Level Design
+* Component Design 
 
-DDD consists of four layers.
+## 🎯 Goals of the System
 
-```
-    ┌──────────────────────────────────────────────────┐         ─────────▶
-    │                Presentation Layer                │──┐      Dependency
-    └──────────────────────────────────────────────────┘  │
-                              │                           │
-                              ▼                           │
-    ┌──────────────────────────────────────────────────┐  │
-    │                Application Layer                 │  │
-    └──────────────────────────────────────────────────┘  │
-                              │                           │
-                              ▼                           │
-    ┌──────────────────────────────────────────────────┐  │
-    │                   Domain Layer                   │◀─┘
-    └──────────────────────────────────────────────────┘
-                              ▲
-                              │
-    ┌──────────────────────────────────────────────────┐
-    │               Infrastructure Layer               │
-    └──────────────────────────────────────────────────┘
+## 🤔 Some Design Considerations
+## 📜 High Level Design
+## 📚 Component Design
     
-                 ▲
-                 │
-    Level of     ├───────────────────┐
-    Abstraction  │ Presentation      │
-                 ├───────────────────┴───────┐
-                 │ Application               │
-                 ├───────────────────────────┴─────────┐
-                 │ Domain                              │
-                 ├─────────────────────────────────────┴────────┐
-                 │ Infrastructure                               │
-                 └──────────────────────────────────────────────┴─────▶
-                                                           Complexity
-```
-
-**Presentation**: 
-* Responsible for presenting information to the user and interpreting user commands.
-* Consists of Widgets and also the state of the Widgets.
-   
-**Application**:
-* Defines the jobs the software is supposed to do. (Shouldn't find any UI code or network code)
-* Coordinates the application activity and delegates work to the next layer down.
-* It doesn't contain any complex business logic but the basic validation on the user input before
-  passing to the other layer.   
-  
-**Domain**: 
-* Responsible for representing concepts of the business.
-* Manages the business state or delegated to the infrastructure layer.
-* Self contained and it doesn't depend on any other layers. Domain should be well isolated from the
-  other layers.
-
-**Infrastructure**: 
-
-This layer acts as a supporting library for all the other layers. It deals with APIs, 
-databases and network, etc.
-
-DDD classifies data as referenceable objects, or entities, and non-referenceable objects, or values.
-
-**Entity** 
-
-user, order, book, table. They are referenceable because they carry an identity which 
-allows us to reference them.
-
-**Value**
-
-email, phone number, name, age, description. They can't be referenced. They can be only included into
-entities and serve as attributes. Values could be simple or could be composite.
-
-**Aggregate** 
-
-entities can be grouped into aggregates. Aggregates can simplify the model by accessing th entire
-aggregate. For instance, Table has lots of row. Each row using the table_id to reference to the 
-table. TableAggregate includes two entities: Table and the Row.
-
-```
-     TableAggregate
-    ┌────────────────────────────────────────────────────────────────┐
-    │                                                                │
-    │  ┌────────────────────┐         ┌─────────────────────────┐    │
-    │  │struct Table {      │         │struct Row {             │    │
-    │  │    id: String,     │         │    table_id: String,    │    │
-    │  │    desc: String,   │◀▶───────│}                        │    │
-    │  │}                   │         │                         │    │
-    │  └────────────────────┘         └─────────────────────────┘    │
-    │                                                                │
-    └────────────────────────────────────────────────────────────────┘
-```
-
-DDD also introduces `Service` and `Repository`.
-
-**Service**
-
-When a significant process of transformation in the domain is not a natural responsibility of an `Entity` or `Value object`, add
-an operation to the model as standalone interface declared as a Service. For instance: The `Value object`, EmailAddress, 
-uses the function `validateEmailAddress` to verify the email address is valid or not. `Service` exists in Application, Domain and
-Infrastructure.
-
-```
-class EmailAddress  {
-  final Either<Failure<String>, String> value;
-
-  factory EmailAddress(String? input) {
-    return EmailAddress._(
-      validateEmailAddress(input),
-    );
-  }
-  
-  const EmailAddress._(this.value);
-}
-
-
-Either<Failure<String>, String> validateEmailAddress(String? input) {
-  ...
-}
-```
-
-**Repository**
-
-Repository offer an interface to retrieve and persist aggregates. They hide the database or network details from the domain.
-The Repository interfaces are declared in the Domain Layer, but the repositories themselves are implemented in the Infrastructure Layer.
-You can replace the interface implementation without impacting the domain layer. For instance:
-
-```
-// Interface:
-abstract class AuthInterface {
-    ...
-}
-
-// Implementation
-class AuthRepository implements AuthInterface {
-    ...
-}
-```
-More often than not, the repository interface can be divided into sub-repository in order to reduce the complexity. 
-
-## AppFlowy Design
-
-The AppFlowy Client consists of lots of modules. Each of them follows the DDD design pattern and using [dependency injection](https://levelup.gitconnected.com/dependency-injection-in-swift-bc16d66b038b)
-to communication with other module.
-
-```
-
-   Client
-  ┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
-  │                                                                                                      │
-  │   Module A                             Module B                 Module C                             │
-  │  ┌───────────────────┐                ┌───────────────────┐    ┌───────────────────┐                 │
-  │  │ presentation      │   Dependency   │ presentation      │    │ presentation      │                 │
-  │  │                   │   Injection    │                   │    │                   │                 │
-  │  │ application       ├───────────────▶│ application       │    │ application       │                 │
-  │  │                   │◀───────────────│                   │    │                   │    ◉  ◉  ◉      │
-  │  │ domain            │                │ domain            │    │ domain            │                 │
-  │  │                   │                │                   │    │                   │                 │
-  │  │ Infrastructure    │                │ Infrastructure    │    │ Infrastructure    │                 │
-  │  └───────────────────┘                └───────────────────┘    └───────────────────┘                 │
-  │            ▲                                                             │                           │
-  │            │                       Dependency Injection                  │                           │
-  │            └─────────────────────────────────────────────────────────────┘                           │
-  │                                                                                                      │
-  └──────────────────────────────────────────────────────────────────────────────────────────────────────┘
-```
-
-Let's dig it how can I construct each module. I take `User` module for demonstration.
-
-```
-
-     presentation            Application                      domain                           Infrastructure
-
-                  │
-                                              │                                  │
-                     7                                 Data Model
-       ┌──────────────────────────────┐       │       ┌────────────────────────┐ │         ┌───────────────────────────┐
-       │          │                   │               │ ┌─────────────┐        │    ┌─────▶│ Repository implementation │
-       ▼             Bloc             │         2.1   │ │  Aggregate  │        │ │  │      └───────────────────────────┘
-┌─────────────┐   │ ┌─────────────────┴─────┐         │ └─────────────┘        │    │                    │  4
-│   Widget    │     │ ┌────────┐ ┌────────┐ │ │       │ ┌────────┐             │ │  │                    ▼
-└─────────────┘   │ │ │ Event  │ │ State  │ │───┬────▶│ │ Entity │             │    │         ┌─────────────────────┐
-       │            │ └────────┘ └────────┘ │ │ │     │ └────────┘             │ │  │         │    Unit of Work     │
-       │          │ └──────▲────────────────┘   │     │ ┌─────────────────┐    │    │         └─────────────────────┘
-       │                   │                  │ │     │ │  Value Object   │    │ │  │                    │  5
-       └──────────┼────────┘                    │     │ └─────────────────┘    │    │                    ▼
-             1                                │ │     └────────────────────────┘ │  │         ┌─────────────────────┐
-                  │                             │                  ◈                │         │ Persistence Service │
-                                              │ │                  │ contain     │  │         └─────────────────────┘
-                  │                             │       ┌────────────────────┐      │
-                                              │ │       │      Service       │   │  │
-                  │                             │       └────────────────────┘      │
-                                              │   2.2                            │  │
-                  │                             │    ┌───────────────────────┐      │
-                                              │ └───▶│ Repository interface  │   │  │
-                  │                                  └───────────────────────┘      │
-                                              │                  │               │  │
-                  │                                              │          3       │
-                                              │                  └───────────────┼──┘
-```
+### 📕 Component 1
+### 📗 Component 2
+### 📘 Component 3
+### 📙 Component 3
 
 
-1.  Send event using the bloc. The bloc does not know about the `Widget`. It should communicate through events.
-2.  The bloc dispatching the event to the appropriate handler of the `Domain`
-    1. Conversion between, DTO (Data Transfer Object) to domain model and Domain Model to DTO.
-    2.  Handling the business logic using the repository interface
-3.  Repository are used to store the domain model data and calls respective service to finish the jobs.
-# Event-Driven

+ 12 - 0
doc/contribute.md

@@ -0,0 +1,12 @@
+[WIP]
+* Contributing
+    * First steps
+    * Opening issues
+    * Participating in discussions
+    * Finding something to work on
+    * Open your PR
+    * Review Process
+    * Getting more involved
+        * Organization membership
+        * Contributor
+        * Maintainer

+ 243 - 0
doc/domain driven design.md

@@ -0,0 +1,243 @@
+
+# 🍔 Domain Driven Design
+
+For many architects, the process of data modeling is driven by intuition. However, there are well-formulated methodologies
+for approaching it more formally. I recommend the [Domain-Driven Design](https://en.wikipedia.org/wiki/Domain-driven_design)
+and choose it as AppFlowy architecture.
+
+## 💥 Layered architecture
+The most common architecture pattern is the layered architecture pattern, known as the n-tier architecture pattern.
+Partition the software into `layers` to reduce the complexity. Each layer of the layered architecture pattern has a
+specific role and responsibility.`DDD` consists of four layers.
+
+```
+    ┌──────────────────────────────────────────────────┐         ─────────▶
+    │                Presentation Layer                │──┐      Dependency
+    └──────────────────────────────────────────────────┘  │
+                              │                           │
+                              ▼                           │
+    ┌──────────────────────────────────────────────────┐  │
+    │                Application Layer                 │  │
+    └──────────────────────────────────────────────────┘  │
+                              │                           │
+                              ▼                           │
+    ┌──────────────────────────────────────────────────┐  │
+    │                   Domain Layer                   │◀─┘
+    └──────────────────────────────────────────────────┘
+                              ▲
+                              │
+    ┌──────────────────────────────────────────────────┐
+    │               Infrastructure Layer               │
+    └──────────────────────────────────────────────────┘
+```
+
+**Presentation Layer**:
+* Responsible for presenting information to the user and interpreting user commands.
+* Consists of Widgets and also the state of the Widgets.
+
+**Application Layer**:
+* Defines the jobs the software is supposed to do. (Shouldn't find any UI code or network code)
+* Coordinates the application activity and delegates work to the next layer down.
+* It doesn't contain any complex business logic but the basic validation on the user input before
+  passing to the other layer.
+
+**Domain Layer**:
+* Responsible for representing concepts of the business.
+* Manages the business state or delegated to the infrastructure layer.
+* Self contained and it doesn't depend on any other layers. Domain should be well isolated from the
+  other layers.
+
+**Infrastructure Layer**:
+
+* Provides generic technical capabilities that support the higher layers. It deals with APIs, persistence and network, etc.
+* Implements the repository interface and hiding the complexity of the Domain layer.
+
+As you see, the `Complexity` and `Abstraction` of these layers are depicted in this diagram. Software system are composed in layers,
+where higher layers use the facilities provided by lower layers. Each layer provides a different abstraction from the layer above
+and below it. As a developer, we should pull the complexity downwards. Simple interface and powerful implementation(Think about the
+[open](https://man7.org/linux/man-pages/man2/open.2.html) function). Another way of expressing this idea is that it is more important
+for a module to have a simple interface than a simple implementation.
+
+
+```
+                 ▲
+                 │
+    Level of     ├───────────────────┐
+    Abstraction  │ Presentation      │
+                 ├───────────────────┴───────┐
+                 │ Application               │
+                 ├───────────────────────────┴─────────┐
+                 │ Domain                              │
+                 ├─────────────────────────────────────┴────────┐
+                 │ Infrastructure                               │
+                 └──────────────────────────────────────────────┴─────▶
+                                                           Complexity
+```
+
+
+### Data Model
+DDD classifies data as referenceable objects, or entities, and non-referenceable objects, or value objects. Let's introduces
+some terminologies from DDD.
+
+**Entity**
+
+`Entities` are referenceable because they carry an identity which allows us to reference them. e.g. user, order, book, etc.
+You can use `entities` to express your business model and encapsulate them into Factory that provides simple API interface
+to create Entities.
+
+
+**Value Object**
+
+`Value Object` can't be referenced. They can be only included into entities and serve as attributes. Value objects could be
+simple and treat as immutable. e.g. email, phone number, name, etc.
+
+**Aggregate**
+
+`Entity` or `Value object` can be grouped into aggregates. Aggregates can simplify the model by accessing the entire aggregate.
+For instance, Table has lots of row. Each row using the table_id to reference to the
+table. TableAggregate includes two entities: Table and the Row.
+
+```
+     TableAggregate
+    ┌────────────────────────────────────────────────────────────────┐
+    │                                                                │
+    │  ┌────────────────────┐         ┌─────────────────────────┐    │
+    │  │struct Table {      │         │struct Row {             │    │
+    │  │    id: String,     │         │    table_id: String,    │    │
+    │  │    desc: String,   │◀▶───────│}                        │    │
+    │  │}                   │         │                         │    │
+    │  └────────────────────┘         └─────────────────────────┘    │
+    │                                                                │
+    └────────────────────────────────────────────────────────────────┘
+```
+
+**Service**
+
+When a significant process of transformation in the domain is not a natural responsibility of an `Entity` or `Value object`, add
+an operation to the model as standalone interface declared as a Service. For instance: The `Value object`, EmailAddress,
+uses the function `validateEmailAddress` to verify the email address is valid or not. `Service` exists in Application, Domain and
+Infrastructure.
+
+```
+class EmailAddress  {
+  final Either<Failure<String>, String> value;
+
+  factory EmailAddress(String? input) {
+    return EmailAddress._(
+      validateEmailAddress(input),
+    );
+  }
+  
+  const EmailAddress._(this.value);
+}
+
+
+Either<Failure<String>, String> validateEmailAddress(String? input) {
+  ...
+}
+```
+
+**Repository**
+
+Repository offer an interface to retrieve and persist aggregates and entities. They hide the database or network details from the domain.
+The Repository interfaces are declared in the Domain Layer, but the repositories themselves are implemented in the Infrastructure Layer.
+You can replace the interface implementation without impacting the domain layer. For instance:
+
+```
+// Interface:
+abstract class AuthInterface {
+    ...
+}
+
+// Implementation
+class AuthRepository implements AuthInterface {
+    ...
+}
+```
+> More often than not, the repository interface can be divided into sub-repository in order to reduce the complexity.
+
+### Relation
+The diagram below is a navigational map. It shows the patterns that form the building blocks of Domain Driven Design and how they relate to each other.
+![[image from here](http://uniknow.github.io/AgileDev/site/0.1.8-SNAPSHOT/parent/ddd/core/building_blocks_ddd.html)](imgs/domain_model_relation.png)
+
+
+## 🔥 Operation Flow
+
+```
+
+       presentation       │          Application                      domain                        Infrastructure
+                                                      │                                   │
+                             7                                 Data Model
+               ┌──────────────────────────────┐       │       ┌────────────────────────┐  │     ┌─────────────────────┐
+               │          │                   │               │ ┌─────────────┐        │        │   Network Service   │
+               ▼             Bloc             │       │       │ │  Aggregate  │        │  │     └─────────────────────┘
+        ┌─────────────┐   │ ┌─────────────────┴─────┐         │ └─────────────┘        │                   ▲
+────────▶   Widget    │     │ ┌────────┐ ┌────────┐ │    2    │ ┌────────┐             │  │                │ 6
+        └─────────────┘   │ │ │ Event  │ │ State  │ │────┬───▶│ │ Entity │             │        ┌─────────────────────┐
+User           │            │ └────────┘ └────────┘ │ │  │    │ └────────┘             │  │     │ Persistence Service │
+interaction    │          │ └──────▲────────────────┘    │    │ ┌─────────────────┐    │        └─────────────────────┘
+               │                   │                  │  │    │ │  Value Object   │    │  │                ▲
+               └──────────┼────────┘                     │    │ └─────────────────┘    │                   │ 5
+                     1                                │  │    └────────────◈───────────┘  │     ┌─────────────────────┐
+                          │                              │                 │contain             │    Unit of Work     │
+                                                      │  │      ┌────────────────────┐    │     └─────────────────────┘
+                          │                              │      │      Service       │                     ▲
+                                                      │  │      └────────────────────┘    │                │
+                          │                              │                                                 │ 4
+                                                      │  │     Repository                 │                │
+                          │                              │   ┌─────────────────────────────────────────────┴───────────────┐
+                                                      │  │   │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐  3  ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │
+                          │                              └───┤         Interface        ────▶       Implementation         │
+                                                      │      │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘     └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │
+                          │                                  └─────────────────────────────────────────────────────────────┘
+                                                      │
+```
+
+
+1.  Widget accepts user interaction and transfers the interactions into specific events. The events will be send to the Application layer,
+    handled by the specific `bloc`. The `bloc` send the states changed by the events back to the widget, and finally the `Widget` update
+    the UI according to the state. The pattern is depicted in this diagram. (More about the flutter [bloc](https://bloclibrary.dev/#/coreconcepts?id=bloc))
+    ```
+                       ┌────────────     State     ────────────┐
+                       │                                       │
+                       ▼                          Bloc         │
+                ┌─────────────┐                  ┌─────────────┼─────────┐
+       ────────▶│   Widget    │                  │ ┌────────┐ ┌┴───────┐ │
+                └─────────────┘                  │ │ Event  │ │ State  │ │
+    User interaction   │                         │ └────────┘ └────────┘ │
+                       │                         └───────────────────────┘
+                       │                                     ▲
+                       │                                     │
+                       └──────────     Event     ────────────┘
+    
+    ```
+
+2.  The `bloc` process the events using the services provided by the `Domain` layer.
+    1. Convert DTO (Data Transfer Object) to domain model and Domain Model to DTO.
+    2. Domain model is the place where all your business logics, business validation and business behaviors will be implemented.
+       The Aggregate Roots, Entities and Value Objects will help to achieve the business logic.
+3. Calling repositories to perform additional operations. The repositories interfaces are declared in `Domain`, implemented in `Infrastructure`.
+   You can reimplement the repository interface with different languages, such as `Rust`, `C++` or `Flutter`. etc.
+   ```
+              Domain                       Infrastructure
+
+     Repository A                │
+    ┌────────────────────────────┼────────────────────────────────┐
+    │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐  │  ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │
+    │         Interface        ──┼─▶       Implementation         │
+    │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘  │  └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │
+    └────────────────────────────┼────────────────────────────────┘
+     Repository B                │
+    ┌────────────────────────────┼────────────────────────────────┐
+    │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐  │  ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │
+    │         Interface        ──┼─▶       Implementation         │
+    │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘  │  └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │
+    └────────────────────────────┴────────────────────────────────┘
+   ```
+4. Responsibility of [Unit of Work](https://martinfowler.com/eaaCatalog/unitOfWork.html) is to maintain a list of objects affected by a
+   business transaction and coordinates the writing out of changes and the resolution of concurrency problems((No intermediate state)).
+   If any one persistence service fails, the whole transaction will be failed so, roll back operation will be called to put the object
+   back in initial state.
+
+5. Handling operations (INSERT, UPDATE and DELETE) with SQLite to persis the data.
+6. Saving or querying the data in the cloud to finish the operation.

+ 0 - 0
doc/getting_started.md


BIN
doc/imgs/ddd_big_pic.png


BIN
doc/imgs/domain_model_relation.png


+ 1 - 0
doc/roadmap.md

@@ -0,0 +1 @@
+[WIP]

+ 1 - 0
doc/why flutter and rust.md

@@ -0,0 +1 @@
+[WIP]