Skip to content

Commit

Permalink
Merge pull request #1070 from line/dev
Browse files Browse the repository at this point in the history
release: 6.2449.71
  • Loading branch information
jihun authored Dec 5, 2024
2 parents 31fdc4a + ef08568 commit 2563b11
Show file tree
Hide file tree
Showing 22 changed files with 3,350 additions and 3,161 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/publish-api-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Publish Api Docs to GitHub Pages

on:
pull_request:
branches: [main]

jobs:
publish-api-docs:
runs-on: ubuntu-latest

services:
mysql:
image: mysql:8.0.39
env:
MYSQL_ROOT_PASSWORD: userfeedback
MYSQL_DATABASE: userfeedback
MYSQL_USER: userfeedback
MYSQL_PASSWORD: userfeedback
TZ: UTC
ports:
- 13306:3306

steps:
- name: Check out repository code
uses: actions/checkout@v4

- name: Build app and swagger docs
run: |
npx corepack enable
pnpm install --frozen-lockfile
pnpm build
cd apps/api
cp .env.example .env
npx ts-node -r tsconfig-paths/register src/scripts/build-swagger-docs.ts
- name: Run Redocly CLI
uses: fluximus-prime/redocly-cli-github-action@v1
with:
args: "build-docs apps/api/swagger.json --output docs/index.html"

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.18.0
22.11.0
6 changes: 3 additions & 3 deletions GUIDE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ABC User Feedback Guide
# ABC User Feedback Integration Guide

## Image Storage Integration

Expand All @@ -8,13 +8,13 @@ ABC User Feedback supports the integration of image storage solutions to handle

There are two methods for uploading images associated with feedback:

1. **Multipart Upload API**: This method requires setting up the [image configuration](#configuration). Once configured, you can use the multipart upload API to securely upload images directly to your storage service.
1. **Multipart Upload API**: This method requires setting up the [image configuration](#S3-configuration). Once configured, you can use the multipart upload API to securely upload images directly to your storage service.

2. **Feedback Creation API with Image URLs**: Alternatively, users can submit feedback with image URLs. This method does not require the image configuration setup; however, the image URLs must come from the whitelisted domains.

**Note**: For detailed instructions on using these methods, please refer to the API documentation. You can see the documentation by accessing to `{API server host}/docs` or `{API server host}/docs/redoc`.

### Configuration
### S3 Configuration

To enable image uploads directly to the server, you must configure the image storage settings. The service uses the following configuration parameters and you can set them in the setting menu.

Expand Down
35 changes: 26 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ ABC User Feedback is a standalone web application that manages Voice of Customer

![sample image](./assets/main.png)

## Table of Contents

- [Features](#Features)
- [Getting Started](#Getting-Started)
- [Configuration](#configuration)
- [Integration](#Integration)
- [Development](#Development)
- [Contributing](#Contributing-Guidelines)
- [License](#license)


## Features

ABC User Feedback provides the following features:
Expand Down Expand Up @@ -56,21 +67,31 @@ docker pull line/abc-user-feedback-web
docker pull line/abc-user-feedback-api
```

### Configuration
## Configuration

**Frontend**
### Frontend

:point_right: [Go to Frontend README](./apps/web/README.md)

You can configure the frontend for session password, maximum time span to query, etc.

**Backend**
### Backend

:point_right: [Go to Backend README](./apps/api/README.md)

You can configure the backend for MySQL, SMTP for email verification, OpenSearch-powered improved search experience, etc.

## Setup Dev Environment using Command Line Tool without Dependencies
## Integration

If you want to integrate ABC User Feedback with your service, you can use the following features:

1. RESTful Web API - [API document page](https://line.github.io/abc-user-feedback).
1. Accept images from user - [S3 Integration](./GUIDE.md#image-storage-integration).
1. Webhooks - [Webhook specification](./GUIDE.md#Webhook-Feature).

## Development

### Setup Dev Environment using Command Line Tool without Dependencies

ABC User Feedback supports a command line tool(`auf-cli`) that easily runs both the frontend and backend.

Expand All @@ -84,7 +105,7 @@ npx auf-cli stop # stop app

Please refer to the following npm package site: https://www.npmjs.com/package/auf-cli

## Setup Dev Environment Manually (Local)
### Setup Dev Environment Manually (Local)

ABC User Feedback is using a monorepo (powered by [TurboRepo](https://turbo.build/)) with multiple apps and packages.

Expand Down Expand Up @@ -129,10 +150,6 @@ pnpm turbo run dev --filter=web
pnpm turbo run dev --filter=api
```

### ADMIN WEB GUIDE

For detailed information on using the admin web interface, please refer to our [Admin Web Guide](./GUIDE.md).

### Build Docker Image

For your code build, you can build docker image using docker-compose. Please refer to [remote caching](https://turbo.build/repo/docs/core-concepts/remote-caching) and [deploying with docker](https://turbo.build/repo/docs/handbook/deploying-with-docker) using `turborepo`.
Expand Down
10 changes: 5 additions & 5 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"@nestjs/terminus": "^10.2.3",
"@nestjs/typeorm": "^10.0.2",
"@opensearch-project/opensearch": "^2.7.0",
"@swc/cli": "^0.4.0",
"@swc/cli": "^0.5.0",
"@swc/helpers": "^0.5.10",
"@types/passport-jwt": "^4.0.1",
"@types/passport-local": "^1.0.38",
Expand Down Expand Up @@ -74,18 +74,18 @@
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"pino-http": "^10.0.0",
"pino-pretty": "^11.0.0",
"pino-pretty": "^13.0.0",
"prom-client": "^15.1.2",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
"source-map-support": "^0.5.21",
"typeorm": "^0.3.20",
"typeorm-naming-strategies": "^4.1.0",
"typeorm-transactional": "^0.5.0",
"uuid": "^10.0.0"
"uuid": "^11.0.0"
},
"devDependencies": {
"@faker-js/faker": "^8.4.1",
"@faker-js/faker": "^9.0.0",
"@nestjs/cli": "^10.3.2",
"@nestjs/schematics": "^10.1.1",
"@nestjs/testing": "^10.3.8",
Expand All @@ -95,7 +95,7 @@
"@types/express": "^5.0.0",
"@types/jest": "^29.5.12",
"@types/luxon": "^3.4.2",
"@types/node": "20.16.14",
"@types/node": "22.10.1",
"@types/nodemailer": "^6.4.15",
"@types/passport-jwt": "*",
"@types/supertest": "^6.0.2",
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/common/dtos/time-range.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
import { ApiProperty } from '@nestjs/swagger';

export class TimeRange {
@ApiProperty()
@ApiProperty({ name: 'gte (UTC)' })
gte: string;
@ApiProperty()
@ApiProperty({ name: 'lt (UTC)' })
lt: string;
}
2 changes: 2 additions & 0 deletions apps/api/src/domains/api/api.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { APIController } from './api.controller';
import { ChannelController } from './channel.controller';
import { FeedbackController } from './feedback.controller';
import { IssueController } from './issue.controller';
import { ProjectController } from './project.controller';

@Module({
imports: [
Expand Down Expand Up @@ -66,6 +67,7 @@ import { IssueController } from './issue.controller';
IssueController,
APIController,
ChannelController,
ProjectController,
],
})
export class APIModule {}
63 changes: 63 additions & 0 deletions apps/api/src/domains/api/project.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Copyright 2023 LINE Corporation
*
* LINE Corporation licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
import {
Controller,
Get,
Param,
ParseIntPipe,
UseGuards,
} from '@nestjs/common';
import {
ApiOkResponse,
ApiOperation,
ApiParam,
ApiSecurity,
ApiTags,
} from '@nestjs/swagger';

import { ApiKeyAuthGuard } from '@/domains/admin/auth/guards';
import { FindProjectByIdResponseDto } from '../admin/project/project/dtos/responses/find-project-by-id-response.dto';
import { ProjectService } from '../admin/project/project/project.service';

@ApiTags('projects')
@Controller('/projects/:projectId')
@ApiSecurity('apiKey')
@UseGuards(ApiKeyAuthGuard)
export class ProjectController {
constructor(private readonly projectService: ProjectService) {}

@ApiOperation({
summary: 'Get Project Info',
description: 'Retreives a project info by project id.',
})
@ApiParam({
name: 'projectId',
type: Number,
description: 'Project id',
example: 1,
})
@ApiOkResponse({
type: FindProjectByIdResponseDto,
description: 'Project info',
})
@ApiOkResponse({ type: FindProjectByIdResponseDto })
@Get('/')
async getProjectInfo(@Param('projectId', ParseIntPipe) projectId: number) {
return FindProjectByIdResponseDto.transform(
await this.projectService.findById({ projectId }),
);
}
}
50 changes: 50 additions & 0 deletions apps/api/src/scripts/build-swagger-docs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Copyright 2023 LINE Corporation
*
* LINE Corporation licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
import { writeFileSync } from 'fs';
import { NestFactory } from '@nestjs/core';
import type { NestFastifyApplication } from '@nestjs/platform-fastify';
import { FastifyAdapter } from '@nestjs/platform-fastify';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { initializeTransactionalContext } from 'typeorm-transactional';

import { AppModule } from '../app.module';
import { APIModule } from '../domains/api/api.module';

async function generateSwaggerDoc() {
initializeTransactionalContext();
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter({}),
{ bufferLogs: true },
);

const documentConfig = new DocumentBuilder()
.setTitle('User Feedback API Document')
.setDescription(
`You can use this API to integrate with your own service or system. This API is protected by a simple API key authentication, so please do not expose this API to the public. You can make an API key in the admin setting page. You should put the API key in the header with the key name 'x-api-key'.
`,
)
.setVersion('1.0.0')
.addApiKey({ type: 'apiKey', name: 'x-api-key', in: 'header' }, 'apiKey')
.build();
const document = SwaggerModule.createDocument(app, documentConfig, {
include: [APIModule],
});
writeFileSync('./swagger.json', JSON.stringify(document));
await app.close();
}

void generateSwaggerDoc();
2 changes: 1 addition & 1 deletion apps/api/test/feedback/channel.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ describe('AppController (e2e)', () => {

await channelRepo.save(
Array.from({ length: total }).map(() => ({
name: faker.random.word(),
name: faker.word.noun(),
description: faker.lorem.lines(1),
project: { id: project.id },
})),
Expand Down
4 changes: 2 additions & 2 deletions apps/api/test/feedback/feedback.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ describe('AppController (e2e)', () => {
beforeEach(async () => {
await clearEntities([projectRepo, channelRepo, fieldRepo]);
const { id: projectId } = await projectService.create({
name: faker.random.word(),
name: faker.word.noun(),
description: faker.lorem.lines(1),
timezone: {
countryCode: 'KR',
Expand All @@ -97,7 +97,7 @@ describe('AppController (e2e)', () => {

const { id: channelId } = await channelService.create({
projectId,
name: faker.string.alphanumeric(20),
name: faker.word.noun(),
description: faker.lorem.lines(1),
fields: Array.from({
length: faker.number.int({ min: 1, max: 10 }),
Expand Down
Loading

0 comments on commit 2563b11

Please sign in to comment.