Code Monkey home page Code Monkey logo

devtest-refactoring's Introduction

Taxually technical test - Original description

This solution contains an API endpoint to register a company for a VAT number. Different approaches are required based on the country where the company is based:

  • UK companies can register via an API
  • French companies must upload a CSV file
  • German companies must upload an XML document

The implementation uses the strategy pattern. In order to add support for a new country, the following steps must be done:

  1. Create your implementation under Taxually.TechnicalTest.Application\VatRegistration\Strategies\YourCountryRegistrationStrategy.cs, which must implement the interface IVatRegistrationStrategy. Return the supported country by .GetSupportedCountry().
  2. Register the new strategy implementation to the DI container. \Taxually.TechnicalTest.Application\DependencyInjection.cs`
  3. Add tests to the Taxually.TechnicalTest.Application.Tests\VatRegistration folder.

Strategy pattern

Note: The manual DI registration can be circumvented with using reflection.

var strategies = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(assembly => assembly.GetTypes())
                .Where(type => typeof(IVatRegistrationStrategy).IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract);

foreach (var strategy in strategies)
{
    builder.Services.AddTransient(
        typeof(IVatRegistrationStrategy), 
        strategy);
}

Personal notes

Architecture

For my refactoring exercise, I've used the clean architecture approach. Generally speaking, I find this code organization pattern clean, easy to read and easy to test, but I have to admit that for this tiny task this might feel like an overkill.

Conditional code execution based on country

This can be solved in many ways. I've used the strategy pattern, as I believe it works good in this case, but a lot depends on the (unknown) requirements. For example, if it is expected that certain countries will receive a much higher load, the separation can be done on a service level (for example, GermanyRegistration service) which can independently scale. In this way a gateway can route the requests to the corresponding endpoints. This is also a useful approach if there are some strict regulations which strictly define that the API/Data should be hosted within the borders of the company. It is also worth discussing whether a flow (e.g. filling a form by the customer) should or should not fail in case there is a downtime of the dependant API and whether eventual consistency can be part of the design. (It can also be part of a regulation) If so, an outbox pattern can also be used for messages sent to an internal queue, which then are handled by the corresponding event handlers (invoking a 3rd party web api, putting a message on the queue, etc.)

Use of async-await

The use of async-await was suboptimal and error-prone throughout the code base, so I've fixed them.

Configuration

The configuration values were added to the appsettings.json which can have separate values per environments.

Development ideas

  • Add proper validation and detach it from the VatRegistration logic (Wrote a TODO to the corresponding code part)
  • Error handling
  • Structured logging
  • Metrics
  • Tracing
  • Resiliency (retries, outbox pattern)
  • Refactor so that API request is independent from the 3rd party UK request (Wrote a TODO to the corresponding code part)
  • ...

devtest-refactoring's People

Contributors

jozsefhalmi avatar

Watchers

József Halmi avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.