Add internet job search feature (cv-search-job)
Build and Push Docker Images / build (push) Failing after 1m36s

- New cv-search-models shared library: EF entities + CvSearchDbContext for cvSearch schema (JobSearchTokens, JobSearchSessions, JobSearchResults tables)
- New cv-search-job worker service: polls DB for pending sessions, scrapes job boards via configurable HTML scraping, runs LLM scoring via cv-matcher-api, emails ranked results
- cv-matcher-api: JobTokenService creates one-time tokens; JobSearchController handles link clicks and creates sessions
- api: proxies job-search start endpoint, appends job search link to match result email
- CI workflow updated to build and push myai-cv-search-job:staging image
- CLAUDE.md documentation added for all affected services

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-22 17:56:23 +03:00
parent a0ae262afc
commit 6293fa89e3
38 changed files with 2074 additions and 18 deletions
+75
View File
@@ -191,6 +191,9 @@ services:
- CvMatcherApi__BaseUrl=${CvMatcherApi__BaseUrl:-http://cv-matcher-api:8080}
- CvMatcherApi__InternalApiKey=${CvMatcherApi__InternalApiKey:-change-this-internal-key}
# JobSearch: base URL used to build the job search link in match emails
- JobSearch__BaseUrl=${JobSearch__JobSearchLinkBaseUrl:-https://myai.ro}
# Rate Limiting: matches api appsettings RateLimiting section
- RateLimiting__Global__PermitLimit=${RateLimiting__Global__PermitLimit:-120}
- RateLimiting__Global__Window=${RateLimiting__Global__Window:-00:01:00}
@@ -274,6 +277,78 @@ services:
labels:
- "com.centurylinklabs.watchtower.enable=true"
cv-search-job:
build:
context: ..
dockerfile: Jobs/cv-search-job/Dockerfile
container_name: myai-cv-search-job
depends_on:
- cv-matcher-api
env_file:
- .env
environment:
# Worker + diagnostics
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
- APP_ENVIRONMENT_NAME=${APP_ENVIRONMENT_NAME:-myai.local}
- LogEnvironmentOnStartup=${LogEnvironmentOnStartup:-true}
# Database
- Database__Host=${Database__Host:-sqlserver}
- Database__Port=${Database__Port:-1433}
- Database__Name=${Database__Name:-MyAiDb}
- Database__User=${Database__User:-sa}
- Database__Password=${Database__Password:-}
- Database__TrustServerCertificate=${Database__TrustServerCertificate:-true}
# CvMatcherApi (internal)
- CvMatcherApi__BaseUrl=${CvMatcherApi__BaseUrl:-http://cv-matcher-api:8080}
- CvMatcherApi__InternalApiKey=${CvMatcherApi__InternalApiKey:-change-this-internal-key}
# SMTP
- Smtp__Host=${Smtp__Host:-}
- Smtp__Port=${Smtp__Port:-587}
- Smtp__Username=${Smtp__Username:-}
- Smtp__Password=${Smtp__Password:-}
- Smtp__UseStartTls=${Smtp__UseStartTls:-false}
# Contact
- Contact__ToEmail=${Contact__ToEmail:-}
# FileStorage (shared volume path must match api container)
- FileStorage__Path=${FileStorage__Path:-Files}
# JobSearch settings
- JobSearch__Enabled=${JobSearch__Enabled:-true}
- JobSearch__JobSearchLinkBaseUrl=${JobSearch__JobSearchLinkBaseUrl:-https://myai.ro}
- JobSearch__TokenExpiryDays=${JobSearch__TokenExpiryDays:-7}
- JobSearch__MinMatchScore=${JobSearch__MinMatchScore:-15}
- JobSearch__MaxJobsToMatch=${JobSearch__MaxJobsToMatch:-15}
# Job task schedule
- Jobs__Tasks__0__TaskType=CvSearch
- Jobs__Tasks__0__Enabled=${Jobs__CvSearchEnabled:-true}
- Jobs__Tasks__0__Interval=${Jobs__CvSearchInterval:-00:00:30}
# Logging / Serilog
- Logging__LogLevel__Default=${Logging__LogLevel__Default:-Information}
- Logging__LogLevel__Microsoft=${Logging__LogLevel__Microsoft:-Warning}
- Logging__LogLevel__Microsoft__Hosting__Lifetime=${Logging__LogLevel__Microsoft__Hosting__Lifetime:-Information}
- Serilog__WriteTo__2__Args__fromEmail=${Serilog__WriteTo__2__Args__fromEmail:-}
- Serilog__WriteTo__2__Args__toEmail=${Serilog__WriteTo__2__Args__toEmail:-}
- Serilog__WriteTo__2__Args__mailServer=${Serilog__WriteTo__2__Args__mailServer:-}
- Serilog__WriteTo__2__Args__networkCredential__userName=${Serilog__WriteTo__2__Args__networkCredential__userName:-}
- Serilog__WriteTo__2__Args__networkCredential__password=${Serilog__WriteTo__2__Args__networkCredential__password:-}
- Serilog__WriteTo__2__Args__port=${Serilog__WriteTo__2__Args__port:-587}
- Serilog__WriteTo__2__Args__enableSsl=${Serilog__WriteTo__2__Args__enableSsl:-true}
volumes:
- ../Jobs/cv-search-job/logs:/app/logs
- ../Apis/api/Files:/app/Files
networks:
- myai-network
restart: unless-stopped
labels:
- "com.centurylinklabs.watchtower.enable=true"
web:
build:
context: ..