Skip to content

Commit abe7716

Browse files
committed
init module category
1 parent 3f15d46 commit abe7716

File tree

9 files changed

+207
-2
lines changed

9 files changed

+207
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Schema } from 'mongoose'
2+
import Mongo from '../mongo'
3+
4+
const schema = new Schema(
5+
{
6+
name: {
7+
type: String,
8+
index: true,
9+
required: true,
10+
},
11+
},
12+
{
13+
timestamps: {
14+
createdAt: 'created_at',
15+
updatedAt: 'updated_at',
16+
},
17+
versionKey: false,
18+
}
19+
)
20+
21+
export default Mongo.Model('categories', schema)

src/main.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import config from './config/config'
22
import Mongo from './database/mongo/mongo'
3+
import Category from './modules/category/category'
34
import Images from './modules/images/images'
45
import Logger from './pkg/logger'
56
import Http from './transport/http/http'
@@ -11,6 +12,7 @@ const main = async () => {
1112

1213
// Start Load Modules
1314
new Images(logger, http, config)
15+
new Category(logger).loadHttp(http)
1416
// End Load Modules
1517

1618
http.Run(config.app.port.http)

src/modules/category/category.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import Http from '../../transport/http/http'
2+
import Logger from '../../pkg/logger'
3+
import Usecase from './usecase/usecase'
4+
import Handler from './delivery/http/handler'
5+
import Repository from './repository/mongo/repository'
6+
7+
class Category {
8+
private usecase: Usecase
9+
constructor(
10+
private logger: Logger,
11+
) {
12+
const repository = new Repository(logger)
13+
const usecase = new Usecase(logger, repository)
14+
this.usecase = usecase
15+
}
16+
17+
public loadHttp(http: Http) {
18+
const handler = new Handler(this.logger, http, this.usecase)
19+
this.httpPrivate(http, handler)
20+
}
21+
22+
private httpPrivate(http: Http, handler: Handler) {
23+
const Router = http.Router()
24+
25+
Router.post('/', handler.Store())
26+
Router.get('/', handler.Fetch())
27+
28+
http.SetRouter('/v1/categories', Router)
29+
}
30+
}
31+
32+
export default Category
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import Http from '../../../../transport/http/http'
2+
import Logger from '../../../../pkg/logger'
3+
import Usecase from '../../usecase/usecase'
4+
import { NextFunction, Request, Response } from 'express'
5+
import statusCode from '../../../../pkg/statusCode'
6+
import { GetMeta, GetRequestParams } from '../../../../helpers/requestParams'
7+
import { ValidateFormRequest } from '../../../../helpers/validate'
8+
import { Store } from '../../entity/schema'
9+
10+
class Handler {
11+
constructor(
12+
private logger: Logger,
13+
private http: Http,
14+
private usecase: Usecase
15+
) {}
16+
17+
public Fetch() {
18+
return async (req: Request, res: Response, next: NextFunction) => {
19+
try {
20+
const request = GetRequestParams(req.query)
21+
const { data, count } = await this.usecase.Fetch(request)
22+
this.logger.Info(statusCode[statusCode.OK], {
23+
additional_info: this.http.AdditionalInfo(
24+
req,
25+
statusCode.OK
26+
),
27+
})
28+
29+
return res.json({ data, meta: GetMeta(request, count) })
30+
} catch (error) {
31+
return next(error)
32+
}
33+
}
34+
}
35+
36+
public Store() {
37+
return async (req: any, res: Response, next: NextFunction) => {
38+
try {
39+
const value = ValidateFormRequest(Store, req.body)
40+
const result = await this.usecase.Store(value)
41+
this.logger.Info(statusCode[statusCode.CREATED], {
42+
additional_info: this.http.AdditionalInfo(
43+
req,
44+
statusCode.CREATED
45+
),
46+
})
47+
48+
return res
49+
.status(statusCode.CREATED)
50+
.json({ data: result, message: 'CREATED' })
51+
} catch (error) {
52+
return next(error)
53+
}
54+
}
55+
}
56+
}
57+
58+
export default Handler
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface Store {
2+
name: string
3+
}

src/modules/category/entity/schema.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import Joi from 'joi'
2+
import { RegexSubdomain } from '../../../helpers/regex'
3+
4+
export const Store = Joi.object({
5+
name: Joi.string().regex(RegexSubdomain).required(),
6+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import Logger from '../../../../pkg/logger'
2+
import { RequestParams } from '../../../../helpers/requestParams'
3+
import categorySchema from '../../../../database/mongo/schemas/category.schema'
4+
import { Store } from '../../entity/interface'
5+
6+
class Repository {
7+
constructor(private logger: Logger) {}
8+
9+
public async Fetch({
10+
offset,
11+
limit,
12+
keyword,
13+
sort_order,
14+
sort_by,
15+
}: RequestParams) {
16+
const filter = {}
17+
const sort = {}
18+
19+
if (keyword)
20+
Object.assign(filter, {
21+
name: {
22+
$regex: new RegExp(keyword, 'i'),
23+
},
24+
})
25+
26+
if (['created_at', 'name'].includes(sort_by)) {
27+
Object.assign(sort, {
28+
[sort_by]: sort_order,
29+
})
30+
}
31+
32+
const data = await categorySchema
33+
.find(filter)
34+
.sort(sort)
35+
.skip(offset)
36+
.limit(limit)
37+
const count = await categorySchema.find(filter).count()
38+
39+
return {
40+
data,
41+
count,
42+
}
43+
}
44+
45+
public async Store(body: Store) {
46+
const schemaNew = new categorySchema(body)
47+
48+
return schemaNew.save()
49+
}
50+
51+
public async FindUnique(name: string) {
52+
const result = await categorySchema.findOne({
53+
name,
54+
})
55+
56+
return result
57+
}
58+
}
59+
60+
export default Repository
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { RequestParams } from '../../../helpers/requestParams'
2+
import error from '../../../pkg/error'
3+
import Logger from '../../../pkg/logger'
4+
import statusCode from '../../../pkg/statusCode'
5+
import { Store } from '../entity/interface'
6+
import Repository from '../repository/mongo/repository'
7+
8+
class Usecase {
9+
constructor(private logger: Logger, private repository: Repository) {}
10+
11+
public async Fetch(request: RequestParams) {
12+
return this.repository.Fetch(request)
13+
}
14+
15+
public async Store(body: Store) {
16+
const item = await this.repository.FindUnique(body.name)
17+
if (item)
18+
throw new error(statusCode.BAD_REQUEST, 'Category Already Exist')
19+
const result = await this.repository.Store(body)
20+
21+
return result
22+
}
23+
}
24+
25+
export default Usecase

src/modules/images/usecase/usecase.ts

-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import {
1111
RegexExtensionImage,
1212
} from '../../../helpers/regex'
1313
import FileGenerator from '../../../external/fileGenerator'
14-
import statusCode from '../../../pkg/statusCode'
15-
import error from '../../../pkg/error'
1614

1715
class Usecase {
1816
constructor(

0 commit comments

Comments
 (0)