Skip to content

Commit bb9e8a7

Browse files
authored
Merge branch 'development' into fix/th-294-user-unlogging-when-server-is-dead
2 parents af3db02 + 35193b2 commit bb9e8a7

File tree

80 files changed

+802
-312
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+802
-312
lines changed

backend/src/libs/enums/enums.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ export {
55
HttpCode,
66
HttpMessage,
77
ServerErrorType,
8+
SortMethod,
89
} from 'shared/build/index.js';
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { type PaginationParameters } from '../types/types.js';
2+
3+
const countOffsetByQuery = ({ page, size }: PaginationParameters): number => {
4+
return page * size;
5+
};
6+
7+
export { countOffsetByQuery };
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {
2+
type AnyColumn,
3+
type SQL,
4+
type SQLWrapper,
5+
asc,
6+
desc,
7+
} from 'drizzle-orm';
8+
9+
import { SortMethod } from '../enums/enums.js';
10+
import { type SortMethodValue } from '../types/types.js';
11+
12+
type ColumnToSorted = SQLWrapper | AnyColumn;
13+
14+
const getSortedBy = (
15+
sortedMethod: SortMethodValue | null,
16+
requiredColumnToSorted: ColumnToSorted,
17+
optionalColumnToSorted: ColumnToSorted,
18+
): SQL[] => {
19+
const sortedBy = [desc(requiredColumnToSorted)];
20+
21+
if (sortedMethod === SortMethod.ASC) {
22+
sortedBy.unshift(asc(optionalColumnToSorted));
23+
}
24+
25+
if (sortedMethod === SortMethod.DESC) {
26+
sortedBy.unshift(desc(optionalColumnToSorted));
27+
}
28+
29+
return sortedBy;
30+
};
31+
32+
export { getSortedBy };
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { countOffsetByQuery } from './count-offset-by-query.helper.js';
2+
export { getSortedBy } from './get-sorted-by.helper.js';
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
ALTER TABLE "trucks"
2+
ADD COLUMN "business_id" integer NOT NULL;
3+
4+
--> statement-breakpoint
5+
DO $$ BEGIN
6+
ALTER TABLE "trucks" ADD CONSTRAINT "trucks_business_id_business_details_id_fk" FOREIGN KEY ("business_id") REFERENCES "business_details"("id") ON DELETE no action ON UPDATE no action;
7+
EXCEPTION
8+
WHEN duplicate_object THEN null;
9+
END $$;

backend/src/libs/packages/database/schema/tables-schema.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,15 @@ const trucks = pgTable(
128128
id: serial('id').primaryKey(),
129129
createdAt: timestamp('created_at').notNull().defaultNow(),
130130
updatedAt: timestamp('updated_at').notNull().defaultNow(),
131+
businessId: integer('business_id')
132+
.notNull()
133+
.references(() => business.id),
131134
manufacturer: varchar('manufacturer').notNull(),
132135
capacity: integer('capacity').notNull(),
133136
pricePerKm: real('price_per_km').notNull(),
134137
licensePlateNumber: varchar('license_plate_number').notNull(),
135138
year: integer('year').notNull(),
136139
towType: varchar('tow_type').notNull(),
137-
businessId: integer('business_id')
138-
.notNull()
139-
.references(() => business.id),
140140
},
141141
(trucks) => {
142142
return {

backend/src/libs/types/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ export {
55
type Id,
66
type NullableProperties,
77
type OperationResult,
8+
type PaginationParameters,
9+
type PaginationWithSortingParameters,
810
type RequireProperty,
911
type ServerCommonErrorResponse,
1012
type ServerValidationErrorResponse,
13+
type SortMethodValue,
1114
type ValidationSchema,
1215
type ValueOf,
1316
} from 'shared/build/index.js';

backend/src/packages/business/business.controller.ts

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
} from '~/libs/packages/controller/controller.js';
77
import { HttpCode } from '~/libs/packages/http/http.js';
88
import { type ILogger } from '~/libs/packages/logger/logger.js';
9+
import { type PaginationWithSortingParameters } from '~/libs/types/types.js';
910
import { AuthStrategy } from '~/packages/auth/libs/enums/enums.js';
1011

1112
import {
@@ -16,6 +17,8 @@ import {
1617
driverCreateUpdateRequestBody,
1718
driverParameters,
1819
} from '../drivers/libs/validation-schemas/validation-schemas.js';
20+
import { type TruckAddRequestDto } from '../trucks/libs/types/types.js';
21+
import { truckCreateRequestBody } from '../trucks/trucks.js';
1922
import { type UserEntityObjectWithGroupT } from '../users/users.js';
2023
import { type BusinessService } from './business.service.js';
2124
import { BusinessApiPath } from './libs/enums/enums.js';
@@ -392,7 +395,23 @@ class BusinessController extends Controller {
392395
handler: (options) =>
393396
this.findAllTrucks(
394397
options as ApiHandlerOptions<{
395-
query: GetPaginatedPageQuery;
398+
query: PaginationWithSortingParameters;
399+
user: UserEntityObjectWithGroupT;
400+
}>,
401+
),
402+
});
403+
404+
this.addRoute({
405+
path: BusinessApiPath.TRUCKS,
406+
method: 'POST',
407+
authStrategy: defaultStrategies,
408+
validation: {
409+
body: truckCreateRequestBody,
410+
},
411+
handler: (request) =>
412+
this.createTruck(
413+
request as ApiHandlerOptions<{
414+
body: TruckAddRequestDto;
396415
user: UserEntityObjectWithGroupT;
397416
}>,
398417
),
@@ -873,11 +892,11 @@ class BusinessController extends Controller {
873892

874893
private async findAllTrucks(
875894
options: ApiHandlerOptions<{
876-
query: GetPaginatedPageQuery;
895+
query: PaginationWithSortingParameters;
877896
user: UserEntityObjectWithGroupT;
878897
}>,
879898
): Promise<ApiHandlerResponse> {
880-
const trucks = await this.businessService.findAllTrucksByOwnerId(
899+
const trucks = await this.businessService.findAllTrucksByBusinessId(
881900
options.user.id,
882901
options.query,
883902
);
@@ -887,6 +906,49 @@ class BusinessController extends Controller {
887906
payload: trucks,
888907
};
889908
}
909+
910+
/**
911+
* @swagger
912+
* /trucks:
913+
* post:
914+
* summary: Create a new truck
915+
* tags:
916+
* - business/trucks
917+
* requestBody:
918+
* description: Truck data to be added
919+
* required: true
920+
* content:
921+
* application/json:
922+
* schema:
923+
* $ref: '#/components/schemas/Truck'
924+
* security:
925+
* - bearerAuth: []
926+
* responses:
927+
* '201':
928+
* description: Truck created successfully
929+
* content:
930+
* application/json:
931+
* schema:
932+
* $ref: '#/components/schemas/TruckResponse'
933+
* '400':
934+
* description: Bad request
935+
*
936+
*/
937+
938+
private async createTruck(
939+
options: ApiHandlerOptions<{
940+
body: TruckAddRequestDto;
941+
user: UserEntityObjectWithGroupT;
942+
}>,
943+
): Promise<ApiHandlerResponse> {
944+
return {
945+
status: HttpCode.CREATED,
946+
payload: await this.businessService.createTruck(
947+
options.body,
948+
options.user.id,
949+
),
950+
};
951+
}
890952
}
891953

892954
export { BusinessController };

backend/src/packages/business/business.service.ts

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { NotFoundError } from '~/libs/exceptions/exceptions.js';
22
import { type IService } from '~/libs/interfaces/interfaces.js';
33
import { HttpCode, HttpError, HttpMessage } from '~/libs/packages/http/http.js';
4-
import { type EntityPagination } from '~/libs/types/types.js';
4+
import { type PaginationWithSortingParameters } from '~/libs/types/types.js';
55
import { UserGroupKey } from '~/packages/users/libs/enums/enums.js';
66

77
import { type DriverService } from '../drivers/driver.service.js';
@@ -12,7 +12,11 @@ import {
1212
type DriverGetAllResponseDto,
1313
} from '../drivers/drivers.js';
1414
import { type ShiftEntity } from '../shifts/shift.js';
15-
import { type TruckEntity } from '../trucks/libs/types/types.js';
15+
import {
16+
type TruckAddRequestDto,
17+
type TruckEntity,
18+
type TruckGetAllResponseDto,
19+
} from '../trucks/libs/types/types.js';
1620
import { type TruckService } from '../trucks/truck.service.js';
1721
import { type UserEntityT } from '../users/users.js';
1822
import { BusinessEntity } from './business.entity.js';
@@ -211,23 +215,26 @@ class BusinessService implements IService {
211215
return await this.driverService.delete(driverId);
212216
}
213217

214-
public checkisDriverBelongedToBusiness({
215-
userId,
216-
driverId,
217-
}: {
218-
userId: UserEntityT['id'];
219-
driverId: ShiftEntity['driverId'];
220-
}): Promise<boolean> {
221-
return this.businessRepository.checkisDriverBelongedToBusiness(
222-
userId,
223-
driverId,
224-
);
218+
public async findAllTrucksByBusinessId(
219+
userId: number,
220+
query: PaginationWithSortingParameters,
221+
): Promise<TruckGetAllResponseDto> {
222+
const business = await this.findByOwnerId(userId);
223+
224+
if (!business) {
225+
throw new HttpError({
226+
status: HttpCode.BAD_REQUEST,
227+
message: HttpMessage.BUSINESS_DOES_NOT_EXIST,
228+
});
229+
}
230+
231+
return await this.truckService.findAllByBusinessId(business.id, query);
225232
}
226233

227-
public async findAllTrucksByOwnerId(
234+
public async createTruck(
235+
payload: TruckAddRequestDto,
228236
userId: number,
229-
query: GetPaginatedPageQuery,
230-
): Promise<EntityPagination<TruckEntity>> {
237+
): Promise<TruckEntity> {
231238
const business = await this.findByOwnerId(userId);
232239

233240
if (!business) {
@@ -237,7 +244,23 @@ class BusinessService implements IService {
237244
});
238245
}
239246

240-
return await this.truckService.findAllByBusinessId(business.id, query);
247+
return await this.truckService.create({
248+
...payload,
249+
businessId: business.id,
250+
});
251+
}
252+
253+
public checkisDriverBelongedToBusiness({
254+
userId,
255+
driverId,
256+
}: {
257+
userId: UserEntityT['id'];
258+
driverId: ShiftEntity['driverId'];
259+
}): Promise<boolean> {
260+
return this.businessRepository.checkisDriverBelongedToBusiness(
261+
userId,
262+
driverId,
263+
);
241264
}
242265
}
243266

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
export { type DriverHaveAccessToTruck } from './driver-have-acces-to-truck.type.js';
22
export { type TruckDatabaseModel } from './truck-entity-type/truck-database-model.type.js';
3-
export { type TruckEntity } from 'shared/build/index.js';
3+
export {
4+
type TruckAddRequestDto,
5+
type TruckEntity,
6+
type TruckGetAllResponseDto,
7+
} from 'shared/build/index.js';

0 commit comments

Comments
 (0)