All notable changes to this project will be documented in this file.
- Forensic-tier analyses failed twice in a row with "Request timed out" after ~15 minutes despite a 10-minute configured timeout — the OpenAI SDK's default automatic retries (maxRetries: 2) were re-waiting the full timeout on each attempt. Set
maxRetries: 0and raised the forensic timeout to 12 minutes (queue/worker job timeouts to 13 minutes) so a single attempt's timeout is a real ceiling, not a multiplier.
- Every analysis failed with "System configuration error" (
CRITICAL: Failed to load prompt from /app/server/prompts/v2/basic-analysis-prompt.txt) — the Dockerfile's runtime stage copied nothing under/app/serverat all, so the prompt files this project keeps out of TS source (per CLAUDE.md) never made it into the production image. Fixed by copyingserver/promptsinto the runner stage.
- Local dev and production shared the same unprefixed BullMQ "analysis-queue" on the same Upstash Redis instance, so a long-running local
nuxt devprocess raced production's worker for the same jobs and sometimes claimed and failed them before production ever saw them — discovered live during LAUNCH-01 verification via BullMQ's own job history showing jobs "completed" that the production worker's logs never mentioned. Fixed by namespacing BullMQ's Redis keys with an environment-derivedprefix(prodvsdev).
- Every PDF analysis in production failed with "Setting up fake worker failed: Cannot find module '.../pdfjs-dist/legacy/build/pdf.worker.mjs'" — discovered live during LAUNCH-01 verification. Same class of bug as the
@napi-rs/canvasfix in alpha.20: Nitro's build tracer silently drops files that pdfjs-dist resolves by runtime path rather than static import. Fixed by copying the completepdfjs-distpackage into the runtime image instead of relying on the tracer's partial copy. Verified locally: extracted real text from a test PDF inside the fixed image before shipping.
- The header's "Iniciar Sesión" link and the two homepage login CTAs went intermittently unresponsive (roughly 50% of clicks, uncorrelated with time since page load). Root cause: those
NuxtLinks sit inside av-if/v-elsepair keyed onuseSupabaseUser()'suserref, and a brief SSR/client mismatch in that value triggers Vue to discard and remount the nav subtree post-hydration — until the remount lands, the server-rendered anchor carries no click binding. Fixed by marking the three/loginlinksexternal, bypassing Vue Router's client-side interception entirely.
- Restored
nuxt-security's'nonce-{{nonce}}'placeholder in the customscript-srcCSP directive. Its absence silently disabled nonce substitution in the response header, so every inline<script>on the page — including Nuxt's own hydration payload — was blocked by CSP in production. This broke client-side hydration entirely (dark mode toggle and other client reactivity silently no-op'd, withCannot read properties of undefined (reading 'app')in the console).
- Structured clause-level prompts v2.1 for Basic, Premium, and Forensic tiers, with Forensic-only numeric coverage fields (
nota_upgrade,error, coverage percentage) - Analysis results UI: category section index with click-to-scroll navigation and keyboard/reduced-motion support, always-visible quoted clause with accessible collapse toggle, per-finding certainty pill, and a combined 0-10 risk score panel with category breakdown bars
- Suspended users are rejected at both
/api/uploadand worker job pickup (ADMIN-04), closing the v1.1 audit gap - Removed prescriptive legal directives from the Forensic tier's example JSON prompt
- Migrated the 3-tier analysis strategy to gpt-6-luna/sol/astra, including the pricing migration
- Fixed a 1000x unit error in the admin cost dashboard
- Funnel Stage 2 now sources from a dedicated RPC (
get_email_verified_users_in_range) with a warn-on-fallback path - Revenue package breakdown now maps from
credits_purchasedinstead of amount-range inference, decoupling it from Stripe price changes - Added a proprietary license
- Aligned the Basic tier's risk algorithm with Premium/Forensic for the single-red-finding case
- Eliminated overlapping
puntaje_riesgoboundary values at 3 and 6 - Worker now detects
DOCUMENT_TOO_LARGEexplicitly and no longer falls back to a deadnivel_riesgopath
- First production deploy:
docker-compose.prod.ymlis aligned to the polaris2 Traefik conventions (entrypointsweb/websecure, resolverletsencryptresolver), references the CI-built image with aCLARIFY_IMAGE_TAGrollback seam, and adds the fullNUXT_-prefixed runtime env contract so the image's baked-in build-time defaults no longer apply in production - Fixed a pre-existing production blocker found while proving the deploy locally:
pdf-parse's@napi-rs/canvasDOMMatrix polyfill was silently dropped by Nitro's build tracer, crashing every container on boot — pinned as an explicit dependency and copied into the runtime image directly - CI Docker actions upgraded for the Node 24 GitHub Actions runner (lands through this release's merge to
main)
- #33 Fix missing rate-limit import in
/api/check-tokens(would have bypassed DoS protection at runtime) - #35 Replace
createRequirewith native ESM import forpdf-parse(restores tree-shaking) - #36 Unify admin authorization in
getRequestUserContextto delegate toisAdminUser(NFKC normalization +admin_emailstable lookup); secondary admins were silently losing privileges in/api/analysesendpoints
- #34 Cancel stale
/api/check-tokensrequests on rapid file selection in dashboard viaAbortController
- #37 Split vitest into
unitandintegrationprojects so the#supabase/servermock alias only applies to unit tests; addsnpm run test:unitandnpm run test:integration - New unit tests for
getRequestUserContextadmin paths - Extract
isAdminEmail(event, email)helper to avoid redundantauth.getUser()round-trip
- Completed v1.1 Admin & Deploy milestone archival
- Branch sync: reconcile develop and main after v1.1 milestone
- CI/CD workflow matches portfolio auto-deploy structure
- Use
environment: prodfor deployment jobs - Docker login on server before pulling images
- Use
docker compose downbeforeup -dfor clean deploy
- Deploy workflow now uses correct secrets (
SSH_HOST, etc.) - Removed lint job from release pipeline (build + deploy only)
- Auto-release GitHub Actions workflow for automated versioning
- Docker-based auto-deploy to home server via SSH
.env.exampletemplate with all production environment variables- Configurable worker concurrency via
BULLMQ_CONCURRENCYenvironment variable - Real Redis health check in
/api/healthendpoint - Production deployment documentation (DEPLOY.md)
- CI/CD pipeline now deploys via Docker Hub + SSH instead of Vercel
- Worker concurrency is now configurable (was hardcoded to 2)
- Health endpoint now performs actual Redis ping verification
- Chart rendering issues in admin analytics (using client components)
- Admin UAT tests now passing
- Complete production deployment guide with GitHub Actions setup
- Phase 07 planning, research, validation, and summary documents
- Phase 07: Production deployment readiness
- Environment configuration template
- Health check with Redis connectivity verification
- Auto-release GitHub Actions workflow for automated versioning
- Docker-based auto-deploy to home server via SSH
.env.exampletemplate with all production environment variables- Configurable worker concurrency via
BULLMQ_CONCURRENCYenvironment variable - Real Redis health check in
/api/healthendpoint - Production deployment documentation (DEPLOY.md)
- CI/CD pipeline now deploys via Docker Hub + SSH instead of Vercel
- Worker concurrency is now configurable (was hardcoded to 2)
- Health endpoint now performs actual Redis ping verification
- Chart rendering issues in admin analytics (using client components)
- Admin UAT tests now passing
- Complete production deployment guide with GitHub Actions setup
- Phase 07 planning, research, validation, and summary documents
- Phase 07: Production deployment readiness
- Environment configuration template
- Health check with Redis connectivity verification
- Admin analytics dashboard
- Revenue tracking charts
- Funnel analysis visualization
- Asynchronous analysis system
- BullMQ worker for queue processing
- Redis integration for job management
- Initial alpha release
- Core analysis functionality
- Basic UI with dark mode support