← Back to case studies

3 assessment flows in production

Case Study — Teste de Perfil

Version: 3.0

Status: Approved

Last updated: 2026-07-06

Type: Prior production system (narrative documentation, source not in this repository)


Overview

Teste de Perfil is a behavioral profile assessment platform for Paulo Odorico and partners (Projeto Vender Mais, Conexão Lucrativa). It delivers DISC-based assessments for online courses, corporate training events, and investor profiling — with personalized PDF workbooks generated server-side.

Role: Full-stack engineer — architecture, assessment engine, PDF pipeline, admin tooling, deployment.

Production: testeperfil.pauloodorico.com.br


Business Problem

Partners needed to deliver behavioral profile assessments at scale — for online course students, in-person training participants, and corporate events. Manual processes (spreadsheets, ad-hoc printing, email PDF delivery) did not scale and did not integrate with course platforms (Kiwify, Hotmart).


Requirements

CategoryRequirement
AssessmentDISC model — Executor, Communicator, Planner, Analyst profiles
Flow 1Online course access via platform token (Kiwify/Hotmart params)
Flow 2Corporate events with classes; result hidden until printed at event
Flow 3Free investor profile test with immediate online result
OutputPersonalized PDF workbook per participant
AdminClass/event management, CSV export, batch PDF ZIP for print shops
AnalyticsFunnel tracking: visits, starts, completions, drop-off per question

Architecture

Teste de Perfil uses a Next.js App Router monolith with API Route Handlers and PostgreSQL — no separate backend service.

FlowRouteAudience
Teste de Perfil/teste-perfilProjeto Vender Mais course students
Perfil Comportamental/perfil-comportamentalCorporate training events
Conexão Lucrativa/clInvestor profiling (free)

Each flow has separate question banks, Prisma tables, and UX rules while sharing PDF infrastructure and deployment.


System Diagram


Technology Stack

LayerTechnology
FrameworkNext.js 16 (App Router), React 19, TypeScript
StylingTailwind CSS 4
DatabasePostgreSQL, Prisma 6
ChartsChart.js + react-chartjs-2
PDFPuppeteer-core + Chromium, pdf-lib, jsPDF
EmailNodemailer (SMTP), file-based queue (.queue/)
ExportJSZip (batch workbook generation)
DeployDocker multi-stage, CapRover

Key Features

  1. Three products, one codebase — Shared infrastructure; isolated Prisma models per flow
  2. Scoring engine — Profile points, percentages, ranking across four DISC profiles
  3. PDF generation — Puppeteer renders internal ?print=true URL to A4 PDF with charts
  4. Email queue — Worker polling (15s) with configurable delay (default 7 min post-completion)
  5. Course integration — URL params from Kiwify/Hotmart → tp_auth cookie
  6. Corporate batch export — ZIP of all class PDFs for print shop; browser print route for events
  7. Funnel analytics/metrics dashboard: visits, completion rate, per-question drop-off

Engineering Challenges

Three products in one repository

Different UX rules per flow: show vs hide result, token-gated vs free access, immediate vs deferred delivery.

Server-side PDF with charts

Puppeteer must wait for Chart.js canvas render; batch ZIP for entire classes can take minutes.

Deployment and migrations

Prisma sqlite → PostgreSQL migration conflict (P3019) during production adoption.

Simple email queue

Jobs deleted on process without automatic SMTP failure retry.

Corporate privacy

Participant does not see result online — print pipeline must be ready before the event.


Trade-offs

DecisionChosenAlternativeRationale
ArchitectureNext.js monolithSeparate API serviceSolo maintainer; low operational overhead
PDF enginePuppeteerreact-pdf / PDFKitCharts and complex layout need real browser render
Email queueFile-based pollingRedis/BullMQSufficient volume; simpler deploy
DB per flowSeparate Prisma modelsSingle generic assessment tableFlow-specific fields without over-abstraction
Corporate UXHide result onlineShow immediatelyBusiness requirement for event reveal

Security

ControlImplementation
Course accessTESTE_PERFIL_TOKEN + platform URL params
Session authtp_auth cookie after token validation
AdminShared admin credentials per flow (PC/CL)
Class linksUUID linkToken per corporate class
Data privacyCorporate results not shown to participants pre-event
SMTPCredentials via environment variables

Performance

AreaApproach
Assessment UXOne question per screen; progress bar; minimal payload
PDF generationInternal INTERNAL_BASE_URL; canvas wait timeout
Batch ZIPAdmin UI communicates processing time for large classes
Email queue15s poll interval; delayed send reduces SMTP burst
MetricsAggregated queries; /metrics for funnel visualization

Scalability

DimensionStrategy
Concurrent usersStateless Next.js handlers; PostgreSQL connection pool
PDF loadSequential generation in batch; queue for email
StoragePostgreSQL for all participant data; no blob store needed
New flowsNew Prisma models + routes; shared PDF/email infrastructure

Deployment

EnvironmentURLNotes
Productiontesteperfil.pauloodorico.com.brCapRover Docker multi-stage
PDF renderInternal Docker network URLChromium in container
MigrationsPrisma migrate deployPostgreSQL in production

Lessons Learned

  1. UX context beats single flow — Course shows result; corporate hides until event; CL is immediate and free.
  2. Puppeteer in Docker is product infrastructure — Chromium, internal URL, and timeouts are core, not extras.
  3. Course platform integration — URL params (Kiwify/Hotmart) and access tokens avoid duplicate registration.
  4. Batch export is critical operations — ZIP for print shops needs UX that communicates processing time.
  5. Simplified DISC scales — Four profiles with percentages serve sales, HR, and financial education with one engine.

Screenshots

ScreenRouteDescription
Assessment/teste-perfilOne-question-per-screen with progress
Result + PDF/teste-perfil/resultadoProfile breakdown and download
Metrics/metricsFunnel analytics dashboard
Admin classes/admin/pcClass management, CSV, batch ZIP
Investor result/cl/resultado/{id}Investor profile (Arrojado, Conservador, etc.)

_Screenshots available on request during technical interviews._


Roadmap (at handoff)

PhaseItemStatus
v1.0Teste de Perfil course flowShipped
v1.5Perfil Comportamental corporateShipped
v2.0Conexão Lucrativa investor flowShipped
v2.5Email queue retry logicPlanned
v3.0Hotmart webhook integrationEvaluating

Relation to NovaDesk

Concepts from Teste de Perfil that inform NovaDesk:

  • Report and PDF generation (Analytics export)
  • State-based flows with progress tracking (onboarding, tickets)
  • Admin with classes/organizations (multi-tenant HelpDesk)
  • Token/invite-based auth (Admin Portal invites)
  • Funnel and drop-off metrics (Analytics Dashboard)
  • CapRover containerized deploy (same pattern as NovaDesk)