Cadastro de Usuário

Open in GitHub Open in Codespaces

Arquivos
invest-app-prismajs-user
├── package-lock.json
├── package.json
├── prisma
│   ├── dev.db
│   ├── migrations
│   │   ├── 20230826214323_init
│   │   │   └── migration.sql
│   │   ├── 20241012023407_create_category_broker
│   │   │   └── migration.sql
│   │   ├── 20241012023426_create_user
│   │   │   └── migration.sql
│   │   └── migration_lock.toml
│   ├── schema.prisma
│   ├── seed.js
│   └── seeders.json
├── public
│   ├── css
│   │   └── style.css
│   ├── home.html
│   ├── js
│   │   ├── home.js
│   │   ├── lib
│   │   │   └── format.js
│   │   ├── services
│   │   │   └── api.js
│   │   ├── signin.js
│   │   └── signup.js
│   ├── signin.html
│   └── signup.html
├── requests.http
└── src
    ├── database
    │   └── database.js
    ├── index.js
    ├── models
    │   ├── Category.js
    │   ├── Investment.js
    │   └── User.js
    └── routes.js
Arquivos
invest-app-prismajs-user
├── package-lock.json
├── package.json
├── prisma
│   ├── dev.db
│   ├── migrations
│   │   ├── 20230826214323_init
│   │   │   └── migration.sql
│   │   ├── 20241012023407_create_category_broker
│   │   │   └── migration.sql
│   │   ├── 20241012023426_create_user
│   │   │   └── migration.sql
│   │   └── migration_lock.toml
│   ├── schema.prisma
│   ├── seed.js
│   └── seeders.json
├── public
│   ├── css
│   │   └── style.css
│   ├── home.html
│   ├── js
│   │   ├── home.js
│   │   ├── lib
│   │   │   └── format.js
│   │   ├── services
│   │   │   └── api.js
│   │   ├── signin.js
│   │   └── signup.js
│   ├── signin.html
│   └── signup.html
├── requests.http
└── src
    ├── database
    │   └── database.js
    ├── index.js
    ├── models
    │   ├── Category.js
    │   ├── Investment.js
    │   └── User.js
    └── routes.js

Migration

/codes/expressjs/invest-app-prismajs-user/prisma/schema.prisma
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
 
generator client {
  provider = "prisma-client-js"
}
 
datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}
 
model Investment {
  id         String   @id @default(uuid())
  name       String
  value      Int
  interest   String
  createdAt  DateTime @default(now())
  category   Category @relation(fields: [categoryId], references: [id])
  categoryId String
  user       User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  userId     String
  broker     Broker   @relation(fields: [brokerId], references: [id])
  brokerId   String
}
 
model Category {
  id          String       @id @default(uuid())
  name        String       @unique
  color       String       @unique
  investments Investment[]
}
 
model User {
  id          String       @id @default(uuid())
  name        String
  email       String       @unique
  password    String
  investments Investment[]
}
 
model Broker {
  id          String       @id @default(uuid())
  name        String       @unique
  investments Investment[]
}
 
/codes/expressjs/invest-app-prismajs-user/prisma/schema.prisma
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
 
generator client {
  provider = "prisma-client-js"
}
 
datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}
 
model Investment {
  id         String   @id @default(uuid())
  name       String
  value      Int
  interest   String
  createdAt  DateTime @default(now())
  category   Category @relation(fields: [categoryId], references: [id])
  categoryId String
  user       User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  userId     String
  broker     Broker   @relation(fields: [brokerId], references: [id])
  brokerId   String
}
 
model Category {
  id          String       @id @default(uuid())
  name        String       @unique
  color       String       @unique
  investments Investment[]
}
 
model User {
  id          String       @id @default(uuid())
  name        String
  email       String       @unique
  password    String
  investments Investment[]
}
 
model Broker {
  id          String       @id @default(uuid())
  name        String       @unique
  investments Investment[]
}
 
$ npx prisma migrate reset
$ npx prisma migrate dev --name create_user
$ npx prisma migrate reset
$ npx prisma migrate dev --name create_user

Tabelas:

Model

Blowfish (bcrypt):

$ npm install bcrypt
$ npm install bcrypt

Encrypt:

bcrypt.hash(plainPassword, saltRounds)

bcrypt.hash('12345678', 10)
//=> $2a$10$13Aak6RFaLSM2BWra67RA.KElfrt41YQsTjy9nul0bxBhXI2vjiPe
bcrypt.hash('12345678', 10)
//=> $2a$10$13Aak6RFaLSM2BWra67RA.KElfrt41YQsTjy9nul0bxBhXI2vjiPe
bcrypt.hash('12345678', 10)
//=> $2a$10$CZHQV57ViPynbUbeffLU7.cTV8Rr9PjlJXkoe/Xu1FIUXA/I0we5C
bcrypt.hash('12345678', 10)
//=> $2a$10$CZHQV57ViPynbUbeffLU7.cTV8Rr9PjlJXkoe/Xu1FIUXA/I0we5C

Decrypt:

bcrypt.compare(plainPassword, hash)

bcrypt.compare(
  '12345678',
  '$2a$10$13Aak6RFaLSM2BWra67RA.KElfrt41YQsTjy9nul0bxBhXI2vjiPe'
)
//=> true
bcrypt.compare(
  '12345678',
  '$2a$10$13Aak6RFaLSM2BWra67RA.KElfrt41YQsTjy9nul0bxBhXI2vjiPe'
)
//=> true
bcrypt.compare(
  '12345678',
  '$2a$10$CZHQV57ViPynbUbeffLU7.cTV8Rr9PjlJXkoe/Xu1FIUXA/I0we5C'
)
//=> true
bcrypt.compare(
  '12345678',
  '$2a$10$CZHQV57ViPynbUbeffLU7.cTV8Rr9PjlJXkoe/Xu1FIUXA/I0we5C'
)
//=> true

dotenv:

$ npm install dotenv
$ npm install dotenv
/codes/expressjs/invest-app-prismajs-user/src/index.js
import 'express-async-errors';
import 'dotenv/config';
import express from 'express';
import cors from 'cors';
import morgan from 'morgan';
import router from './routes.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.get('/', (req, res) => {
  res.redirect('/signup.html');
});
 
server.use('/api', router);
 
server.listen(3000, () => {
  console.log('Server is running on port 3000');
});
 
/codes/expressjs/invest-app-prismajs-user/src/index.js
import 'express-async-errors';
import 'dotenv/config';
import express from 'express';
import cors from 'cors';
import morgan from 'morgan';
import router from './routes.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.get('/', (req, res) => {
  res.redirect('/signup.html');
});
 
server.use('/api', router);
 
server.listen(3000, () => {
  console.log('Server is running on port 3000');
});
 
/codes/expressjs/invest-app-prismajs-user/.env.example
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema

# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings

DATABASE_URL="file:./dev.db"

# BCRYPT
BCRYPT_SALT=10
/codes/expressjs/invest-app-prismajs-user/.env.example
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema

# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings

DATABASE_URL="file:./dev.db"

# BCRYPT
BCRYPT_SALT=10
$ cp .env.example .env
$ cp .env.example .env
/codes/expressjs/invest-app-prismajs-user/src/models/User.js
import bcrypt from 'bcrypt';
import prisma from '../database/database.js';
 
const saltRounds = Number(process.env.BCRYPT_SALT);
 
async function create({ name, email, password }) {
  if (name && email && password) {
    const hash = await bcrypt.hash(password, saltRounds);
 
    const createdUser = await prisma.user.create({
      data: { name, email, password: hash },
    });
 
    return createdUser;
  } else {
    throw new Error('Unable to create user');
  }
}
 
async function read(where) {
  const users = await prisma.user.findMany({
    where,
  });
 
  if (users.length === 1 && where) {
    return users[0];
  }
 
  return users;
}
 
async function readById(id) {
  if (id) {
    const user = await prisma.user.findUnique({
      where: {
        id,
      },
    });
 
    return user;
  } else {
    throw new Error('Unable to find user');
  }
}
 
async function update({ id, name, email, password }) {
  if (name && email && password && id) {
    const hash = await bcrypt.hash(password, saltRounds);
 
    const updatedUser = await prisma.user.update({
      where: {
        id,
      },
      data: { name, email, password: hash },
    });
 
    return updatedUser;
  } else {
    throw new Error('Unable to update user');
  }
}
 
async function remove(id) {
  if (id) {
    await prisma.user.delete({
      where: {
        id,
      },
    });
 
    return true;
  } else {
    throw new Error('Unable to remove user');
  }
}
 
export default { create, read, readById, update, remove };
 
/codes/expressjs/invest-app-prismajs-user/src/models/User.js
import bcrypt from 'bcrypt';
import prisma from '../database/database.js';
 
const saltRounds = Number(process.env.BCRYPT_SALT);
 
async function create({ name, email, password }) {
  if (name && email && password) {
    const hash = await bcrypt.hash(password, saltRounds);
 
    const createdUser = await prisma.user.create({
      data: { name, email, password: hash },
    });
 
    return createdUser;
  } else {
    throw new Error('Unable to create user');
  }
}
 
async function read(where) {
  const users = await prisma.user.findMany({
    where,
  });
 
  if (users.length === 1 && where) {
    return users[0];
  }
 
  return users;
}
 
async function readById(id) {
  if (id) {
    const user = await prisma.user.findUnique({
      where: {
        id,
      },
    });
 
    return user;
  } else {
    throw new Error('Unable to find user');
  }
}
 
async function update({ id, name, email, password }) {
  if (name && email && password && id) {
    const hash = await bcrypt.hash(password, saltRounds);
 
    const updatedUser = await prisma.user.update({
      where: {
        id,
      },
      data: { name, email, password: hash },
    });
 
    return updatedUser;
  } else {
    throw new Error('Unable to update user');
  }
}
 
async function remove(id) {
  if (id) {
    await prisma.user.delete({
      where: {
        id,
      },
    });
 
    return true;
  } else {
    throw new Error('Unable to remove user');
  }
}
 
export default { create, read, readById, update, remove };
 
/codes/expressjs/invest-app-prismajs-user/src/models/Investment.js
import prisma from '../database/database.js';
 
async function create({
  name,
  value,
  interest,
  createdAt,
  categoryId,
  userId,
  broker,
}) {
  if (name && value && interest && categoryId && userId && broker) {
    const createdInvestment = await prisma.investment.create({
      data: {
        name,
        value,
        interest,
        createdAt,
        category: {
          connect: {
            id: categoryId,
          },
        },
        user: {
          connect: {
            id: userId,
          },
        },
        broker: {
          connectOrCreate: {
            where: {
              name: broker,
            },
            create: {
              name: broker,
            },
          },
        },
      },
      include: {
        category: true,
        user: {
          select: {
            id: true,
            name: true,
            email: true,
          },
        },
        broker: true,
      },
    });
 
    return createdInvestment;
  } else {
    throw new Error('Unable to create investment');
  }
}
 
async function read(where) {
  if (where?.name) {
    where.name = {
      contains: where.name,
    };
  }
 
  const investments = await prisma.investment.findMany({
    where,
    include: {
      category: true,
      user: {
        select: {
          id: true,
          name: true,
          email: true,
        },
      },
      broker: true,
    },
  });
 
  if (
    investments.length === 1 &&
    Object.keys(where).some((key) => key !== 'userId')
  ) {
    return investments[0];
  }
 
  return investments;
}
 
async function readById(id, where) {
  if (id) {
    const investment = await prisma.investment.findUnique({
      where: {
        id,
        ...where,
      },
      include: {
        category: true,
        broker: true,
        user: {
          select: {
            id: true,
            name: true,
            email: true,
          },
        },
      },
    });
 
    return investment;
  } else {
    throw new Error('Unable to find investment');
  }
}
 
async function update({
  id,
  name,
  value,
  interest,
  createdAt,
  categoryId,
  userId,
  broker,
}) {
  if (name && value && interest && categoryId && userId && broker && id) {
    const updatedInvestment = await prisma.investment.update({
      where: {
        id,
      },
      data: {
        name,
        value,
        interest,
        createdAt,
        category: {
          connect: {
            id: categoryId,
          },
        },
        user: {
          connect: {
            id: userId,
          },
        },
        broker: {
          connectOrCreate: {
            where: {
              name: broker,
            },
            create: {
              name: broker,
            },
          },
        },
      },
      include: {
        category: true,
        user: {
          select: {
            id: true,
            name: true,
            email: true,
          },
        },
        broker: true,
      },
    });
 
    return updatedInvestment;
  } else {
    throw new Error('Unable to update investment');
  }
}
 
async function remove(id) {
  if (id) {
    await prisma.investment.delete({
      where: {
        id,
      },
    });
 
    return true;
  } else {
    throw new Error('Unable to remove investment');
  }
}
 
export default { create, read, readById, update, remove };
 
/codes/expressjs/invest-app-prismajs-user/src/models/Investment.js
import prisma from '../database/database.js';
 
async function create({
  name,
  value,
  interest,
  createdAt,
  categoryId,
  userId,
  broker,
}) {
  if (name && value && interest && categoryId && userId && broker) {
    const createdInvestment = await prisma.investment.create({
      data: {
        name,
        value,
        interest,
        createdAt,
        category: {
          connect: {
            id: categoryId,
          },
        },
        user: {
          connect: {
            id: userId,
          },
        },
        broker: {
          connectOrCreate: {
            where: {
              name: broker,
            },
            create: {
              name: broker,
            },
          },
        },
      },
      include: {
        category: true,
        user: {
          select: {
            id: true,
            name: true,
            email: true,
          },
        },
        broker: true,
      },
    });
 
    return createdInvestment;
  } else {
    throw new Error('Unable to create investment');
  }
}
 
async function read(where) {
  if (where?.name) {
    where.name = {
      contains: where.name,
    };
  }
 
  const investments = await prisma.investment.findMany({
    where,
    include: {
      category: true,
      user: {
        select: {
          id: true,
          name: true,
          email: true,
        },
      },
      broker: true,
    },
  });
 
  if (
    investments.length === 1 &&
    Object.keys(where).some((key) => key !== 'userId')
  ) {
    return investments[0];
  }
 
  return investments;
}
 
async function readById(id, where) {
  if (id) {
    const investment = await prisma.investment.findUnique({
      where: {
        id,
        ...where,
      },
      include: {
        category: true,
        broker: true,
        user: {
          select: {
            id: true,
            name: true,
            email: true,
          },
        },
      },
    });
 
    return investment;
  } else {
    throw new Error('Unable to find investment');
  }
}
 
async function update({
  id,
  name,
  value,
  interest,
  createdAt,
  categoryId,
  userId,
  broker,
}) {
  if (name && value && interest && categoryId && userId && broker && id) {
    const updatedInvestment = await prisma.investment.update({
      where: {
        id,
      },
      data: {
        name,
        value,
        interest,
        createdAt,
        category: {
          connect: {
            id: categoryId,
          },
        },
        user: {
          connect: {
            id: userId,
          },
        },
        broker: {
          connectOrCreate: {
            where: {
              name: broker,
            },
            create: {
              name: broker,
            },
          },
        },
      },
      include: {
        category: true,
        user: {
          select: {
            id: true,
            name: true,
            email: true,
          },
        },
        broker: true,
      },
    });
 
    return updatedInvestment;
  } else {
    throw new Error('Unable to update investment');
  }
}
 
async function remove(id) {
  if (id) {
    await prisma.investment.delete({
      where: {
        id,
      },
    });
 
    return true;
  } else {
    throw new Error('Unable to remove investment');
  }
}
 
export default { create, read, readById, update, remove };
 

Router

/codes/expressjs/invest-app-prismajs-user/src/routes.js
import express from 'express';
import Category from './models/Category.js';
import Investment from './models/Investment.js';
import User from './models/User.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;
 
    if (investment.createdAt) {
      investment.createdAt = new Date(
        investment.createdAt + 'T00:00:00-03:00'
      ).toISOString();
    }
 
    if (!investment.userId) {
      investment.userId = (await User.read({ email: 'admin@email.com' })).id;
    }
 
    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;
 
    let investments;
 
    if (name) {
      investments = await Investment.read({ name });
    } else {
      investments = await Investment.read();
    }
 
    return res.json(investments);
  } catch (error) {
    console.error(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);
 
    return res.json(investment);
  } catch (error) {
    throw new HTTPError('Unable to find investment', 400);
  }
});
 
router.put('/investments/:id', async (req, res) => {
  try {
    const id = req.params.id;
 
    const investment = req.body;
 
    if (investment.createdAt) {
      investment.createdAt = new Date(
        investment.createdAt + 'T00:00:00-03:00'
      ).toISOString();
    }
 
    if (!investment.userId) {
      investment.userId = (await User.read({ email: 'admin@email.com' })).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) => {
  try {
    const id = req.params.id;
 
    if (await Investment.remove(id)) {
      return res.sendStatus(204);
    } else {
      throw new Error();
    }
  } catch (error) {
    throw new HTTPError('Unable to remove investment', 400);
  }
});
 
router.get('/categories', async (req, res) => {
  try {
    const { name } = req.query;
 
    let categories;
 
    if (name) {
      categories = await Category.read({ name });
    } else {
      categories = await Category.read();
    }
 
    return res.json(categories);
  } catch (error) {
    throw new HTTPError('Unable to read investments', 400);
  }
});
 
router.post('/users', async (req, res) => {
  try {
    const user = req.body;
 
    delete user.confirmationPassword;
 
    const newUser = await User.create(user);
 
    delete newUser.password;
 
    res.status(201).json(newUser);
  } catch (error) {
    throw new HTTPError('Unable to create user', 400);
  }
});
 
// 404 handler
router.use((req, res, next) => {
  return res.status(404).json({ message: 'Content not found!' });
});
 
// Error handler
router.use((err, req, res, next) => {
  // console.error(err.stack);
  if (err instanceof HTTPError) {
    return res.status(err.code).json({ message: err.message });
  } else {
    return res.status(500).json({ message: 'Something broke!' });
  }
});
 
export default router;
 
/codes/expressjs/invest-app-prismajs-user/src/routes.js
import express from 'express';
import Category from './models/Category.js';
import Investment from './models/Investment.js';
import User from './models/User.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;
 
    if (investment.createdAt) {
      investment.createdAt = new Date(
        investment.createdAt + 'T00:00:00-03:00'
      ).toISOString();
    }
 
    if (!investment.userId) {
      investment.userId = (await User.read({ email: 'admin@email.com' })).id;
    }
 
    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;
 
    let investments;
 
    if (name) {
      investments = await Investment.read({ name });
    } else {
      investments = await Investment.read();
    }
 
    return res.json(investments);
  } catch (error) {
    console.error(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);
 
    return res.json(investment);
  } catch (error) {
    throw new HTTPError('Unable to find investment', 400);
  }
});
 
router.put('/investments/:id', async (req, res) => {
  try {
    const id = req.params.id;
 
    const investment = req.body;
 
    if (investment.createdAt) {
      investment.createdAt = new Date(
        investment.createdAt + 'T00:00:00-03:00'
      ).toISOString();
    }
 
    if (!investment.userId) {
      investment.userId = (await User.read({ email: 'admin@email.com' })).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) => {
  try {
    const id = req.params.id;
 
    if (await Investment.remove(id)) {
      return res.sendStatus(204);
    } else {
      throw new Error();
    }
  } catch (error) {
    throw new HTTPError('Unable to remove investment', 400);
  }
});
 
router.get('/categories', async (req, res) => {
  try {
    const { name } = req.query;
 
    let categories;
 
    if (name) {
      categories = await Category.read({ name });
    } else {
      categories = await Category.read();
    }
 
    return res.json(categories);
  } catch (error) {
    throw new HTTPError('Unable to read investments', 400);
  }
});
 
router.post('/users', async (req, res) => {
  try {
    const user = req.body;
 
    delete user.confirmationPassword;
 
    const newUser = await User.create(user);
 
    delete newUser.password;
 
    res.status(201).json(newUser);
  } catch (error) {
    throw new HTTPError('Unable to create user', 400);
  }
});
 
// 404 handler
router.use((req, res, next) => {
  return res.status(404).json({ message: 'Content not found!' });
});
 
// Error handler
router.use((err, req, res, next) => {
  // console.error(err.stack);
  if (err instanceof HTTPError) {
    return res.status(err.code).json({ message: err.message });
  } else {
    return res.status(500).json({ message: 'Something broke!' });
  }
});
 
export default router;
 
/codes/expressjs/invest-app-prismajs-user/requests.http
@host = http://localhost:3000/api
@createdInvestmentId = {{createdInvestment.response.body.$.id}}
@createdUserId = {{createdUser.response.body.$.id}}
 
### Create User
 
# @name createdUser
POST {{host}}/users
Content-Type: application/json
 
{
  "name": "Luiz",
  "email": "luiz@email.com",
  "password": "123"
}
 
### Read Categories
 
GET {{host}}/categories
 
### Read Categories by Name
 
# @name categoryPos
GET {{host}}/categories?name=Pós
 
### Read Categories by Name
 
# @name categoryIpca
GET {{host}}/categories?name=IPCA
 
### Create Investment
 
@categoryIpcaId = {{categoryIpca.response.body.$.id}}
 
# @name createdInvestment
POST {{host}}/investments
Content-Type: application/json
 
{
  "name": "Tesouro Selic 2029",
  "value": 10000,
  "categoryId": "{{categoryIpcaId}}",
  "userId": "{{createdUserId}}"
}
 
### Read Investments
 
GET {{host}}/investments
 
### Read Investments by Name
 
GET {{host}}/investments?name=Tesouro
 
### Update Investment
 
@categoryPosId = {{categoryPos.response.body.$.id}}
 
PUT {{host}}/investments/{{createdInvestmentId}}
Content-Type: application/json
 
{
  "name": "Tesouro Selic 2029",
  "value": 20000,
  "categoryId": "{{categoryPosId}}",
  "userId": "{{createdUserId}}"
}
 
### Delete Investment
 
DELETE {{host}}/investments/{{createdInvestmentId}}
 
 
/codes/expressjs/invest-app-prismajs-user/requests.http
@host = http://localhost:3000/api
@createdInvestmentId = {{createdInvestment.response.body.$.id}}
@createdUserId = {{createdUser.response.body.$.id}}
 
### Create User
 
# @name createdUser
POST {{host}}/users
Content-Type: application/json
 
{
  "name": "Luiz",
  "email": "luiz@email.com",
  "password": "123"
}
 
### Read Categories
 
GET {{host}}/categories
 
### Read Categories by Name
 
# @name categoryPos
GET {{host}}/categories?name=Pós
 
### Read Categories by Name
 
# @name categoryIpca
GET {{host}}/categories?name=IPCA
 
### Create Investment
 
@categoryIpcaId = {{categoryIpca.response.body.$.id}}
 
# @name createdInvestment
POST {{host}}/investments
Content-Type: application/json
 
{
  "name": "Tesouro Selic 2029",
  "value": 10000,
  "categoryId": "{{categoryIpcaId}}",
  "userId": "{{createdUserId}}"
}
 
### Read Investments
 
GET {{host}}/investments
 
### Read Investments by Name
 
GET {{host}}/investments?name=Tesouro
 
### Update Investment
 
@categoryPosId = {{categoryPos.response.body.$.id}}
 
PUT {{host}}/investments/{{createdInvestmentId}}
Content-Type: application/json
 
{
  "name": "Tesouro Selic 2029",
  "value": 20000,
  "categoryId": "{{categoryPosId}}",
  "userId": "{{createdUserId}}"
}
 
### Delete Investment
 
DELETE {{host}}/investments/{{createdInvestmentId}}
 
 

View

/codes/expressjs/invest-app-prismajs-user/public/signup.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Cadastro de Usuário</title>
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD"
      crossorigin="anonymous"
    />
  </head>
 
  <body>
    <nav class="navbar navbar-expand-lg bg-light">
      <div class="container">
        <a class="navbar-brand" href="#">Monitor App</a>
        <button
          class="navbar-toggler"
          type="button"
          data-bs-toggle="collapse"
          data-bs-target="#navbarSupportedContent"
          aria-controls="navbarSupportedContent"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav me-auto mb-2 mb-lg-0">
            <li class="nav-item">
              <a class="nav-link" href="/signin.html">Entrar</a>
            </li>
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/signup.html"
                >Cadastrar</a
              >
            </li>
          </ul>
        </div>
      </div>
    </nav>
    <div class="container pb-5">
      <h1 class="text-center my-5 fw-bold">Cadastro de Usuário</h1>
 
      <div class="row justify-content-center">
        <form
          class="col-6 needs-validation"
          onsubmit="handleSubmit(event)"
          novalidate
        >
          <div class="mb-3">
            <label for="name" class="form-label">Nome</label>
            <input
              type="text"
              class="form-control"
              id="name"
              name="name"
              required
            />
            <div class="invalid-feedback">Informe o nome do usuário.</div>
          </div>
          <div class="mb-3">
            <label for="email" class="form-label">Email</label>
            <input
              type="email"
              class="form-control"
              id="email"
              name="email"
              required
            />
            <div class="invalid-feedback">Informe o email do usuário.</div>
          </div>
          <div class="mb-3">
            <label for="password" class="form-label">Senha</label>
            <!-- pattern="(?=.*[A-Z])(?=.*[!@#$&*])(?=.*[0-9])(?=.*[a-z]).{8}" -->
            <input
              type="password"
              class="form-control"
              id="password"
              name="password"
              minlength="8"
              required
            />
            <div class="invalid-feedback">
              Informe a senha com 8 caracteres.
            </div>
          </div>
          <div class="mb-3">
            <label for="confirmationPassword" class="form-label"
              >Confirmar Senha</label
            >
            <input
              type="password"
              class="form-control"
              id="confirmationPassword"
              name="confirmationPassword"
              required
            />
            <div class="invalid-feedback">Informe a confirmação de senha.</div>
          </div>
          <div class="mb-3">
            <input type="submit" class="btn btn-primary" value="Cadastrar" />
          </div>
        </form>
      </div>
    </div>
 
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN"
      crossorigin="anonymous"
    ></script>
    <script src="js/signup.js" type="module"></script>
  </body>
</html>
 
/codes/expressjs/invest-app-prismajs-user/public/signup.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Cadastro de Usuário</title>
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD"
      crossorigin="anonymous"
    />
  </head>
 
  <body>
    <nav class="navbar navbar-expand-lg bg-light">
      <div class="container">
        <a class="navbar-brand" href="#">Monitor App</a>
        <button
          class="navbar-toggler"
          type="button"
          data-bs-toggle="collapse"
          data-bs-target="#navbarSupportedContent"
          aria-controls="navbarSupportedContent"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav me-auto mb-2 mb-lg-0">
            <li class="nav-item">
              <a class="nav-link" href="/signin.html">Entrar</a>
            </li>
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="/signup.html"
                >Cadastrar</a
              >
            </li>
          </ul>
        </div>
      </div>
    </nav>
    <div class="container pb-5">
      <h1 class="text-center my-5 fw-bold">Cadastro de Usuário</h1>
 
      <div class="row justify-content-center">
        <form
          class="col-6 needs-validation"
          onsubmit="handleSubmit(event)"
          novalidate
        >
          <div class="mb-3">
            <label for="name" class="form-label">Nome</label>
            <input
              type="text"
              class="form-control"
              id="name"
              name="name"
              required
            />
            <div class="invalid-feedback">Informe o nome do usuário.</div>
          </div>
          <div class="mb-3">
            <label for="email" class="form-label">Email</label>
            <input
              type="email"
              class="form-control"
              id="email"
              name="email"
              required
            />
            <div class="invalid-feedback">Informe o email do usuário.</div>
          </div>
          <div class="mb-3">
            <label for="password" class="form-label">Senha</label>
            <!-- pattern="(?=.*[A-Z])(?=.*[!@#$&*])(?=.*[0-9])(?=.*[a-z]).{8}" -->
            <input
              type="password"
              class="form-control"
              id="password"
              name="password"
              minlength="8"
              required
            />
            <div class="invalid-feedback">
              Informe a senha com 8 caracteres.
            </div>
          </div>
          <div class="mb-3">
            <label for="confirmationPassword" class="form-label"
              >Confirmar Senha</label
            >
            <input
              type="password"
              class="form-control"
              id="confirmationPassword"
              name="confirmationPassword"
              required
            />
            <div class="invalid-feedback">Informe a confirmação de senha.</div>
          </div>
          <div class="mb-3">
            <input type="submit" class="btn btn-primary" value="Cadastrar" />
          </div>
        </form>
      </div>
    </div>
 
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN"
      crossorigin="anonymous"
    ></script>
    <script src="js/signup.js" type="module"></script>
  </body>
</html>
 
/codes/expressjs/invest-app-prismajs-user/public/js/signup.js
import API from './services/api.js';
 
const form = document.querySelector('form');
 
window.handleSubmit = handleSubmit;
 
async function handleSubmit(event) {
  event.preventDefault();
 
  const user = Object.fromEntries(new FormData(form));
 
  const { email } = await API.create('/users', user);
 
  if (email) {
    location.href = '/signin.html';
  } else {
    console.log('Error no cadastro');
  }
}
 
/codes/expressjs/invest-app-prismajs-user/public/js/signup.js
import API from './services/api.js';
 
const form = document.querySelector('form');
 
window.handleSubmit = handleSubmit;
 
async function handleSubmit(event) {
  event.preventDefault();
 
  const user = Object.fromEntries(new FormData(form));
 
  const { email } = await API.create('/users', user);
 
  if (email) {
    location.href = '/signin.html';
  } else {
    console.log('Error no cadastro');
  }
}
 

Editar esta página