Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frontend
VITE_API_URL=
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing environment variable VITE_CLIENT_URL. The diff shows VITE_CLIENT_URL being added to various configuration files (setup/src/types.ts, products/frontend/.env.example, GitHub workflows), but it's missing from the root .env.example file. This variable should be added after VITE_API_URL for consistency.

Suggested change
VITE_API_URL=
VITE_API_URL=
VITE_CLIENT_URL=

Copilot uses AI. Check for mistakes.
VITE_REDIRECT_URL=

# backend
POSTGRES_USER=
Expand All @@ -11,3 +12,5 @@ BETTER_AUTH_URL=
BETTER_AUTH_SECRET=
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
1 change: 1 addition & 0 deletions .github/workflows/deploy-frontend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
- name: Build
env:
VITE_API_URL: ${{ secrets.VITE_API_URL }}
VITE_CLIENT_URL: ${{ secrets.VITE_CLIENT_URL }}
VITE_REDIRECT_URL: ${{ secrets.VITE_REDIRECT_URL }}
run: nix develop --command bash -c "pnpm i && pnpm run build"
# Deploy Frontend to Cloudflare Workers
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/preview-frontend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
id: build
env:
VITE_API_URL: ${{ secrets.VITE_API_URL }}
VITE_CLIENT_URL: ${{ secrets.VITE_CLIENT_URL }}
VITE_REDIRECT_URL: ${{ secrets.VITE_REDIRECT_URL }}
run: nix develop --command bash -c "pnpm i && pnpm run frontend:build"
# Deploy Preview to Cloudflare Workers
Expand Down
7 changes: 0 additions & 7 deletions assets/er.mmd
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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"
Expand Down
Binary file modified assets/er.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ catalogs:
turbo: ^2.5.8
setup:
dotenv: ^17.2.3
dotenv-caster: ^2.1.23
dotenv-caster: ^2.2.1

ignoredBuiltDependencies:
- '@swc/core'
Expand Down
3 changes: 3 additions & 0 deletions products/backend/.env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DATABASE_URL=
DATABASE_CREDENTIALS_SSL_REJECT_UNAUTHORIZED=
BETTER_AUTH_URL=
BETTER_AUTH_SECRET=
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
22 changes: 22 additions & 0 deletions products/backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -100,6 +104,21 @@ 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
auth-schema --> schema
relation --> schema
pay-crew2 --> relation
pay-crew2 --> schema
```

## 構造

この構造は、レイヤードアーキテクチャから着想を得て定義している。
Expand All @@ -116,6 +135,7 @@ pnpm run backend:deploy
- hono
- @hono/zod-openapi
- zod-openapi-share
- better-auth


#### presentation/share
Expand All @@ -128,6 +148,7 @@ presentation層で共通して使用するエンティティを定義する。

- 外部依存
- drizzle
- better-auth

### db

Expand All @@ -146,6 +167,7 @@ openapi.jsonの生成を行う処理を定義している。
- hono
- @hono/zod-openapi
- zod-openapi-share
- better-auth

## 依存関係

Expand Down
2 changes: 1 addition & 1 deletion products/backend/drizzle.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const databaseCredentialsSslRejectUnauthorized = caster.castBoolean(

export default {
dialect: 'postgresql',
schema: './src/db/schema.ts',
schema: ['./src/db/auth-schema.ts', './src/db/pay-crew2-schema.ts', './src/db/relation.ts'],
out: './drizzle',
dbCredentials: {
url: databaseUrl,
Expand Down
36 changes: 13 additions & 23 deletions products/backend/src/db/auth-schema.ts
Original file line number Diff line number Diff line change
@@ -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),
]
);

Expand Down
19 changes: 3 additions & 16 deletions products/backend/src/db/relation.ts
Original file line number Diff line number Diff line change
@@ -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],
}),
export const userRelations = relations(user, ({ many }) => ({
sessions: many(session, {
relationName: 'user__session_userId',
}),
Expand All @@ -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],
Expand Down
2 changes: 2 additions & 0 deletions products/backend/src/db/schema.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from './auth-schema';
export * from './pay-crew2-schema';
export * from './relation';
2 changes: 1 addition & 1 deletion products/backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion products/backend/src/presentation/factory/hono.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const honoFactory = () => {
if (!result.success) {
console.error(result.error);
throw new HTTPException(400, {
message: 'Zod Validation Error',
message: 'Bad Request',
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message has been changed from "Zod Validation Error" to the generic "Bad Request". While this may be intentional for security reasons to avoid exposing internal validation details, it makes debugging more difficult. Consider logging the specific validation error internally while returning a generic message to the client, or provide more specific error messages in a development environment.

Copilot uses AI. Check for mistakes.
});
}
},
Expand Down
Loading
Loading