From 7340d879cf4ea11c2f0912d422698555b228556d Mon Sep 17 00:00:00 2001 From: Myxogastria0808 Date: Sat, 10 Jan 2026 06:32:17 +0900 Subject: [PATCH 1/6] wip --- products/backend/src/presentation/routes/group.ts | 2 +- products/backend/src/presentation/routes/info.ts | 2 +- products/backend/src/presentation/routes/userProfile.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/products/backend/src/presentation/routes/group.ts b/products/backend/src/presentation/routes/group.ts index 4d5ac4a..835ecbc 100644 --- a/products/backend/src/presentation/routes/group.ts +++ b/products/backend/src/presentation/routes/group.ts @@ -560,7 +560,7 @@ const deleteGroupDebtSchema = route.createSchema( }, responses: { 200: { - description: 'Created', + description: 'Deleted', content: { 'application/json': { schema: deleteGroupDebtResponseSchema, diff --git a/products/backend/src/presentation/routes/info.ts b/products/backend/src/presentation/routes/info.ts index 0634a47..10c2aab 100644 --- a/products/backend/src/presentation/routes/info.ts +++ b/products/backend/src/presentation/routes/info.ts @@ -262,7 +262,7 @@ const infoUserRepaymentSchema = route.createSchema( }, responses: { 200: { - description: 'Created', + description: 'Deleted', content: { 'application/json': { schema: deleteInfoAboutUserRepaymentResponseSchema, diff --git a/products/backend/src/presentation/routes/userProfile.ts b/products/backend/src/presentation/routes/userProfile.ts index 5fa3170..7b7f2f1 100644 --- a/products/backend/src/presentation/routes/userProfile.ts +++ b/products/backend/src/presentation/routes/userProfile.ts @@ -94,7 +94,7 @@ const updateUserProfile = route.createSchema( }, responses: { 200: { - description: 'OK', + description: 'Updated', content: { 'application/json': { schema: updateUserProfileResponseSchema, From 9431c40cdae1a3e5dcbc6cc11b75101a32394443 Mon Sep 17 00:00:00 2001 From: Myxogastria0808 Date: Sat, 10 Jan 2026 19:00:11 +0900 Subject: [PATCH 2/6] wip --- assets/er.mmd | 7 - assets/er.png | Bin 75901 -> 86844 bytes flake.lock | 6 +- products/backend/README.md | 20 + products/backend/src/db/auth-schema.ts | 36 +- products/backend/src/db/relation.ts | 17 +- products/backend/src/index.ts | 2 +- .../backend/src/presentation/factory/hono.ts | 2 +- .../backend/src/presentation/routes/group.ts | 468 ++- .../backend/src/presentation/routes/info.ts | 194 +- .../src/presentation/routes/userProfile.ts | 117 +- .../backend/src/presentation/utils/types.ts | 5 + products/frontend/openapi.json | 2746 ++++------------- products/frontend/src/api/openapi.d.ts | 228 +- .../src/routes/GenerateGroup/index.tsx | 42 +- .../frontend/src/routes/GroupDetail/index.tsx | 97 +- products/frontend/src/routes/Invite/index.tsx | 29 +- .../frontend/src/routes/Profile/index.tsx | 55 +- products/frontend/src/routes/Root/index.tsx | 30 +- products/validator/src/form/group.ts | 5 + products/validator/src/index.ts | 12 +- products/validator/src/request/group.ts | 2 +- products/validator/src/response/group.ts | 6 - products/validator/src/response/info.ts | 6 - products/validator/src/response/sample.ts | 8 - .../validator/src/response/userProfile.ts | 8 - 26 files changed, 1088 insertions(+), 3060 deletions(-) create mode 100644 products/backend/src/presentation/utils/types.ts create mode 100644 products/validator/src/form/group.ts delete mode 100644 products/validator/src/response/sample.ts diff --git a/assets/er.mmd b/assets/er.mmd index 9f9a9aa..882ff85 100644 --- a/assets/er.mmd +++ b/assets/er.mmd @@ -7,15 +7,10 @@ erDiagram text image created_at timestamp updated_at timestamp - } - UserProfile { - text user_id "PK FK" text display_name text avatar_url text bio - created_at timestamp - updated_at timestamp } Session { @@ -84,8 +79,6 @@ erDiagram User ||--|{ Session : "id<->user_id" User ||--|{ Account : "id<->user_id" - User ||--o| UserProfile : "id<->user_id" - User ||--o{ Group : "id<->created_by" Group ||--o{ GroupMembership : "id<->group_id" diff --git a/assets/er.png b/assets/er.png index b07ad4b36234f16743eb1f9b1a6776fe798cba7b..eea88dd978f8101d954403e2314555d85cfceeb1 100644 GIT binary patch literal 86844 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 pz!?Sv}-L3q|h?s*l9 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±tSq?OC@(@+%xmw-_E2< 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 diff --git a/flake.lock b/flake.lock index 8af9108..58e912d 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1764642553, - "narHash": "sha256-mvbFFzVBhVK1FjyPHZGMAKpNiqkr7k++xIwy+p/NQvA=", + "lastModified": 1767966113, + "narHash": "sha256-mSTsvXa4WveSRJexsmCbm9dY17B1fKp7NLpJxllpQw4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "f720de59066162ee879adcc8c79e15c51fe6bfb4", + "rev": "5f02c91314c8ba4afe83b256b023756412218535", "type": "github" }, "original": { diff --git a/products/backend/README.md b/products/backend/README.md index f6ab4d9..254726f 100644 --- a/products/backend/README.md +++ b/products/backend/README.md @@ -36,6 +36,10 @@ better-authが実行時に参照する設定ファイル。 pnpm run backend:better-auth:generate ``` +`auto-auth-schema.ts`が更新される。 + +このファイルを読み、適宜`src/db/auth-schema.ts`を手動で更新する。 + 3. `pnpm run backend:drizzle:generate`を実行する。 ```sh @@ -100,6 +104,19 @@ pnpm run backend:deploy ※ HyperdriveのIDが漏洩すると、他者にデータベースを操作される可能性があるため、デプロイ完了後は必ず元に戻してからステージング (`git add`) をすること。 +## drizzleのスキーマファイルの構造 + +```mermaid +flowchart LR + auth-schema["src/db/auth-schema.ts (better-auth関係のテーブル定義用)"] + pay-crew2["src/db/pay-crew2-schema.ts (pay-crew2関係のテーブル定義用)"] + relation["src/db/relation.ts (リレーション定義用)"] + schema["src/db/schema.ts (エクスポート用)"] + auth-schema --> relation + pay-crew2 --> relation + relation --> schema +``` + ## 構造 この構造は、レイヤードアーキテクチャから着想を得て定義している。 @@ -116,6 +133,7 @@ pnpm run backend:deploy - hono - @hono/zod-openapi - zod-openapi-share + - better-auth #### presentation/share @@ -128,6 +146,7 @@ presentation層で共通して使用するエンティティを定義する。 - 外部依存 - drizzle + - better-auth ### db @@ -146,6 +165,7 @@ openapi.jsonの生成を行う処理を定義している。 - hono - @hono/zod-openapi - zod-openapi-share + - better-auth ## 依存関係 diff --git a/products/backend/src/db/auth-schema.ts b/products/backend/src/db/auth-schema.ts index 9949897..5f9fb35 100644 --- a/products/backend/src/db/auth-schema.ts +++ b/products/backend/src/db/auth-schema.ts @@ -1,36 +1,26 @@ import { pgTable, text, timestamp, boolean, index } from 'drizzle-orm/pg-core'; -export const user = pgTable('user', { - id: text('id').primaryKey(), - name: text('name').notNull(), - email: text('email').notNull().unique(), - emailVerified: boolean('email_verified').default(false).notNull(), - image: text('image'), - createdAt: timestamp('created_at').defaultNow().notNull(), - updatedAt: timestamp('updated_at') - .defaultNow() - .$onUpdate(() => /* @__PURE__ */ new Date()) - .notNull(), -}); - -export const userProfile = pgTable( - 'user_profile', +export const user = pgTable( + 'user', { - userId: text('user_id') - .primaryKey() - .references(() => user.id, { onDelete: 'cascade' }), - displayName: text('display_name'), - avatarUrl: text('avatar_url'), - bio: text('bio'), + id: text('id').primaryKey(), + name: text('name').notNull(), + email: text('email').notNull().unique(), + emailVerified: boolean('email_verified').default(false).notNull(), + image: text('image'), createdAt: timestamp('created_at').defaultNow().notNull(), updatedAt: timestamp('updated_at') .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()) .notNull(), + // 追加のプロフィール情報 + displayName: text('display_name'), + avatarUrl: text('avatar_url'), + bio: text('bio'), }, (table) => [ - // displayName に対する二次索引を作成 - index('user_profile_display_name_idx').on(table.displayName), + // display_name に対する二次索引を作成 + index('user_display_name_idx').on(table.displayName), ] ); diff --git a/products/backend/src/db/relation.ts b/products/backend/src/db/relation.ts index fee3630..a7505b2 100644 --- a/products/backend/src/db/relation.ts +++ b/products/backend/src/db/relation.ts @@ -1,17 +1,11 @@ // drizzle import { relations } from 'drizzle-orm'; -import { account, session, user, userProfile } from './auth-schema'; -import { debt, group, groupMembership } from './pay-crew2-schema'; // tables -export { user, userProfile, session, account, verification } from './auth-schema'; -export { group, groupMembership, debt } from './pay-crew2-schema'; +import { account, session, user } from './auth-schema'; +import { debt, group, groupMembership } from './pay-crew2-schema'; // auth-schema export const userRelations = relations(user, ({ one, many }) => ({ - userProfile: one(userProfile, { - fields: [user.id], - references: [userProfile.userId], - }), sessions: many(session, { relationName: 'user__session_userId', }), @@ -35,13 +29,6 @@ export const userRelations = relations(user, ({ one, many }) => ({ }), })); -export const userProfileRelations = relations(userProfile, ({ one }) => ({ - user: one(user, { - fields: [userProfile.userId], - references: [user.id], - }), -})); - export const sessionRelations = relations(session, ({ one }) => ({ user: one(user, { fields: [session.userId], diff --git a/products/backend/src/index.ts b/products/backend/src/index.ts index 4fc0e9d..48635be 100644 --- a/products/backend/src/index.ts +++ b/products/backend/src/index.ts @@ -20,7 +20,7 @@ app.use( cors({ origin: ['https://pay-crew2.yukiosada.work', 'http://localhost:5173'], allowHeaders: ['Content-Type', 'Authorization', 'baggage', 'sentry-trace'], - allowMethods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS'], + allowMethods: ['POST', 'PUT', 'PATCH', 'GET', 'DELETE', 'OPTIONS'], exposeHeaders: ['Content-Length'], maxAge: 600, credentials: true, diff --git a/products/backend/src/presentation/factory/hono.ts b/products/backend/src/presentation/factory/hono.ts index 399a708..3d02f8d 100644 --- a/products/backend/src/presentation/factory/hono.ts +++ b/products/backend/src/presentation/factory/hono.ts @@ -14,7 +14,7 @@ const honoFactory = () => { if (!result.success) { console.error(result.error); throw new HTTPException(400, { - message: 'Zod Validation Error', + message: 'Bad Request', }); } }, diff --git a/products/backend/src/presentation/routes/group.ts b/products/backend/src/presentation/routes/group.ts index 835ecbc..6f48811 100644 --- a/products/backend/src/presentation/routes/group.ts +++ b/products/backend/src/presentation/routes/group.ts @@ -21,8 +21,6 @@ import { registerGroupDebtResponseSchema, type RegisterGroupDebtResponseSchemaType, deleteGroupDebtRequestSchema, - deleteGroupDebtResponseSchema, - type DeleteGroupDebtResponseSchemaType, } from 'validator'; // error schema import { route } from '../share/error'; @@ -30,7 +28,7 @@ import { route } from '../share/error'; import { drizzle } from 'drizzle-orm/node-postgres'; import { and, eq, isNull } from 'drizzle-orm'; import { group, debt, groupMembership } from '../../db/pay-crew2-schema'; -import { user, userProfile } from '../../db/auth-schema'; +import { user } from '../../db/auth-schema'; const hono = honoFactory(); @@ -39,7 +37,7 @@ const createGroupSchema = route.createSchema( { path: '/api/group/create', method: 'post', - description: 'create a new group', + description: 'グループを新規作成するエンドポイント', security: [{ SessionCookie: [] }], request: { body: { @@ -62,55 +60,44 @@ const createGroupSchema = route.createSchema( }, }, }, - [400, 401, 500] as const + [401, 500] as const ); hono.openapi(createGroupSchema, async (c) => { - c.status(201); + const loginUser = c.get('user'); const body = c.req.valid('json'); - const user = c.get('user'); - //validation - if (!body || !body.name) { - throw new HTTPException(400, { message: 'Bad Request' }); - } - // set group name - const groupName = body.name; - - // create invited_id - let uuid1 = crypto.randomUUID(); - let uuid2 = crypto.randomUUID(); - // invite_id format: - - const invite_id = `${uuid1}-${uuid2}`; + // 現在時刻の取得 + const now = new Date(); - // connect to db + // データベース接続 const db = drizzle({ connection: c.env.HYPERDRIVE }); - //* insert group data *// + //* グループ情報を挿入 *// const result = await db .insert(group) .values({ id: crypto.randomUUID(), - name: groupName, - invite_id: invite_id, - createdBy: user.id, - createdAt: new Date(), - updatedAt: new Date(), + name: body.group_name, + invite_id: `${crypto.randomUUID()}-${crypto.randomUUID()}`, + createdBy: loginUser.id, + createdAt: now, + updatedAt: now, }) - .returning(); + .returning({ + id: group.id, + invite_id: group.invite_id, + }); - //* insert created_by user to groupMembership *// - await db - .insert(groupMembership) - .values({ - id: crypto.randomUUID(), - groupId: result[0].id, - userId: user.id, - joinedAt: new Date(), - }) - .returning(); + //* グループ作成者をgroupMembershipに挿入 *// + await db.insert(groupMembership).values({ + id: crypto.randomUUID(), + groupId: result[0].id, + userId: loginUser.id, + joinedAt: now, + }); - // return response + // レスポンス return c.json( { group_id: result[0].id, @@ -125,7 +112,7 @@ const joinGroupSchema = route.createSchema( { path: '/api/group/join', method: 'post', - description: 'join an existing group', + description: '招待IDを使ってグループに参加するエンドポイント', security: [{ SessionCookie: [] }], request: { body: { @@ -152,39 +139,43 @@ const joinGroupSchema = route.createSchema( ); hono.openapi(joinGroupSchema, async (c) => { - c.status(201); const body = c.req.valid('json'); const user = c.get('user'); - //validation - if (!body || !body.invite_id) { - throw new HTTPException(400, { message: 'Bad Request' }); - } - const inviteId = body.invite_id; + // 現在時刻の取得 + const now = new Date(); - // connect to db + // データベース接続 const db = drizzle({ connection: c.env.HYPERDRIVE }); - // find group by invite_id - const groupData = await db.select().from(group).where(eq(group.invite_id, inviteId)).limit(1); + // invite_id から group を取得 + const groupData = await db + .select({ + id: group.id, + }) + .from(group) + .where(eq(group.invite_id, body.invite_id)) + .limit(1); + + // invite_id が不正な場合はエラー if (groupData.length === 0) { - // validate invite_id - throw new HTTPException(401, { message: 'Invalid invite_id' }); + throw new HTTPException(400, { message: 'Bad Request' }); } - // add user to the group - const groupId = groupData[0].id; + // loginUser を invite_id の group に参加させる const result = await db .insert(groupMembership) .values({ id: crypto.randomUUID(), - groupId: groupId, + groupId: groupData[0].id, userId: user.id, - joinedAt: new Date(), + joinedAt: now, }) - .returning(); + .returning({ + groupId: groupMembership.groupId, + }); - // return response + // レスポンス return c.json( { group_id: result[0].groupId, @@ -211,8 +202,8 @@ const getGroupInfoSchema = route.createSchema( }, }, responses: { - 200: { - description: 'OK', + 201: { + description: 'Created', content: { 'application/json': { schema: getGroupInfoResponseSchema, @@ -225,106 +216,98 @@ const getGroupInfoSchema = route.createSchema( ); hono.openapi(getGroupInfoSchema, async (c) => { - c.status(201); const body = c.req.valid('json'); const loginUser = c.get('user'); - // NOTE: このvalidationは、groupのhistoryの取得のエンドポイントでも全く同じものを使うので、共通化を検討すること - // NOTE: --- 共通化開始 --- - // validation - if (!body || !body.group_id) { - throw new HTTPException(400, { message: 'Bad Request' }); - } - const groupId = body.group_id; - - // connect to db + // データベース接続 const db = drizzle({ connection: c.env.HYPERDRIVE }); - // find me from the group (validation) + // NOTE: --- 共通化開始 --- + // loginUser が body.group_id のグループのメンバーであることを確認 const me = await db - .select() + .select({ + groupMembershipId: groupMembership.id, + }) .from(groupMembership) - .where(and(eq(groupMembership.groupId, groupId), eq(groupMembership.userId, loginUser.id))) + .where(and(eq(groupMembership.groupId, body.group_id), eq(groupMembership.userId, loginUser.id))) .limit(1); + + // body.group_id のグループのメンバーでない場合はエラー if (me.length === 0) { - // validate membership - throw new HTTPException(401, { message: 'User is not a member of the group' }); + throw new HTTPException(400, { message: 'Bad Request' }); } // NOTE: --- 共通化終了 --- - //* get group info *// - const groupData = await db.select().from(group).where(eq(group.id, groupId)).limit(1); - if (groupData.length === 0) { - // validate group_id - throw new HTTPException(401, { message: 'Invalid group_id' }); - } + //* body.group_id のグループ情報を取得 *// + const groupData = await db + .select({ + name: group.name, + createdBy: group.createdBy, + }) + .from(group) + .where(eq(group.id, body.group_id)) + .limit(1); - //* get created_by member's name *// - const createdByUserId = groupData[0].createdBy; - let createdByUserName = ''; - // get user name from user table - const createdByUserInfo = await db.select().from(user).where(eq(user.id, createdByUserId)).limit(1); - if (createdByUserInfo.length === 0) { - throw new HTTPException(500, { message: 'The creator of the group was not found' }); - } - createdByUserName = createdByUserInfo[0].name; - // get display name from user_profile table - const createdByDisplayNameInfo = await db - .select() - .from(userProfile) - .where(eq(userProfile.userId, createdByUserId)) + //* body.group_id のグループ作成者情報を取得 *// + // NOTE: 共通化できそう + // ユーザ名を取得 (user table) + const createdByUserNameInfo = await db + .select({ + name: user.name, + displayName: user.displayName, + }) + .from(user) + .where(eq(user.id, groupData[0].createdBy)) .limit(1); - if ( - createdByDisplayNameInfo.length > 0 && - typeof createdByDisplayNameInfo[0].displayName === 'string' && - createdByDisplayNameInfo[0].displayName.length > 0 - ) { - createdByUserName = createdByDisplayNameInfo[0].displayName; - } - //* get members *// - // get all member userIds from groupMembership table - const membersData = await db.select().from(groupMembership).where(eq(groupMembership.groupId, groupId)); - const memberUserIds = membersData.map((member) => member.userId); - // get user name or display name for each member + // NOTE: 共通化できそう (info.ts と group.ts で共通化) + // NOTE: --- 共通化開始 --- + //* body.group_id のメンバー情報を取得 *// + // グループメンバーのユーザーIDを取得 (group_membership table) + const memberUserIds = await db + .select({ + userId: groupMembership.userId, + }) + .from(groupMembership) + .where(eq(groupMembership.groupId, body.group_id)); + + // メンバー情報を格納する配列 const members: GetGroupInfoResponseMemberElementSchemaType[] = []; + for (const memberUserId of memberUserIds) { - // initialize user name - let userName = ''; - - // get user name from user table - const userNameInfo = await db.select().from(user).where(eq(user.id, memberUserId)).limit(1); - if (userNameInfo.length === 0) { - throw new HTTPException(500, { message: 'A group member was not found' }); - } - //set user name - userName = userNameInfo[0].name; - - // get display name from user_profile table - const displayNameInfo = await db.select().from(userProfile).where(eq(userProfile.userId, memberUserId)).limit(1); - if ( - displayNameInfo.length > 0 && - typeof displayNameInfo[0].displayName === 'string' && - displayNameInfo[0].displayName.length > 0 - ) { - userName = displayNameInfo[0].displayName; - } - - // push to members array + // NOTE: 共通化できそう + // ユーザ名を取得 (user table) + const memberUserNameInfo = await db + .select({ + name: user.name, + displayName: user.displayName, + }) + .from(user) + .where(eq(user.id, memberUserId.userId)) + .limit(1); + + // メンバー情報を配列に追加 members.push({ - user_id: memberUserId, - user_name: userName, + user_id: memberUserId.userId, + user_name: + memberUserNameInfo[0].displayName !== null && memberUserNameInfo[0].displayName.length > 0 + ? memberUserNameInfo[0].displayName + : memberUserNameInfo[0].name, }); } + // NOTE: --- 共通化終了 --- // return response return c.json( { group_name: groupData[0].name, - created_by: createdByUserName, + created_by: + createdByUserNameInfo[0].displayName !== null && createdByUserNameInfo[0].displayName.length > 0 + ? createdByUserNameInfo[0].displayName + : createdByUserNameInfo[0].name, members: members, } satisfies GetGroupInfoResponseSchemaType, - 200 + 201 ); }); @@ -346,8 +329,8 @@ const getGroupDebtHistorySchema = route.createSchema( }, }, responses: { - 200: { - description: 'OK', + 201: { + description: 'Created', content: { 'application/json': { schema: getGroupDebtHistoryResponseSchema, @@ -360,97 +343,91 @@ const getGroupDebtHistorySchema = route.createSchema( ); hono.openapi(getGroupDebtHistorySchema, async (c) => { - c.status(201); - const body = c.req.valid('json'); const loginUser = c.get('user'); + const body = c.req.valid('json'); - // NOTE: このvalidationは、各グループの情報を取得するエンドポイントでも全く同じものを使うので、共通化を検討すること - // NOTE: --- 共通化開始 --- - // validation - if (!body || !body.group_id) { - throw new HTTPException(400, { message: 'Bad Request' }); - } - const groupId = body.group_id; - - // connect to db + // データベース接続 const db = drizzle({ connection: c.env.HYPERDRIVE }); - // find me from the group (validation) + // NOTE: --- 共通化開始 --- + // loginUser が body.group_id のグループのメンバーであることを確認 const me = await db - .select() + .select({ + groupMembershipId: groupMembership.id, + }) .from(groupMembership) - .where(and(eq(groupMembership.groupId, groupId), eq(groupMembership.userId, loginUser.id))) + .where(and(eq(groupMembership.groupId, body.group_id), eq(groupMembership.userId, loginUser.id))) .limit(1); + + // body.group_id のグループのメンバーでない場合はエラー if (me.length === 0) { - // validate membership - throw new HTTPException(401, { message: 'User is not a member of the group' }); + throw new HTTPException(400, { message: 'Bad Request' }); } // NOTE: --- 共通化終了 --- - //* get each group debt info *// + //* グループの貸し借り履歴を取得 *// + // 貸し借り履歴を格納する配列 let debtData: GetGroupDebtHistoryResponseElementSchemaType[] = []; + + // body.group_id の貸し借り履歴を取得 (debt table) const rawDebtData = await db - .select() + .select({ + id: debt.id, + debtorId: debt.debtorId, + creditorId: debt.creditorId, + amount: debt.amount, + }) .from(debt) - .where(and(eq(debt.groupId, groupId), isNull(debt.deletedAt))); + .where(and(eq(debt.groupId, body.group_id), isNull(debt.deletedAt))); + for (const debtEntry of rawDebtData) { - // get debtor name from user table - const debtorInfo = await db.select().from(user).where(eq(user.id, debtEntry.debtorId)).limit(1); - if (debtorInfo.length === 0) { - throw new HTTPException(500, { message: 'A debtor user was not found' }); - } - let debtorName = debtorInfo[0].name; - // get display name from user_profile table - const debtorDisplayNameInfo = await db - .select() - .from(userProfile) - .where(eq(userProfile.userId, debtEntry.debtorId)) + // debt_name を取得 + // NOTE: 共通化できそう + // ユーザ名を取得 (user table) + const DebtorNameInfo = await db + .select({ + name: user.name, + displayName: user.displayName, + }) + .from(user) + .where(eq(user.id, debtEntry.debtorId)) .limit(1); - if ( - debtorDisplayNameInfo.length > 0 && - typeof debtorDisplayNameInfo[0].displayName === 'string' && - debtorDisplayNameInfo[0].displayName.length > 0 - ) { - debtorName = debtorDisplayNameInfo[0].displayName; - } - - // get creditor name from user table - const creditorInfo = await db.select().from(user).where(eq(user.id, debtEntry.creditorId)).limit(1); - if (creditorInfo.length === 0) { - throw new HTTPException(500, { message: 'A creditor user was not found' }); - } - let creditorName = creditorInfo[0].name; - // get display name from user_profile table - const creditorDisplayNameInfo = await db - .select() - .from(userProfile) - .where(eq(userProfile.userId, debtEntry.creditorId)) + + // creditor_name を取得 + // NOTE: 共通化できそう + // ユーザ名を取得 (user table) + const CreditorNameInfo = await db + .select({ + name: user.name, + displayName: user.displayName, + }) + .from(user) + .where(eq(user.id, debtEntry.creditorId)) .limit(1); - if ( - creditorDisplayNameInfo.length > 0 && - typeof creditorDisplayNameInfo[0].displayName === 'string' && - creditorDisplayNameInfo[0].displayName.length > 0 - ) { - creditorName = creditorDisplayNameInfo[0].displayName; - } - - // push to debtData array + + // 貸し借り履歴データを配列に追加 debtData.push({ debt_id: debtEntry.id, debtor_id: debtEntry.debtorId, - debtor_name: debtorName, + debtor_name: + DebtorNameInfo[0].displayName !== null && DebtorNameInfo[0].displayName.length > 0 + ? DebtorNameInfo[0].displayName + : DebtorNameInfo[0].name, creditor_id: debtEntry.creditorId, - creditor_name: creditorName, + creditor_name: + CreditorNameInfo[0].displayName !== null && CreditorNameInfo[0].displayName.length > 0 + ? CreditorNameInfo[0].displayName + : CreditorNameInfo[0].name, amount: debtEntry.amount, }); } - // return response + // レスポンス return c.json( { debts: debtData, } satisfies GetGroupDebtHistoryResponseSchemaType, - 200 + 201 ); }); @@ -486,49 +463,51 @@ const registerGroupDebtSchema = route.createSchema( ); hono.openapi(registerGroupDebtSchema, async (c) => { - c.status(201); - const body = c.req.valid('json'); const loginUser = c.get('user'); + const body = c.req.valid('json'); - // NOTE: このvalidationは、各グループの情報を取得するエンドポイントでも全く同じものを使うので、共通化を検討すること - // NOTE: --- 共通化開始 --- - // validation - if (!body || !body.group_id) { - throw new HTTPException(400, { message: 'Bad Request' }); - } - const groupId = body.group_id; + // 現在時刻の取得 + const now = new Date(); - // connect to db + // データベース接続 const db = drizzle({ connection: c.env.HYPERDRIVE }); - // find me from the group (validation) + // NOTE: --- 共通化開始 --- + // loginUser が body.group_id のグループのメンバーであることを確認 const me = await db - .select() + .select({ + groupMembershipId: groupMembership.id, + }) .from(groupMembership) - .where(and(eq(groupMembership.groupId, groupId), eq(groupMembership.userId, loginUser.id))) + .where(and(eq(groupMembership.groupId, body.group_id), eq(groupMembership.userId, loginUser.id))) .limit(1); + + // body.group_id のグループのメンバーでない場合はエラー if (me.length === 0) { - // validate membership - throw new HTTPException(401, { message: 'User is not a member of the group' }); + throw new HTTPException(400, { message: 'Bad Request' }); } // NOTE: --- 共通化終了 --- - // register group debt entry + // body.group_id に貸し借り履歴を追加 (debt table) const result = await db .insert(debt) .values({ id: crypto.randomUUID(), - groupId: groupId, + groupId: body.group_id, creditorId: body.creditor_id, debtorId: body.debtor_id, amount: body.amount, - description: body.description ? body.description : null, - occurredAt: body.occurred_at ? new Date(body.occurred_at) : new Date(), - createdAt: new Date(), - updatedAt: new Date(), - deletedBy: null, + description: typeof body.description === 'undefined' ? null : body.description, + occurredAt: body.occurred_at ? new Date(body.occurred_at) : now, + createdAt: now, + updatedAt: now, }) - .returning(); + .returning({ + creditorId: debt.creditorId, + debtorId: debt.debtorId, + amount: debt.amount, + occurredAt: debt.occurredAt, + }); return c.json( { @@ -559,13 +538,8 @@ const deleteGroupDebtSchema = route.createSchema( }, }, responses: { - 200: { - description: 'Deleted', - content: { - 'application/json': { - schema: deleteGroupDebtResponseSchema, - }, - }, + 204: { + description: 'No Content', }, }, }, @@ -573,51 +547,43 @@ const deleteGroupDebtSchema = route.createSchema( ); hono.openapi(deleteGroupDebtSchema, async (c) => { - c.status(200); - const body = c.req.valid('json'); const loginUser = c.get('user'); + const body = c.req.valid('json'); - // NOTE: このvalidationは、各グループの情報を取得するエンドポイントでも全く同じものを使うので、共通化を検討すること - // NOTE: --- 共通化開始 --- - // validation - if (!body || !body.group_id) { - throw new HTTPException(400, { message: 'Bad Request' }); - } - const groupId = body.group_id; + // 現在時刻の取得 + const now = new Date(); - // connect to db + // データベース接続 const db = drizzle({ connection: c.env.HYPERDRIVE }); - // find me from the group (validation) + // NOTE: --- 共通化開始 --- + // loginUser が body.group_id のグループのメンバーであることを確認 const me = await db - .select() + .select({ + groupMembershipId: groupMembership.id, + }) .from(groupMembership) - .where(and(eq(groupMembership.groupId, groupId), eq(groupMembership.userId, loginUser.id))) + .where(and(eq(groupMembership.groupId, body.group_id), eq(groupMembership.userId, loginUser.id))) .limit(1); + + // body.group_id のグループのメンバーでない場合はエラー if (me.length === 0) { - // validate membership - throw new HTTPException(401, { message: 'User is not a member of the group' }); + throw new HTTPException(400, { message: 'Bad Request' }); } // NOTE: --- 共通化終了 --- - const now = new Date(); - // delete group debt entry (soft delete) - const result = await db + //* body.debt_id の貸し借りの履歴の削除 (論理削除) *// + await db .update(debt) .set({ deletedBy: loginUser.id, deletedAt: now, updatedAt: now, }) - .where(and(eq(debt.id, body.debt_id), eq(debt.groupId, groupId))) - .returning(); + .where(and(eq(debt.id, body.debt_id), eq(debt.groupId, body.group_id), isNull(debt.deletedAt))); - return c.json( - { - debt_id: result[0].id, - } satisfies DeleteGroupDebtResponseSchemaType, - 200 - ); + // レスポンス + return c.body(null, 204); }); export default hono; diff --git a/products/backend/src/presentation/routes/info.ts b/products/backend/src/presentation/routes/info.ts index 10c2aab..5900b78 100644 --- a/products/backend/src/presentation/routes/info.ts +++ b/products/backend/src/presentation/routes/info.ts @@ -1,5 +1,4 @@ // hono instance -import { HTTPException } from 'hono/http-exception'; import honoFactory from '../factory/hono'; // validator import { @@ -11,8 +10,6 @@ import { type InfoAboutGroupsTheUserBelongsToResponseGroupElementSchemaType, type InfoAboutGroupsTheUserBelongsToResponseSchemaType, deleteInfoAboutUserRepaymentRequestSchema, - deleteInfoAboutUserRepaymentResponseSchema, - DeleteInfoAboutUserRepaymentResponseSchemaType, } from 'validator'; // error schema import { route } from '../share/error'; @@ -20,7 +17,9 @@ import { route } from '../share/error'; import { drizzle } from 'drizzle-orm/node-postgres'; import { and, or, eq, inArray, isNull } from 'drizzle-orm'; import { group, debt, groupMembership } from '../../db/pay-crew2-schema'; -import { user, userProfile } from '../../db/auth-schema'; +import { user } from '../../db/auth-schema'; +// types +import { TransactionType } from '../utils/types'; const hono = honoFactory(); @@ -29,7 +28,7 @@ const infoAboutGroupsTheUserBelongsToSchema = route.createSchema( { path: '/api/info/group', method: 'get', - description: 'get info about groups the user belongs to', + description: 'ログインユーザーが参加しているグループ一覧を取得するエンドポイント', security: [{ SessionCookie: [] }], request: {}, responses: { @@ -49,11 +48,13 @@ const infoAboutGroupsTheUserBelongsToSchema = route.createSchema( hono.openapi(infoAboutGroupsTheUserBelongsToSchema, async (c) => { const loginUser = c.get('user'); - // connect to db + // データベース接続 const db = drizzle({ connection: c.env.HYPERDRIVE }); - //* get group info that belongs to the user *// + // グループ情報格納用配列 let groupInfo: InfoAboutGroupsTheUserBelongsToResponseGroupElementSchemaType[] = []; + + //* ユーザが参加しているグループ情報を取得 (group table) *// const groupsData = await db .select({ id: group.id, @@ -72,50 +73,53 @@ hono.openapi(infoAboutGroupsTheUserBelongsToSchema, async (c) => { ); for (const groupData of groupsData) { - //* get members *// - // get all member userIds from groupMembership table - const membersData = await db.select().from(groupMembership).where(eq(groupMembership.groupId, groupData.id)); - const memberUserIds = membersData.map((member) => member.userId); - // get user name or display name for each member - const members: InfoAboutGroupsTheUserBelongsToResponseMemberElementSchemaType[] = []; - for (const memberUserId of memberUserIds) { - // initialize user name - let userName = ''; + // NOTE: 共通化できそう + // NOTE: --- 共通化開始 --- + //* groupData.id のメンバー情報を取得 *// + // グループメンバーのユーザーIDを取得 (group_membership table) + const memberUserIds = await db + .select({ + userId: groupMembership.userId, + }) + .from(groupMembership) + .where(eq(groupMembership.groupId, groupData.id)); - // get user name from user table - const userNameInfo = await db.select().from(user).where(eq(user.id, memberUserId)).limit(1); - if (userNameInfo.length === 0) { - throw new HTTPException(500, { message: 'A group member was not found' }); - } - //set user name - userName = userNameInfo[0].name; + // メンバー情報を格納する配列 + const members: InfoAboutGroupsTheUserBelongsToResponseMemberElementSchemaType[] = []; - // get display name from user_profile table - const displayNameInfo = await db.select().from(userProfile).where(eq(userProfile.userId, memberUserId)).limit(1); - if ( - displayNameInfo.length > 0 && - typeof displayNameInfo[0].displayName === 'string' && - displayNameInfo[0].displayName.length > 0 - ) { - userName = displayNameInfo[0].displayName; - } + for (const memberUserId of memberUserIds) { + // NOTE: 共通化できそう + // ユーザ名を取得 (user table) + const userNameInfo = await db + .select({ + name: user.name, + displayName: user.displayName, + }) + .from(user) + .where(eq(user.id, memberUserId.userId)) + .limit(1); - // push to members array + // メンバー情報を配列に追加 members.push({ - user_id: memberUserId, - user_name: userName, + user_id: memberUserId.userId, + user_name: + userNameInfo[0].displayName !== null && userNameInfo[0].displayName.length > 0 + ? userNameInfo[0].displayName + : userNameInfo[0].name, }); } - // push to groupInfo array + + // グループ情報を配列に追加 groupInfo.push({ group_id: groupData.id, group_name: groupData.name, created_by: groupData.createdBy, members: members, }); + // NOTE: --- 共通化終了 --- } - // return response + // レスポンス return c.json( { groups: groupInfo, @@ -129,7 +133,7 @@ const infoAboutUserTransactionsSchema = route.createSchema( { path: '/api/info/transaction', method: 'get', - description: 'get info about user transactions', + description: 'ログインユーザーの貸し借りの履歴を取得するエンドポイント', security: [{ SessionCookie: [] }], request: {}, responses: { @@ -146,39 +150,40 @@ const infoAboutUserTransactionsSchema = route.createSchema( [401, 500] as const ); -type TransactionType = { - user_id: string; // 取引相手のユーザID - lent_amount: number; // 貸した金額 - borrowed_amount: number; // 借りた金額 -}; - hono.openapi(infoAboutUserTransactionsSchema, async (c) => { const loginUser = c.get('user'); - // connect to db + // データベース接続 const db = drizzle({ connection: c.env.HYPERDRIVE }); - // loginUserが貸している取引履歴を取得 + //* loginUserが貸している取引履歴を取得 *// // マイナス n 円 const creditorTransactions = await db - .select() + .select({ + debtorId: debt.debtorId, + amount: debt.amount, + }) .from(debt) .where(and(eq(debt.creditorId, loginUser.id), isNull(debt.deletedAt))); - // loginUserが借りている取引履歴を取得 + //* loginUserが借りている取引履歴を取得 *// // プラス n 円 const debtorTransactions = await db - .select() + .select({ + creditorId: debt.creditorId, + amount: debt.amount, + }) .from(debt) .where(and(eq(debt.debtorId, loginUser.id), isNull(debt.deletedAt))); - // 取引相手ごとに集計 + //* 取引相手ごとに集計 *// + // 集計結果を格納するMap const transactions: Map = new Map(); // 貸している取引を集計 - for (const transaction of creditorTransactions) { - const userId = transaction.debtorId; - const amount = transaction.amount; + for (const creditorTransaction of creditorTransactions) { + const userId = creditorTransaction.debtorId; + const amount = creditorTransaction.amount; if (!transactions.has(userId)) { transactions.set(userId, { user_id: userId, lent_amount: 0, borrowed_amount: 0 }); } @@ -187,9 +192,9 @@ hono.openapi(infoAboutUserTransactionsSchema, async (c) => { } // 借りている取引を集計 - for (const transaction of debtorTransactions) { - const userId = transaction.creditorId; - const amount = transaction.amount; + for (const debtorTransaction of debtorTransactions) { + const userId = debtorTransaction.creditorId; + const amount = debtorTransaction.amount; if (!transactions.has(userId)) { transactions.set(userId, { user_id: userId, lent_amount: 0, borrowed_amount: 0 }); } @@ -197,38 +202,33 @@ hono.openapi(infoAboutUserTransactionsSchema, async (c) => { existing.borrowed_amount += amount; } - // netAmount の計算 + // 集計結果を格納する配列 const aggregatedTransactions: InfoAboutUserTransactionsResponseTransactionElementSchemaType[] = []; + + // 貸し借りの合算 for (const transaction of transactions.values()) { - // calculate net amount: netAmount = borrowed_amount - lent_amount + // 合算結果: netAmount = borrowed_amount - lent_amount const netAmount = transaction.borrowed_amount - transaction.lent_amount; - let userName = ''; - // get user name from user table - const userInfo = await db.select().from(user).where(eq(user.id, transaction.user_id)).limit(1); - if (userInfo.length === 0) { - throw new HTTPException(500, { message: 'A transaction counterparty was not found' }); - } - userName = userInfo[0].name; - // get display name from user_profile table - const displayNameInfo = await db - .select() - .from(userProfile) - .where(eq(userProfile.userId, transaction.user_id)) + // NOTE: 共通化できそう + // ユーザ名を取得 (user table) + const userNameInfo = await db + .select({ + name: user.name, + displayName: user.displayName, + }) + .from(user) + .where(eq(user.id, transaction.user_id)) .limit(1); - if ( - displayNameInfo.length > 0 && - typeof displayNameInfo[0].displayName === 'string' && - displayNameInfo[0].displayName.length > 0 - ) { - userName = displayNameInfo[0].displayName; - } - // push to aggregatedTransactions array if netAmount is not zero + // netAmount が 0 でない場合のみ配列に追加 if (netAmount !== 0) { aggregatedTransactions.push({ counterparty_id: transaction.user_id, - counterparty_name: userName, + counterparty_name: + userNameInfo[0].displayName !== null && userNameInfo[0].displayName.length > 0 + ? userNameInfo[0].displayName + : userNameInfo[0].name, amount: netAmount, }); } @@ -248,7 +248,7 @@ const infoUserRepaymentSchema = route.createSchema( { path: '/api/info/transaction', method: 'delete', - description: 'do user repayment', + description: 'ログインユーザーと指定された取引相手間の取引履歴を削除する (完済する) エンドポイント', security: [{ SessionCookie: [] }], request: { body: { @@ -261,34 +261,24 @@ const infoUserRepaymentSchema = route.createSchema( }, }, responses: { - 200: { - description: 'Deleted', - content: { - 'application/json': { - schema: deleteInfoAboutUserRepaymentResponseSchema, - }, - }, + 204: { + description: 'No Content', }, }, }, - [400, 401, 500] as const + [401, 500] as const ); hono.openapi(infoUserRepaymentSchema, async (c) => { - const body = c.req.valid('json'); const loginUser = c.get('user'); + const body = c.req.valid('json'); - // validation - if (!body || !body.counterparty_id) { - throw new HTTPException(400, { message: 'Bad Request' }); - } - - // connect to db + // データベース接続 const db = drizzle({ connection: c.env.HYPERDRIVE }); const now = new Date(); // loginUser <-> counterparty_id 間の取引履歴を削除(deletedAt, deletedBy をセット) - const creditorTransactions = await db + await db .update(debt) .set({ deletedBy: loginUser.id, @@ -300,16 +290,10 @@ hono.openapi(infoUserRepaymentSchema, async (c) => { and(eq(debt.creditorId, loginUser.id), eq(debt.debtorId, body.counterparty_id), isNull(debt.deletedAt)), and(eq(debt.debtorId, loginUser.id), eq(debt.creditorId, body.counterparty_id), isNull(debt.deletedAt)) ) - ) - .returning(); + ); - // return response - return c.json( - { - counterparty_id: body.counterparty_id, - } satisfies DeleteInfoAboutUserRepaymentResponseSchemaType, - 200 - ); + // レスポンス + return c.body(null, 204); }); export default hono; diff --git a/products/backend/src/presentation/routes/userProfile.ts b/products/backend/src/presentation/routes/userProfile.ts index 7b7f2f1..912d9ae 100644 --- a/products/backend/src/presentation/routes/userProfile.ts +++ b/products/backend/src/presentation/routes/userProfile.ts @@ -1,20 +1,17 @@ // hono instance -import { HTTPException } from 'hono/http-exception'; import honoFactory from '../factory/hono'; // validator import { getUserProfileResponseSchema, type GetUserProfileResponseSchemaType, updateUserProfileRequestSchema, - updateUserProfileResponseSchema, - type UpdateUserProfileResponseSchemaType, } from 'validator'; // error schema import { route } from '../share/error'; // drizzle import { drizzle } from 'drizzle-orm/node-postgres'; import { eq } from 'drizzle-orm'; -import { userProfile } from '../../db/auth-schema'; +import { user } from '../../db/auth-schema'; const hono = honoFactory(); @@ -23,7 +20,7 @@ const getUserProfile = route.createSchema( { path: '/api/profile', method: 'get', - description: 'get user profile', + description: 'ログインユーザーのプロフィール情報を取得するエンドポイント', security: [{ SessionCookie: [] }], request: {}, responses: { @@ -37,39 +34,28 @@ const getUserProfile = route.createSchema( }, }, }, - [400, 401, 500] as const + [401, 500] as const ); hono.openapi(getUserProfile, async (c) => { - const user = c.get('user'); + const loginUser = c.get('user'); - // connect to db + // データベース接続 const db = drizzle({ connection: c.env.HYPERDRIVE }); - //* get user profile *// - const userProfileData = await db - .select({ display_name: userProfile.displayName, avatar_url: userProfile.avatarUrl, bio: userProfile.bio }) - .from(userProfile) - .where(eq(userProfile.userId, user.id)) + //* ユーザ情報を取得 (user table) *// + const userData = await db + .select({ display_name: user.displayName, avatar_url: user.avatarUrl, bio: user.bio }) + .from(user) + .where(eq(user.id, loginUser.id)) .limit(1); - if (userProfileData.length === 0) { - return c.json( - { - display_name: '', - avatar_url: '', - bio: '', - } satisfies GetUserProfileResponseSchemaType, - 200 - ); - } - - // return response + // レスポンス return c.json( { - display_name: userProfileData[0].display_name === null ? '' : userProfileData[0].display_name, - avatar_url: userProfileData[0].avatar_url === null ? '' : userProfileData[0].avatar_url, - bio: userProfileData[0].bio === null ? '' : userProfileData[0].bio, + display_name: userData[0].display_name === null ? '' : userData[0].display_name, + avatar_url: userData[0].avatar_url === null ? '' : userData[0].avatar_url, + bio: userData[0].bio === null ? '' : userData[0].bio, } satisfies GetUserProfileResponseSchemaType, 200 ); @@ -79,8 +65,8 @@ hono.openapi(getUserProfile, async (c) => { const updateUserProfile = route.createSchema( { path: '/api/profile', - method: 'put', - description: 'update user profile', + method: 'patch', + description: 'ログインユーザーのプロフィール情報を更新するエンドポイント', security: [{ SessionCookie: [] }], request: { body: { @@ -93,78 +79,33 @@ const updateUserProfile = route.createSchema( }, }, responses: { - 200: { - description: 'Updated', - content: { - 'application/json': { - schema: updateUserProfileResponseSchema, - }, - }, + 204: { + description: 'No Content', }, }, }, - [400, 401, 500] as const + [401, 500] as const ); hono.openapi(updateUserProfile, async (c) => { - const user = c.get('user'); + const loginUser = c.get('user'); const body = c.req.valid('json'); - // connect to db + // データベース接続 const db = drizzle({ connection: c.env.HYPERDRIVE }); - //* check user profile exists *// - const isUserProfileData = await db - .select({ display_name: userProfile.displayName, avatar_url: userProfile.avatarUrl, bio: userProfile.bio }) - .from(userProfile) - .where(eq(userProfile.userId, user.id)) - .limit(1); - - if (isUserProfileData.length === 0) { - //* insert empty profile *// - const result = await db.insert(userProfile).values({ - userId: user.id, + //* ユーザ情報を更新 (user table) *// + await db + .update(user) + .set({ displayName: typeof body.display_name === 'undefined' ? null : body.display_name, avatarUrl: typeof body.avatar_url === 'undefined' ? null : body.avatar_url, bio: typeof body.bio === 'undefined' ? null : body.bio, - }); - - console.log('Update Result:', result); - } else { - //* update user profile *// - const result = await db - .update(userProfile) - .set({ - displayName: typeof body.display_name === 'undefined' ? null : body.display_name, - avatarUrl: typeof body.avatar_url === 'undefined' ? null : body.avatar_url, - bio: typeof body.bio === 'undefined' ? null : body.bio, - }) - .where(eq(userProfile.userId, user.id)); + }) + .where(eq(user.id, loginUser.id)); - console.log('Update Result:', result); - } - - //* get updated user profile *// - const userProfileData = await db - .select({ display_name: userProfile.displayName, avatar_url: userProfile.avatarUrl, bio: userProfile.bio }) - .from(userProfile) - .where(eq(userProfile.userId, user.id)) - .limit(1); - - // validation - if (userProfileData.length === 0) { - throw new HTTPException(500, { message: 'Failed to retrieve updated user profile' }); - } - - // return response - return c.json( - { - display_name: userProfileData[0].display_name === null ? '' : userProfileData[0].display_name, - avatar_url: userProfileData[0].avatar_url === null ? '' : userProfileData[0].avatar_url, - bio: userProfileData[0].bio === null ? '' : userProfileData[0].bio, - } satisfies UpdateUserProfileResponseSchemaType, - 200 - ); + // レスポンス + return c.body(null, 204); }); export default hono; diff --git a/products/backend/src/presentation/utils/types.ts b/products/backend/src/presentation/utils/types.ts new file mode 100644 index 0000000..b853b82 --- /dev/null +++ b/products/backend/src/presentation/utils/types.ts @@ -0,0 +1,5 @@ +export type TransactionType = { + user_id: string; // 取引相手のユーザID + lent_amount: number; // 貸した金額 + borrowed_amount: number; // 借りた金額 +}; diff --git a/products/frontend/openapi.json b/products/frontend/openapi.json index 0789491..946d37e 100644 --- a/products/frontend/openapi.json +++ b/products/frontend/openapi.json @@ -1,10 +1,5 @@ { "openapi": "3.1.0", - "security": [ - { - "SessionCookie": [] - } - ], "info": { "title": "Pay Crew2 API", "version": "0.0.1", @@ -24,7 +19,7 @@ "paths": { "/api/info/group": { "get": { - "description": "get info about groups the user belongs to", + "description": "ログインユーザーが参加しているグループ一覧を取得するエンドポイント", "security": [ { "SessionCookie": [] @@ -873,7 +868,7 @@ }, "/api/info/transaction": { "get": { - "description": "get info about user transactions", + "description": "ログインユーザーの貸し借りの履歴を取得するエンドポイント", "security": [ { "SessionCookie": [] @@ -1699,7 +1694,7 @@ } }, "delete": { - "description": "do user repayment", + "description": "ログインユーザーと指定された取引相手間の取引履歴を削除する (完済する) エンドポイント", "security": [ { "SessionCookie": [] @@ -1725,27 +1720,11 @@ } }, "responses": { - "200": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "counterparty_id": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "counterparty_id" - ] - } - } - } + "204": { + "description": "No Content" }, - "400": { - "description": "Bad Request", + "401": { + "description": "Unauthorized", "content": { "application/json": { "schema": { @@ -2132,8 +2111,8 @@ } } }, - "401": { - "description": "Unauthorized", + "500": { + "description": "Internal Server Error", "content": { "application/json": { "schema": { @@ -2519,9 +2498,64 @@ } } } + } + } + } + }, + "/api/group/create": { + "post": { + "description": "グループを新規作成するエンドポイント", + "security": [ + { + "SessionCookie": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group_name": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "group_name" + ] + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group_id": { + "type": "string", + "format": "uuid" + }, + "invite_id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "group_id", + "invite_id" + ] + } + } + } }, - "500": { - "description": "Internal Server Error", + "401": { + "description": "Unauthorized", "content": { "application/json": { "schema": { @@ -2907,64 +2941,9 @@ } } } - } - } - } - }, - "/api/group/create": { - "post": { - "description": "create a new group", - "security": [ - { - "SessionCookie": [] - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "name" - ] - } - } - } - }, - "responses": { - "201": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "group_id": { - "type": "string", - "format": "uuid" - }, - "invite_id": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "group_id", - "invite_id" - ] - } - } - } }, - "400": { - "description": "Bad Request", + "500": { + "description": "Internal Server Error", "content": { "application/json": { "schema": { @@ -3350,9 +3329,59 @@ } } } + } + } + } + }, + "/api/group/join": { + "post": { + "description": "招待IDを使ってグループに参加するエンドポイント", + "security": [ + { + "SessionCookie": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "invite_id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "invite_id" + ] + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group_id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "group_id" + ] + } + } + } }, - "401": { - "description": "Unauthorized", + "400": { + "description": "Bad Request", "content": { "application/json": { "schema": { @@ -3739,8 +3768,8 @@ } } }, - "500": { - "description": "Internal Server Error", + "401": { + "description": "Unauthorized", "content": { "application/json": { "schema": { @@ -4126,59 +4155,9 @@ } } } - } - } - } - }, - "/api/group/join": { - "post": { - "description": "join an existing group", - "security": [ - { - "SessionCookie": [] - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "invite_id": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "invite_id" - ] - } - } - } - }, - "responses": { - "201": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "group_id": { - "type": "string", - "format": "uuid" - } - }, - "required": [ - "group_id" - ] - } - } - } }, - "400": { - "description": "Bad Request", + "500": { + "description": "Internal Server Error", "content": { "application/json": { "schema": { @@ -4564,15 +4543,91 @@ } } } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { + } + } + } + }, + "/api/group/info": { + "post": { + "description": "get group information", + "security": [ + { + "SessionCookie": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group_id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "group_id" + ] + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group_name": { + "type": "string", + "format": "uuid" + }, + "created_by": { + "type": "string", + "minLength": 1 + }, + "members": { + "type": "array", + "items": { + "type": "object", + "properties": { + "user_id": { + "type": "string", + "minLength": 1 + }, + "user_name": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "user_id", + "user_name" + ] + } + } + }, + "required": [ + "group_name", + "created_by", + "members" + ] + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "status": { "anyOf": [ { "type": "number", @@ -4953,8 +5008,8 @@ } } }, - "500": { - "description": "Internal Server Error", + "401": { + "description": "Unauthorized", "content": { "application/json": { "schema": { @@ -5340,85 +5395,9 @@ } } } - } - } - } - }, - "/api/group/info": { - "post": { - "description": "get group information", - "security": [ - { - "SessionCookie": [] - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "group_id": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "group_id" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "group_name": { - "type": "string", - "format": "uuid" - }, - "created_by": { - "type": "string", - "minLength": 1 - }, - "members": { - "type": "array", - "items": { - "type": "object", - "properties": { - "user_id": { - "type": "string", - "minLength": 1 - }, - "user_name": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "user_id", - "user_name" - ] - } - } - }, - "required": [ - "group_name", - "created_by", - "members" - ] - } - } - } }, - "400": { - "description": "Bad Request", + "500": { + "description": "Internal Server Error", "content": { "application/json": { "schema": { @@ -5804,36 +5783,122 @@ } } } - }, - "401": { - "description": "Unauthorized", + } + } + } + }, + "/api/group/debt/history": { + "post": { + "description": "get group debt history", + "security": [ + { + "SessionCookie": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group_id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "group_id" + ] + } + } + } + }, + "responses": { + "201": { + "description": "Created", "content": { "application/json": { "schema": { "type": "object", "properties": { - "status": { - "anyOf": [ - { - "type": "number", - "enum": [ - 100 - ] - }, - { - "type": "number", - "enum": [ - 102 - ] - }, - { - "type": "number", - "enum": [ - 103 - ] + "debts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "debt_id": { + "type": "string", + "minLength": 1 + }, + "debtor_id": { + "type": "string", + "minLength": 1 + }, + "debtor_name": { + "type": "string", + "minLength": 1 + }, + "creditor_id": { + "type": "string", + "minLength": 1 + }, + "creditor_name": { + "type": "string", + "minLength": 1 + }, + "amount": { + "type": "number", + "minimum": 0 + } }, - { - "type": "number", + "required": [ + "debt_id", + "debtor_id", + "debtor_name", + "creditor_id", + "creditor_name", + "amount" + ] + } + } + }, + "required": [ + "debts" + ] + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "status": { + "anyOf": [ + { + "type": "number", + "enum": [ + 100 + ] + }, + { + "type": "number", + "enum": [ + 102 + ] + }, + { + "type": "number", + "enum": [ + 103 + ] + }, + { + "type": "number", "enum": [ 200 ] @@ -6193,8 +6258,8 @@ } } }, - "500": { - "description": "Internal Server Error", + "401": { + "description": "Unauthorized", "content": { "application/json": { "schema": { @@ -6580,95 +6645,9 @@ } } } - } - } - } - }, - "/api/group/debt/history": { - "post": { - "description": "get group debt history", - "security": [ - { - "SessionCookie": [] - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "group_id": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "group_id" - ] - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "debts": { - "type": "array", - "items": { - "type": "object", - "properties": { - "debt_id": { - "type": "string", - "minLength": 1 - }, - "debtor_id": { - "type": "string", - "minLength": 1 - }, - "debtor_name": { - "type": "string", - "minLength": 1 - }, - "creditor_id": { - "type": "string", - "minLength": 1 - }, - "creditor_name": { - "type": "string", - "minLength": 1 - }, - "amount": { - "type": "number", - "minimum": 0 - } - }, - "required": [ - "debt_id", - "debtor_id", - "debtor_name", - "creditor_id", - "creditor_name", - "amount" - ] - } - } - }, - "required": [ - "debts" - ] - } - } - } }, - "400": { - "description": "Bad Request", + "500": { + "description": "Internal Server Error", "content": { "application/json": { "schema": { @@ -7054,9 +7033,95 @@ } } } + } + } + } + }, + "/api/group/debt/register": { + "post": { + "description": "register group debt entry", + "security": [ + { + "SessionCookie": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group_id": { + "type": "string", + "minLength": 1 + }, + "creditor_id": { + "type": "string", + "minLength": 1 + }, + "debtor_id": { + "type": "string", + "minLength": 1 + }, + "amount": { + "type": "number", + "minimum": 0 + }, + "description": { + "type": "string" + }, + "occurred_at": { + "type": "string" + } + }, + "required": [ + "group_id", + "creditor_id", + "debtor_id", + "amount" + ] + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "creditorId": { + "type": "string", + "minLength": 1 + }, + "debtorId": { + "type": "string", + "minLength": 1 + }, + "amount": { + "type": "number", + "minimum": 0 + }, + "occurredAt": { + "type": "string", + "format": "date" + } + }, + "required": [ + "creditorId", + "debtorId", + "amount", + "occurredAt" + ] + } + } + } }, - "401": { - "description": "Unauthorized", + "400": { + "description": "Bad Request", "content": { "application/json": { "schema": { @@ -7411,1733 +7476,40 @@ "enum": [ 510 ] - }, - { - "type": "number", - "enum": [ - 511 - ] - }, - { - "type": "number", - "enum": [ - -1 - ] - } - ], - "example": 400, - "description": "HTTPステータスコード" - }, - "message": { - "type": "string", - "minLength": 1, - "example": "Bad Request", - "description": "エラーメッセージ" - } - }, - "required": [ - "status", - "message" - ] - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { - "anyOf": [ - { - "type": "number", - "enum": [ - 100 - ] - }, - { - "type": "number", - "enum": [ - 102 - ] - }, - { - "type": "number", - "enum": [ - 103 - ] - }, - { - "type": "number", - "enum": [ - 200 - ] - }, - { - "type": "number", - "enum": [ - 201 - ] - }, - { - "type": "number", - "enum": [ - 202 - ] - }, - { - "type": "number", - "enum": [ - 203 - ] - }, - { - "type": "number", - "enum": [ - 206 - ] - }, - { - "type": "number", - "enum": [ - 207 - ] - }, - { - "type": "number", - "enum": [ - 208 - ] - }, - { - "type": "number", - "enum": [ - 226 - ] - }, - { - "type": "number", - "enum": [ - 300 - ] - }, - { - "type": "number", - "enum": [ - 301 - ] - }, - { - "type": "number", - "enum": [ - 302 - ] - }, - { - "type": "number", - "enum": [ - 303 - ] - }, - { - "type": "number", - "enum": [ - 305 - ] - }, - { - "type": "number", - "enum": [ - 306 - ] - }, - { - "type": "number", - "enum": [ - 307 - ] - }, - { - "type": "number", - "enum": [ - 308 - ] - }, - { - "type": "number", - "enum": [ - 400 - ] - }, - { - "type": "number", - "enum": [ - 401 - ] - }, - { - "type": "number", - "enum": [ - 402 - ] - }, - { - "type": "number", - "enum": [ - 403 - ] - }, - { - "type": "number", - "enum": [ - 404 - ] - }, - { - "type": "number", - "enum": [ - 405 - ] - }, - { - "type": "number", - "enum": [ - 406 - ] - }, - { - "type": "number", - "enum": [ - 407 - ] - }, - { - "type": "number", - "enum": [ - 408 - ] - }, - { - "type": "number", - "enum": [ - 409 - ] - }, - { - "type": "number", - "enum": [ - 410 - ] - }, - { - "type": "number", - "enum": [ - 411 - ] - }, - { - "type": "number", - "enum": [ - 412 - ] - }, - { - "type": "number", - "enum": [ - 413 - ] - }, - { - "type": "number", - "enum": [ - 414 - ] - }, - { - "type": "number", - "enum": [ - 415 - ] - }, - { - "type": "number", - "enum": [ - 416 - ] - }, - { - "type": "number", - "enum": [ - 417 - ] - }, - { - "type": "number", - "enum": [ - 418 - ] - }, - { - "type": "number", - "enum": [ - 421 - ] - }, - { - "type": "number", - "enum": [ - 422 - ] - }, - { - "type": "number", - "enum": [ - 423 - ] - }, - { - "type": "number", - "enum": [ - 424 - ] - }, - { - "type": "number", - "enum": [ - 425 - ] - }, - { - "type": "number", - "enum": [ - 426 - ] - }, - { - "type": "number", - "enum": [ - 428 - ] - }, - { - "type": "number", - "enum": [ - 429 - ] - }, - { - "type": "number", - "enum": [ - 431 - ] - }, - { - "type": "number", - "enum": [ - 451 - ] - }, - { - "type": "number", - "enum": [ - 500 - ] - }, - { - "type": "number", - "enum": [ - 501 - ] - }, - { - "type": "number", - "enum": [ - 502 - ] - }, - { - "type": "number", - "enum": [ - 503 - ] - }, - { - "type": "number", - "enum": [ - 504 - ] - }, - { - "type": "number", - "enum": [ - 505 - ] - }, - { - "type": "number", - "enum": [ - 506 - ] - }, - { - "type": "number", - "enum": [ - 507 - ] - }, - { - "type": "number", - "enum": [ - 508 - ] - }, - { - "type": "number", - "enum": [ - 510 - ] - }, - { - "type": "number", - "enum": [ - 511 - ] - }, - { - "type": "number", - "enum": [ - -1 - ] - } - ], - "example": 400, - "description": "HTTPステータスコード" - }, - "message": { - "type": "string", - "minLength": 1, - "example": "Bad Request", - "description": "エラーメッセージ" - } - }, - "required": [ - "status", - "message" - ] - } - } - } - } - } - } - }, - "/api/group/debt/register": { - "post": { - "description": "register group debt entry", - "security": [ - { - "SessionCookie": [] - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "group_id": { - "type": "string", - "minLength": 1 - }, - "creditor_id": { - "type": "string", - "minLength": 1 - }, - "debtor_id": { - "type": "string", - "minLength": 1 - }, - "amount": { - "type": "number", - "minimum": 0 - }, - "description": { - "type": "string" - }, - "occurred_at": { - "type": "string" - } - }, - "required": [ - "group_id", - "creditor_id", - "debtor_id", - "amount" - ] - } - } - } - }, - "responses": { - "201": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "creditorId": { - "type": "string", - "minLength": 1 - }, - "debtorId": { - "type": "string", - "minLength": 1 - }, - "amount": { - "type": "number", - "minimum": 0 - }, - "occurredAt": { - "type": "string", - "format": "date" - } - }, - "required": [ - "creditorId", - "debtorId", - "amount", - "occurredAt" - ] - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { - "anyOf": [ - { - "type": "number", - "enum": [ - 100 - ] - }, - { - "type": "number", - "enum": [ - 102 - ] - }, - { - "type": "number", - "enum": [ - 103 - ] - }, - { - "type": "number", - "enum": [ - 200 - ] - }, - { - "type": "number", - "enum": [ - 201 - ] - }, - { - "type": "number", - "enum": [ - 202 - ] - }, - { - "type": "number", - "enum": [ - 203 - ] - }, - { - "type": "number", - "enum": [ - 206 - ] - }, - { - "type": "number", - "enum": [ - 207 - ] - }, - { - "type": "number", - "enum": [ - 208 - ] - }, - { - "type": "number", - "enum": [ - 226 - ] - }, - { - "type": "number", - "enum": [ - 300 - ] - }, - { - "type": "number", - "enum": [ - 301 - ] - }, - { - "type": "number", - "enum": [ - 302 - ] - }, - { - "type": "number", - "enum": [ - 303 - ] - }, - { - "type": "number", - "enum": [ - 305 - ] - }, - { - "type": "number", - "enum": [ - 306 - ] - }, - { - "type": "number", - "enum": [ - 307 - ] - }, - { - "type": "number", - "enum": [ - 308 - ] - }, - { - "type": "number", - "enum": [ - 400 - ] - }, - { - "type": "number", - "enum": [ - 401 - ] - }, - { - "type": "number", - "enum": [ - 402 - ] - }, - { - "type": "number", - "enum": [ - 403 - ] - }, - { - "type": "number", - "enum": [ - 404 - ] - }, - { - "type": "number", - "enum": [ - 405 - ] - }, - { - "type": "number", - "enum": [ - 406 - ] - }, - { - "type": "number", - "enum": [ - 407 - ] - }, - { - "type": "number", - "enum": [ - 408 - ] - }, - { - "type": "number", - "enum": [ - 409 - ] - }, - { - "type": "number", - "enum": [ - 410 - ] - }, - { - "type": "number", - "enum": [ - 411 - ] - }, - { - "type": "number", - "enum": [ - 412 - ] - }, - { - "type": "number", - "enum": [ - 413 - ] - }, - { - "type": "number", - "enum": [ - 414 - ] - }, - { - "type": "number", - "enum": [ - 415 - ] - }, - { - "type": "number", - "enum": [ - 416 - ] - }, - { - "type": "number", - "enum": [ - 417 - ] - }, - { - "type": "number", - "enum": [ - 418 - ] - }, - { - "type": "number", - "enum": [ - 421 - ] - }, - { - "type": "number", - "enum": [ - 422 - ] - }, - { - "type": "number", - "enum": [ - 423 - ] - }, - { - "type": "number", - "enum": [ - 424 - ] - }, - { - "type": "number", - "enum": [ - 425 - ] - }, - { - "type": "number", - "enum": [ - 426 - ] - }, - { - "type": "number", - "enum": [ - 428 - ] - }, - { - "type": "number", - "enum": [ - 429 - ] - }, - { - "type": "number", - "enum": [ - 431 - ] - }, - { - "type": "number", - "enum": [ - 451 - ] - }, - { - "type": "number", - "enum": [ - 500 - ] - }, - { - "type": "number", - "enum": [ - 501 - ] - }, - { - "type": "number", - "enum": [ - 502 - ] - }, - { - "type": "number", - "enum": [ - 503 - ] - }, - { - "type": "number", - "enum": [ - 504 - ] - }, - { - "type": "number", - "enum": [ - 505 - ] - }, - { - "type": "number", - "enum": [ - 506 - ] - }, - { - "type": "number", - "enum": [ - 507 - ] - }, - { - "type": "number", - "enum": [ - 508 - ] - }, - { - "type": "number", - "enum": [ - 510 - ] - }, - { - "type": "number", - "enum": [ - 511 - ] - }, - { - "type": "number", - "enum": [ - -1 - ] - } - ], - "example": 400, - "description": "HTTPステータスコード" - }, - "message": { - "type": "string", - "minLength": 1, - "example": "Bad Request", - "description": "エラーメッセージ" - } - }, - "required": [ - "status", - "message" - ] - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { - "anyOf": [ - { - "type": "number", - "enum": [ - 100 - ] - }, - { - "type": "number", - "enum": [ - 102 - ] - }, - { - "type": "number", - "enum": [ - 103 - ] - }, - { - "type": "number", - "enum": [ - 200 - ] - }, - { - "type": "number", - "enum": [ - 201 - ] - }, - { - "type": "number", - "enum": [ - 202 - ] - }, - { - "type": "number", - "enum": [ - 203 - ] - }, - { - "type": "number", - "enum": [ - 206 - ] - }, - { - "type": "number", - "enum": [ - 207 - ] - }, - { - "type": "number", - "enum": [ - 208 - ] - }, - { - "type": "number", - "enum": [ - 226 - ] - }, - { - "type": "number", - "enum": [ - 300 - ] - }, - { - "type": "number", - "enum": [ - 301 - ] - }, - { - "type": "number", - "enum": [ - 302 - ] - }, - { - "type": "number", - "enum": [ - 303 - ] - }, - { - "type": "number", - "enum": [ - 305 - ] - }, - { - "type": "number", - "enum": [ - 306 - ] - }, - { - "type": "number", - "enum": [ - 307 - ] - }, - { - "type": "number", - "enum": [ - 308 - ] - }, - { - "type": "number", - "enum": [ - 400 - ] - }, - { - "type": "number", - "enum": [ - 401 - ] - }, - { - "type": "number", - "enum": [ - 402 - ] - }, - { - "type": "number", - "enum": [ - 403 - ] - }, - { - "type": "number", - "enum": [ - 404 - ] - }, - { - "type": "number", - "enum": [ - 405 - ] - }, - { - "type": "number", - "enum": [ - 406 - ] - }, - { - "type": "number", - "enum": [ - 407 - ] - }, - { - "type": "number", - "enum": [ - 408 - ] - }, - { - "type": "number", - "enum": [ - 409 - ] - }, - { - "type": "number", - "enum": [ - 410 - ] - }, - { - "type": "number", - "enum": [ - 411 - ] - }, - { - "type": "number", - "enum": [ - 412 - ] - }, - { - "type": "number", - "enum": [ - 413 - ] - }, - { - "type": "number", - "enum": [ - 414 - ] - }, - { - "type": "number", - "enum": [ - 415 - ] - }, - { - "type": "number", - "enum": [ - 416 - ] - }, - { - "type": "number", - "enum": [ - 417 - ] - }, - { - "type": "number", - "enum": [ - 418 - ] - }, - { - "type": "number", - "enum": [ - 421 - ] - }, - { - "type": "number", - "enum": [ - 422 - ] - }, - { - "type": "number", - "enum": [ - 423 - ] - }, - { - "type": "number", - "enum": [ - 424 - ] - }, - { - "type": "number", - "enum": [ - 425 - ] - }, - { - "type": "number", - "enum": [ - 426 - ] - }, - { - "type": "number", - "enum": [ - 428 - ] - }, - { - "type": "number", - "enum": [ - 429 - ] - }, - { - "type": "number", - "enum": [ - 431 - ] - }, - { - "type": "number", - "enum": [ - 451 - ] - }, - { - "type": "number", - "enum": [ - 500 - ] - }, - { - "type": "number", - "enum": [ - 501 - ] - }, - { - "type": "number", - "enum": [ - 502 - ] - }, - { - "type": "number", - "enum": [ - 503 - ] - }, - { - "type": "number", - "enum": [ - 504 - ] - }, - { - "type": "number", - "enum": [ - 505 - ] - }, - { - "type": "number", - "enum": [ - 506 - ] - }, - { - "type": "number", - "enum": [ - 507 - ] - }, - { - "type": "number", - "enum": [ - 508 - ] - }, - { - "type": "number", - "enum": [ - 510 - ] - }, - { - "type": "number", - "enum": [ - 511 - ] - }, - { - "type": "number", - "enum": [ - -1 - ] - } - ], - "example": 400, - "description": "HTTPステータスコード" - }, - "message": { - "type": "string", - "minLength": 1, - "example": "Bad Request", - "description": "エラーメッセージ" - } - }, - "required": [ - "status", - "message" - ] - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { - "anyOf": [ - { - "type": "number", - "enum": [ - 100 - ] - }, - { - "type": "number", - "enum": [ - 102 - ] - }, - { - "type": "number", - "enum": [ - 103 - ] - }, - { - "type": "number", - "enum": [ - 200 - ] - }, - { - "type": "number", - "enum": [ - 201 - ] - }, - { - "type": "number", - "enum": [ - 202 - ] - }, - { - "type": "number", - "enum": [ - 203 - ] - }, - { - "type": "number", - "enum": [ - 206 - ] - }, - { - "type": "number", - "enum": [ - 207 - ] - }, - { - "type": "number", - "enum": [ - 208 - ] - }, - { - "type": "number", - "enum": [ - 226 - ] - }, - { - "type": "number", - "enum": [ - 300 - ] - }, - { - "type": "number", - "enum": [ - 301 - ] - }, - { - "type": "number", - "enum": [ - 302 - ] - }, - { - "type": "number", - "enum": [ - 303 - ] - }, - { - "type": "number", - "enum": [ - 305 - ] - }, - { - "type": "number", - "enum": [ - 306 - ] - }, - { - "type": "number", - "enum": [ - 307 - ] - }, - { - "type": "number", - "enum": [ - 308 - ] - }, - { - "type": "number", - "enum": [ - 400 - ] - }, - { - "type": "number", - "enum": [ - 401 - ] - }, - { - "type": "number", - "enum": [ - 402 - ] - }, - { - "type": "number", - "enum": [ - 403 - ] - }, - { - "type": "number", - "enum": [ - 404 - ] - }, - { - "type": "number", - "enum": [ - 405 - ] - }, - { - "type": "number", - "enum": [ - 406 - ] - }, - { - "type": "number", - "enum": [ - 407 - ] - }, - { - "type": "number", - "enum": [ - 408 - ] - }, - { - "type": "number", - "enum": [ - 409 - ] - }, - { - "type": "number", - "enum": [ - 410 - ] - }, - { - "type": "number", - "enum": [ - 411 - ] - }, - { - "type": "number", - "enum": [ - 412 - ] - }, - { - "type": "number", - "enum": [ - 413 - ] - }, - { - "type": "number", - "enum": [ - 414 - ] - }, - { - "type": "number", - "enum": [ - 415 - ] - }, - { - "type": "number", - "enum": [ - 416 - ] - }, - { - "type": "number", - "enum": [ - 417 - ] - }, - { - "type": "number", - "enum": [ - 418 - ] - }, - { - "type": "number", - "enum": [ - 421 - ] - }, - { - "type": "number", - "enum": [ - 422 - ] - }, - { - "type": "number", - "enum": [ - 423 - ] - }, - { - "type": "number", - "enum": [ - 424 - ] - }, - { - "type": "number", - "enum": [ - 425 - ] - }, - { - "type": "number", - "enum": [ - 426 - ] - }, - { - "type": "number", - "enum": [ - 428 - ] - }, - { - "type": "number", - "enum": [ - 429 - ] - }, - { - "type": "number", - "enum": [ - 431 - ] - }, - { - "type": "number", - "enum": [ - 451 - ] - }, - { - "type": "number", - "enum": [ - 500 - ] - }, - { - "type": "number", - "enum": [ - 501 - ] - }, - { - "type": "number", - "enum": [ - 502 - ] - }, - { - "type": "number", - "enum": [ - 503 - ] - }, - { - "type": "number", - "enum": [ - 504 - ] - }, - { - "type": "number", - "enum": [ - 505 - ] - }, - { - "type": "number", - "enum": [ - 506 - ] - }, - { - "type": "number", - "enum": [ - 507 - ] - }, - { - "type": "number", - "enum": [ - 508 - ] - }, - { - "type": "number", - "enum": [ - 510 - ] - }, - { - "type": "number", - "enum": [ - 511 - ] - }, - { - "type": "number", - "enum": [ - -1 - ] - } - ], - "example": 400, - "description": "HTTPステータスコード" - }, - "message": { - "type": "string", - "minLength": 1, - "example": "Bad Request", - "description": "エラーメッセージ" - } - }, - "required": [ - "status", - "message" - ] - } - } - } - } - } - } - }, - "/api/group/debt/delete": { - "delete": { - "description": "delete group debt entry", - "security": [ - { - "SessionCookie": [] - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "group_id": { - "type": "string", - "minLength": 1 - }, - "debt_id": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "group_id", - "debt_id" - ] - } - } - } - }, - "responses": { - "200": { - "description": "Created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "debt_id": { + }, + { + "type": "number", + "enum": [ + 511 + ] + }, + { + "type": "number", + "enum": [ + -1 + ] + } + ], + "example": 400, + "description": "HTTPステータスコード" + }, + "message": { "type": "string", - "minLength": 1 + "minLength": 1, + "example": "Bad Request", + "description": "エラーメッセージ" } }, "required": [ - "debt_id" + "status", + "message" ] } } } }, - "400": { - "description": "Bad Request", + "401": { + "description": "Unauthorized", "content": { "application/json": { "schema": { @@ -9524,8 +7896,8 @@ } } }, - "401": { - "description": "Unauthorized", + "500": { + "description": "Internal Server Error", "content": { "application/json": { "schema": { @@ -9911,9 +8283,48 @@ } } } + } + } + } + }, + "/api/group/debt/delete": { + "delete": { + "description": "delete group debt entry", + "security": [ + { + "SessionCookie": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group_id": { + "type": "string", + "minLength": 1 + }, + "debt_id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "group_id", + "debt_id" + ] + } + } + } + }, + "responses": { + "204": { + "description": "No Content" }, - "500": { - "description": "Internal Server Error", + "400": { + "description": "Bad Request", "content": { "application/json": { "schema": { @@ -10299,49 +8710,9 @@ } } } - } - } - } - }, - "/api/profile": { - "get": { - "description": "get user profile", - "security": [ - { - "SessionCookie": [] - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "display_name": { - "type": "string", - "minLength": 1 - }, - "avatar_url": { - "type": "string", - "format": "uri" - }, - "bio": { - "type": "string" - } - }, - "required": [ - "display_name", - "avatar_url", - "bio" - ] - } - } - } }, - "400": { - "description": "Bad Request", + "401": { + "description": "Unauthorized", "content": { "application/json": { "schema": { @@ -10728,8 +9099,8 @@ } } }, - "401": { - "description": "Unauthorized", + "500": { + "description": "Internal Server Error", "content": { "application/json": { "schema": { @@ -11115,9 +9486,49 @@ } } } + } + } + } + }, + "/api/profile": { + "get": { + "description": "ログインユーザーのプロフィール情報を取得するエンドポイント", + "security": [ + { + "SessionCookie": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "display_name": { + "type": "string", + "minLength": 1 + }, + "avatar_url": { + "type": "string", + "format": "uri" + }, + "bio": { + "type": "string" + } + }, + "required": [ + "display_name", + "avatar_url", + "bio" + ] + } + } + } }, - "500": { - "description": "Internal Server Error", + "401": { + "description": "Unauthorized", "content": { "application/json": { "schema": { @@ -11503,69 +9914,9 @@ } } } - } - } - }, - "put": { - "description": "update user profile", - "security": [ - { - "SessionCookie": [] - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "display_name": { - "type": "string" - }, - "avatar_url": { - "type": "string", - "format": "uri" - }, - "bio": { - "type": "string" - } - } - } - } - } - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "display_name": { - "type": "string", - "minLength": 1 - }, - "avatar_url": { - "type": "string", - "format": "uri" - }, - "bio": { - "type": "string" - } - }, - "required": [ - "display_name", - "avatar_url", - "bio" - ] - } - } - } }, - "400": { - "description": "Bad Request", + "500": { + "description": "Internal Server Error", "content": { "application/json": { "schema": { @@ -11951,6 +10302,41 @@ } } } + } + } + }, + "patch": { + "description": "ログインユーザーのプロフィール情報を更新するエンドポイント", + "security": [ + { + "SessionCookie": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + }, + "avatar_url": { + "type": "string", + "format": "uri" + }, + "bio": { + "type": "string" + } + } + } + } + } + }, + "responses": { + "204": { + "description": "No Content" }, "401": { "description": "Unauthorized", diff --git a/products/frontend/src/api/openapi.d.ts b/products/frontend/src/api/openapi.d.ts index d65d222..367767b 100644 --- a/products/frontend/src/api/openapi.d.ts +++ b/products/frontend/src/api/openapi.d.ts @@ -4,85 +4,6 @@ */ export interface paths { - "/api/session": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** @description sample endpoint to get session info */ - get: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - id: string; - email: string; - }; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** - * @description HTTPステータスコード - * @example 400 - */ - status: 100 | 102 | 103 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | -1; - /** - * @description エラーメッセージ - * @example Bad Request - */ - message: string; - }; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** - * @description HTTPステータスコード - * @example 400 - */ - status: 100 | 102 | 103 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | -1; - /** - * @description エラーメッセージ - * @example Bad Request - */ - message: string; - }; - }; - }; - }; - }; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; "/api/info/group": { parameters: { query?: never; @@ -90,7 +11,7 @@ export interface paths { path?: never; cookie?: never; }; - /** @description get info about groups the user belongs to */ + /** @description ログインユーザーが参加しているグループ一覧を取得するエンドポイント */ get: { parameters: { query?: never; @@ -177,7 +98,7 @@ export interface paths { path?: never; cookie?: never; }; - /** @description get info about user transactions */ + /** @description ログインユーザーの貸し借りの履歴を取得するエンドポイント */ get: { parameters: { query?: never; @@ -246,7 +167,7 @@ export interface paths { }; put?: never; post?: never; - /** @description do user repayment */ + /** @description ログインユーザーと指定された取引相手間の取引履歴を削除する (完済する) エンドポイント */ delete: { parameters: { query?: never; @@ -262,36 +183,12 @@ export interface paths { }; }; responses: { - /** @description Created */ - 200: { + /** @description No Content */ + 204: { headers: { [name: string]: unknown; }; - content: { - "application/json": { - counterparty_id: string; - }; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** - * @description HTTPステータスコード - * @example 400 - */ - status: 100 | 102 | 103 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | -1; - /** - * @description エラーメッセージ - * @example Bad Request - */ - message: string; - }; - }; + content?: never; }; /** @description Unauthorized */ 401: { @@ -349,7 +246,7 @@ export interface paths { }; get?: never; put?: never; - /** @description create a new group */ + /** @description グループを新規作成するエンドポイント */ post: { parameters: { query?: never; @@ -360,7 +257,7 @@ export interface paths { requestBody: { content: { "application/json": { - name: string; + group_name: string; }; }; }; @@ -378,26 +275,6 @@ export interface paths { }; }; }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** - * @description HTTPステータスコード - * @example 400 - */ - status: 100 | 102 | 103 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | -1; - /** - * @description エラーメッセージ - * @example Bad Request - */ - message: string; - }; - }; - }; /** @description Unauthorized */ 401: { headers: { @@ -455,7 +332,7 @@ export interface paths { }; get?: never; put?: never; - /** @description join an existing group */ + /** @description 招待IDを使ってグループに参加するエンドポイント */ post: { parameters: { query?: never; @@ -576,8 +453,8 @@ export interface paths { }; }; responses: { - /** @description OK */ - 200: { + /** @description Created */ + 201: { headers: { [name: string]: unknown; }; @@ -686,8 +563,8 @@ export interface paths { }; }; responses: { - /** @description OK */ - 200: { + /** @description Created */ + 201: { headers: { [name: string]: unknown; }; @@ -912,16 +789,12 @@ export interface paths { }; }; responses: { - /** @description Created */ - 200: { + /** @description No Content */ + 204: { headers: { [name: string]: unknown; }; - content: { - "application/json": { - debt_id: string; - }; - }; + content?: never; }; /** @description Bad Request */ 400: { @@ -997,7 +870,7 @@ export interface paths { path?: never; cookie?: never; }; - /** @description get user profile */ + /** @description ログインユーザーのプロフィール情報を取得するエンドポイント */ get: { parameters: { query?: never; @@ -1021,26 +894,6 @@ export interface paths { }; }; }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - /** - * @description HTTPステータスコード - * @example 400 - */ - status: 100 | 102 | 103 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | -1; - /** - * @description エラーメッセージ - * @example Bad Request - */ - message: string; - }; - }; - }; /** @description Unauthorized */ 401: { headers: { @@ -1083,8 +936,13 @@ export interface paths { }; }; }; - /** @description update user profile */ - put: { + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + /** @description ログインユーザーのプロフィール情報を更新するエンドポイント */ + patch: { parameters: { query?: never; header?: never; @@ -1102,39 +960,12 @@ export interface paths { }; }; responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - display_name: string; - /** Format: uri */ - avatar_url: string; - bio: string; - }; - }; - }; - /** @description Bad Request */ - 400: { + /** @description No Content */ + 204: { headers: { [name: string]: unknown; }; - content: { - "application/json": { - /** - * @description HTTPステータスコード - * @example 400 - */ - status: 100 | 102 | 103 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | -1; - /** - * @description エラーメッセージ - * @example Bad Request - */ - message: string; - }; - }; + content?: never; }; /** @description Unauthorized */ 401: { @@ -1178,11 +1009,6 @@ export interface paths { }; }; }; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; trace?: never; }; } diff --git a/products/frontend/src/routes/GenerateGroup/index.tsx b/products/frontend/src/routes/GenerateGroup/index.tsx index ddb1360..2a26e16 100644 --- a/products/frontend/src/routes/GenerateGroup/index.tsx +++ b/products/frontend/src/routes/GenerateGroup/index.tsx @@ -1,6 +1,5 @@ import { useState, type FC } from 'react'; // @tanstack/react-query -// import { useQueryClient } from '@tanstack/react-query'; import { $api } from '../../api/fetchClient'; // react-hook-form import { ErrorMessage } from '@hookform/error-message'; @@ -14,22 +13,18 @@ import { } from 'validator'; const GenerateGroup: FC = () => { - // const queryClient = useQueryClient(); - const [isResultError, setIsResultError] = useState(false); + // グループ作成処理 const [result, setResult] = useState(null); const { mutate, isSuccess, isPending, isError, error } = $api.useMutation('post', '/api/group/create', { onSuccess: (data) => { - if (!data?.group_id || !data?.invite_id) { - setIsResultError(true); - } else { - setResult({ - group_id: data?.group_id, - invite_id: data?.invite_id, - }); - } + setResult({ + group_id: data?.group_id, + invite_id: data?.invite_id, + }); }, }); + // react-hook-formの設定 const { register, handleSubmit, @@ -37,10 +32,11 @@ const GenerateGroup: FC = () => { } = useForm({ resolver: zodResolver(createGroupRequestSchema), defaultValues: { - name: '', + group_name: '', }, }); + // グループ作成ハンドラ const onSubmit: SubmitHandler = async (formData) => { mutate({ body: formData, credentials: 'include' }); }; @@ -50,9 +46,9 @@ const GenerateGroup: FC = () => {

グループの作成

- - - + + +
))} - ) : isDebtHistoryResultError ? ( -

グループの履歴の取得に失敗しました。再度お試しください。

- ) : null} + )} ); }; diff --git a/products/frontend/src/routes/Invite/index.tsx b/products/frontend/src/routes/Invite/index.tsx index 6f84ad1..9b2e232 100644 --- a/products/frontend/src/routes/Invite/index.tsx +++ b/products/frontend/src/routes/Invite/index.tsx @@ -1,49 +1,42 @@ import { useState, type FC } from 'react'; import { Link, useParams } from 'react-router'; // @tanstack/react-query -// import { useQueryClient } from '@tanstack/react-query'; import { $api } from '../../api/fetchClient'; const Invite: FC = () => { + // URLパラメータからinviteIdを取得 const { inviteId } = useParams<{ inviteId: string }>(); + + // inviteIdが存在しない場合の処理 if (!inviteId) return

Invite ID is not provided.

; - const [isResultError, setIsResultError] = useState(false); + // グループ参加処理 const [result, setResult] = useState(null); const { mutate, isSuccess, isPending, isError, error } = $api.useMutation('post', `/api/group/join`, { onSuccess: (data) => { - if (!data?.group_id) { - setIsResultError(true); - } else { - setResult(data.group_id); - } + // グループIDをセット + setResult(data.group_id); }, }); - const inviteClickHandler = (inviteId: string) => { + // グループ参加ハンドラ + const inviteHandler = (inviteId: string) => { mutate({ body: { invite_id: inviteId }, credentials: 'include' }); }; return ( <>

招待

-

招待ID: {inviteId}

- + {isPending &&

参加処理中...

} - {result &&

参加したグループID: {result}

} {isError &&

エラーが発生しました: {error.message}

} - {isSuccess && !isResultError && result ? ( + {isSuccess && ( <>

グループ参加結果

グループID: {result} に参加しました。

グループページへ移動 - ) : isResultError ? ( - <> -

グループ参加結果

-

グループの参加に失敗しました。再度お試しください。

- - ) : null} + )} ); }; diff --git a/products/frontend/src/routes/Profile/index.tsx b/products/frontend/src/routes/Profile/index.tsx index a2fdca3..9f50fd7 100644 --- a/products/frontend/src/routes/Profile/index.tsx +++ b/products/frontend/src/routes/Profile/index.tsx @@ -1,41 +1,22 @@ -import { useEffect, useState, type FC } from 'react'; +import { useEffect, type FC } from 'react'; // @tanstack/react-query -// import { useQueryClient } from '@tanstack/react-query'; import { $api } from '../../api/fetchClient'; -import { - updateUserProfileRequestSchema, - type UpdateUserProfileRequestSchemaType, - type UpdateUserProfileResponseSchemaType, -} from 'validator'; +import { updateUserProfileRequestSchema, type UpdateUserProfileRequestSchemaType } from 'validator'; // react-hook-form import { ErrorMessage } from '@hookform/error-message'; import { zodResolver } from '@hookform/resolvers/zod'; import { useForm, type SubmitHandler } from 'react-hook-form'; const Profile: FC = () => { + // ユーサープロフィール情報の取得 const userProfileQuery = $api.useQuery('get', '/api/profile', { credentials: 'include', }); - const [isUserProfileResultError, setIsUserProfileResultError] = useState(false); - const [userProfileResult, setUserProfileResult] = useState(null); - const userProfileMutation = $api.useMutation('put', `/api/profile`, { - onSuccess: (data) => { - if (!data) { - setIsUserProfileResultError(true); - } else { - // convert dat to UpdateUserProfileResponseSchemaType - const userProfile: UpdateUserProfileResponseSchemaType = { - display_name: data.display_name, - avatar_url: data.avatar_url, - bio: data.bio, - }; - // set group info result - setUserProfileResult(userProfile); - } - }, - }); + // ユーザープロフィール情報の更新 + const userProfileMutation = $api.useMutation('patch', `/api/profile`); + // react-hook-formの設定 const { register, handleSubmit, @@ -50,6 +31,7 @@ const Profile: FC = () => { } satisfies UpdateUserProfileRequestSchemaType, }); + // ユーザープロフィール情報が取得できたらフォームに現在のユーザープロフィール情報をセット useEffect(() => { if (userProfileQuery.data) { reset({ @@ -60,6 +42,7 @@ const Profile: FC = () => { } }, [userProfileQuery.data, reset]); + // プロフィール更新ハンドラ const onSubmit: SubmitHandler = (formData) => { userProfileMutation.mutate({ body: { ...formData }, credentials: 'include' }); }; @@ -67,11 +50,9 @@ const Profile: FC = () => { return ( <>

プロフィールの編集

- {userProfileQuery.isLoading ? ( -

Loading...

- ) : userProfileQuery.isError ? ( -

Error: {userProfileQuery.error.message}

- ) : ( + {userProfileQuery.isLoading &&

Loading...

} + {userProfileQuery.isError &&

Error: {userProfileQuery.error.message}

} + {userProfileQuery.isSuccess && ( <>
@@ -85,6 +66,7 @@ const Profile: FC = () => { />
+
{ />
+