npx claudepluginhub joshuarweaver/cascade-code-general-misc-1 --plugin tubone24-claude-code-settingsThis skill uses the workspace's default tool permissions.
スケーラブルなサーバーサイドアプリケーションのためのバックエンドアーキテクチャパターン。
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
スケーラブルなサーバーサイドアプリケーションのためのバックエンドアーキテクチャパターン。
GET /api/markets # リソース一覧
GET /api/markets/:id # 単一リソース取得
POST /api/markets # リソース作成
PUT /api/markets/:id # リソース置換
PATCH /api/markets/:id # リソース更新
DELETE /api/markets/:id # リソース削除
// フィルタリング、ソート、ページネーション
GET /api/markets?status=active&sort=volume&limit=20&offset=0
interface MarketRepository {
findAll(filters?: MarketFilters): Promise<Market[]>
findById(id: string): Promise<Market | null>
create(data: CreateMarketDto): Promise<Market>
update(id: string, data: UpdateMarketDto): Promise<Market>
delete(id: string): Promise<void>
}
class SupabaseMarketRepository implements MarketRepository {
async findAll(filters?: MarketFilters): Promise<Market[]> {
let query = supabase.from('markets').select('*')
if (filters?.status) query = query.eq('status', filters.status)
if (filters?.limit) query = query.limit(filters.limit)
const { data, error } = await query
if (error) throw new Error(error.message)
return data
}
}
export function withAuth(handler: NextApiHandler): NextApiHandler {
return async (req, res) => {
const token = req.headers.authorization?.replace('Bearer ', '')
if (!token) return res.status(401).json({ error: 'Unauthorized' })
try {
const user = await verifyToken(token)
req.user = user
return handler(req, res)
} catch (error) {
return res.status(401).json({ error: 'Invalid token' })
}
}
}
// ❌ 悪い例: N+1クエリ問題
const markets = await getMarkets()
for (const market of markets) {
market.creator = await getUser(market.creator_id)
}
// ✅ 良い例: バッチ取得
const markets = await getMarkets()
const creatorIds = markets.map(m => m.creator_id)
const creators = await getUsers(creatorIds)
const creatorMap = new Map(creators.map(c => [c.id, c]))
markets.forEach(market => {
market.creator = creatorMap.get(market.creator_id)
})
// ✅ 必要なカラムのみ選択
const { data } = await supabase
.from('markets')
.select('id, name, status, volume')
.eq('status', 'active')
.order('volume', { ascending: false })
.limit(10)
async function getMarketWithCache(id: string): Promise<Market> {
const cacheKey = `market:${id}`
const cached = await redis.get(cacheKey)
if (cached) return JSON.parse(cached)
const market = await db.markets.findUnique({ where: { id } })
if (!market) throw new Error('Market not found')
await redis.setex(cacheKey, 300, JSON.stringify(market))
return market
}
class ApiError extends Error {
constructor(
public statusCode: number,
public message: string,
public isOperational = true
) {
super(message)
}
}
export function errorHandler(error: unknown, req: Request): Response {
if (error instanceof ApiError) {
return NextResponse.json({
success: false,
error: error.message
}, { status: error.statusCode })
}
if (error instanceof z.ZodError) {
return NextResponse.json({
success: false,
error: 'Validation failed',
details: error.errors
}, { status: 400 })
}
return NextResponse.json({
success: false,
error: 'Internal server error'
}, { status: 500 })
}
async function fetchWithRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
let lastError: Error
for (let i = 0; i < maxRetries; i++) {
try {
return await fn()
} catch (error) {
lastError = error as Error
if (i < maxRetries - 1) {
const delay = Math.pow(2, i) * 1000
await new Promise(resolve => setTimeout(resolve, delay))
}
}
}
throw lastError!
}
const rolePermissions: Record<User['role'], Permission[]> = {
admin: ['read', 'write', 'delete', 'admin'],
moderator: ['read', 'write', 'delete'],
user: ['read', 'write']
}
export function hasPermission(user: User, permission: Permission): boolean {
return rolePermissions[user.role].includes(permission)
}
class RateLimiter {
private requests = new Map<string, number[]>()
async checkLimit(identifier: string, maxRequests: number, windowMs: number): Promise<boolean> {
const now = Date.now()
const requests = this.requests.get(identifier) || []
const recentRequests = requests.filter(time => now - time < windowMs)
if (recentRequests.length >= maxRequests) return false
recentRequests.push(now)
this.requests.set(identifier, recentRequests)
return true
}
}