Estruturação do Projeto

Open in GitHub Open in Codespaces

Arquivos
invest-app-mvc
├── package-lock.json
├── package.json
├── public
│   ├── css
│   │   └── style.css
│   ├── index.html
│   └── js
│       ├── index.js
│       ├── lib
│       │   └── format.js
│       └── services
│           └── api.js
├── requests.http
└── src
    ├── database
    │   ├── data.js
    │   ├── seeders.js
    │   └── seeders.json
    ├── index.js
    ├── models
    │   └── Investment.js
    └── routes.js
Arquivos
invest-app-mvc
├── package-lock.json
├── package.json
├── public
│   ├── css
│   │   └── style.css
│   ├── index.html
│   └── js
│       ├── index.js
│       ├── lib
│       │   └── format.js
│       └── services
│           └── api.js
├── requests.http
└── src
    ├── database
    │   ├── data.js
    │   ├── seeders.js
    │   └── seeders.json
    ├── index.js
    ├── models
    │   └── Investment.js
    └── routes.js

Database

/codes/expressjs/invest-app-mvc/src/database/data.js
export const investments = [];
 
/codes/expressjs/invest-app-mvc/src/database/data.js
export const investments = [];
 

Model

/codes/expressjs/invest-app-mvc/src/models/Investment.js
import { v4 as uuidv4 } from 'uuid';
import { investments } from '../database/data.js';
 
function create({ name, value }) {
  const id = uuidv4();
 
  const investment = { name, value, id };
 
  if (name && value) {
    investments.push(investment);
 
    return investment;
  } else {
    throw new Error('Unable to create investment');
  }
}
 
function read(field, value) {
  if (field && value) {
    const filteredInvestments = investments.filter((investment) =>
      investment[field].includes(value)
    );
 
    return filteredInvestments;
  }
 
  return investments;
}
 
function readById(id) {
  if (id) {
    const index = investments.findIndex((investment) => investment.id === id);
 
    if (!investments[index]) {
      throw new Error('Investment not found');
    }
 
    return investments[index];
  } else {
    throw new Error('Unable to find investment');
  }
}
 
function update({ id, name, value }) {
  if (name && value && id) {
    const newInvestment = { name, value, id };
 
    const index = investments.findIndex((investment) => investment.id === id);
 
    if (!investments[index]) {
      throw new Error('Investment not found');
    }
 
    investments[index] = newInvestment;
 
    return newInvestment;
  } else {
    throw new Error('Unable to update investment');
  }
}
 
function remove(id) {
  if (id) {
    const index = investments.findIndex((investment) => investment.id === id);
 
    investments.splice(index, 1);
 
    return true;
  } else {
    throw new Error('Investment not found');
  }
}
 
export default { create, read, readById, update, remove };
 
/codes/expressjs/invest-app-mvc/src/models/Investment.js
import { v4 as uuidv4 } from 'uuid';
import { investments } from '../database/data.js';
 
function create({ name, value }) {
  const id = uuidv4();
 
  const investment = { name, value, id };
 
  if (name && value) {
    investments.push(investment);
 
    return investment;
  } else {
    throw new Error('Unable to create investment');
  }
}
 
function read(field, value) {
  if (field && value) {
    const filteredInvestments = investments.filter((investment) =>
      investment[field].includes(value)
    );
 
    return filteredInvestments;
  }
 
  return investments;
}
 
function readById(id) {
  if (id) {
    const index = investments.findIndex((investment) => investment.id === id);
 
    if (!investments[index]) {
      throw new Error('Investment not found');
    }
 
    return investments[index];
  } else {
    throw new Error('Unable to find investment');
  }
}
 
function update({ id, name, value }) {
  if (name && value && id) {
    const newInvestment = { name, value, id };
 
    const index = investments.findIndex((investment) => investment.id === id);
 
    if (!investments[index]) {
      throw new Error('Investment not found');
    }
 
    investments[index] = newInvestment;
 
    return newInvestment;
  } else {
    throw new Error('Unable to update investment');
  }
}
 
function remove(id) {
  if (id) {
    const index = investments.findIndex((investment) => investment.id === id);
 
    investments.splice(index, 1);
 
    return true;
  } else {
    throw new Error('Investment not found');
  }
}
 
export default { create, read, readById, update, remove };
 

Seed

/codes/expressjs/invest-app-mvc/src/database/seeders.json
{
  "investments": [
    {
      "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
      "name": "Tesouro Selic 2029",
      "value": 1000
    },
    {
      "id": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed",
      "name": "Tesouro Selic 2029",
      "value": 500
    }
  ]
}
 
/codes/expressjs/invest-app-mvc/src/database/seeders.json
{
  "investments": [
    {
      "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
      "name": "Tesouro Selic 2029",
      "value": 1000
    },
    {
      "id": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed",
      "name": "Tesouro Selic 2029",
      "value": 500
    }
  ]
}
 
/codes/expressjs/invest-app-mvc/src/database/seeders.js
import { resolve } from 'node:path';
import { readFileSync } from 'node:fs';
import Investment from '../models/Investment.js';
 
async function up() {
  const file = resolve('src', 'database', 'seeders.json');
 
  const seed = JSON.parse(readFileSync(file));
 
  for (const investment of seed.investments) {
    await Investment.create(investment);
  }
}
 
export default { up };
 
/codes/expressjs/invest-app-mvc/src/database/seeders.js
import { resolve } from 'node:path';
import { readFileSync } from 'node:fs';
import Investment from '../models/Investment.js';
 
async function up() {
  const file = resolve('src', 'database', 'seeders.json');
 
  const seed = JSON.parse(readFileSync(file));
 
  for (const investment of seed.investments) {
    await Investment.create(investment);
  }
}
 
export default { up };
 

Loader

/codes/expressjs/invest-app-mvc/src/index.js
import 'express-async-errors';
import express from 'express';
import cors from 'cors';
import morgan from 'morgan';
import router from './routes.js';
import Seed from './database/seeders.js';
 
const server = express();
 
server.use(morgan('tiny'));
 
server.use(
  cors({
    origin: '*',
    methods: 'GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE',
    allowedHeaders: ['Content-Type', 'Authorization'],
    credentials: true,
    preflightContinue: false,
  })
);
 
server.use(express.json());
 
server.use(express.static('public'));
 
server.use('/api', router);
 
await Seed.up();
 
server.listen(3000, () => {
  console.log('Server is running on port 3000');
});
 
/codes/expressjs/invest-app-mvc/src/index.js
import 'express-async-errors';
import express from 'express';
import cors from 'cors';
import morgan from 'morgan';
import router from './routes.js';
import Seed from './database/seeders.js';
 
const server = express();
 
server.use(morgan('tiny'));
 
server.use(
  cors({
    origin: '*',
    methods: 'GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE',
    allowedHeaders: ['Content-Type', 'Authorization'],
    credentials: true,
    preflightContinue: false,
  })
);
 
server.use(express.json());
 
server.use(express.static('public'));
 
server.use('/api', router);
 
await Seed.up();
 
server.listen(3000, () => {
  console.log('Server is running on port 3000');
});
 

Router

/codes/expressjs/invest-app-mvc/src/routes.js
import express from 'express';
import Investment from './models/Investment.js';
 
class HTTPError extends Error {
  constructor(message, code) {
    super(message);
    this.code = code;
  }
}
 
const router = express.Router();
 
router.post('/investments', async (req, res) => {
  try {
    const investment = req.body;
 
    const createdInvestment = await Investment.create(investment);
 
    return res.json(createdInvestment);
  } catch (error) {
    throw new HTTPError('Unable to create investment', 400);
  }
});
 
router.get('/investments', async (req, res) => {
  try {
    const { name } = req.query;
 
    const investments = await Investment.read('name', name);
 
    res.json(investments);
  } catch (error) {
    throw new HTTPError('Unable to read investments', 400);
  }
});
 
router.get('/investments/:id', async (req, res) => {
  try {
    const id = req.params.id;
 
    const investment = await Investment.readById(id);
 
    res.json(investment);
  } catch (error) {
    throw new HTTPError('Unable to find investment', 400);
  }
});
 
router.put('/investments/:id', async (req, res) => {
  try {
    const investment = req.body;
 
    const id = req.params.id;
 
    const updatedInvestment = await Investment.update({ ...investment, id });
 
    return res.json(updatedInvestment);
  } catch (error) {
    throw new HTTPError('Unable to update investment', 400);
  }
});
 
router.delete('/investments/:id', async (req, res) => {
  const id = req.params.id;
 
  if (await Investment.remove(id)) {
    res.sendStatus(204);
  } else {
    throw new HTTPError('Unable to remove investment', 400);
  }
});
 
// 404 handler
router.use((req, res, next) => {
  res.status(404).json({ message: 'Content not found!' });
});
 
// Error handler
router.use((err, req, res, next) => {
  // console.error(err.stack);
  if (err instanceof HTTPError) {
    res.status(err.code).json({ message: err.message });
  } else {
    res.status(500).json({ message: 'Something broke!' });
  }
});
 
export default router;
 
/codes/expressjs/invest-app-mvc/src/routes.js
import express from 'express';
import Investment from './models/Investment.js';
 
class HTTPError extends Error {
  constructor(message, code) {
    super(message);
    this.code = code;
  }
}
 
const router = express.Router();
 
router.post('/investments', async (req, res) => {
  try {
    const investment = req.body;
 
    const createdInvestment = await Investment.create(investment);
 
    return res.json(createdInvestment);
  } catch (error) {
    throw new HTTPError('Unable to create investment', 400);
  }
});
 
router.get('/investments', async (req, res) => {
  try {
    const { name } = req.query;
 
    const investments = await Investment.read('name', name);
 
    res.json(investments);
  } catch (error) {
    throw new HTTPError('Unable to read investments', 400);
  }
});
 
router.get('/investments/:id', async (req, res) => {
  try {
    const id = req.params.id;
 
    const investment = await Investment.readById(id);
 
    res.json(investment);
  } catch (error) {
    throw new HTTPError('Unable to find investment', 400);
  }
});
 
router.put('/investments/:id', async (req, res) => {
  try {
    const investment = req.body;
 
    const id = req.params.id;
 
    const updatedInvestment = await Investment.update({ ...investment, id });
 
    return res.json(updatedInvestment);
  } catch (error) {
    throw new HTTPError('Unable to update investment', 400);
  }
});
 
router.delete('/investments/:id', async (req, res) => {
  const id = req.params.id;
 
  if (await Investment.remove(id)) {
    res.sendStatus(204);
  } else {
    throw new HTTPError('Unable to remove investment', 400);
  }
});
 
// 404 handler
router.use((req, res, next) => {
  res.status(404).json({ message: 'Content not found!' });
});
 
// Error handler
router.use((err, req, res, next) => {
  // console.error(err.stack);
  if (err instanceof HTTPError) {
    res.status(err.code).json({ message: err.message });
  } else {
    res.status(500).json({ message: 'Something broke!' });
  }
});
 
export default router;
 

Editar esta página