fix: 5 bugs critiques de l'éditeur (Phase 1 audit)
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 5m39s
CI / Deploy production (on server) (push) Successful in 22s

1. replaceAll (Find & Replace) — une seule transaction ProseMirror
   au lieu d'un forEach cassé. Tous les matchs sont maintenant remplacés.

2. Link Preview unwrap — deleteNode() au lieu de clearer les attrs
   qui laissaient un nœud fantôme invisible dans le document.

3. Conversion Markdown → richtext — breaks: true dans marked.parse()
   Les simple newlines sont maintenant convertis en <br>.
   + préserve les blocs custom (toggle, callout, math, columns,
   outline, link-preview) en commentaires HTML lors de l'export MD.

4. emitNoteChange exercices — shape corrigée (type:'created' attend
   un objet Note, pas noteId/notebookId séparés).

5. Raccourcis clavier sans conflit :
   Cmd+Shift+C → Cmd+Alt+C (callout, avant: copier)
   Cmd+Shift+O → Cmd+Alt+O (outline, avant: historique/signets)
   Cmd+Shift+L → Cmd+Alt+L (colonnes, avant: lock screen macOS)
This commit is contained in:
Antigravity
2026-06-20 15:48:18 +00:00
parent 5b13a88b72
commit ee70e74bf5
51 changed files with 1483 additions and 252 deletions

View File

@@ -140,7 +140,7 @@ export async function updateUserRole(userId: string, newRole: string) {
}
export async function updateUserSubscription(userId: string, tier: string) {
await checkAdmin()
const session = await checkAdmin()
const validTiers: string[] = ['BASIC', 'PRO', 'BUSINESS', 'ENTERPRISE']
if (!validTiers.includes(tier)) {
@@ -148,6 +148,9 @@ export async function updateUserSubscription(userId: string, tier: string) {
}
try {
const existing = await prisma.subscription.findUnique({ where: { userId } })
const oldTier = existing?.tier ?? 'BASIC'
const now = new Date()
const periodEnd = new Date(now)
periodEnd.setFullYear(periodEnd.getFullYear() + 1)
@@ -168,6 +171,15 @@ export async function updateUserSubscription(userId: string, tier: string) {
currentPeriodEnd: periodEnd,
},
})
const { logAuditEventAsync } = await import('@/lib/audit-log')
await logAuditEventAsync({
userId: session.user?.id,
action: 'SUBSCRIPTION_OVERRIDE',
resource: userId,
metadata: { oldTier, newTier: tier, targetUserId: userId },
})
revalidatePath('/admin')
return { success: true }
} catch (error) {