feat: POST /simulations — quota check + insert productions — 65/65 tests

This commit is contained in:
Hermann_Kitio 2026-04-16 14:13:47 +03:00
parent 2fba6f2003
commit bf2c48b2c7
5 changed files with 361 additions and 0 deletions

View file

@ -0,0 +1,76 @@
import { supabase } from '../lib/supabase'
import { canUserSimulate, getPlanPermissions } from '../lib/access'
import type { Plan } from '../lib/access'
import type { AuthProfile } from '../middleware/auth'
export type Tache = 'EE_T1' | 'EE_T2' | 'EE_T3' | 'EO_T1' | 'EO_T3' | 'EO_T2_LIVE'
export type Mode = 'entrainement' | 'examen'
export interface CreateBody {
tache: Tache
mode: Mode
contenu?: string
}
export interface CreateResult {
id: string
tache: Tache
mode: Mode
created_at: string
}
type CreateError = {
error: true
code: string
message: string
status: number
}
export async function create(
body: CreateBody,
profile: AuthProfile
): Promise<{ data: CreateResult } | CreateError> {
// 1. Vérifier le quota via canUserSimulate (lib/access.ts)
const check = canUserSimulate({ plan: profile.plan, simulations_used: profile.simulations_used })
if (!check.allowed) {
return {
error: true,
code: 'QUOTA_REACHED',
message:
'Vous avez utilisé vos 5 simulations gratuites. Passez en Standard pour continuer votre préparation.',
status: 403,
}
}
// 2. Insérer dans productions
const { data, error } = await supabase
.from('productions')
.insert({
user_id: profile.id,
tache: body.tache,
mode: body.mode,
contenu: body.contenu ?? null,
})
.select('id, tache, mode, created_at')
.single()
if (error || !data) {
return {
error: true,
code: 'INTERNAL_ERROR',
message: 'Une erreur est survenue. Veuillez réessayer dans quelques instants.',
status: 500,
}
}
// 3. Incrémenter simulations_used si le plan a une limite (via access.ts — Règle D)
const perms = getPlanPermissions(profile.plan as Plan)
if (perms.simulations_lifetime !== null) {
await supabase
.from('profiles')
.update({ simulations_used: profile.simulations_used + 1 })
.eq('id', profile.id)
}
return { data: data as CreateResult }
}