Skip to content
This repository was archived by the owner on Mar 8, 2025. It is now read-only.

Lokilife/support-server-test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

What is this

This is my solution to test task which I should do before I will be hired. This readme isn't complete 'cuz I found meaningless to finish it.

Long story short

What I told to make

My main task is to make a simple web-server for ticket support system. What endpoints I told to implement:

  1. Create ticket
  2. Take ticket
  3. Close ticket
  4. Reject ticket
  5. Get tickets with date filter
  6. Endpoint to reject all tickets with status "In work"

When ticket is created there should be ability to send message and subject. When ticket is closed there should be ability to send message containing solution of the problem. When ticket is rejected there should be ability to send message containing reason of rejection. All tickets is anonymous, no work with users.

Well, I still decided to add users logic to make the task harder.

UPD. Well I got way deeper in learning of new complicated things that I barely implemented users logic on time so there is no hardness but still initial task have been done.

My decisions

I don't really like Express, I hate default MVC projects made using Express, they're hell for supporting and have the ugliest code. So I have decided to make experiment, cuz Express is flexible framework and doesn't forces us to specific archicture, giving to us freedom how to make it, I decided to implement Clean Archicture (that one which is described by Robert Martin, yeah) which is really popular in ASP.NET. C# is my secondary language, through I really don't like JavaScript itself, I know ASP.NET much worse, so I don't have enough experience with it to make some really valuable project.

For database I'm gonna use PostgreSQL. PostgreSQL for storing user data and basic tickets information. Why? I just love this database for all usual cases.

Clean Architecture

Quick description of Domain Driven Design: All project is devided into layers like onion. DDD do have the following layers: API -> Application -> Domain -> Infrastucture. API contains Express-specific logic. Application is... Let's just say it's a wrapper of domain layer, which structures all possible interactions in our application (which is implemented by domain layer) into specific use cases needed. Domain layer do contain primary bussiness logic. And infrastructure layer provides access to external dependencies like database, other services and etc. In this project domain layer and infrastucture layer bound through Dependency Injection, domain layer describes interface, infrastucture layer implements it and DI passes specific needed implementation to domain layer.

It's will be easier to understand with the following scheme. img

Project design

File structure

Here is folder structure which quick description so you can easier understand what the hell I did

Folder Description
src/ ikr
src/entry.ts Project entry point
src/api/ API layer, client interactions handling
src/api/controllers/ API Controllers
src/api/middlewares/ API Middlewares
src/app/ Application layer
src/app/use-cases/ Bussiness logic
src/app/services/ Data-handling helping services
src/domain/ Domain application layer
src/domain/entities/ Entities models
src/domain/repositories/ Contains interfaces for working with data which should be implemented by infrastructure layer
src/infrastructure/ Infrastructure layer, all external dependencies
src/infrastructure/db/ All direct work with databases goes here, implements all abstract layers
src/infrastructure/db/repositores/ Repositories implementation
src/infrastructure/db/migrations/ Database migrations
src/shared/ Modules, constants, utils and etc which is shared for all layers
src/shared/errors/ Errors handling
src/shared/utils/ Some utils and helper functions
src/shared/config/ Configuration

Entities and Factories

All entities in domain layer should be abstract, as they're abstract we'll need abstract factory for each entity which should be implemented in infrastructure layer.

Here is why. By Clean Architecture principes domain layer shouldn't access TypeORM directly, only through it's abstractions implemented in infrastructure layer and managed by TypeDI. If I would wanna keep concrete implementations in domain layer then I will be forced to implement wrapper for each entity in infrastructure layer and have a lot of a headache with type-safety of each of them. Having an factory without additional logic for each entity can sound like overengeneering but it's better than having headache with wrappers in infrastructure layer as entity creation mostly performed once in the project unlike any other entities operations.

Managers

It's more about infrastructure or, rather, about project core. For example, we have database manager which should be initialized at project startup. It should set up DI for entities and repositories, initialize database connection, manage transactions and etc. And it cannot be just a service - they're more about helpers upon entities, as database manager is separate structure. It also can become abstract and have different implementations if, for example, we decided to switch up to different database which our ORM doesn't support (not such a good example as we can just implement adapter for TypeORM but I tried to make you understand)

LICENSE

This project is under CC0 1.0, do with it whatever you want

About

Another test task made for work search

Resources

License

Stars

Watchers

Forks