Skip to content

Commit

Permalink
user signup/login teams fixtures, alot
Browse files Browse the repository at this point in the history
  • Loading branch information
Victor committed Aug 1, 2022
1 parent 0f73fd7 commit ffd0f41
Show file tree
Hide file tree
Showing 28 changed files with 1,300 additions and 145 deletions.
23 changes: 23 additions & 0 deletions @types/express/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Express } from 'express';

import { User } from '../../src/user/interfaces';

declare global {
namespace Express {
interface Request {
user: User;
}
}
}

// export interface CustomRequest extends Request {
// user?: User;
// }

// import { User } from '../src/user/interfaces';

// declare module 'express' {
// export interface Request {
// user?: User;
// }
// }
4 changes: 4 additions & 0 deletions config/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ export default {
database: {
url: process.env.DATABASE_URL,
},
jwt: {
secret: process.env.JWT_SECRET,
expiresIn: process.env.JWT_EXPIRES_IN,
},
};
454 changes: 313 additions & 141 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,32 @@
"license": "ISC",
"dependencies": {
"@types/hpp": "^0.2.2",
"bcryptjs": "^2.4.3",
"config": "^3.3.7",
"dotenv": "^16.0.1",
"express": "^4.18.1",
"express-mongo-sanitize": "^2.2.0",
"express-rate-limit": "^6.5.1",
"helmet": "^5.1.1",
"hpp": "^0.2.3",
"mongoose": "^6.5.0",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"mongoose": "^5.5.15",
"morgan": "^1.10.0",
"validator": "^13.7.0",
"winston": "^3.8.1"
},
"devDependencies": {
"@types/bcryptjs": "^2.4.2",
"@types/config": "0.0.41",
"@types/express": "^4.17.13",
"@types/jsonwebtoken": "^8.5.8",
"@types/lodash": "^4.14.182",
"@types/mongoose": "^5.11.97",
"@types/morgan": "^1.9.3",
"@types/node": "^18.6.1",
"@types/validator": "^13.7.4",
"nodemon": "^2.0.19",
"ts-node": "^10.9.1",
"typescript": "^4.7.4"
Expand Down
14 changes: 14 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ require('dotenv').config();

import logger from './logger';
import connect from './database/connection';
import userRouter from './routes/userRouter';
import teamRouter from './routes/teamRouter';
import { errorHandler } from './middlewares/errorHandler';
import AppError from './utils/appError';

const app: Application = express();

Expand Down Expand Up @@ -42,6 +46,10 @@ app.use(
})
);

// app.use('/api/v1/auth', authRouter);
app.use('/api/v1/user', userRouter);
app.use('/api/v1/team', teamRouter);

app.get('/', (req: Request, res: Response, next: NextFunction) => {
res.send('Hello world!');
});
Expand All @@ -53,4 +61,10 @@ app.listen(port, () => {
connect();
});

app.all('*', (req, res, next) => {
next(new AppError(`Can't find ${req.originalUrl} on this server`, 404));
});

app.use(errorHandler);

module.exports = app;
7 changes: 6 additions & 1 deletion src/database/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ const connect = async () => {
try {
const dbUri = config.get('database.url') as string;
await mongoose
.connect(dbUri)
.connect(dbUri, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false,
})
.then(() => logger.info('Database connection successfull'));
} catch (error) {
logger.error('error connecting to database', error);
Expand Down
91 changes: 91 additions & 0 deletions src/fixtures/controllers/fixturesController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { NextFunction, Request, Response } from 'express';
import { clone } from 'lodash';

import logger from '../../logger';
import catchAsync from '../../utils/catchAsync';
import { signToken } from '../../utils/signToken';
import { Team } from '../interfaces';
import { create, findOne, update } from '../services/fixturesService';

export const createTeam = catchAsync(
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
try {
const { name, shortName, email }: Team = req.body;
const user = clone(req.user);
const payload = {
name,
shortName,
email,
createdBy: user?.id,
} as Team;

const data = await create(payload);

res.status(201).json({
message: 'Team created successfully',
status: 'success',
data,
});
} catch (error: any) {
logger.error(
`Error occurred while creating team: ${JSON.stringify(error)}`
);
res.status(error.statusCode || 500).json({
status: error.status || 'error',
message: error.message,
});
}
}
);

export const findTeamById = catchAsync(
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
try {
const { id } = req.params;

const data = await findOne(id);

res.status(200).json({
message: 'Team fetched successfully',
status: 'success',
data,
});
} catch (error: any) {
logger.error(
`Error occurred while fetching team: ${JSON.stringify(error)}`
);
res.status(error.statusCode || 500).json({
status: error.status || 'error',
message: error.message,
});
}
}
);

export const updateTeam = catchAsync(
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
try {
const { id } = req.params;

const payload = {
...req.body,
} as Omit<Team, 'updatedAt'>;

const data = await update(id, payload);

res.status(200).json({
message: 'Team Updated successfully',
status: 'success',
data,
});
} catch (error: any) {
logger.error(
`Error occurred while fetching team: ${JSON.stringify(error)}`
);
res.status(error.statusCode || 500).json({
status: error.status || 'error',
message: error.message,
});
}
}
);
16 changes: 16 additions & 0 deletions src/fixtures/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Document } from 'mongoose';

export interface Fixture extends Document {
name: string;
shortName: string;
email: string;
readonly createdBy: string;
readonly createdAt?: Date;
updatedAt?: Date;
}

export enum FixtureStatues {
Completed = 'Completed',
Pending = 'Pending',
Ongoing = 'Ongoing',
}
71 changes: 71 additions & 0 deletions src/fixtures/models/fixturesModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import mongoose, { Schema, HookNextFunction } from 'mongoose';
import * as bcrypt from 'bcryptjs';
import validator from 'validator';

import { Fixture, FixtureStatues } from '../interfaces';
import moment from 'moment';

const fixtureSchema = new Schema(
{
home: {
team: {
type: Schema.Types.ObjectId,
ref: 'Team',
required: true,
},
score: {
type: Number,
default: 0,
},
},
away: {
team: {
type: Schema.Types.ObjectId,
ref: 'Team',
required: true,
},
score: {
type: Number,
default: 0,
},
},
status: {
type: String,
enum: {
values: FixtureStatues,
message: 'Team status is either completed, pending or ongoing',
},
default: FixtureStatues.Pending,
},
createdBy: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true,
},
createdAt: {
type: Date,
default: Date.now(),
},
updatedAt: {
type: Date,
},
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
);

fixtureSchema.pre('save', function (next: HookNextFunction) {
const fixture = this as Fixture;

if (fixture.isNew) return next();

fixture.updatedAt = moment().toDate();

next();
});

const Team = mongoose.model<Fixture>('Fixture', fixtureSchema);

export default Team;
57 changes: 57 additions & 0 deletions src/fixtures/services/fixturesService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { NextFunction, Request, Response } from 'express';

import logger from '../../logger';
import AppError from '../../utils/appError';
import { Fixture } from '../interfaces';
import FixtureModel from '../models/fixturesModel';

export const create = async (payload: Fixture): Promise<Fixture> => {
logger.info(`Creating fixture with payload', ${JSON.stringify(payload)}`);

return FixtureModel.create(payload);
};

export const findOne = async (id: string): Promise<Fixture> => {
logger.info(`finding fixture with ID ${id}`);

const fixture = (await FixtureModel.findById(id)
.populate({
path: 'createdBy',
select: 'name role',
})
.populate({
path: 'home',
select: 'name shortName',
})
.populate({
path: 'away',
select: 'name shortName',
})) as Fixture;

if (!fixture) {
throw new AppError('No fixture found with that ID', 400);
}

return fixture;
};

export const update = async (
id: string,
payload: Fixture
): Promise<Fixture> => {
logger.info(
`attempting to update team with ID: ${id} with paylod: ${JSON.stringify(
payload
)}`
);

const fixture = (await FixtureModel.findOneAndUpdate({ _id: id }, payload, {
new: true,
})) as Fixture;

if (!fixture) {
throw new AppError('No fixture found with that ID', 400);
}

return fixture;
};
Loading

0 comments on commit ffd0f41

Please sign in to comment.