Skip to content

Commit 1c55b55

Browse files
committed
feat: add date of birth and sex to user model
1 parent a3af0ab commit 1c55b55

6 files changed

Lines changed: 46 additions & 11 deletions

File tree

apps/api/prisma/schema.prisma

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ model UserModel {
164164
lastName String
165165
password String
166166
username String
167+
sex Sex?
168+
dateOfBirth DateTime? @db.Date
167169
}
168170

169171
enum SessionType {

apps/api/src/ability/__tests__/ability.factory.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ describe('AbilityFactory', () => {
1717
userModelStub = {
1818
basePermissionLevel: null,
1919
createdAt: new Date(),
20+
dateOfBirth: null,
2021
firstName: 'Jane',
2122
groupIds: [],
2223
id: '12345',
2324
lastName: 'Doe',
2425
password: 'Password123',
26+
sex: null,
2527
updatedAt: new Date(),
2628
username: 'user'
2729
};

apps/api/src/users/dto/create-user.dto.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { ValidationSchema } from '@douglasneuroinformatics/libnest/core';
22
import { estimatePasswordStrength } from '@douglasneuroinformatics/libpasswd';
33
import { ApiProperty } from '@nestjs/swagger';
4+
import type { Sex } from '@opendatacapture/schemas/subject';
45
import { $CreateUserData } from '@opendatacapture/schemas/user';
5-
import type { BasePermissionLevel } from '@opendatacapture/schemas/user';
6+
import type { BasePermissionLevel, CreateUserData } from '@opendatacapture/schemas/user';
67
import { z } from 'zod';
78

89
@ValidationSchema(
@@ -20,14 +21,17 @@ import { z } from 'zod';
2021
})
2122
})
2223
)
23-
export class CreateUserDto {
24+
export class CreateUserDto implements CreateUserData {
2425
@ApiProperty({
2526
description: "Determines the user's base permissions, which may later be modified by an admin",
2627
enum: ['ADMIN', 'GROUP_MANAGER', 'STANDARD'] satisfies BasePermissionLevel[],
2728
type: String
2829
})
2930
basePermissionLevel: BasePermissionLevel | null;
3031

32+
@ApiProperty({ description: 'Date of Birth' })
33+
dateOfBirth?: Date;
34+
3135
@ApiProperty({ description: 'First Name' })
3236
firstName: string;
3337

@@ -44,6 +48,10 @@ export class CreateUserDto {
4448
})
4549
password: string;
4650

51+
@ApiProperty({ description: 'Sex at Birth' })
52+
@ApiProperty()
53+
sex?: Sex;
54+
4755
@ApiProperty({
4856
description: 'A unique descriptive name associated with this user',
4957
example: 'JaneDoeMemoryClinic'

apps/api/src/users/users.service.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export class UsersService {
3030

3131
/** Adds a new user to the database with default permissions, verifying the provided groups exist */
3232
async create(
33-
{ basePermissionLevel, firstName, groupIds, lastName, password, username }: CreateUserDto,
33+
{ basePermissionLevel, dateOfBirth, firstName, groupIds, lastName, password, sex, username }: CreateUserDto,
3434
options?: EntityOperationOptions
3535
) {
3636
if (await this.userModel.exists({ username })) {
@@ -50,12 +50,14 @@ export class UsersService {
5050
return this.userModel.create({
5151
data: {
5252
basePermissionLevel,
53+
dateOfBirth,
5354
firstName,
5455
groups: {
5556
connect: groupIds.map((id) => ({ id }))
5657
},
5758
lastName,
5859
password: hashedPassword,
60+
sex,
5961
username: username
6062
}
6163
});

apps/web/src/features/admin/pages/CreateUserPage.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,19 @@ export const CreateUserPage = () => {
9494
kind: 'string',
9595
label: t('core.identificationData.lastName.label'),
9696
variant: 'input'
97+
},
98+
sex: {
99+
kind: 'string',
100+
label: t('core.identificationData.sex.label'),
101+
options: {
102+
MALE: t('core.identificationData.sex.male'),
103+
FEMALE: t('core.identificationData.sex.female')
104+
},
105+
variant: 'select'
106+
},
107+
dateOfBirth: {
108+
kind: 'date',
109+
label: t('core.identificationData.dateOfBirth.label')
97110
}
98111
},
99112
title: t({

packages/schemas/src/user/user.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { z } from 'zod';
22

33
import { $BaseModel } from '../core/core.js';
4+
import { $Sex } from '../subject/subject.js';
45

56
export const $BasePermissionLevel = z.enum(['ADMIN', 'GROUP_MANAGER', 'STANDARD']);
67

@@ -9,22 +10,29 @@ export type BasePermissionLevel = z.infer<typeof $BasePermissionLevel>;
910
export type User = z.infer<typeof $User>;
1011
export const $User = $BaseModel.extend({
1112
basePermissionLevel: $BasePermissionLevel.nullable(),
13+
dateOfBirth: z.coerce.date().nullish(),
1214
firstName: z.string().min(1),
1315
groupIds: z.array(z.string()),
1416
lastName: z.string().min(1),
1517
password: z.string().min(1),
18+
sex: $Sex.nullish(),
1619
username: z.string().min(1)
1720
});
1821

1922
export type CreateUserData = z.infer<typeof $CreateUserData>;
20-
export const $CreateUserData = $User.pick({
21-
basePermissionLevel: true,
22-
firstName: true,
23-
groupIds: true,
24-
lastName: true,
25-
password: true,
26-
username: true
27-
});
23+
export const $CreateUserData = $User
24+
.pick({
25+
basePermissionLevel: true,
26+
firstName: true,
27+
groupIds: true,
28+
lastName: true,
29+
password: true,
30+
username: true
31+
})
32+
.extend({
33+
dateOfBirth: z.coerce.date().optional(),
34+
sex: $Sex.optional()
35+
});
2836

2937
export type UpdateUserData = z.infer<typeof $UpdateUserData>;
3038
export const $UpdateUserData = $CreateUserData.partial();

0 commit comments

Comments
 (0)