The sudden soft-launch of Belgian Brewed has been successfull and currently the errors have been reduced to 0, which i'm quite proud of since the shop had been launched early :).
We already received orders across Europe ( Denmark, Germany, UK, Spain, Italy, Netherlands and Belgium). Even someone from Malta who had to use a proxy delivery service, since our package provider does not deliver there.
I'm using Elmah for error logging, it's been very easy to use and implement.
I saw that i could see a users password when a error occured during the login process.
And since the elmah portal was publicly available ( by default) on the /Elmah endpoint. I immediately made it available for Admins only.
Then I noted all the errors that were happening, removed all the logs and then fixed them.
I also replace every form field that contains "password" and replace it with the value "HIDDEN" when a error occurs now. So it wouldn't be possible to log a password anymore.
An unlucky visitor that started ordering in the beta phase, had an edge case when trying it again in the production site. It is fixed now.
No logs are logged when a useragent contains the word BOT or DAUM, since they seem to have incorrect behaviour.
No log errors are logged when the path contains "wp-includes, .php, .js.map, .css.map". Which seem to be mostly crawlers that try to exploit 0-day vulnerabilities.
These 2 actions greatly reduced the amount of daily errors ( from > 50 daily errors, to 1 error logged yesterday)
So in general, i'm still monitoring if errors are occuring. But currently, everything looks ok (y)
I'm currently working on the customer zone functionality. Which will contain the following functionality:
Since i'm currently transitioning to DDD, this caused 2 more modules to be developped in the application:
Also, i've implemented the Specification Pattern which i'm quite proud of. It's the foundation of implementing filters on the shop so customer can filter for price and alcohol %.
The repository for orders currently looks like this:
public interface IOrderRepository
{
Task<IReadOnlyCollection<OrderAggregate>> GetOrders(ISpecification<OrderAggregate, IOrderSpecificationVisitor> spec);
Task<OrderAggregate> GetById(Guid Id);
}
A specification is anything that should be filtered ( eg. The specification to filter by a customer is the "OrderOfCustomer" Specification and it contains a Guid CustomerId)
In the infrastructure layer, i translate the specification to Expression Trees and can do additional logic on everything that is required. ( = Visitor Pattern )
Eg. While the Specificiation filters by the customer. I do not want to show the orders that are still in progress ( since i'm transitioning to DDD, the data is still in one SQL database ).
So in my infrastructure layer, i have to include the additional complexity for filtering orders and i have to exlude some OrderStates, namely:
In practise. This means that in my core layer. The specification only contains a CustomerId to filter on .
And my infrastructure layer contains the additional filtering logic:
public void Visit(OrderOfCustomer spec)
=> Expr = expr => expr.CustomerId == spec.CustomerId && expr.Status != Enums.OrderStatus.Init && expr.Status != Enums.OrderStatus.OnHold;
Since i'm using expression trees and Entity Framework in my Infrastructure. These Expression trees are converted to SQL by the ORM.
:)