Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoleamber committed Sep 1, 2023
1 parent b360a8d commit c2d3081
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 34 deletions.
26 changes: 26 additions & 0 deletions server/src/api/jobs/job.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
import { PartialType } from '@nestjs/mapped-types';
import { ApiProperty } from '@nestjs/swagger';
import { Status, Tag } from '@prisma/client';
import { Transform } from 'class-transformer';
import { IsString } from 'class-validator';

export class CreateJobDto {}

export class UpdateJobDto extends PartialType(CreateJobDto) {}

export class JobQueryDto {
@ApiProperty({ required: false })
@IsString()
search: string;

@ApiProperty({ required: false })
@IsString()
tag: Tag;

@ApiProperty({ required: false })
@IsString()
status: Status;

@ApiProperty({ required: false })
@Transform(({ value }) => new Date(value).getTime())
startDate: Date;

@ApiProperty({ required: false })
@Transform(({ value }) => new Date(value).getTime())
endDate: Date;
}
8 changes: 7 additions & 1 deletion server/src/api/jobs/job.entity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { Job, PaymentMethod, Schedule, Tag } from '@prisma/client';
import { Estimation, Job, PaymentMethod, Schedule, Tag } from '@prisma/client';

export class JobEntity implements Job {
@ApiProperty()
Expand Down Expand Up @@ -29,9 +29,15 @@ export class JobEntity implements Job {
@ApiProperty({ nullable: true })
schedules: Schedule[]

@ApiProperty({nullable: true})
estimation: Estimation

@ApiProperty()
createdAt: Date;

@ApiProperty()
updatedAt: Date;

@ApiProperty({ nullable: true })
createdAtTimestamp: number;
}
15 changes: 6 additions & 9 deletions server/src/api/jobs/jobs.controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Controller, Get, Query } from '@nestjs/common';
import { ApiOkResponse, ApiQuery, ApiTags } from '@nestjs/swagger';
import { ApiOkResponse, ApiTags } from '@nestjs/swagger';
import { JobQueryDto } from './job.dto';
import { JobEntity } from './job.entity';
import { JobsService } from './jobs.service';

Expand All @@ -9,14 +10,10 @@ export class JobsController {
constructor(private readonly jobsService: JobsService) {}

@ApiOkResponse({ type: JobEntity, isArray: true })
@ApiQuery({
name: 'search',
required: false,
type: String,
description: "Optional search keyword"
})
@Get()
async findAll(@Query('search') search: string) {
return await this.jobsService.findAll(search);
async findAll(
@Query() jobFilter: JobQueryDto,
) {
return await this.jobsService.findAll(jobFilter);
}
}
32 changes: 22 additions & 10 deletions server/src/api/jobs/jobs.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
import { Job } from '@prisma/client';
import { PrismaService } from 'src/database/connection.service';
import { SearchService } from '../search/search.service';
import { JobQueryDto } from './job.dto';

@Injectable()
export class JobsService {
Expand All @@ -10,17 +11,28 @@ export class JobsService {
private searchService: SearchService
){}

async findAll(search?: string): Promise<Job[] | null> {
let jobs: Job[] = [];
async findAll(query?: JobQueryDto): Promise<Job[] | null> {
const jobs = await this.prisma.job.findMany({
include: {
estimation: {
select: {
status: true
}
}
}
});

jobs = await this.prisma.job.findMany();
await this.searchService.addDocuments(jobs);

if (search) {
const results = await this.searchService.search(search);
jobs = results.hits.map((hit) => hit._formatted as Job);
}
const documents = jobs.map((job: Job) => {
const date = job.createdAt
job['createdAtTimestamp'] = new Date(date.setHours(0, 0, 0, 0)).getTime();
return job;
})

return jobs;
console.log(new Date(query.startDate).getTime())

await this.searchService.addDocuments(documents);

const results = await this.searchService.search(query);
return results.hits.map((hit) => hit._formatted as Job);
}
}
65 changes: 55 additions & 10 deletions server/src/api/search/search.service.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,52 @@
import { Injectable } from '@nestjs/common';
import { Job } from '@prisma/client';
import { EnqueuedTask, Index, MeiliSearch, SearchResponse } from 'meilisearch';
import { JobQueryDto } from '../jobs/job.dto';

@Injectable()
export class SearchService {
private SearchClient: MeiliSearch;
private readonly searchClient: MeiliSearch;

constructor() {
this.SearchClient = new MeiliSearch({
this.searchClient = new MeiliSearch({
host: 'http://meilisearch:7700',
})
});

this.SearchClient.createIndex('jobs', { primaryKey: 'id'})
this.initIndex();
}

private async initIndex(): Promise<void> {
try {
await this.searchClient.createIndex('jobs', { primaryKey: 'id' });

const index = this.searchClient.index('jobs');
await index.updateSettings({
searchableAttributes: ['title'],
filterableAttributes: ['tags', 'estimation.status', 'createdAtTimestamp'],
rankingRules: [
'words',
'proximity',
'exactness'
],
typoTolerance: {
enabled: false
},
})
} catch(e) {
console.log('Error initializing index', e);
throw e;
}
}

private getIndex(): Index {
return this.SearchClient.index('jobs');
return this.searchClient.index('jobs');
}

async addDocuments(docs: Job[]): Promise<EnqueuedTask> {
const index = this.getIndex();

const i = await index.getSettings();
console.log(i);

try {
return await index.addDocuments(docs);
Expand All @@ -29,15 +56,33 @@ export class SearchService {
}
}

async search(query: string): Promise<SearchResponse> {
async search(query: JobQueryDto): Promise<SearchResponse> {
const index = this.getIndex();
let tagFilter = '';
let statusFilter = '';
let dateFilter = '';

const { search, tag, status, startDate, endDate } = query;

console.log(query);

if (tag) {
tagFilter = `tags = ${tag}`;
}

if (status) {
statusFilter = `estimation.status = ${status}`;
}

if (startDate && endDate) {
dateFilter = `createdAtTimestamp >= ${startDate} AND createdAtTimestamp <= ${endDate}`;
}

return await index.searchGet(
query,
return await index.search(
search,
{
attributesToHighlight: ['title'],
attributesToSearchOn: ['title'],
attributesToRetrieve: ['*'],
filter: [tagFilter, statusFilter, dateFilter],
}
);
}
Expand Down
18 changes: 18 additions & 0 deletions server/src/models/data/estimation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { faker } from '@faker-js/faker';
import { Status } from '@prisma/client';

const estimations = [];
const status = Object.values(Status);

for (let i = 0; i < 10; i ++) {
const j = i + 1
estimations.push({
id: j,
title: faker.lorem.word(),
document: faker.system.commonFileName('pdf'),
status: faker.helpers.arrayElement(status),
jobId: j,
})
}

export { estimations };
6 changes: 4 additions & 2 deletions server/src/models/data/jobs.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { faker } from '@faker-js/faker';
import { PaymentMethod } from '@prisma/client';
import { PaymentMethod, Tag } from '@prisma/client';

const jobs = [];
const paymentMethod = Object.values(PaymentMethod);
const tags = Object.values(Tag);

for (let i = 0; i < 20; i ++) {
const j = i + 1;
Expand All @@ -12,7 +13,8 @@ for (let i = 0; i < 20; i ++) {
type: faker.lorem.word(),
personInChargeId: faker.number.int({ min: 1, max: 10 }),
customerId: j,
paymentMethod: faker.helpers.arrayElement(paymentMethod)
paymentMethod: faker.helpers.arrayElement(paymentMethod),
tags: faker.helpers.arrayElements(tags, {min: 0, max: 3}),
})
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-- CreateEnum
CREATE TYPE "Status" AS ENUM ('NOT_YET_CREATED', 'MAKING', 'APPROVED', 'SENT_TO_CUSTOMER', 'CLOSED');

-- CreateTable
CREATE TABLE "Estimation" (
"id" SERIAL NOT NULL,
"title" TEXT NOT NULL,
"document" TEXT NOT NULL,
"status" "Status" NOT NULL,
"jobId" INTEGER NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "Estimation_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "Estimation_jobId_key" ON "Estimation"("jobId");

-- AddForeignKey
ALTER TABLE "Estimation" ADD CONSTRAINT "Estimation_jobId_fkey" FOREIGN KEY ("jobId") REFERENCES "Job"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
20 changes: 20 additions & 0 deletions server/src/models/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ model Job {
paymentMethod PaymentMethod
tags Tag[]
schedules Schedule[]
estimation Estimation?
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
}
Expand Down Expand Up @@ -61,6 +62,17 @@ model Schedule {
updatedAt DateTime @default(now())
}

model Estimation {
id Int @id @default(autoincrement())
title String
document String
status Status
job Job @relation(fields: [jobId], references: [id])
jobId Int @unique
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
}

enum Role {
USER
ADMIN
Expand All @@ -77,3 +89,11 @@ enum PaymentMethod {
CARD
BANK_TRANSFER
}

enum Status {
NOT_YET_CREATED
MAKING
APPROVED
SENT_TO_CUSTOMER
CLOSED
}
10 changes: 8 additions & 2 deletions server/src/models/seed.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { PrismaClient } from '@prisma/client';
import { customers } from './data/customers';
import { estimations } from './data/estimation';
import { jobs } from './data/jobs';
import { users } from './data/users';

const prisma = new PrismaClient();

const load = async () => {
const seed = async () => {
try {
await prisma.$transaction([
prisma.estimation.deleteMany(),
prisma.job.deleteMany(),
prisma.user.deleteMany(),
prisma.customer.deleteMany(),
Expand All @@ -23,6 +25,10 @@ const load = async () => {
prisma.job.createMany({
data: jobs
}),

prisma.estimation.createMany({
data: estimations
})
]);
} catch (error) {
console.log('Error seeding database');
Expand All @@ -32,4 +38,4 @@ const load = async () => {
}
}

load();
seed();

0 comments on commit c2d3081

Please sign in to comment.