- Add ProjectReference to email-api-data; remove myai-data reference
- Program.cs: register EmailApiDbContext (no migrate), IEmailTemplateRepository
(scoped), IEmailTemplateService (singleton); remove MyAiDbContext +
ITemplateService registrations and their migration call
- CvSearchEmailSender: inject IEmailTemplateService; replace
_config["Contact:ToEmail"] with GetOperatorCopy("email.search-results.subject")
for operator copy logic; remove IConfiguration injection
- docker-compose: remove Contact__ToEmail from cv-search-job service block;
add Database__* env vars to email-api service (needed for EmailApiDbContext)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- docker-compose: add email-api service (internal, no ports)
with Smtp__* + FileStorage__Path + Files volume mount
- api + cv-search-job: remove Smtp__* vars, add EmailApi__BaseUrl
and EmailApi__InternalApiKey; add depends_on: email-api
- .sln: move email-api-models to Models virtual folder
- CLAUDE.md: add email-api/email-api-models to layout, update
service dependency diagram and internal API key table
Closes#22
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Upgrades 8 email body templates from plain text to styled HTML.
Templates: email.match.body, email.match.job-search-footer,
email.search-results.body, email.search-results.empty (en + ro each).
All use inline CSS only (Gmail-compatible). Branded #2c5282 accent.
Closes#22
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- CvSearchEmailSender now injects IEmailApiClient instead of IConfiguration+MailKit
- BuildBody updated to produce styled HTML job cards
- CvSearchJobTask passes only filename (not full path) to email sender
- IEmailApiClient registered in Program.cs with EmailApi:BaseUrl + InternalApiKey
- MailKit removed from cv-search-job.csproj
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- EmailApiEmailSender calls email-api via IEmailApiClient Refit client
- HTML bodies built inline for contact/subscribe/file-download emails
- match and job-search emails use DB templates (rendered in caller)
- SmtpSettings moved from api-models to email-api (kept in Models.Settings namespace)
- MailKit removed from api.csproj
- SmtpEmailSender deleted; IEmailSender interface unchanged
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New internal service that centralises SMTP email sending.
- email-api-models: SendEmailRequest DTO, IEmailApiClient Refit interface, EmailApiSettings
- email-api: SmtpEmailDispatcher (MailKit), EmailController (POST /api/email/send),
branded HTML shell wrapper, shared-Files-volume attachment support
- Protected by X-Internal-Api-Key via UseInternalApiKeyProtection()
- No exposed Docker port — internal network only (http://email-api:8080)
Closes#22
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Stores the canonical general-dev-workflow skill definition alongside the
codebase so it travels with the project and can be evolved via normal PRs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Changed CORS allowed origin from localhost:5000 to localhost:5140
- Updated docker-compose.override.yml port mapping from 5000:8080 to 5140:8080
- Aligns local development port with staging (myai.easysoft.ro) and production (myai.ro) Caddy reverse proxy configuration on port 5140
The docker-compose refactor moved port 5000:8080 to the override file.
Caddy on staging routes myai.easysoft.ro → localhost:5000, so the port
must be present in the deployment compose. Restoring it as WEB_PORT env var
(default 5000) and adding missing watchtower label.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
api now registers MyAiDbContext for template loading and needs
Database__* connection string vars like the other DB-connected services.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New Apis/myai-models project: MyAiDbContext (schema myAi), TemplateEntity,
ITemplateService, DbTemplateService with 10-min in-memory cache
- Seeds EN+RO variants for all user-facing templates (match email, job search
results email, HTML status pages, AI system prompt)
- Match result email now sent in user's UI language (en/ro)
- Job search results email now respects session language
- Language propagates: MatchJobRequest -> token -> session -> email
- Add Language column to JobSearchTokens and JobSearchSessions (default 'en')
- All three Dockerfiles updated to include myai-models in build context
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The <p> wrapping the copyright line had default browser margins (1em top/bottom)
which offset it above the sibling flex items despite align-items: center.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The frontend sends the active language code (currentLang()) with every match
request. CvMatcherService injects a language instruction into the system prompt
so the LLM returns summary, strengths, gaps, recommendations, and evidence in
the correct language. The match result cache (CvMatchResults) now includes
Language as part of the lookup key so Romanian and English results are stored
and retrieved independently. Existing cached rows default to 'en'.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Every public action now has <summary>, <param>, and <returns> XML docs
plus matching SwaggerOperation/SwaggerResponse attributes with typed response
descriptions. Class-level summaries added to CvController, JobSearchController,
and RagController. Explanatory inline comments removed from FileDownloadController
per project conventions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Uses GetApplicationVersion(Assembly.GetExecutingAssembly()) — the same
timestamp-based version already logged at startup and baked into the
assembly via the csproj <Version> property. Removes the minimal-API
/version endpoint from web/Program.cs and reverts the web Dockerfile
APP_VERSION build-arg (no longer needed).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Setting APP_VERSION in docker-compose with a :-unknown fallback would override
the version baked into the image at build time. The CI already embeds it via
--build-arg APP_VERSION=1.0.<commit-count>, so compose should stay silent.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Exposes GET /version endpoint in the web container (reads APP_VERSION env var).
CI computes the version as 1.0.<git-commit-count> and passes it via --build-arg at build time.
Both index.html and cv-matcher/index.html show the version in the footer via a JS fetch.
docker-compose passes APP_VERSION through to the running container.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude Code stores session files under .claude/ — these are local tooling
artifacts and should not be tracked in the repository.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- docker-compose.yml is now the single file for Portainer (staging and prod).
Uses registry images with ${IMAGE_TAG:-staging}, ${LOGS_PATH:-/opt/myai/logs},
and ${FILES_PATH:-/opt/myai/files} so the same file works for all environments.
- docker-compose.override.yml adds build context, ports, and env_file for local dev
and is auto-merged by "docker compose up" (no extra flags needed).
- .env.template documents IMAGE_TAG, LOGS_PATH, FILES_PATH alongside existing vars.
- docker-compose.dcproj updated so override file nests under docker-compose.yml in
Solution Explorer.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dotnet restore failed in CI because cv-search-models.csproj was added as
a ProjectReference but not copied into the Docker build context.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>