Skip to content

Commit

Permalink
feat: create project/channel (#73)
Browse files Browse the repository at this point in the history
* feat: create project page

* impl: wireframe

* impl: ui

* feat: input type

* impl: create project feature

* impl: create channel and project ui

* impl: create project channel

* impl: shared pacakge

* impl: create project channel

* impl: input hint

* impl: change validation method

* impl: i18n

* impl: fix test user find-by-id

* impl: permission

* fix: tooltip

* fix: create channel tooltip

* fix: remove env validation while api test

* fix: turbo command
  • Loading branch information
chiol authored Nov 17, 2023
1 parent f02617e commit c0b0e96
Show file tree
Hide file tree
Showing 183 changed files with 6,224 additions and 1,045 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@ yarn-error.log*

volumes

dist
dist

tsconfig.tsbuildinfo
Empty file removed .turbo/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@nestjs/terminus": "^10.1.1",
"@nestjs/typeorm": "^10.0.0",
"@opensearch-project/opensearch": "^2.4.0",
"@ufb/shared": "^0.1.0",
"@willsoto/nestjs-prometheus": "^6.0.0",
"axios": "^1.5.1",
"bcrypt": "^5.1.1",
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/common/repositories/large-window.exception.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class LargeWindowException extends BadRequestException {
constructor(message: string) {
Expand Down
6 changes: 6 additions & 0 deletions apps/api/src/constants/error-code.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ const Project = {
ProjectNotFound: 'ProjectNotFound',
ProjectInvalidName: 'ProjectInvalidName',
};

const Channel = {
ChannelAlreadyExists: 'ChannelAlreadyExists',
ChannelNotFound: 'ChannelNotFound',
ChannelInvalidName: 'ChannelInvalidName',
};

const Issue = {
IssueNameDuplicated: 'IssueNameDuplicated',
IssueInvalidName: 'IssueInvalidName',
Expand All @@ -73,20 +75,24 @@ const Option = {
OptionNameDuplicated: 'OptionNameDuplicated',
OptionKeyDuplicated: 'OptionKeyDuplicated',
};

const Feedback = {
InvalidExpressionFormat: 'InvalidExpressionFormat',
InvalidFieldType: 'InvalidFieldType',
InvalidFieldRequest: 'InvalidFieldRequest',
NotFoundAddressInfo: 'NotFoundAddressInfo',
};

const Member = {
MemberAlreadyExists: 'MemberAlreadyExists',
MemberNotFound: 'MemberNotFound',
MemberUpdateRoleNotMatchedProject: 'MemberUpdateRoleNotMatchedProject ',
};

const Opensearch = {
LargeWindow: 'LargeWindow',
};

export const ErrorCode = {
Tenant,
Role,
Expand Down
18 changes: 9 additions & 9 deletions apps/api/src/domains/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* under the License.
*/
import { HttpModule } from '@nestjs/axios';
import { Module } from '@nestjs/common';
import { forwardRef, Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
Expand All @@ -34,14 +34,14 @@ import { LocalStrategy } from './strategies/local.strategy';

@Module({
imports: [
CodeModule,
UserModule,
PassportModule,
MailingModule,
ApiKeyModule,
TenantModule,
RoleModule,
MemberModule,
forwardRef(() => CodeModule),
forwardRef(() => UserModule),
forwardRef(() => PassportModule),
forwardRef(() => MailingModule),
forwardRef(() => ApiKeyModule),
forwardRef(() => TenantModule),
forwardRef(() => RoleModule),
forwardRef(() => MemberModule),
HttpModule.register({
timeout: 5000,
maxRedirects: 5,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { UnauthorizedException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class PasswordNotMatchException extends UnauthorizedException {
constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { UnauthorizedException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class UserBlockedException extends UnauthorizedException {
constructor() {
Expand Down
10 changes: 10 additions & 0 deletions apps/api/src/domains/channel/channel/channel.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
Post,
Put,
Query,
UseGuards,
} from '@nestjs/common';
import {
ApiCreatedResponse,
Expand All @@ -31,6 +32,7 @@ import {
ApiTags,
} from '@nestjs/swagger';

import { JwtAuthGuard } from '@/domains/auth/guards';
import { PermissionEnum } from '@/domains/project/role/permission.enum';
import { RequirePermission } from '@/domains/project/role/require-permission.decorator';
import { ChannelService } from './channel.service';
Expand Down Expand Up @@ -82,6 +84,14 @@ export class ChannelController {
}),
);
}
@UseGuards(JwtAuthGuard)
@Get('/name-check')
async checkName(
@Param('projectId', ParseIntPipe) projectId: number,
@Query('name') name: string,
) {
return this.channelService.checkName({ projectId, name });
}

@ApiParam({ name: 'projectId', type: Number })
@RequirePermission(PermissionEnum.channel_read)
Expand Down
11 changes: 10 additions & 1 deletion apps/api/src/domains/channel/channel/channel.mysql.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ import { Transactional } from 'typeorm-transactional';

import { isSelectFieldFormat } from '@/common/enums';
import { ChannelEntity } from './channel.entity';
import type { FindAllChannelsByProjectIdDto, FindByChannelIdDto } from './dtos';
import type {
FindAllChannelsByProjectIdDto,
FindByChannelIdDto,
FindOneByNameAndProjectIdDto,
} from './dtos';
import { CreateChannelDto, UpdateChannelDto } from './dtos';
import {
ChannelAlreadyExistsException,
Expand All @@ -35,6 +39,11 @@ export class ChannelMySQLService {
@InjectRepository(ChannelEntity)
private readonly repository: Repository<ChannelEntity>,
) {}
async findOneBy({ name, projectId }: FindOneByNameAndProjectIdDto) {
return await this.repository.findOne({
where: { name, project: { id: projectId } },
});
}

@Transactional()
async create(dto: CreateChannelDto) {
Expand Down
11 changes: 10 additions & 1 deletion apps/api/src/domains/channel/channel/channel.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ import { OpensearchRepository } from '@/common/repositories';
import { ProjectService } from '@/domains/project/project/project.service';
import { FieldService } from '../field/field.service';
import { ChannelMySQLService } from './channel.mysql.service';
import type { FindAllChannelsByProjectIdDto, FindByChannelIdDto } from './dtos';
import type {
FindAllChannelsByProjectIdDto,
FindByChannelIdDto,
FindOneByNameAndProjectIdDto,
} from './dtos';
import {
CreateChannelDto,
UpdateChannelDto,
Expand All @@ -38,6 +42,11 @@ export class ChannelService {
private readonly configService: ConfigService,
) {}

async checkName(dto: FindOneByNameAndProjectIdDto) {
const res = await this.channelMySQLService.findOneBy(dto);
return !!res;
}

@Transactional()
async create(dto: CreateChannelDto) {
await this.projectService.findById({ projectId: dto.projectId });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
import { useContext } from 'react';

import { UserContext } from '@/contexts/user.context';

export default function useUser() {
return useContext(UserContext);
export class FindOneByNameAndProjectIdDto {
name: string;
projectId: number;
}
1 change: 1 addition & 0 deletions apps/api/src/domains/channel/channel/dtos/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ export { CreateChannelDto } from './create-channel.dto';
export { UpdateChannelDto } from './update-channel.dto';
export { FindByChannelIdDto } from './find-by-channel-id.dto';
export { UpdateChannelFieldsDto } from './update-channel-fields.dto';
export { FindOneByNameAndProjectIdDto } from './find-one-by-name-and-project-id.dto';
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
ArrayNotEmpty,
IsEnum,
IsNumber,
IsOptional,
Expand Down Expand Up @@ -88,7 +87,7 @@ export class CreateChannelRequestFieldDto {
export class CreateChannelRequestDto {
@ApiProperty()
@IsString()
@MinLength(2)
@MinLength(1)
name: string;

@ApiProperty({ nullable: true })
Expand All @@ -99,6 +98,5 @@ export class CreateChannelRequestDto {
@ApiProperty({ type: [CreateChannelRequestFieldDto] })
@Type(() => CreateChannelRequestFieldDto)
@ValidateNested({ each: true })
@ArrayNotEmpty()
fields: CreateChannelRequestFieldDto[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { IsNullable } from '@/domains/user/decorators';
export class UpdateChannelRequestDto {
@ApiProperty()
@IsString()
@MinLength(2)
@MinLength(1)
name: string;

@ApiProperty({ nullable: true })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class ChannelAlreadyExistsException extends BadRequestException {
constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class ChannelInvalidNameException extends BadRequestException {
constructor(description: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class ChannelNotFoundException extends BadRequestException {
constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class FieldKeyDuplicatedException extends BadRequestException {
constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class FieldNameDuplicatedException extends BadRequestException {
constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class OptionKeyDuplicatedException extends BadRequestException {
constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class OptionNameDuplicatedException extends BadRequestException {
constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ import { IsString, MinLength } from 'class-validator';
export class CreateIssueRequestDto {
@ApiProperty()
@IsString()
@MinLength(2)
@MinLength(1)
name: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class IssueInvalidNameException extends BadRequestException {
constructor(description: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class IssueNameDuplicatedException extends BadRequestException {
constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class IssueNotFoundException extends BadRequestException {
constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class MemberAlreadyExistsException extends BadRequestException {
constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class InvalidFieldTypeException extends BadRequestException {
constructor(fieldType: string) {
export class MemberInvalidUserException extends BadRequestException {
constructor() {
super({
code: ErrorCode.Feedback.InvalidFieldType,
message: 'Invalid Field Type : ' + fieldType,
code: ErrorCode.Member.MemberInvalidUser,
message: '',
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class MemberNotFoundException extends BadRequestException {
constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { BadRequestException } from '@nestjs/common';

import { ErrorCode } from '@/constants/error-code.enum';
import { ErrorCode } from '@ufb/shared';

export class MemberUpdateRoleNotMatchedProjectException extends BadRequestException {
constructor() {
Expand Down
Loading

0 comments on commit c0b0e96

Please sign in to comment.