feat: POST /simulations — quota check + insert productions — 65/65 tests
This commit is contained in:
parent
2fba6f2003
commit
bf2c48b2c7
5 changed files with 361 additions and 0 deletions
76
src/controllers/simulationController.ts
Normal file
76
src/controllers/simulationController.ts
Normal 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 }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue