feat: wire email-api into docker-compose, .sln and CLAUDE.md
- 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>
This commit is contained in:
@@ -35,7 +35,7 @@ This applies to both the staging and production repos as appropriate.
|
||||
- Entity Framework Core + SQL Server (multi-schema)
|
||||
- Refit for typed HTTP clients between services
|
||||
- Serilog (JSON structured logging, Console + File + Email sinks)
|
||||
- MailKit for SMTP
|
||||
- MailKit for SMTP (used exclusively in `email-api`)
|
||||
- Docker Compose for local and production deployment
|
||||
- Watchtower for automatic container updates in production
|
||||
|
||||
@@ -63,6 +63,8 @@ This applies to both the staging and production repos as appropriate.
|
||||
Apis/
|
||||
api/ Public-facing proxy API (port 8080). Handles CORS, rate limiting, captcha, email.
|
||||
api-models/ DTOs and settings for api only.
|
||||
email-api/ Internal SMTP email relay (no public port). All email sending goes here.
|
||||
email-api-models/ Refit client + SendEmailRequest + EmailApiSettings (shared by api and cv-search-job).
|
||||
cv-matcher-api/ Internal CV match engine (port 8082). Runs CvMatcher + CvSearch + MyAi DB migrations.
|
||||
cv-matcher-api-models/ DTOs shared between api and cv-matcher-api (incl. JobSearchSettings).
|
||||
rag-api/ Internal RAG/vector-search service (port 8081).
|
||||
@@ -148,26 +150,36 @@ EF tools version warning ("older than runtime") is expected and harmless. The `H
|
||||
|
||||
```
|
||||
web → api → cv-matcher-api → rag-api
|
||||
↑
|
||||
cv-search-job
|
||||
↓ ↓
|
||||
| email-api
|
||||
↓ ↑
|
||||
cv-search-job
|
||||
```
|
||||
|
||||
`api` and `cv-search-job` both call `email-api` for all outbound email (SMTP).
|
||||
`api` never talks directly to `rag-api` — always via `cv-matcher-api`.
|
||||
|
||||
## Internal API key auth
|
||||
|
||||
All internal service-to-service calls require the `X-Internal-Api-Key` header.
|
||||
The key is shared via the `CvMatcherApi__InternalApiKey` and `RagApi__InternalApiKey` env vars.
|
||||
`startup-helpers` provides `UseInternalApiKeyProtection()` middleware that enforces it on `cv-matcher-api` and `rag-api`.
|
||||
All internal service-to-service calls require the `X-Internal-Api-Key` header.
|
||||
|
||||
| Caller | Target | Env var for key |
|
||||
|--------|--------|-----------------|
|
||||
| `api`, `cv-search-job` | `email-api` | `EmailApi__InternalApiKey` |
|
||||
| `api`, `cv-search-job` | `cv-matcher-api` | `CvMatcherApi__InternalApiKey` |
|
||||
| `cv-matcher-api` | `rag-api` | `RagApi__InternalApiKey` |
|
||||
|
||||
`startup-helpers` provides `UseInternalApiKeyProtection()` middleware (reads `InternalApi:ApiKey`); enforced on `cv-matcher-api`, `rag-api`, and `email-api`.
|
||||
|
||||
## Shared file storage
|
||||
|
||||
CV PDFs are written by `api` to `Apis/api/Files/` and read by `cv-cleanup-job` and `cv-search-job`.
|
||||
All three containers mount the same bind volume:
|
||||
CV PDFs are written by `api` to `Apis/api/Files/` and read by `cv-cleanup-job`, `cv-search-job`, and `email-api` (for email attachments).
|
||||
All four containers mount the same bind volume:
|
||||
```yaml
|
||||
- ../Apis/api/Files:/app/Files
|
||||
- ${FILES_PATH:-/opt/myai/files}:/app/Files
|
||||
```
|
||||
The path inside containers is controlled by `FileStorage__Path` (default: `Files`).
|
||||
The path inside containers is controlled by `FileStorage__Path` (default: `Files`).
|
||||
`email-api` receives only the relative filename (e.g. `abc123.pdf`) and resolves it against `FileStorage__Path`.
|
||||
|
||||
## Job task pattern
|
||||
|
||||
|
||||
Reference in New Issue
Block a user