From feab36fa4207fc9ffa89c19628378e2aaf2ed544 Mon Sep 17 00:00:00 2001 From: Ren Adachi <49895682+moeyashi@users.noreply.github.com> Date: Sat, 16 Mar 2024 15:00:57 +0900 Subject: [PATCH 1/5] chore: update .dockerignore Signed-off-by: Ren Adachi <49895682+moeyashi@users.noreply.github.com> --- .dockerignore | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.dockerignore b/.dockerignore index 85fa9b4..b97a372 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,10 @@ -# flyctl launch added from .gitignore -node_modules -**\.env +.github/ +node_modules/ +wr-python/ +**/.env* +.eslint* +.git* fly.toml +**/*.md +schema.hcl +**/*.test.* From c51953afa2d6f11924867d7211ad8afdef2c9dee Mon Sep 17 00:00:00 2001 From: Ren Adachi <49895682+moeyashi@users.noreply.github.com> Date: Sun, 17 Mar 2024 11:27:31 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat(selectRanking):=20limit=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=20#61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ren Adachi <49895682+moeyashi@users.noreply.github.com> --- package.json | 4 +++ src/infra/repository/nita.js | 16 +++++----- src/infra/repository/nita.test.js | 49 +++++++++++++++++++++++++++++++ src/types.d.ts | 6 +++- vite.config.ts | 12 ++++++++ 5 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 src/infra/repository/nita.test.js create mode 100644 vite.config.ts diff --git a/package.json b/package.json index 8025e6e..48f4f35 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,10 @@ "type": "module", "scripts": { "lint": "eslint .", + "db:run": "docker run --name mk8d-nita-record-db -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres -e POSTGRES_DB=postgres -p 25432:5432 -d postgres", + "db:migrate": "atlas schema apply --url \"postgres://postgres:postgres@localhost:25432?sslmode=disable\" --file schema.hcl --auto-approve", + "db:clean": "atlas schema clean --url \"postgres://postgres:postgres@localhost:25432?sslmode=disable\" --auto-approve", + "db:reset": "npm run db:clean && npm run db:migrate", "test": "vitest", "start": "node .", "deploy:commands": "node ./src/deploy-commands.js" diff --git a/src/infra/repository/nita.js b/src/infra/repository/nita.js index 024c47e..10f47d1 100644 --- a/src/infra/repository/nita.js +++ b/src/infra/repository/nita.js @@ -18,7 +18,7 @@ export const postgresNitaRepository = () => { host: process.env.DATABASE_HOST, username: process.env.DATABASE_USERNAME, password: process.env.DATABASE_PASSWORD, - port: 5432, + port: Number(process.env.DATABASE_PORT || '5432'), }; const sql = postgres(config); @@ -88,15 +88,15 @@ export const postgresNitaRepository = () => { lastMilliseconds: row.last_milliseconds, })); }, - /** - * @param {string} trackCode - * @param {import('discord.js').GuildMember[]} discordMembers - * @returns {Promise<{member: import('discord.js').GuildMember, milliseconds: number}[]>} - */ - async selectRanking(trackCode, discordMembers) { + async selectRanking(trackCode, discordMembers, limit = 20) { const discordUserIds = discordMembers.map((member) => member.user.id); const results = await sql` - SELECT discord_user_id, milliseconds FROM nita WHERE discord_user_id IN ${sql(discordUserIds)} AND track_code = ${trackCode} ORDER BY milliseconds ASC + SELECT discord_user_id, milliseconds + FROM nita + WHERE discord_user_id IN ${sql(discordUserIds)} + AND track_code = ${trackCode} + ORDER BY milliseconds ASC + LIMIT ${limit} `; return results.map((row) => ({ member: discordMembers.find(member => member.user.id === row.discord_user_id) || discordMembers[0], diff --git a/src/infra/repository/nita.test.js b/src/infra/repository/nita.test.js new file mode 100644 index 0000000..6d75ff8 --- /dev/null +++ b/src/infra/repository/nita.test.js @@ -0,0 +1,49 @@ +import { execSync } from 'child_process'; +import { expect, test, describe, beforeAll } from 'vitest'; +import { postgresNitaRepository } from './nita.js'; + +describe('postgresNitaRepository', () => { + const repo = postgresNitaRepository(); + describe('selectRanking', async () => { + const trackCode = 'MKS'; + const users = Array.from({ length: 21 }).map((_, i) => ({ + user: { id: `${i + 1}` }, + })); + beforeAll(async () => { + execSync('npm run db:reset'); + for (const i of users) { + await repo.insertNita({ + discordUserId: i.user.id, + trackCode, + milliseconds: i.user.id === '2' ? 99999 : 1000 + Number(i.user.id), + }); + } + }); + + test('上位20名が取得されること', async () => { + const ranking = await repo.selectRanking(trackCode, users); + expect(ranking).toEqual([ + { member: { user: { id: '1' } }, milliseconds: 1001 }, + { member: { user: { id: '3' } }, milliseconds: 1003 }, + { member: { user: { id: '4' } }, milliseconds: 1004 }, + { member: { user: { id: '5' } }, milliseconds: 1005 }, + { member: { user: { id: '6' } }, milliseconds: 1006 }, + { member: { user: { id: '7' } }, milliseconds: 1007 }, + { member: { user: { id: '8' } }, milliseconds: 1008 }, + { member: { user: { id: '9' } }, milliseconds: 1009 }, + { member: { user: { id: '10' } }, milliseconds: 1010 }, + { member: { user: { id: '11' } }, milliseconds: 1011 }, + { member: { user: { id: '12' } }, milliseconds: 1012 }, + { member: { user: { id: '13' } }, milliseconds: 1013 }, + { member: { user: { id: '14' } }, milliseconds: 1014 }, + { member: { user: { id: '15' } }, milliseconds: 1015 }, + { member: { user: { id: '16' } }, milliseconds: 1016 }, + { member: { user: { id: '17' } }, milliseconds: 1017 }, + { member: { user: { id: '18' } }, milliseconds: 1018 }, + { member: { user: { id: '19' } }, milliseconds: 1019 }, + { member: { user: { id: '20' } }, milliseconds: 1020 }, + { member: { user: { id: '21' } }, milliseconds: 1021 }, + ]); + }); + }); +}); diff --git a/src/types.d.ts b/src/types.d.ts index 4deaaf5..e0acf3d 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -8,6 +8,9 @@ import type { export type EventType = keyof ClientEvents; +type InsertNitaParameters = Nita; +type UpdateNitaParameters = Nita; + export type NitaRepository = { insertNita: (params: InsertNitaParameters) => Promise; updateNita: (params: UpdateNitaParameters) => Promise; @@ -19,7 +22,8 @@ export type NitaRepository = { selectNitaByUser: (discordUserId: string) => Promise; selectRanking: ( trackCode: string, - discordMembers: GuildMember[] + discordMembers: GuildMember[], + limit?: number ) => Promise<{ member: GuildMember; milliseconds: number }[]>; }; diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..29cfefc --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + env: { + DATABASE_HOST: "localhost", + DATABASE_PORT: "25432", + DATABASE_USERNAME: "postgres", + DATABASE_PASSWORD: "postgres", + }, + }, +}); From 8d05b2eb21e99bbb1d2b4d8a4517a2f78146fcea Mon Sep 17 00:00:00 2001 From: Ren Adachi <49895682+moeyashi@users.noreply.github.com> Date: Sun, 17 Mar 2024 11:35:43 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat(/ranking):=20temp=20message=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E8=A8=98=20#61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ren Adachi <49895682+moeyashi@users.noreply.github.com> --- src/slash-command/ranking.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slash-command/ranking.js b/src/slash-command/ranking.js index 4b1090c..f1f4086 100644 --- a/src/slash-command/ranking.js +++ b/src/slash-command/ranking.js @@ -47,7 +47,7 @@ export default { const groupedRanking = groppByRank(track, ranking); await interaction.followUp({ - content: `NITAランキング - ${track.trackName}`, + content: `## NITAランキング - ${track.trackName}\n※一時的に上位20名までを出力しています`, embeds: groupedRanking.flatMap(([rank, color, nita]) => { /** @type {import('discord.js').APIEmbed[]} */ const embeds = []; From 04b1d13ab2df7bcdbb9ddc45cdfc18b475077636 Mon Sep 17 00:00:00 2001 From: Ren Adachi <49895682+moeyashi@users.noreply.github.com> Date: Sun, 17 Mar 2024 11:38:59 +0900 Subject: [PATCH 4/5] =?UTF-8?q?chore:=20track.js=E3=81=A0=E3=81=91?= =?UTF-8?q?=E3=81=A7=E3=81=AA=E3=81=8F=E3=81=99=E3=81=B9=E3=81=A6=E3=81=AE?= =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E3=82=92=E3=81=99=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ren Adachi <49895682+moeyashi@users.noreply.github.com> --- .github/workflows/test-track-js.yml | 17 ----------------- .github/workflows/test.yml | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 17 deletions(-) delete mode 100644 .github/workflows/test-track-js.yml create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test-track-js.yml b/.github/workflows/test-track-js.yml deleted file mode 100644 index 0f88b5f..0000000 --- a/.github/workflows/test-track-js.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Test Track.js - -on: - pull_request: - -jobs: - test: - runs-on: ubuntu-latest - # https://github.com/peter-evans/create-pull-request/tree/v6/#:~:text=request%20branch%20name.-,create%2Dpull%2Drequest/patch,-delete%2Dbranch - if: ${{ github.head_ref == 'create-pull-request/patch' }} - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - cache: "npm" - - run: npm install - - run: npm test run src/const/track.test.js diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..e0faa04 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,25 @@ +name: Test + +on: + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + services: + postgres: + image: postgres + # refer: https://hub.docker.com/_/postgres + env: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + POSTGRES_DB: postgres + ports: + - 25432:5432 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + cache: "npm" + - run: npm install + - run: npm test run From 973efbf4006ef89f81b39a82c3ccf1cee6fbfc31 Mon Sep 17 00:00:00 2001 From: Ren Adachi <49895682+moeyashi@users.noreply.github.com> Date: Sun, 17 Mar 2024 11:41:44 +0900 Subject: [PATCH 5/5] =?UTF-8?q?chore:=20github=20actions=E3=81=A7atlas?= =?UTF-8?q?=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89=E3=81=8C=E4=BD=BF=E3=81=88?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ren Adachi <49895682+moeyashi@users.noreply.github.com> --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e0faa04..869a9c2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,6 +18,7 @@ jobs: - 25432:5432 steps: - uses: actions/checkout@v4 + - uses: ariga/setup-atlas@master - uses: actions/setup-node@v4 with: cache: "npm"