because I got bored of customising my CV for every job
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor(CVG-49): extract @cv/mail package; api no longer composes mail directly

Mail (Resend provider, console provider, Handlebars template service, MailService interface) lived in @cv/core/modules/mail despite being a self-contained side-effect concern. Extracted to packages/mail mirroring @cv/auth/@cv/file-storage/@cv/handlers shape. api no longer imports ResendModule/TemplateModule - sending password reset / verification email is core's auth-domain concern, api stays a thin GraphQL shell. core/auth/providers/password and core/authentication import @cv/mail directly. Verified by full docker compose rebuild + boot.

+93 -32
+1 -8
apps/api/src/modules/app.module.ts
··· 1 1 import { AuthorizationModule, EventsModule, UserModule } from "@cv/core"; 2 2 import { AuthModule } from "@cv/auth"; 3 3 import { FileStorageModule } from "@cv/file-storage"; 4 - import { 5 - BaseModule, 6 - DatabaseModule, 7 - ResendModule, 8 - TemplateModule, 9 - } from "@cv/core"; 4 + import { BaseModule, DatabaseModule } from "@cv/core"; 10 5 import { ApolloDriver, type ApolloDriverConfig } from "@nestjs/apollo"; 11 6 import { Module } from "@nestjs/common"; 12 7 import { ConfigModule, ConfigService } from "@nestjs/config"; ··· 76 71 AppConfigModule, 77 72 BaseModule, 78 73 DatabaseModule, 79 - ResendModule, 80 - TemplateModule, 81 74 AuthModule, 82 75 AuthorizationModule, 83 76 AuthenticationModule,
+1 -8
apps/api/src/modules/authentication/authentication.module.ts
··· 1 1 import { AuthModule } from "@cv/auth"; 2 - import { 3 - BaseModule, 4 - DatabaseModule, 5 - ResendModule, 6 - TemplateModule, 7 - } from "@cv/core"; 2 + import { BaseModule, DatabaseModule } from "@cv/core"; 8 3 import { Module } from "@nestjs/common"; 9 4 import { ConfigModule } from "@nestjs/config"; 10 5 import { AuthenticationService } from "@cv/core"; ··· 18 13 AuthModule, 19 14 BaseModule, 20 15 DatabaseModule, 21 - ResendModule, 22 - TemplateModule, 23 16 PasswordProviderModule, 24 17 ], 25 18 controllers: [AuthenticationController],
-3
apps/api/src/modules/authentication/providers/password/password-provider.module.ts
··· 7 7 TemplatedEmailService, 8 8 VerificationEmailListener, 9 9 } from "@cv/core"; 10 - import { ResendModule, TemplateModule } from "@cv/core"; 11 10 import { Module } from "@nestjs/common"; 12 11 import { ConfigModule, ConfigService } from "@nestjs/config"; 13 12 import { PasswordAuthenticationResolver } from "./graphql/password-authentication.resolver"; ··· 16 15 imports: [ 17 16 ConfigModule, 18 17 AuthPasswordProviderModule, 19 - ResendModule, 20 - TemplateModule, 21 18 ], 22 19 providers: [ 23 20 PasswordAuthenticationResolver,
+1 -2
packages/core/package.json
··· 15 15 "@cv/cv-renderer": "workspace:*", 16 16 "@cv/file-storage": "workspace:*", 17 17 "@cv/file-upload": "workspace:*", 18 + "@cv/mail": "workspace:*", 18 19 "@cv/utils": "workspace:*", 19 20 "@nestjs/common": "^11.1.18", 20 21 "@nestjs/config": "^4.0.4", ··· 35 36 "dataloader": "^2.2.3", 36 37 "express": "^5.1.0", 37 38 "graphql": "^16.12.0", 38 - "handlebars": "^4.7.9", 39 39 "mammoth": "^1.11.0", 40 40 "multer": "^2.0.2", 41 41 "nest-commander": "^3.16.0", ··· 47 47 "pdf-parse": "^1.1.4", 48 48 "pg": "^8.16.3", 49 49 "reflect-metadata": "^0.2.2", 50 - "resend": "^6.5.2", 51 50 "rxjs": "^7.8.1", 52 51 "turndown": "^7.2.0", 53 52 "zod": "^4.3.6"
-1
packages/core/src/index.ts
··· 1 1 export * from "./shared"; 2 2 export * from "./modules/database"; 3 - export * from "./modules/mail"; 4 3 export * from "./modules/auth"; 5 4 export * from "./modules/events"; 6 5 export * from "./modules/application";
+1 -1
packages/core/src/modules/auth/providers/password/credentials/templated-email.service.ts
··· 3 3 type HandlebarsTemplateService, 4 4 MAIL_SERVICE_TOKEN, 5 5 type MailService, 6 - } from "../../../../mail"; 6 + } from "@cv/mail"; 7 7 import { Inject, Injectable } from "@nestjs/common"; 8 8 import { EMAIL_CONFIG_TOKEN, type EmailConfig } from "./email.config"; 9 9
+1 -1
packages/core/src/modules/auth/providers/password/password-provider.module.ts
··· 3 3 ResendModule, 4 4 TemplateModule, 5 5 TemplateRegistryService, 6 - } from "../../../mail"; 6 + } from "@cv/mail"; 7 7 import { Module, type OnModuleInit } from "@nestjs/common"; 8 8 import { ConfigModule, ConfigService } from "@nestjs/config"; 9 9 import { AuthorizationModule } from "../../authorization/authorization.module";
+1 -1
packages/core/src/modules/authentication/authentication.module.ts
··· 3 3 import { UserModule } from "../auth/user/user.module"; 4 4 import { BaseModule } from "../../shared"; 5 5 import { DatabaseModule } from "../database"; 6 - import { ResendModule, TemplateModule } from "../mail"; 6 + import { ResendModule, TemplateModule } from "@cv/mail"; 7 7 import { Module } from "@nestjs/common"; 8 8 import { ConfigModule } from "@nestjs/config"; 9 9 import { AuthenticationService } from "./authentication.service";
+1 -1
packages/core/src/modules/authentication/providers/password/password-provider.module.ts
··· 7 7 TemplatedEmailService, 8 8 VerificationEmailListener, 9 9 } from "../../../auth"; 10 - import { ResendModule, TemplateModule } from "../../../mail"; 10 + import { ResendModule, TemplateModule } from "@cv/mail"; 11 11 import { Module } from "@nestjs/common"; 12 12 import { ConfigModule, ConfigService } from "@nestjs/config"; 13 13
packages/core/src/modules/mail/index.ts packages/mail/src/index.ts
packages/core/src/modules/mail/mail.module.ts packages/mail/src/mail.module.ts
packages/core/src/modules/mail/mail.service.interface.ts packages/mail/src/mail.service.interface.ts
packages/core/src/modules/mail/providers/console-mail.service.ts packages/mail/src/providers/console-mail.service.ts
packages/core/src/modules/mail/providers/example-mail.service.ts packages/mail/src/providers/example-mail.service.ts
packages/core/src/modules/mail/resend/index.ts packages/mail/src/resend/index.ts
packages/core/src/modules/mail/resend/resend-mail.service.ts packages/mail/src/resend/resend-mail.service.ts
packages/core/src/modules/mail/resend/resend.module.ts packages/mail/src/resend/resend.module.ts
packages/core/src/modules/mail/template/handlebars-template.service.ts packages/mail/src/template/handlebars-template.service.ts
packages/core/src/modules/mail/template/index.ts packages/mail/src/template/index.ts
packages/core/src/modules/mail/template/template-registry.service.ts packages/mail/src/template/template-registry.service.ts
packages/core/src/modules/mail/template/template.module.ts packages/mail/src/template/template.module.ts
+40
packages/mail/package.json
··· 1 + { 2 + "name": "@cv/mail", 3 + "version": "0.0.0", 4 + "private": true, 5 + "main": "./src/index.ts", 6 + "types": "./src/index.ts", 7 + "exports": { 8 + ".": { 9 + "require": "./src/index.ts", 10 + "import": "./src/index.ts", 11 + "types": "./src/index.ts" 12 + } 13 + }, 14 + "files": [ 15 + "src/" 16 + ], 17 + "scripts": { 18 + "lint": "biome check .", 19 + "lint:fix": "biome check --write .", 20 + "typecheck": "tsc -b" 21 + }, 22 + "dependencies": { 23 + "@nestjs/common": "^11.1.18", 24 + "@nestjs/config": "^4.0.4", 25 + "@nestjs/core": "^11.1.18", 26 + "handlebars": "^4.7.9", 27 + "resend": "^6.5.2" 28 + }, 29 + "devDependencies": { 30 + "@biomejs/biome": "^2.2.6", 31 + "@cv/biome-config": "*", 32 + "@cv/tsconfig": "*", 33 + "typescript": "^5.6.3" 34 + }, 35 + "peerDependencies": { 36 + "@nestjs/common": "^11.1.18", 37 + "@nestjs/config": "^4.0.4", 38 + "@nestjs/core": "^11.1.18" 39 + } 40 + }
+12
packages/mail/tsconfig.json
··· 1 + { 2 + "extends": "@cv/tsconfig/tsconfig.library.json", 3 + "compilerOptions": { 4 + "outDir": "./dist", 5 + "rootDir": "./src", 6 + "baseUrl": ".", 7 + "composite": true, 8 + "declaration": true, 9 + "emitDeclarationOnly": true 10 + }, 11 + "include": ["src/**/*"] 12 + }
+34 -6
pnpm-lock.yaml
··· 675 675 '@cv/file-upload': 676 676 specifier: workspace:* 677 677 version: link:../file-upload 678 + '@cv/mail': 679 + specifier: workspace:* 680 + version: link:../mail 678 681 '@cv/utils': 679 682 specifier: workspace:* 680 683 version: link:../utils ··· 735 738 graphql: 736 739 specifier: ^16.12.0 737 740 version: 16.12.0 738 - handlebars: 739 - specifier: ^4.7.9 740 - version: 4.7.9 741 741 mammoth: 742 742 specifier: ^1.11.0 743 743 version: 1.11.0 ··· 771 771 reflect-metadata: 772 772 specifier: ^0.2.2 773 773 version: 0.2.2 774 - resend: 775 - specifier: ^6.5.2 776 - version: 6.6.0 777 774 rxjs: 778 775 specifier: ^7.8.1 779 776 version: 7.8.2 ··· 964 961 version: 22.19.3 965 962 typescript: 966 963 specifier: ^5.3.3 964 + version: 5.9.3 965 + 966 + packages/mail: 967 + dependencies: 968 + '@nestjs/common': 969 + specifier: ^11.1.18 970 + version: 11.1.18(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) 971 + '@nestjs/config': 972 + specifier: ^4.0.4 973 + version: 4.0.4(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) 974 + '@nestjs/core': 975 + specifier: ^11.1.18 976 + version: 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) 977 + handlebars: 978 + specifier: ^4.7.9 979 + version: 4.7.9 980 + resend: 981 + specifier: ^6.5.2 982 + version: 6.6.0 983 + devDependencies: 984 + '@biomejs/biome': 985 + specifier: ^2.2.6 986 + version: 2.3.11 987 + '@cv/biome-config': 988 + specifier: '*' 989 + version: link:../biome-config 990 + '@cv/tsconfig': 991 + specifier: '*' 992 + version: link:../tsconfig 993 + typescript: 994 + specifier: ^5.6.3 967 995 version: 5.9.3 968 996 969 997 packages/routing: