diff --git a/Configuration/.gitkeep b/Configuration/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/Constants/.gitkeep b/Constants/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/Controllers/.gitkeep b/Controllers/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/Controllers/XTermsAndComditionsControllerBase.cs b/Controllers/XTermsAndComditionsControllerBase.cs
new file mode 100644
index 0000000..15141c0
--- /dev/null
+++ b/Controllers/XTermsAndComditionsControllerBase.cs
@@ -0,0 +1,313 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using xCommons.Configurations;
+using xCommons.Extensions;
+using xCommons.Providers;
+using xExceptions.Constants;
+using xIdentityService.Controllers;
+using xIdentityService.Interfaces;
+using xModels.Base;
+using xTermsAndConditionsService.Interfaces;
+
+namespace xTermsAndConditionsService.Controllers
+{
+ ///
+ /// a Base Controller Implementation for Providing Base Actions of
+ /// Terms and Conditions Provided Actions ...
+ ///
+ [AllowAnonymous]
+ public abstract class XTermsAndComditionsControllerBase : XBaseIdentityApiV1Controller, IXTermsAndComditionsController
+ {
+ private readonly IXTermsAndComditionsProvider provider;
+
+ protected XTermsAndComditionsControllerBase(
+ ILogger logger,
+ XAppConfiguration appConfiguration,
+ IXIdentityProvider identityProvider,
+ IXTermsAndComditionsProvider provider,
+ XValidationProvider validationProvider
+ ) : base(
+ logger,
+ appConfiguration,
+ identityProvider,
+ validationProvider
+ )
+ {
+ this.provider = provider;
+ }
+
+ //
+ #region Actions ...
+ ///
+ /// Retrieved all Exists Languages Terms and Conditions ...
+ ///
+ ///
+ [HttpGet("Terms/Languages")]
+ public virtual async Task>> TermsLanguages(
+ CancellationToken cancellationToken = default
+ )
+ {
+ //
+ try
+ {
+ //
+ var result = await provider.TermsLanguages(
+ cancellationToken: cancellationToken
+ );
+
+ //
+ return Ok(result.ToDynamicObject());
+ }
+ catch (Exception ex)
+ {
+ //
+ var result = GetExceptionActionResult(ex);
+ return result;
+ }
+ }
+
+ ///
+ /// Check Has Terms and Conditions based on Specified Language ...
+ ///
+ /// if null, used Default Language ...
+ ///
+ [HttpGet("Terms/{language}/Has")]
+ public virtual async Task> HasTerms(
+ [FromRoute] string language = null,
+ CancellationToken cancellationToken = default
+ )
+ {
+ //
+ try
+ {
+ //
+ // Validate ...
+ if (!ModelState.IsValid)
+ {
+ XException.InvalidArgs.Throw();
+ }
+ await ValidationProvider
+ .GroupValidationBuilder()
+ .AddNotEmpty(language)
+ .ValidateGroupAsync();
+
+ //
+ var result = await provider.HasTerms(
+ language: language,
+ cancellationToken: cancellationToken
+ );
+
+ //
+ return Ok(result);
+ }
+ catch (Exception ex)
+ {
+ //
+ var result = GetExceptionActionResult(ex);
+ return result;
+ }
+ }
+
+ ///
+ /// Retrieve Terms and Conditions for Specified Language ...
+ ///
+ /// if null, used Default Language ...
+ ///
+ [HttpGet("Terms/{language}")]
+ public virtual async Task> GetTerms(
+ [FromRoute] string language = null,
+ CancellationToken cancellationToken = default
+ )
+ {
+ //
+ try
+ {
+ //
+ // Validate ...
+ if (!ModelState.IsValid)
+ {
+ XException.InvalidArgs.Throw();
+ }
+ await ValidationProvider
+ .GroupValidationBuilder()
+ .AddNotEmpty(language)
+ .ValidateGroupAsync();
+
+ //
+ var result = await provider.GetTerms(
+ language: language,
+ cancellationToken: cancellationToken
+ );
+
+ //
+ return Ok(result);
+ }
+ catch (Exception ex)
+ {
+ //
+ var result = GetExceptionActionResult(ex);
+ return result;
+ }
+ }
+
+ ///
+ /// Add Terms and Conditions for Specified Language ...
+ ///
+ ///
+ ///
+ ///
+ [HttpPost("Terms/{language}")]
+ public virtual async Task> AddTerms(
+ [FromRoute] string language,
+ [FromBody] XBaseValueContainer terms,
+ CancellationToken cancellationToken = default
+ )
+ {
+ //
+ try
+ {
+ //
+ // Validate ...
+ if (!ModelState.IsValid)
+ {
+ XException.InvalidArgs.Throw();
+ }
+ await ValidationProvider
+ .GroupValidationBuilder()
+ .AddNotEmpty(language)
+ .AddNotNull(terms)
+ .AddNotEmpty(terms.Value)
+ .ValidateGroupAsync();
+
+ //
+ var userInfo = await GetUserInfo();
+ var connectionId = GetConnectionId();
+
+ //
+ var result = await provider.AddTerms(
+ language: language,
+ terms: terms.Value,
+ userInfo: userInfo,
+ connectionId: connectionId,
+ cancellationToken: cancellationToken
+ );
+
+ //
+ return Ok(result);
+ }
+ catch (Exception ex)
+ {
+ //
+ var result = GetExceptionActionResult(ex);
+ return result;
+ }
+ }
+
+ ///
+ /// Remove Terms and Conditions of Specified Language ...
+ ///
+ ///
+ ///
+ [HttpDelete("Terms/{language}")]
+ public virtual async Task> RemoveTerms(
+ [FromRoute] string language,
+ CancellationToken cancellationToken = default
+ )
+ {
+ //
+ try
+ {
+ //
+ // Validate ...
+ if (!ModelState.IsValid)
+ {
+ XException.InvalidArgs.Throw();
+ }
+ await ValidationProvider
+ .GroupValidationBuilder()
+ .AddNotEmpty(language)
+ .ValidateGroupAsync();
+
+ //
+ var userInfo = await GetUserInfo();
+ var connectionId = GetConnectionId();
+
+ //
+ var result = await provider.RemoveTerms(
+ language: language,
+ userInfo: userInfo,
+ connectionId: connectionId,
+ cancellationToken: cancellationToken
+ );
+
+ //
+ return Ok(result);
+ }
+ catch (Exception ex)
+ {
+ //
+ var result = GetExceptionActionResult(ex);
+ return result;
+ }
+ }
+
+ ///
+ /// Update Terms and Conditions of Specified Language ...
+ ///
+ ///
+ ///
+ ///
+ [HttpPut("Terms/{language}")]
+ public virtual async Task> UpdateTerms(
+ [FromRoute] string language,
+ [FromBody] XBaseValueContainer terms,
+ CancellationToken cancellationToken = default
+ )
+ {
+ //
+ try
+ {
+ //
+ // Validate ...
+ if (!ModelState.IsValid)
+ {
+ XException.InvalidArgs.Throw();
+ }
+ await ValidationProvider
+ .GroupValidationBuilder()
+ .AddNotEmpty(language)
+ .AddNotNull(terms)
+ .AddNotEmpty(terms.Value)
+ .ValidateGroupAsync();
+
+ //
+ var userInfo = await GetUserInfo();
+ var connectionId = GetConnectionId();
+
+ //
+ var result = await provider.UpdateTerms(
+ language: language,
+ terms: terms.Value,
+ userInfo: userInfo,
+ connectionId: connectionId,
+ cancellationToken: cancellationToken
+ );
+
+ //
+ return Ok(result);
+ }
+ catch (Exception ex)
+ {
+ //
+ var result = GetExceptionActionResult(ex);
+ return result;
+ }
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DI/.gitkeep b/DI/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/DI/XDIHelperExtension.cs b/DI/XDIHelperExtension.cs
index 4790954..157cd73 100644
--- a/DI/XDIHelperExtension.cs
+++ b/DI/XDIHelperExtension.cs
@@ -6,9 +6,12 @@ using Microsoft.Extensions.DependencyInjection;
using xCommons.Configurations;
using xCommons.Extensions;
using xExceptions.Constants;
+using xPushService.DI;
+using xPushService.Helpers;
using xStringService.Interfaces.Dtos;
using xTermsAndConditionsService.Configuration;
using xTermsAndConditionsService.Constants;
+using xTermsAndConditionsService.Hubs;
using xTermsAndConditionsService.Interfaces;
using xTermsAndConditionsService.Providers;
@@ -123,6 +126,12 @@ namespace xTermsAndConditionsService.DI
var stringProvider = scope.ServiceProvider.GetService();
var serviceConfiguration = scope.ServiceProvider.GetService();
+ //
+ // Using XTerms Hub ...
+ var pushHelper = new XPushServiceHelper();
+ pushHelper.AddHub("termsHub");
+ app.UseXPushService(pushHelper);
+
//
// Validate Requirements Exists ...
var isValid =
diff --git a/Hubs/.gitkeep b/Hubs/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/Interfaces/.gitkeep b/Interfaces/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/Providers/.gitkeep b/Providers/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/README.md b/README.md
index 59ea654..13eab4d 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,107 @@ its depends on:
- **xStringService**
+## Providers
+
+in this module all requirements tools for manage Terms and Conditions Integrated and Provided.
+
+- **IXTermsAndComditionsProvider**: an Interface for Describe Provided Actions for Terms and Conditions Management.
+- **XTermsAndComditionsProvider**: an Implementation of Provided Actions for Terms and Conditions Management.
+- **XTermsHub**: a Hub Implementation for Notifing Terms Changes to Connected Clients.
+- **IXTermsAndComditionsController**: an Interface for Describe base Terms and Conditions Management Controller Actions.
+- **XTermsAndComditionsControllerBase**: an Abstract Base Implementation of base Terms and Conditions Management Controller Actions.
+
+## Implementation
+
+you have to follow these steps for using this Module.
+
+### Configure Service
+
+all of Requirements for Terms and Conditions must be Configured using appSettings and provided by IConfiguration to Modules.
+
+fo using Service you Have to Configure the Service in you appSettings.json file.
+
+this configurations mapped to **XTermsAndConditionsServiceConfiguration** class.
+
+```C#
+///
+/// Terms and Conditions Configuration ...
+///
+public class XTermsAndConditionsServiceConfiguration
+{
+ ///
+ /// Terms And Conditions Resource Title in XString Table ...
+ ///
+ public string ResourceTitle { get; set; } = "terms_and_conditions";
+
+ ///
+ /// Seeding Mode for Terms and Conditions ...
+ ///
+ public XDbSeedingMode SeedingMode { get; set; } = XDbSeedingMode.AddIfNotExists;
+
+ ///
+ /// Default Terms and Conditions for Add to Databse on App Startup ...
+ ///
+ public List TermsAndConditions { get; set; } = null;
+}
+```
+
+a sample Configuration must like this:
+
+```json
+{
+ ...
+ "TermsAndConditionsService": {
+ "ResourceTitle": "terms_and_conditions",
+ "SeedingMode": "AddIfNotExists",
+ "TermsAndConditions": [
+ {
+ "Language": "fa-IR",
+ "TranslatedValue": "شرایط و ضوابط ثبت نام در سامانه"
+ }
+ ]
+ },
+ ...
+}
+```
+
+### Register Service
+
+after preparation of all requirements, final steps is Register Service.
+
+there are two main step:
+
+- **DI Registration**: in this phase, all Provided Services Registered in DI.
+- **Middleware Usage**: in this phase, if any Terms and Conditions Provided in Configuration, Seeded in Data Persist System using Provided Services.
+
+```C#
+public class Startup
+{
+ //
+ public void ConfigureServices(IServiceCollection services)
+ {
+ ...
+ //
+ // Register Terms and Conditions Service ...
+ services.AddXTermsConditionsService(
+ lifeTime: lifeTime,
+ configuration: configuration
+ );
+ ...
+ }
+
+ //
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+ {
+ ...
+ //
+ // Using Terms and Conditions Service ...
+ app.UseXTermsAndConditionsService();
+ ...
+ }
+}
+```
+
## Maintainer
Hadi Khazaee asl