Skip to content

Commit 7fc9463

Browse files
authored
Merge pull request #176 from TECH-C-LT/feature/playground-usage-count
Playgroundに使用回数カウントを追加
2 parents e73cb05 + ea73cb3 commit 7fc9463

File tree

5 files changed

+176
-30
lines changed

5 files changed

+176
-30
lines changed

apps/web/src/app/(main)/dashboard/(palygroud)/actions/index.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import { parseWithZod } from '@conform-to/zod'
44

5+
import { createClient } from '~/lib/supabase/server'
6+
57
import { playgroundSchema } from '../schemas'
68

79
export async function handlePlayground(prevState: unknown, formData: FormData) {
@@ -13,8 +15,20 @@ export async function handlePlayground(prevState: unknown, formData: FormData) {
1315

1416
const { api, text, score_threshold } = submission.value
1517

18+
const count = await checkUsageCount()
19+
20+
if (count >= 10) {
21+
submission.value.isLimitReached = true
22+
return {
23+
status: submission.status,
24+
value: submission.value,
25+
}
26+
}
27+
1628
const result = await fetchApi(api, text, score_threshold)
1729

30+
await incrementPlaygroundUsage()
31+
1832
submission.value.result = JSON.stringify(result, null, 2)
1933

2034
return {
@@ -42,3 +56,40 @@ async function fetchApi(api: string, text: string, score_threshold: number) {
4256

4357
return result
4458
}
59+
60+
async function checkUsageCount(): Promise<number> {
61+
const supabase = createClient()
62+
63+
const { data } = await supabase.auth.getUser()
64+
65+
if (!data.user?.id) {
66+
throw new Error('User not found')
67+
}
68+
69+
const PlaygroundUsageRes = await supabase
70+
.from('playground_usage')
71+
.select('count')
72+
.eq('user_id', data.user?.id)
73+
74+
return PlaygroundUsageRes.data?.[0]?.count as number
75+
}
76+
77+
async function incrementPlaygroundUsage() {
78+
const supabase = createClient()
79+
80+
const { data } = await supabase.auth.getUser()
81+
82+
const { data: res, error } = await (supabase.rpc as any)(
83+
'increment_playground_usage',
84+
{
85+
input_user_id: data.user?.id,
86+
},
87+
)
88+
89+
if (error) {
90+
console.error(error)
91+
throw new Error('Failed to increment playground usage')
92+
}
93+
94+
return
95+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
'use client'
2+
3+
import {
4+
AlertDialog,
5+
AlertDialogAction,
6+
AlertDialogContent,
7+
AlertDialogDescription,
8+
AlertDialogFooter,
9+
AlertDialogHeader,
10+
AlertDialogTitle,
11+
} from '@peace-net/ui/components/ui/alert-dialog'
12+
import type { User } from '@supabase/supabase-js'
13+
import Link from 'next/link'
14+
import { useEffect, useState } from 'react'
15+
16+
import GitHub from '~/components/header/github'
17+
import { createClient } from '~/lib/supabase/client'
18+
19+
export default function LimitReachedDialog() {
20+
const [user, setUser] = useState<User | null>(null)
21+
22+
const handleGetSession = async () => {
23+
const supabase = createClient()
24+
25+
const { data } = await supabase.auth.getUser()
26+
27+
if (data) {
28+
setUser(data.user)
29+
}
30+
}
31+
32+
useEffect(() => {
33+
handleGetSession()
34+
}, [])
35+
36+
return (
37+
<AlertDialog defaultOpen>
38+
<AlertDialogContent>
39+
<AlertDialogHeader>
40+
<AlertDialogTitle>これ以上使用できません。😭</AlertDialogTitle>
41+
<AlertDialogDescription>
42+
プレイグラウンドの利用回数が上限に達しました。
43+
<br />
44+
実際のAPIを使用してください。
45+
</AlertDialogDescription>
46+
</AlertDialogHeader>
47+
<AlertDialogFooter>
48+
<AlertDialogAction asChild>
49+
{user?.is_anonymous ? (
50+
<GitHub />
51+
) : (
52+
<Link href="/dashboard/api-keys">APIキー管理ページ</Link>
53+
)}
54+
</AlertDialogAction>
55+
</AlertDialogFooter>
56+
</AlertDialogContent>
57+
</AlertDialog>
58+
)
59+
}

apps/web/src/app/(main)/dashboard/(palygroud)/components/playground-form.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { TextareaConform } from '~/components/conform/textarea'
1515
import { handlePlayground } from '../actions'
1616
import type { Playground } from '../schemas'
1717
import { playgroundSchema } from '../schemas'
18+
import LimitReachedDialog from './limit-reached-dialog'
1819
import { ResultSyntax } from './result-syntax'
1920

2021
function isSuccessResult(
@@ -42,6 +43,7 @@ export function PlaygroundForm() {
4243
result: isSuccessResult(lastResult) ? lastResult.value.result : '',
4344
},
4445
})
46+
4547
return (
4648
<div className="flex flex-wrap gap-3 rounded border p-4">
4749
<form
@@ -106,9 +108,12 @@ export function PlaygroundForm() {
106108
</Button>
107109
</div>
108110
</form>
109-
{isSuccessResult(lastResult) && (
111+
{isSuccessResult(lastResult) && !lastResult.value.isLimitReached && (
110112
<ResultSyntax code={lastResult.value.result} />
111113
)}
114+
{isSuccessResult(lastResult) && lastResult.value.isLimitReached && (
115+
<LimitReachedDialog />
116+
)}
112117
</div>
113118
)
114119
}

apps/web/src/app/(main)/dashboard/(palygroud)/schemas/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const playgroundSchema = z.object({
1010
.max(500, { message: 'テキストは500文字以下で入力してください' }),
1111
score_threshold: z.number().max(1).min(0).optional().default(0.5),
1212
result: z.any().optional(),
13+
isLimitReached: z.boolean().optional(),
1314
})
1415

1516
export type Playground = z.infer<typeof playgroundSchema>

packages/shared/src/types/database.ts

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,14 @@ export type Json =
77
| Json[]
88

99
export type Database = {
10-
graphql_public: {
11-
Tables: {
12-
[_ in never]: never
13-
}
14-
Views: {
15-
[_ in never]: never
16-
}
17-
Functions: {
18-
graphql: {
19-
Args: {
20-
operationName?: string
21-
query?: string
22-
variables?: Json
23-
extensions?: Json
24-
}
25-
Returns: Json
26-
}
27-
}
28-
Enums: {
29-
[_ in never]: never
30-
}
31-
CompositeTypes: {
32-
[_ in never]: never
33-
}
34-
}
3510
public: {
3611
Tables: {
3712
api_keys: {
3813
Row: {
3914
created_at: string | null
4015
description: string | null
41-
expires_at: string | null
4216
encrypted_key: string | null
17+
expires_at: string | null
4318
id: string
4419
is_active: boolean | null
4520
last_used: string | null
@@ -49,8 +24,8 @@ export type Database = {
4924
Insert: {
5025
created_at?: string | null
5126
description?: string | null
52-
expires_at?: string | null
5327
encrypted_key?: string | null
28+
expires_at?: string | null
5429
id?: string
5530
is_active?: boolean | null
5631
last_used?: string | null
@@ -60,8 +35,8 @@ export type Database = {
6035
Update: {
6136
created_at?: string | null
6237
description?: string | null
63-
expires_at?: string | null
6438
encrypted_key?: string | null
39+
expires_at?: string | null
6540
id?: string
6641
is_active?: boolean | null
6742
last_used?: string | null
@@ -102,6 +77,38 @@ export type Database = {
10277
}
10378
Relationships: []
10479
}
80+
playground_usage: {
81+
Row: {
82+
count: number | null
83+
id: string
84+
last_reset: string | null
85+
total_count: number | null
86+
user_id: string
87+
}
88+
Insert: {
89+
count?: number | null
90+
id?: string
91+
last_reset?: string | null
92+
total_count?: number | null
93+
user_id: string
94+
}
95+
Update: {
96+
count?: number | null
97+
id?: string
98+
last_reset?: string | null
99+
total_count?: number | null
100+
user_id?: string
101+
}
102+
Relationships: [
103+
{
104+
foreignKeyName: 'playground_usage_user_id_fkey'
105+
columns: ['user_id']
106+
isOneToOne: true
107+
referencedRelation: 'users'
108+
referencedColumns: ['id']
109+
},
110+
]
111+
}
105112
usage_logs: {
106113
Row: {
107114
api_key_id: string | null
@@ -181,7 +188,30 @@ export type Database = {
181188
[_ in never]: never
182189
}
183190
Functions: {
184-
[_ in never]: never
191+
increment_playground_usage: {
192+
Args: {
193+
input_user_id: string
194+
}
195+
Returns: {
196+
new_count: number
197+
new_total_count: number
198+
remaining: number
199+
}[]
200+
}
201+
increment_total_requests_used: {
202+
Args: {
203+
p_user_id: string
204+
}
205+
Returns: undefined
206+
}
207+
increment_usage_log: {
208+
Args: {
209+
p_api_key_id: string
210+
p_endpoint: string
211+
p_date: string
212+
}
213+
Returns: undefined
214+
}
185215
}
186216
Enums: {
187217
[_ in never]: never

0 commit comments

Comments
 (0)