Skip to content

Commit

Permalink
Merge pull request #20 from yurenju/feat/user-mongo-model
Browse files Browse the repository at this point in the history
feat: implemented user model with mongo integration
  • Loading branch information
yurenju authored Sep 15, 2023
2 parents 5e4232a + 329ee48 commit 9d071e2
Show file tree
Hide file tree
Showing 15 changed files with 1,018 additions and 189 deletions.
3 changes: 2 additions & 1 deletion apps/sample-verifier/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
createWalletClient,
custom,
http,
WalletClient,
} from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { mainnet, goerli } from 'viem/chains';
Expand Down Expand Up @@ -68,7 +69,7 @@ function getMockConnector(chain: Chain) {
return new MockConnector({ options: mockOptions });
}

export function getWalletClient() {
export function getWalletClient(): WalletClient {
const chain = getChain();

if (import.meta.env.MODE === 'e2e') {
Expand Down
1 change: 1 addition & 0 deletions apps/server/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
scripts/init-mongo.js
11 changes: 11 additions & 0 deletions apps/server/scripts/init-mongo.js.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const MONGO_DATABASE = '<MONGO_DATABASE>';
const MONGO_DATABASE_USERNAME = '<MONGO_DATABASE_USERNAME>';
const MONGO_DATABASE_PASSWORD = '<MONGO_DATABASE_PASSWORD>';

db = db.getSiblingDB(MONGO_DATABASE);

db.createUser({
user: MONGO_DATABASE_USERNAME,
pwd: MONGO_DATABASE_PASSWORD,
roles: [{ role: 'readWrite', db: MONGO_DATABASE }],
});
31 changes: 31 additions & 0 deletions apps/server/scripts/start-db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const { join } = require('path');
const shell = require('shelljs');
require('dotenv').config({
path: join(__dirname, '..', '.env.local'),
});

let template = shell.cat(join(__dirname, 'init-mongo.js.template'));
const replaceTerms = [
'MONGO_DATABASE',
'MONGO_DATABASE_USERNAME',
'MONGO_DATABASE_PASSWORD',
];

replaceTerms.forEach((term) => {
template = template.replaceAll(`<${term}>`, process.env[term]);
});

const outputFile = join(__dirname, 'init-mongo.js');
shell.ShellString(template).to(outputFile);

const command = `docker run \
--name ${process.env.MONGO_CONTAINER_NAME} \
-e MONGO_INITDB_ROOT_USERNAME=${process.env.MONGO_INITDB_ROOT_USERNAME} \
-e MONGO_INITDB_ROOT_PASSWORD=${process.env.MONGO_INITDB_ROOT_PASSWORD} \
-p 27017:27017 \
-v ${outputFile}:/docker-entrypoint-initdb.d/init-mongo.js:ro \
mongo`;

shell.exec(`docker stop ${process.env.MONGO_CONTAINER_NAME}`);
shell.exec(`docker rm ${process.env.MONGO_CONTAINER_NAME}`);
shell.exec(command);
25 changes: 24 additions & 1 deletion apps/server/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { ConfigModule, ConfigService } from '@nestjs/config';

import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from '../user/user.module';
import { Config, getConfig } from '../config/configuration';

@Module({
imports: [],
imports: [
ConfigModule.forRoot({
envFilePath: ['.env', '.env.local'],
load: [getConfig],
}),
MongooseModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => {
const host = configService.get<Config>('mongo.host');
const database = configService.get<Config>('mongo.database');
const username = configService.get<Config>('mongo.username');
const password = configService.get<Config>('mongo.password');
return {
uri: `mongodb://${username}:${password}@${host}/${database}`,
};
},
}),
UsersModule,
],
controllers: [AppController],
providers: [AppService],
})
Expand Down
38 changes: 38 additions & 0 deletions apps/server/src/config/configuration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export interface Config {
mongo: {
username: string;
password: string;
host: string;
database: string;
};
}

class PropertyNotFoundError extends Error {
constructor(missingProperties: string[]) {
const missings = missingProperties.join(', ');
super(`The following properties could not be found: ${missings}`);
this.name = 'PropertyNotFoundError';
Object.setPrototypeOf(this, PropertyNotFoundError.prototype);
}
}

export function getConfig(): Config {
const config = {
mongo: {
username: process.env.MONGO_DATABASE_USERNAME,
password: process.env.MONGO_DATABASE_PASSWORD,
host: process.env.MONGO_HOST,
database: process.env.MONGO_DATABASE,
},
};

const missingProperties = Object.keys(config.mongo).filter(
(key) => !config.mongo[key]
);

if (missingProperties.length > 0) {
throw new PropertyNotFoundError(missingProperties);
}

return config;
}
3 changes: 3 additions & 0 deletions apps/server/src/user/create-user.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export class CreateUserDto {
nationalId: string;
}
12 changes: 12 additions & 0 deletions apps/server/src/user/schemas/user.schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';

export type UserDocument = HydratedDocument<User>;

@Schema()
export class User {
@Prop({ required: true })
nationalId: string;
}

export const UserSchema = SchemaFactory.createForClass(User);
19 changes: 19 additions & 0 deletions apps/server/src/user/user.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Body, Controller, Get, Post } from '@nestjs/common';
import { User } from './schemas/user.schema';
import { UsersService } from './user.service';
import { CreateUserDto } from './create-user.dto';

@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}

@Post()
create(@Body() createUserDto: CreateUserDto) {
this.usersService.create(createUserDto);
}

@Get()
findAll(): Promise<User[]> {
return this.usersService.findAll();
}
}
14 changes: 14 additions & 0 deletions apps/server/src/user/user.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from './schemas/user.schema';
import { UsersController } from './user.controller';
import { UsersService } from './user.service';

@Module({
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
],
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}
27 changes: 27 additions & 0 deletions apps/server/src/user/user.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Injectable, OnModuleInit } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { User } from './schemas/user.schema';
import { CreateUserDto } from './create-user.dto';
import { Model } from 'mongoose';

@Injectable()
export class UsersService implements OnModuleInit {
constructor(@InjectModel(User.name) private userModel: Model<User>) {}

async create(createUserDto: CreateUserDto): Promise<User> {
const createdUser = new this.userModel(createUserDto);
return createdUser.save();
}

async findAll(): Promise<User[]> {
return this.userModel.find().exec();
}

async onModuleInit() {
const count = await this.userModel.count();
if (count === 0) {
const dto: CreateUserDto = { nationalId: 'A123456789' };
return this.create(dto);
}
}
}
Loading

0 comments on commit 9d071e2

Please sign in to comment.