Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
APP_NAME="Ai Solutions"
APP_ENV=local
APP_KEY=base64:OQqxXY8BLTx6HpYlFI4KprLwgkBjINQeU7HtBjy2BOc=
APP_DEBUG=true
APP_URL=http://app.local.com.br

LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=app
DB_USERNAME=app
DB_PASSWORD=app

BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=redis
SESSION_DRIVER=file
SESSION_LIFETIME=120

MEMCACHED_HOST=127.0.0.1

REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_HOST=
PUSHER_PORT=443
PUSHER_SCHEME=https
PUSHER_APP_CLUSTER=mt1

VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.env.production
.phpunit.result.cache
Expand Down
75 changes: 66 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,79 @@
![Logo AI Solutions](http://aisolutions.tec.br/wp-content/uploads/sites/2/2019/04/logo.png)

# AI Solutions

## Teste para novos candidatos (PHP/Laravel)
## Ambiente Docker

Foi utlizado a arquitetura abaixo para concepção do projeto.


Estilo arquitetural: Hexagonal

Conceitos utilizados: Services, Repository, DI, IoC, Acl, Docker e outros padrões.

OBS: Portas 80, 8081, 3306 e 6379 precisam estar liberadas.

1. Clonar o repositório:
```
git clone https://github.com/nilbertooliveira/teste-php-laravel-ai-solutions.git
```

### Introdução
2. Rodar o comando abaixo para fazer o build do projeto, pulling das images, criar rede externa e hosts:
```
./entrypoint.sh
docker-compose up -d
```
3. Instalar as dependências e permissões:
```
docker exec app composer install
docker exec app npm install
docker exec app npm run build
sudo chmod -R 777 storage/
```

Este teste utiliza PHP 8.1, Laravel 10 e um banco de dados SQLite simples.
4. Configurar a base de dados
```
docker exec app php artisan migrate
docker exec app php artisan db:seed
```
5. Executar testes (Arquivo: data/test.json)
```
docker exec app php artisan test
```
6. Executar jobs
```
docker exec app php artisan horizon
```
O titulo do documento está como único e importando a segunda vez os erros vão para failed_jobs intencionalmente


7. Dados para teste:
```
Host: 54.198.116.11
Email: administrator@test.com.br
Password: 123456
```

1. Faça o clone desse repositório;
1. Execute o `composer install`;
1. Crie e ajuste o `.env` conforme necessário
1. Execute as migrations e os seeders;

### Primeira Tarefa:

Crítica das Migrations e Seeders: Aponte problemas, se houver, e solucione; Implemente melhorias;

categories
1) Incluir índice único em name e um index do tipo HASH para acelerar a consulta de dados exatos(Manual statement)
2) Ordenar os tipos de colunas para melhor leitura e identificação dos campos e manutenção EX(Id, campos obrigatórios, campos opcionais, FKs)
3) O tamanho da coluna name com apenas 20 caracteres pode impedir a evolução da aplicação e exigir mudança depois em um grande volume de dados.

documents

1) O campo bigInteger possui menos performance, pois armazena o sinal do dígito ( - ou +)
Como estamos falando de volumes importados, isto trará impactos.
2) Podemos incluir um índice para as FKs para aumentar o desempenho em leitura, porem na escrita fica mais lento e ocupa mais espaço(Avaliar as regras do processo)
3) O tamanho da coluna name com title 60 caracteres pode impedir a evolução da aplicação e exigir mudança depois em um grande volume de dados.
4) Title caso seja único, deve ser criado o index unique e index de desepenh
5) Utilização de cascade pode ser um problema ao deletar uma categoria, apagando toda a árvore
6) Poderia ser usado um index do tipo FULLTEXT para content para agilizar a leitura, porem gravação perde desempenho.

Recomendado criar indexes separado para separação de responsabilidades e manutenção.

### Segunda Tarefa:

Crie a estrutura completa de uma tela que permita adicionar a importação do arquivo `storage/data/2023-03-28.json`, para a tabela `documents`. onde cada registro representado neste arquivo seja adicionado a uma fila para importação.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Console;
namespace App\Application\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
Expand Down
28 changes: 28 additions & 0 deletions app/Application/Controllers/HomeController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Application\Controllers;

use App\Http\Controllers\Controller;

class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}

/**
* Show the application dashboard.
*
* @return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
return view('home');
}
}
45 changes: 45 additions & 0 deletions app/Application/Controllers/ImportFileController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace App\Application\Controllers;

use App\Domain\Interfaces\Services\IImportFileService;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class ImportFileController extends Controller
{
private IImportFileService $fileImportService;

/**
* @param IImportFileService $fileImportService
*/
public function __construct(IImportFileService $fileImportService)
{
$this->fileImportService = $fileImportService;
}

/**
* @return View
*/
public function uploadView(): View
{
$errors = $this->fileImportService->listErrors();

$response = $this->fileImportService->list();

return view('import-file.upload', ['data' => $response->getData(), 'errors' => $errors->getData()]);
}

/**
* @param Request $request
* @return RedirectResponse
*/
public function upload(Request $request): RedirectResponse
{
$this->fileImportService->uploadFile($request);

return redirect()->back();
}
}
10 changes: 10 additions & 0 deletions app/Application/Enums/Status.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace App\Application\Enums;

enum Status: string {
case PENDING = 'pending';
case PROCESSING = 'processing';
case SUCCESS = 'success';
case ERROR = 'error';
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Exceptions;
namespace App\Application\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
Expand Down
18 changes: 9 additions & 9 deletions app/Http/Kernel.php → app/Application/Kernel.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Http;
namespace App\Application;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

Expand All @@ -15,11 +15,11 @@ class Kernel extends HttpKernel
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\App\Application\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\App\Application\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\App\Application\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];

Expand All @@ -30,11 +30,11 @@ class Kernel extends HttpKernel
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\App\Application\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\App\Application\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],

Expand All @@ -53,14 +53,14 @@ class Kernel extends HttpKernel
* @var array<string, class-string|string>
*/
protected $middlewareAliases = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth' => \App\Application\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'guest' => \App\Application\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \App\Http\Middleware\ValidateSignature::class,
'signed' => \App\Application\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Http\Middleware;
namespace App\Application\Middleware;

use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Http\Request;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Http\Middleware;
namespace App\Application\Middleware;

use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Http\Middleware;
namespace App\Application\Middleware;

use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php

namespace App\Http\Middleware;
namespace App\Application\Middleware;

use App\Providers\RouteServiceProvider;
use App\Infrastructure\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Http\Middleware;
namespace App\Application\Middleware;

use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Http\Middleware;
namespace App\Application\Middleware;

use Illuminate\Http\Middleware\TrustHosts as Middleware;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Http\Middleware;
namespace App\Application\Middleware;

use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Http\Middleware;
namespace App\Application\Middleware;

use Illuminate\Routing\Middleware\ValidateSignature as Middleware;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Http\Middleware;
namespace App\Application\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

Expand Down
Loading