diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/astro-cqrs-framework-doc.iml b/.idea/astro-cqrs-framework-doc.iml
new file mode 100644
index 0000000..24643cc
--- /dev/null
+++ b/.idea/astro-cqrs-framework-doc.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..a55e7a1
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..8818ea3
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/astro.config.mjs b/astro.config.mjs
index 1b39364..681a3a9 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -4,24 +4,60 @@ import starlight from '@astrojs/starlight';
// https://astro.build/config
export default defineConfig({
+ /*redirects: {
+ '/': '/en/'
+ },*/
+ trailingSlash: 'always',
integrations: [
starlight({
- title: 'My Docs',
- social: {
- github: 'https://github.com/withastro/starlight',
+ title: 'Open Harbor',
+ logo: {
+ replacesTitle: true,
+ light: './src/assets/logo.png',
+ dark: './src/assets/dark-logo.png',
+ },
+ defaultLocale: 'en',
+ locales: {
+ en: {
+ label: 'English'
+ },
+ fr: {
+ label: 'Français'
+ }
},
+ social: { // todo: implement gitea social
+ github: 'https://git.openharbor.io/Open-Harbor/dotnet-cqrs',
+ },
+ customCss: [
+ './src/styles/global.css'
+ ],
sidebar: [
{
- label: 'Guides',
- items: [
- // Each item here is one entry in the navigation menu.
- { label: 'Example Guide', slug: 'guides/example' },
- ],
- },
- {
- label: 'Reference',
- autogenerate: { directory: 'reference' },
- },
+ label: '.NET',
+ items: [
+ {
+ label: 'Guides',
+ items: [
+ { label: 'Concept', slug: 'dotnet/guides/concept' },
+ { label: 'Getting Started', slug: 'dotnet/guides/getting-started' },
+ { label: 'Adding your first command', slug: 'dotnet/guides/first-command' },
+ ]
+ },
+ {
+ label: 'References',
+ items: [
+ 'dotnet/references/example'
+ ]
+ },
+ {
+ label: 'Resources',
+ items: [
+ 'dotnet/resources/nugets',
+ { label: 'Git', link: 'https://git.openharbor.io/Open-Harbor/dotnet-cqrs' }
+ ]
+ }
+ ],
+ }
],
}),
],
diff --git a/package.json b/package.json
index 5870b43..c89c2b5 100644
--- a/package.json
+++ b/package.json
@@ -13,5 +13,6 @@
"@astrojs/starlight": "^0.30.3",
"astro": "^5.0.2",
"sharp": "^0.32.5"
- }
-}
\ No newline at end of file
+ },
+ "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
+}
diff --git a/public/favicon.svg b/public/favicon.svg
index cba5ac1..fb36d04 100644
--- a/public/favicon.svg
+++ b/public/favicon.svg
@@ -1 +1,91 @@
-
\ No newline at end of file
+
+
+
diff --git a/src/assets/dark-logo.png b/src/assets/dark-logo.png
new file mode 100644
index 0000000..16d0892
Binary files /dev/null and b/src/assets/dark-logo.png differ
diff --git a/src/assets/houston.webp b/src/assets/houston.webp
deleted file mode 100644
index 930c164..0000000
Binary files a/src/assets/houston.webp and /dev/null differ
diff --git a/src/assets/logo.png b/src/assets/logo.png
new file mode 100644
index 0000000..a8f02f0
Binary files /dev/null and b/src/assets/logo.png differ
diff --git a/src/content.config.ts b/src/content.config.ts
index d9ee8c9..1bcecb9 100644
--- a/src/content.config.ts
+++ b/src/content.config.ts
@@ -1,7 +1,15 @@
import { defineCollection } from 'astro:content';
-import { docsLoader } from '@astrojs/starlight/loaders';
-import { docsSchema } from '@astrojs/starlight/schema';
+import {docsLoader, i18nLoader} from '@astrojs/starlight/loaders';
+import {docsSchema, i18nSchema} from '@astrojs/starlight/schema';
export const collections = {
- docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
+ docs: defineCollection({
+ loader: docsLoader(),
+ schema: docsSchema(),
+ }),
+
+ /*i18n: defineCollection({
+ loader: i18nLoader(),
+ schema: i18nSchema(),
+ }),*/
};
diff --git a/src/content/docs/en/dotnet/guides/concept.mdx b/src/content/docs/en/dotnet/guides/concept.mdx
new file mode 100644
index 0000000..ede2b98
--- /dev/null
+++ b/src/content/docs/en/dotnet/guides/concept.mdx
@@ -0,0 +1,74 @@
+---
+title: CQRS Patterns
+description: A beginner-friendly explanation of Command Query Responsibility Segregation (CQRS).
+---
+
+import { Aside } from '@astrojs/starlight/components';
+
+# Understanding CQRS Patterns
+
+Command Query Responsibility Segregation (CQRS) is a software design pattern that separates the concerns of reading and writing data into distinct models. This pattern helps improve scalability, performance, and maintainability, especially in systems with complex business logic.
+
+---
+
+## Why Use CQRS?
+
+In a traditional CRUD (Create, Read, Update, Delete) architecture, the same model is often used for both reading and writing data. While this works for simple applications, it can become a bottleneck as the application grows.
+
+CQRS addresses these challenges by introducing two distinct models:
+- **Command Model**: Handles write operations (e.g., creating, updating, or deleting data).
+- **Query Model**: Handles read operations (e.g., fetching data for display).
+
+By separating these concerns, CQRS allows for better optimization and customization of each model to meet specific requirements.
+
+---
+
+## How Does CQRS Work?
+
+The CQRS pattern divides your application into the following responsibilities:
+
+### Commands
+Commands represent actions or tasks that change the state of your application. Examples include:
+- Creating a new user
+- Updating an order
+- Deleting a record
+
+Commands are processed through a **command handler**, which ensures that business rules and validations are enforced.
+
+### Queries
+Queries are used to retrieve data from your system. They do not modify the application's state and are designed to be fast and efficient. Examples include:
+- Fetching a list of users
+- Getting order details
+
+Queries are often optimized for read performance, using dedicated data models or projections.
+
+---
+
+## Benefits of CQRS
+
+1. **Scalability**: Separating reads and writes allows you to independently scale the read and write sides of your application.
+2. **Performance**: Optimize read operations for speed while maintaining robust write logic.
+3. **Flexibility**: Use different technologies or data models for reads and writes.
+4. **Maintainability**: Clear separation of concerns makes the system easier to understand and maintain.
+
+---
+
+## When to Use CQRS?
+
+CQRS is particularly beneficial in the following scenarios:
+- Applications with complex business rules.
+- Systems that require high read or write throughput.
+- Scenarios where read and write operations have vastly different performance or structure requirements.
+- Event-driven architectures or systems utilizing Event Sourcing.
+
+---
+
+## Conclusion
+
+CQRS is a powerful pattern that enables better scalability, performance, and maintainability by separating the responsibilities of reading and writing data. By leveraging this pattern, developers can design systems that are easier to scale, optimize, and evolve over time.
+
+Ready to dive deeper? Check out our [Getting Started Guide](/en/dotnet/guides/getting-started/) to see how the CQRS pattern can be implemented in practice!
+
+---
+
+
\ No newline at end of file
diff --git a/src/content/docs/en/dotnet/guides/first-command.mdx b/src/content/docs/en/dotnet/guides/first-command.mdx
new file mode 100644
index 0000000..8ca8df9
--- /dev/null
+++ b/src/content/docs/en/dotnet/guides/first-command.mdx
@@ -0,0 +1,4 @@
+---
+title: Adding a command to your project
+description: Adding a command to your project
+---
\ No newline at end of file
diff --git a/src/content/docs/en/dotnet/guides/getting-started.mdx b/src/content/docs/en/dotnet/guides/getting-started.mdx
new file mode 100644
index 0000000..f5718ec
--- /dev/null
+++ b/src/content/docs/en/dotnet/guides/getting-started.mdx
@@ -0,0 +1,50 @@
+---
+title: Getting started with .NET Core
+description: Getting started with .NET Core
+---
+
+import { Code } from '@astrojs/starlight/components';
+import { Aside } from '@astrojs/starlight/components';
+
+import installCode from 'install.sh?raw';
+import healthQueryCode from 'health-query.cs?raw';
+import programCode from 'program.cs?raw';
+
+export const highlights = ['OpenHarbor.CQRS', 'OpenHarbor.CQRS.AspNetCore.Mvc', 'AddDefaultCommandDiscovery', 'AddDefaultQueryDiscovery', 'AddOpenHarborCommands', 'AddOpenHarborQueries', 'AddQuery', 'IQueryHandler'];
+
+In this tutorial, we will create a simple health query within a brand-new .NET 8 Web API project using the Open Harbor CQRS framework.
+
+### Setup
+
+Let's get started by creating a brand-new project!
+
+
+### Install the .NET package
+Run the following commands to install the required packages:
+
+
+### Creating our first query
+We will create a simple health check endpoint to verify that our API is running:
+
+
+
+
+### Preparing our program using MVC to bind our queries and commands
+
+
+
+`AddDefaultCommandDiscovery` and `AddDefaultQueryDiscovery` are the default implementations in the CQRS framework for discovering the commands and queries defined in your application. To learn more about how they work, you can check out their functionality here.
+
+`AddQuery` is used to register your query, allowing the framework to expose it automatically.
+
+`AddOpenHarborCommands` and `AddOpenHarborQueries` dynamically generate controllers for your application, leveraging the MVC features of .NET
+
+
+
+### Reaping the rewards of our work!
+
+Run the project and navigate to `/api/query/health` in your browser to see the result.
+
+### What's next?
+
+🎉 Congratulations! You've successfully created your first CQRS Web API with a simple health check query. In the next guide, we’ll explore adding a command and a query that interact with each other, showcasing the endless possibilities you can unlock with our CQRS framework. Let your imagination run wild!
diff --git a/src/content/docs/en/dotnet/guides/health-query.cs b/src/content/docs/en/dotnet/guides/health-query.cs
new file mode 100644
index 0000000..2f6fb9b
--- /dev/null
+++ b/src/content/docs/en/dotnet/guides/health-query.cs
@@ -0,0 +1,11 @@
+using OpenHarbor.CQRS.Abstractions;
+
+namespace OpenHarbor.Guide.Query;
+
+public class HealthQuery { }
+
+public class HealthQueryHandler : IQueryHandler
+{
+ public Task HandleAsync(HealthQuery query, CancellationToken cancellationToken = new CancellationToken())
+ => Task.FromResult(true);
+}
\ No newline at end of file
diff --git a/src/content/docs/en/dotnet/guides/install.sh b/src/content/docs/en/dotnet/guides/install.sh
new file mode 100644
index 0000000..cd75d1e
--- /dev/null
+++ b/src/content/docs/en/dotnet/guides/install.sh
@@ -0,0 +1,2 @@
+dotnet add package OpenHarbor.CQRS
+dotnet add package OpenHarbor.CQRS.AspNetCore
\ No newline at end of file
diff --git a/src/content/docs/en/dotnet/guides/program.cs b/src/content/docs/en/dotnet/guides/program.cs
new file mode 100644
index 0000000..5fbe46f
--- /dev/null
+++ b/src/content/docs/en/dotnet/guides/program.cs
@@ -0,0 +1,25 @@
+using OpenHarbor.CQRS;
+using OpenHarbor.CQRS.AspNetCore.Mvc;
+using OpenHarbor.Guide.Query;
+
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddDefaultCommandDiscovery();
+builder.Services.AddDefaultQueryDiscovery();
+
+builder.Services.AddQuery();
+
+var mvcBuilder = builder.Services
+ .AddControllers();
+
+mvcBuilder
+ .AddOpenHarborCommands();
+
+mvcBuilder
+ .AddOpenHarborQueries();
+
+var app = builder.Build();
+
+app.MapControllers();
+
+app.Run();
\ No newline at end of file
diff --git a/src/content/docs/reference/example.md b/src/content/docs/en/dotnet/references/example.md
similarity index 85%
rename from src/content/docs/reference/example.md
rename to src/content/docs/en/dotnet/references/example.md
index 0224f09..7d83ffb 100644
--- a/src/content/docs/reference/example.md
+++ b/src/content/docs/en/dotnet/references/example.md
@@ -1,6 +1,6 @@
---
title: Example Reference
-description: A reference page in my new Starlight docs site.
+description: A references page in my new Starlight docs site.
---
Reference pages are ideal for outlining how things work in terse and clear terms.
diff --git a/src/content/docs/en/dotnet/resources/nugets.mdx b/src/content/docs/en/dotnet/resources/nugets.mdx
new file mode 100644
index 0000000..254aa99
--- /dev/null
+++ b/src/content/docs/en/dotnet/resources/nugets.mdx
@@ -0,0 +1,24 @@
+---
+title: Nugets
+description: A references page in my new Starlight docs site.
+---
+
+
+
+## Implementations Packages
+
+| Name | NuGet |
+|-----------------------------------------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| OpenHarbor.CQRS | [![NuGet](https://img.shields.io/nuget/v/OpenHarbor.CQRS.svg?style=flat-square&label=nuget)](https://www.nuget.org/packages/OpenHarbor.CQRS/) |
+| OpenHarbor.CQRS.AspNetCore | [![NuGet](https://img.shields.io/nuget/v/OpenHarbor.CQRS.AspNetCore.svg?style=flat-square&label=nuget)](https://www.nuget.org/packages/OpenHarbor.CQRS.AspNetCore/) |
+| OpenHarbor.CQRS.FluentValidation | [![NuGet](https://img.shields.io/nuget/v/OpenHarbor.CQRS.FluentValidation.svg?style=flat-square&label=nuget)](https://www.nuget.org/packages/OpenHarbor.CQRS.FluentValidation/) |
+| OpenHarbor.CQRS.DynamicQuery | [![NuGet](https://img.shields.io/nuget/v/OpenHarbor.CQRS.DynamicQuery.svg?style=flat-square&label=nuget)](https://www.nuget.org/packages/OpenHarbor.CQRS.DynamicQuery/) |
+| OpenHarbor.CQRS.DynamicQuery.AspNetCore | [![NuGet](https://img.shields.io/nuget/v/OpenHarbor.CQRS.DynamicQuery.AspNetCore.svg?style=flat-square&label=nuget)](https://www.nuget.org/packages/OpenHarbor.CQRS.DynamicQuery.AspNetCore/) |
+
+## Abstractions Packages
+
+| Name | NuGet |
+|-------------------------------------------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| OpenHarbor.CQRS.Abstractions | [![NuGet](https://img.shields.io/nuget/v/OpenHarbor.CQRS.Abstractions.svg?style=flat-square&label=nuget)](https://www.nuget.org/packages/OpenHarbor.CQRS.Abstractions/) |
+| OpenHarbor.CQRS.AspNetCore.Abstractions | [![NuGet](https://img.shields.io/nuget/v/OpenHarbor.CQRS.AspNetCore.Abstractions.svg?style=flat-square&label=nuget)](https://www.nuget.org/packages/OpenHarbor.CQRS.AspNetCore.Abstractions/) |
+| OpenHarbor.CQRS.DynamicQuery.Abstractions | [![NuGet](https://img.shields.io/nuget/v/OpenHarbor.CQRS.DynamicQuery.Abstractions.svg?style=flat-square&label=nuget)](https://www.nuget.org/packages/OpenHarbor.CQRS.DynamicQuery.Abstractions/) |
\ No newline at end of file
diff --git a/src/content/docs/en/index.mdx b/src/content/docs/en/index.mdx
new file mode 100644
index 0000000..74546b1
--- /dev/null
+++ b/src/content/docs/en/index.mdx
@@ -0,0 +1,30 @@
+---
+title: Welcome Open Harbor CQRS Framework Documentation
+description: Open Harbor CQRS Framework
+template: splash
+hero:
+ tagline: Get started building your apis in .net with our CQRS framework
+ image:
+ file: ../../../assets/logo.png
+ actions:
+ - text: Get Started
+ link: dotnet/guides/getting-started
+ icon: right-arrow
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+
+
+ Modular architecture designed for extensibility.
+
+
+ Separate your reads and writes with just a few lines of code.
+
+
+ Let your code do the talking and simplify the complexity.
+
+
+ Learn more from the [documentations](dotnet/guides/getting-started).
+
+
diff --git a/src/content/docs/index.mdx b/src/content/docs/fr/index.mdx
similarity index 65%
rename from src/content/docs/index.mdx
rename to src/content/docs/fr/index.mdx
index 664b681..cf33ddd 100644
--- a/src/content/docs/index.mdx
+++ b/src/content/docs/fr/index.mdx
@@ -1,19 +1,15 @@
---
-title: Welcome to Starlight
-description: Get started building your docs site with Starlight.
+title: Welcome Open Harbor CQRS Framework Documentation
+description: Open Harbor CQRS Framework
template: splash
hero:
- tagline: Congrats on setting up a new Starlight project!
+ tagline: Get started building your apis in .net with our CQRS framework
image:
- file: ../../assets/houston.webp
+ file: ../../../assets/logo.png
actions:
- - text: Example Guide
- link: /guides/example/
+ - text: Get Started
+ link: fr/guides/example/
icon: right-arrow
- - text: Read the Starlight docs
- link: https://starlight.astro.build
- icon: external
- variant: minimal
---
import { Card, CardGrid } from '@astrojs/starlight/components';
diff --git a/src/content/docs/guides/example.md b/src/content/docs/guides/example.md
deleted file mode 100644
index ebd0f3b..0000000
--- a/src/content/docs/guides/example.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-title: Example Guide
-description: A guide in my new Starlight docs site.
----
-
-Guides lead a user through a specific task they want to accomplish, often with a sequence of steps.
-Writing a good guide requires thinking about what your users are trying to do.
-
-## Further reading
-
-- Read [about how-to guides](https://diataxis.fr/how-to-guides/) in the Diátaxis framework
diff --git a/src/styles/global.css b/src/styles/global.css
new file mode 100644
index 0000000..e69de29