Consolidates the two public job posting routes into the single canonical
flow at /jobs/new. The /publicar-vaga route already redirected there.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Frontend (jobs/new):
- Replace isValidCNPJ (checksum algorithm) with isValidDocument: accepts
any tax document with 5–30 alphanumeric chars (CNPJ, EIN, VAT, etc.)
- Add cleanPhone(): strips formatting chars (dashes, spaces, parens) and
keeps only digits + optional leading '+'; replaces cleanDigits+prepend
- Phone sent as '+5511999998888' if user typed '+55...', or '11999998888'
if no country code was provided — no '+' blindly prepended anymore
- Company document sent stripped of all non-alphanumeric before API call
- Update label placeholder from '00.000.000/0000-00' to 'CNPJ, EIN, VAT...'
- Rename error key invalidCnpj → invalidDocument in all 3 locales (pt, en, es)
Backend (create_company use case):
- Add SanitizePhone() to utils/sanitizer.go: strips all non-digit chars
except a leading '+'; '(11) 99999-8888' → '11999998888'
- Apply SanitizePhone to input.Phone before persisting to DB
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace free-text location input with debounced autocomplete
- On country select, fetch its numeric ID from /api/v1/locations/countries
and use it to scope the search results to that country
- Typing ≥2 chars in location field triggers GET /api/v1/locations/search
with 350ms debounce; results show city (blue) and state (green) badges
- On result selection, stores cityId + regionId and sets the display label
to "Name, Region" format; IDs are included in the job creation payload
- Spinner shown while searching; dropdown closes on outside click / select
- CEP search button preserved alongside the autocomplete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add password + confirm-password fields to billing step (Step 3) so the
recruiter creates their account credentials during the job posting flow
- Validate password length (≥8) and confirmation match before proceeding
- Extract company `id` from POST /auth/register/company response and send
it as `companyId` in the job creation payload (was missing — caused 400)
- Pass `contact` (full name) to company registration endpoint
- Remove hardcoded "Temp@123456" password; use the user-provided one
- Remove hardcoded "+55" phone prefix; send raw digits with "+" prefix
- Add translations (pt-BR, en, es) for password fields and error messages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix nullable location in my-jobs search filter (job.location ?? '')
- Fix Locale type assertion in jobs/new description language select
- Fix nullable location in api.ts transformApiJobToFrontend
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace all hardcoded Portuguese strings with locale-aware translations
using contentByLocale object. All 4 steps (job details, preview,
billing, payment), labels, placeholders, options, error messages,
and button texts now adapt to the user's selected language.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Initialize useState with getInitialLocale() instead of hardcoded 'en',
so the correct locale is used from the very first render
- Default to 'pt-BR' instead of 'en' for SSR and fallback
- Add fallback chain in t(): tries current locale -> pt-BR -> en
- Extract resolveKey() helper for cleaner key resolution
- Cast dictionaries as Record<string, unknown> to avoid type issues
- Wrap localStorage access in try-catch for blocked storage scenarios
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove `export const runtime = "edge"` which could interfere with i18n
JSON imports causing translation keys to render as literal text. Also
add fallback text when job description is empty.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removed leftover <<<<<<< Updated upstream conflict markers that were breaking TypeScript compilation,
preventing the job detail page (/jobs/[id]) from loading real data.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Frontend: adiciona API_URL e BACKOFFICE_URL como variáveis runtime
- Seeder: corrige parsing de sslmode do DATABASE_URL
- Seeder: aumenta timeout do healthcheck para 30s
- Add 'read' field to Notification interface in api.ts
- Remove duplicate Notification interface in candidate-dashboard.tsx
- Import Notification type from api.ts to ensure consistency
- Frontend: Remove duplicate useState import in applications page
- Backoffice: Install devDependencies during build for nest CLI
- Seeder: Fix healthcheck port to match app port (8080)
- Add Coolify CI/CD workflow for automatic deployment on push to dev
- Update DEVOPS.md with Coolify environment documentation
Backend:
- Fix migrations 037-041 to use UUID v7 (uuid_generate_v7)
- Fix CORS defaults to include localhost:8963
- Fix FRONTEND_URL default to localhost:8963
- Update superadmin password hash with pepper
- Add PASSWORD_PEPPER environment variable
Frontend:
- Replace mockJobs with real API calls in home page
- Replace mockNotifications with notificationsApi in context
- Replace mockApplications with applicationsApi in dashboard
- Fix register/user page to call real registerCandidate API
- Fix hardcoded values in backoffice and messages pages
Auth:
- Support both HTTPOnly cookie and Bearer token authentication
- Login returns token + sets HTTPOnly cookie
- Logout clears HTTPOnly cookie
- Token valid for 24h
- Video Interview system (backend + frontend)
- Date Posted filter (24h, 7d, 30d)
- Company filter in jobs listing
- Recent searches persistence (LocalStorage)
- Job Alerts with email confirmation
- Favorite jobs with API
- Company followers system
- Careerjet URL compatibility (s/l aliases)