Skip to main content
backend-patterns Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes.
Aller à l'installation Skills Marketplace Découvrez et explorez les compétences IA créées par la communauté.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Copier le promptAfficher les détails du prompt Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
npx skills add https://github.com/forgivesam168/ai-dev-workflow --skill backend-patternsLa commande reste sur une seule ligne. Faites défiler horizontalement pour la vérifier avant de la copier.
Vous préférez une copie locale ? Téléchargez les fichiers actuellement disponibles dans SkillsMP.
Télécharger Zip Téléchargement... Plus depuis ce dépôt Comprehensive code quality and security audit for financial systems. Use when asked to "review code", "code review", "security audit", "check for issues", "審核程式碼", "檢查安全性", or before merging changes. Focuses on DDD compliance, financial precision (no floats for money), security vulnerabilities, and test coverage.
Finalize and document completed change packages at Stage 6. Use when asked to archive changes, finalize work, or close change-package documentation.
Orchestrate the six-stage development workflow. Use when user asks "what stage am I at?", "what's next?", "workflow status", "where should I start?", "工作流程", "下一步是什麼", "我在哪個階段", or wants guidance on the development process. Detects current state by checking changes/ folder and guides users through brainstorm → spec → plan → tdd → review → archive stages.
Métiers associés SOC
Basé sur la classification professionnelle SOC
name backend-patterns description Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes.
Backend Development Patterns
Backend architecture patterns and best practices for scalable server-side applications.
Database Design and Review Tactics
Use this method when the DBA specialist is asked to consult on a Spec or Plan:
Schema contract : identify entities, columns, types, nullability, constraints, relationships, ownership, and compatibility boundaries before proposing implementation.
Migration safety : classify expand/contract impact, bound the affected data, and define an executable migration plus rollback, restore, compensation, or safe-stop path appropriate to the risk.
Financial precision : represent money with decimal types or integer minor units and an explicit currency; reject floating-point storage or arithmetic for monetary values.
Index discipline : justify each index against measured read behavior and document write/storage trade-offs; do not add speculative indexes.
Query evidence : use the database's query-plan evidence such as EXPLAIN or EXPLAIN ANALYZE when performance is in scope, and separate observed results from assumptions.
Handoff : return the schema decisions, migration/rollback requirements, query or index evidence, compatibility impact, risks, and unresolved questions to the requesting Spec or Plan owner.
API Design Patterns
RESTful API Structure
GET /api/markets # List resources
GET /api/markets/:id # single resource
/api/markets # resource
/api/markets/:id # resource
/api/markets/:id # resource
/api/markets/:id # resource
/api/markets?status=active&sort=volume&limit= &offset=
Get
POST
Create
PUT
Replace
PATCH
Update
DELETE
Delete
GET
20
0
Repository Pattern
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
}
}
Service Layer Pattern
class MarketService {
constructor (private marketRepo : MarketRepository ) {}
async searchMarkets (query : string , limit : number = 10 ): Promise <Market []> {
const embedding = await generateEmbedding (query)
const results = await this .vectorSearch (embedding, limit)
const markets = await this .marketRepo .findByIds (results.map (r => r.id ))
return markets.sort ((a, b ) => {
const scoreA = results.find (r => r.id === a.id )?.score || 0
const scoreB = results.find (r => r.id === b.id )?.score || 0
return scoreA - scoreB
})
}
private async vectorSearch (embedding : number [], limit : number ) {
}
}
Middleware Pattern
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' })
}
}
}
export default withAuth (async (req, res) => {
})
Database Patterns
Query Optimization
const { data } = await supabase
.from ('markets' )
.select ('id, name, status, volume' )
.eq ('status' , 'active' )
.order ('volume' , { ascending : false })
.limit (10 )
const { data } = await supabase
.from ('markets' )
.select ('*' )
N+1 Query Prevention
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 )
})
Transaction Pattern async function createMarketWithPosition (
marketData : CreateMarketDto ,
positionData : CreatePositionDto
) {
const { data, error } = await supabase.rpc ('create_market_with_position' , {
market_data : marketData,
position_data : positionData
})
if (error) throw new Error ('Transaction failed' )
return data
}
CREATE OR REPLACE FUNCTION create_market_with_position (
market_data jsonb,
position_data jsonb
)
RETURNS jsonb
LANGUAGE plpgsql
AS $$
BEGIN
-- Start transaction automatically
INSERT INTO markets VALUES (market_data);
INSERT INTO positions VALUES (position_data);
RETURN jsonb_build_object ('success' , true );
EXCEPTION
WHEN OTHERS THEN
-- Rollback happens automatically
RETURN jsonb_build_object ('success' , false , 'error' , SQLERRM );
END ;
$$;
Caching Strategies
Redis Caching Layer class CachedMarketRepository implements MarketRepository {
constructor (
private baseRepo : MarketRepository ,
private redis : RedisClient
) {}
async findById (id : string ): Promise <Market | null > {
const cached = await this .redis .get (`market:${id} ` )
if (cached) {
return JSON .parse (cached)
}
const market = await this .baseRepo .findById (id)
if (market) {
await this .redis .setex (`market:${id} ` , 300 , JSON .stringify (market))
}
return market
}
async invalidateCache (id : string ): Promise <void > {
await this .redis .del (`market:${id} ` )
}
}
Cache-Aside Pattern 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
}
Error Handling Patterns
Centralized Error Handler class ApiError extends Error {
constructor (
public statusCode : number ,
public message : string ,
public isOperational = true
) {
super (message)
Object .setPrototypeOf (this , ApiError .prototype )
}
}
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 })
}
console .error ('Unexpected error:' , error)
return NextResponse .json ({
success : false ,
error : 'Internal server error'
}, { status : 500 })
}
export async function GET (request : Request ) {
try {
const data = await fetchData ()
return NextResponse .json ({ success : true , data })
} catch (error) {
return errorHandler (error, request)
}
}
Retry with Exponential Backoff 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 data = await fetchWithRetry (() => fetchFromAPI ())
Authentication & Authorization
JWT Token Validation import jwt from 'jsonwebtoken'
interface JWTPayload {
userId : string
email : string
role : 'admin' | 'user'
}
export function verifyToken (token : string ): JWTPayload {
try {
const payload = jwt.verify (token, process.env .JWT_SECRET !) as JWTPayload
return payload
} catch (error) {
throw new ApiError (401 , 'Invalid token' )
}
}
export async function requireAuth (request : Request ) {
const token = request.headers .get ('authorization' )?.replace ('Bearer ' , '' )
if (!token) {
throw new ApiError (401 , 'Missing authorization token' )
}
return verifyToken (token)
}
export async function GET (request : Request ) {
const user = await requireAuth (request)
const data = await getDataForUser (user.userId )
return NextResponse .json ({ success : true , data })
}
Role-Based Access Control type Permission = 'read' | 'write' | 'delete' | 'admin'
interface User {
id : string
role : 'admin' | 'moderator' | 'user'
}
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)
}
export function requirePermission (permission : Permission ) {
return (handler : (request: Request, user: User) => Promise <Response > ) => {
return async (request : Request ) => {
const user = await requireAuth (request)
if (!hasPermission (user, permission)) {
throw new ApiError (403 , 'Insufficient permissions' )
}
return handler (request, user)
}
}
}
export const DELETE = requirePermission ('delete' )(
async (request : Request , user : User ) => {
return new Response ('Deleted' , { status : 200 })
}
)
Rate Limiting
Simple In-Memory Rate Limiter 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
}
}
const limiter = new RateLimiter ()
export async function GET (request : Request ) {
const ip = request.headers .get ('x-forwarded-for' ) || 'unknown'
const allowed = await limiter.checkLimit (ip, 100 , 60000 )
if (!allowed) {
return NextResponse .json ({
error : 'Rate limit exceeded'
}, { status : 429 })
}
}
Background Jobs & Queues
Simple Queue Pattern class JobQueue <T> {
private queue : T[] = []
private processing = false
async add (job : T): Promise <void > {
this .queue .push (job)
if (!this .processing ) {
this .process ()
}
}
private async process (): Promise <void > {
this .processing = true
while (this .queue .length > 0 ) {
const job = this .queue .shift ()!
try {
await this .execute (job)
} catch (error) {
console .error ('Job failed:' , error)
}
}
this .processing = false
}
private async execute (job : T): Promise <void > {
}
}
interface IndexJob {
marketId : string
}
const indexQueue = new JobQueue <IndexJob >()
export async function POST (request : Request ) {
const { marketId } = await request.json ()
await indexQueue.add ({ marketId })
return NextResponse .json ({ success : true , message : 'Job queued' })
}
Logging & Monitoring
Structured Logging interface LogContext {
userId ?: string
requestId ?: string
method ?: string
path ?: string
[key : string ]: unknown
}
class Logger {
log (level : 'info' | 'warn' | 'error' , message : string , context ?: LogContext ) {
const entry = {
timestamp : new Date ().toISOString (),
level,
message,
...context
}
console .log (JSON .stringify (entry))
}
info (message : string , context ?: LogContext ) {
this .log ('info' , message, context)
}
warn (message : string , context ?: LogContext ) {
this .log ('warn' , message, context)
}
error (message : string , error : Error , context ?: LogContext ) {
this .log ('error' , message, {
...context,
error : error.message ,
stack : error.stack
})
}
}
const logger = new Logger ()
export async function GET (request : Request ) {
const requestId = crypto.randomUUID ()
logger.info ('Fetching markets' , {
requestId,
method : 'GET' ,
path : '/api/markets'
})
try {
const markets = await fetchMarkets ()
return NextResponse .json ({ success : true , data : markets })
} catch (error) {
logger.error ('Failed to fetch markets' , error as Error , { requestId })
return NextResponse .json ({ error : 'Internal error' }, { status : 500 })
}
}
Remember : Backend patterns enable scalable, maintainable server-side applications. Choose patterns that fit your complexity level.