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
13 changes: 13 additions & 0 deletions back-end/softcom-challenge/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# editorconfig.org
root = true

[*]
indent_size = 2
indent_style = space
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
19 changes: 19 additions & 0 deletions back-end/softcom-challenge/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
HOST=127.0.0.1
PORT=3333
NODE_ENV=development

APP_NAME=AdonisJs
APP_URL=http://${HOST}:${PORT}

CACHE_VIEWS=false

APP_KEY=

DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=root
DB_PASSWORD=
DB_DATABASE=adonis

HASH_DRIVER=bcrypt
11 changes: 11 additions & 0 deletions back-end/softcom-challenge/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Node modules
node_modules

# Adonis directory for storing tmp files
tmp

# Environment variables, never commit this file
.env

# The development sqlite file
database/*.sqlite
2 changes: 2 additions & 0 deletions back-end/softcom-challenge/Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
release: ENV_SILENT=true node ace migration:run — force
web: ENV_SILENT=true npm start
28 changes: 28 additions & 0 deletions back-end/softcom-challenge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Adonis API application

This is the boilerplate for creating an API server in AdonisJs, it comes pre-configured with.

1. Bodyparser
2. Authentication
3. CORS
4. Lucid ORM
5. Migrations and seeds

## Setup

Use the adonis command to install the blueprint

```bash
adonis new yardstick --api-only
```

or manually clone the repo and then run `npm install`.


### Migrations

Run the following command to run startup migrations.

```js
adonis migration:run
```
21 changes: 21 additions & 0 deletions back-end/softcom-challenge/ace
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict'

/*
|--------------------------------------------------------------------------
| Ace Commands
|--------------------------------------------------------------------------
|
| The ace file is just a regular Javascript file but with no extension. You
| can call `node ace` followed by the command name and it just works.
|
| Also you can use `adonis` followed by the command name, since the adonis
| global proxies all the ace commands.
|
*/

const { Ignitor } = require('@adonisjs/ignitor')

new Ignitor(require('@adonisjs/fold'))
.appRoot(__dirname)
.fireAce()
.catch(console.error)
65 changes: 65 additions & 0 deletions back-end/softcom-challenge/app/Controllers/Http/ItemController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use strict'

const Item = use("App/Models/Item");

const User = use("App/Models/User")

class ItemController {

async index ({ auth, request, response }) {
let items = await auth.user.items().fetch()
const user = await User.find(auth.user.id)

const res = {
items: items,
user: user
}
return response.json(res)
}

async store ({ request, auth, response }) {
try{
let item = await auth.user.items().create(request.all())
await item.load('user');
return response.json(item)
} catch (e) {
return response.json({
message: 'You are not authorized to perform this action'
})
}
}

async show ({ params, request, response, view }) {
let item = await Item.find(params.itemId)
return response.json(item)

}

async update ({ auth, params, request, response }) {
let item = await Item.find(params.itemId)
if (item.user_id !== auth.user.id) {
return response.status(401).send({ error: 'Not authorized' })
}

item.name = request.input('name')
item.description = request.input('description')
item.price = request.input('price')

await item.save()
await item.load('user');
return response.json(item)

}

async destroy ({ params, auth, response }) {
const item = await Item.findOrFail(params.itemId)

if (item.user_id !== auth.user.id) {
return response.status(401).send({ error: 'Not authorized' })
}

await item.delete()
}
}

module.exports = ItemController
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use strict'

class SessionController {
async create ({ request, auth }) {
const { email, password } = request.all()

const token = await auth.attempt(email, password)

return token
}
}

module.exports = SessionController
23 changes: 23 additions & 0 deletions back-end/softcom-challenge/app/Controllers/Http/UserController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"use strict"

const User = use("App/Models/User")

class UserController {

async show ({ params, request, response, view }) {
let user = await User.find(params.id)
return response.json(user)

}

async create ({ request }) {
const data = request.only(["username", "email", "cnpj", "password"])

const user = await User.create(data)

return user
}

}

module.exports = UserController
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict'

class ConvertEmptyStringsToNull {
async handle ({ request }, next) {
if (Object.keys(request.body).length) {
request.body = Object.assign(
...Object.keys(request.body).map(key => ({
[key]: request.body[key] !== '' ? request.body[key] : null
}))
)
}

await next()
}
}

module.exports = ConvertEmptyStringsToNull
12 changes: 12 additions & 0 deletions back-end/softcom-challenge/app/Models/Item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict'

/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
const Model = use('Model')

class Item extends Model {
user() {
return this.belongsTo('App/Models/User');
}
}

module.exports = Item
9 changes: 9 additions & 0 deletions back-end/softcom-challenge/app/Models/Token.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict'

/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
const Model = use('Model')

class Token extends Model {
}

module.exports = Token
16 changes: 16 additions & 0 deletions back-end/softcom-challenge/app/Models/Traits/NoTimestamp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict'

class NoTimestamp {
register (Model) {
Object.defineProperties(Model, {
createdAtColumn: {
get: () => null,
},
updatedAtColumn: {
get: () => null,
}
})
}
}

module.exports = NoTimestamp
44 changes: 44 additions & 0 deletions back-end/softcom-challenge/app/Models/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict'

/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
const Model = use('Model')

/** @type {import('@adonisjs/framework/src/Hash')} */
const Hash = use('Hash')

class User extends Model {

items () {
return this.hasMany('App/Models/Item')
}

static boot () {
super.boot()

/**
* A hook to hash the user password before saving
* it to the database.
*/
this.addHook('beforeSave', async (userInstance) => {
if (userInstance.dirty.password) {
userInstance.password = await Hash.make(userInstance.password)
}
})
}

/**
* A relationship on tokens is required for auth to
* work. Since features like `refreshTokens` or
* `rememberToken` will be saved inside the
* tokens table.
*
* @method tokens
*
* @return {Object}
*/
tokens () {
return this.hasMany('App/Models/Token')
}
}

module.exports = User
Loading