diff --git a/apps/api/scripts/post-build.sh b/apps/api/scripts/post-build.sh index e098c17..8f139be 100755 --- a/apps/api/scripts/post-build.sh +++ b/apps/api/scripts/post-build.sh @@ -3,5 +3,5 @@ set -eu DIST_DIR="dist" -mkdir -p "${DIST_DIR}/cv-templates" -cp src/seed/seeders/cv-templates/* "${DIST_DIR}/cv-templates/" +mkdir -p "${DIST_DIR}/templates" +cp ../../packages/core/src/modules/cv-template/templates/* "${DIST_DIR}/templates/" diff --git a/apps/api/src/modules/cv-template/cv-template.module.ts b/apps/api/src/modules/cv-template/cv-template.module.ts index e8ae9b3..5ebd513 100644 --- a/apps/api/src/modules/cv-template/cv-template.module.ts +++ b/apps/api/src/modules/cv-template/cv-template.module.ts @@ -6,9 +6,9 @@ import { CVRendererService, CVService, CVTemplatePolicy, + CVTemplateSeedService, CVTemplateService, DatabaseModule, - PdfDownloadController, } from "@cv/core"; import { Module } from "@nestjs/common"; import { AuthenticationModule } from "@/modules/authentication/authentication.module"; @@ -17,7 +17,7 @@ import { CVDataLoaderService } from "./cv.dataloader"; import { CVResolver, CVTemplateResolver } from "./graphql/cv-template.resolver"; import { ProfileCVFieldResolver } from "./graphql/profile-cv-field.resolver"; import { CVUserFieldResolver } from "./graphql/user-field.resolver"; -import { CVTemplateSeedService } from "@/seed/seeders/cv-template.seed"; +import { PdfDownloadController } from "./pdf-download.controller"; @Module({ imports: [ diff --git a/packages/core/src/modules/cv-template/pdf-download.controller.ts b/apps/api/src/modules/cv-template/pdf-download.controller.ts similarity index 79% rename from packages/core/src/modules/cv-template/pdf-download.controller.ts rename to apps/api/src/modules/cv-template/pdf-download.controller.ts index 9a65a90..0460003 100644 --- a/packages/core/src/modules/cv-template/pdf-download.controller.ts +++ b/apps/api/src/modules/cv-template/pdf-download.controller.ts @@ -1,3 +1,10 @@ +import { JwtAuthGuard, VerifiedScopeGuard } from "@cv/auth"; +import { + AuthorizationService, + CV as CVEntity, + CVService, + User as DomainUser, +} from "@cv/core"; import { FILE_STORAGE, type FileStorage } from "@cv/file-storage"; import { Controller, @@ -7,13 +14,12 @@ import { Param, Req, Res, + UseGuards, } from "@nestjs/common"; import type { Response } from "express"; -import { AuthorizationService, User as DomainUser } from "../auth"; -import { CV } from "./cv.entity"; -import { CVService } from "./cv.service"; @Controller("api/cv") +@UseGuards(JwtAuthGuard, VerifiedScopeGuard) export class PdfDownloadController { constructor( private readonly cvService: CVService, @@ -28,10 +34,9 @@ export class PdfDownloadController { @Res() res: Response, ): Promise { const cv = await this.cvService.findByIdOrFail(id); - await this.authorizationService.canView(req.user, cv, CV); + await this.authorizationService.canView(req.user, cv, CVEntity); const key = `${id}.pdf`; - if (!(await this.storage.exists(key))) { throw new NotFoundException("PDF not yet available"); } diff --git a/apps/api/src/modules/job-experience/skill/skill.module.ts b/apps/api/src/modules/job-experience/skill/skill.module.ts index 92d1127..d599f1c 100644 --- a/apps/api/src/modules/job-experience/skill/skill.module.ts +++ b/apps/api/src/modules/job-experience/skill/skill.module.ts @@ -10,7 +10,7 @@ import { import { Module } from "@nestjs/common"; import { AuthenticationModule } from "@/modules/authentication/authentication.module"; import { JobExperienceSeedService } from "@/seed/seeders/job-experience.seed"; -import { ReferenceDataSeedService } from "@/seed/seeders/reference-data.seed"; +import { ReferenceDataSeedService } from "@cv/core"; import { SkillResolver } from "./graphql/skill.resolver"; @Module({ diff --git a/apps/api/src/scripts/seed-test.ts b/apps/api/src/scripts/seed-test.ts index d447d42..2239eb9 100644 --- a/apps/api/src/scripts/seed-test.ts +++ b/apps/api/src/scripts/seed-test.ts @@ -1,6 +1,6 @@ import { NestFactory } from "@nestjs/core"; import { SeedModule } from "@/seed/seed.module"; -import { SeedService } from "@/seed/seed.service"; +import { SeedService } from "@cv/core"; async function main(): Promise { const app = await NestFactory.createApplicationContext(SeedModule); diff --git a/apps/api/src/scripts/seed.ts b/apps/api/src/scripts/seed.ts index 940a60e..2e5905d 100644 --- a/apps/api/src/scripts/seed.ts +++ b/apps/api/src/scripts/seed.ts @@ -1,6 +1,6 @@ import { NestFactory } from "@nestjs/core"; import { AppModule } from "../modules/app.module"; -import { SeedService } from "@/seed/seed.service"; +import { SeedService } from "@cv/core"; async function bootstrap() { const app = await NestFactory.createApplicationContext(AppModule); diff --git a/apps/api/src/seed/seed.module.ts b/apps/api/src/seed/seed.module.ts index 2a735f5..ea96538 100644 --- a/apps/api/src/seed/seed.module.ts +++ b/apps/api/src/seed/seed.module.ts @@ -1,12 +1,15 @@ import { AuthModule } from "@cv/auth"; -import { DatabaseModule } from "@cv/core"; +import { DatabaseModule, SeedService } from "@cv/core"; import { Module } from "@nestjs/common"; import { ConfigModule } from "@nestjs/config"; import { DiscoveryModule } from "@nestjs/core"; -import { CVTemplateSeedService } from "@/seed/seeders/cv-template.seed"; import { UserSeedService } from "@/seed/seeders/user.seed"; -import { SeedService } from "./seed.service"; +/** + * Seed orchestrator. Production seeders are registered in their owning + * core modules (CVTemplateModule, DatabaseModule); this module only + * contributes apps/api dev-fixture seeders. + */ @Module({ imports: [ ConfigModule.forRoot(), @@ -14,7 +17,7 @@ import { SeedService } from "./seed.service"; DiscoveryModule, AuthModule, ], - providers: [SeedService, UserSeedService, CVTemplateSeedService], + providers: [SeedService, UserSeedService], exports: [SeedService], }) export class SeedModule {} diff --git a/apps/api/src/seed/seeders/job-experience.seed.ts b/apps/api/src/seed/seeders/job-experience.seed.ts index 367bb7c..b485850 100644 --- a/apps/api/src/seed/seeders/job-experience.seed.ts +++ b/apps/api/src/seed/seeders/job-experience.seed.ts @@ -1,9 +1,11 @@ -import { PrismaService } from "@cv/core"; +import { + PrismaService, + ReferenceDataSeedService, + type Seeder, + SeederDecorator, +} from "@cv/core"; import { faker } from "@faker-js/faker"; import { Injectable, Logger } from "@nestjs/common"; -import { Seeder } from "@/seed/seed.service"; -import { Seeder as SeederDecorator } from "@/seed/seeder.decorator"; -import { ReferenceDataSeedService } from "./reference-data.seed"; @Injectable() @SeederDecorator({ diff --git a/apps/api/src/seed/seeders/membership.seed.ts b/apps/api/src/seed/seeders/membership.seed.ts index 1843e5c..a771097 100644 --- a/apps/api/src/seed/seeders/membership.seed.ts +++ b/apps/api/src/seed/seeders/membership.seed.ts @@ -1,8 +1,6 @@ -import { PrismaService } from "@cv/core"; +import { type Seeder, SeederDecorator, PrismaService } from "@cv/core"; import { faker } from "@faker-js/faker"; import { Injectable, Logger } from "@nestjs/common"; -import { Seeder } from "@/seed/seed.service"; -import { Seeder as SeederDecorator } from "@/seed/seeder.decorator"; @Injectable() @SeederDecorator({ name: "Memberships", dependsOn: ["Users", "Organizations"] }) diff --git a/apps/api/src/seed/seeders/organization.seed.ts b/apps/api/src/seed/seeders/organization.seed.ts index 8c30fab..fe56893 100644 --- a/apps/api/src/seed/seeders/organization.seed.ts +++ b/apps/api/src/seed/seeders/organization.seed.ts @@ -1,8 +1,6 @@ -import { PrismaService } from "@cv/core"; +import { type Seeder, SeederDecorator, PrismaService } from "@cv/core"; import { faker } from "@faker-js/faker"; import { Injectable, Logger } from "@nestjs/common"; -import { Seeder } from "@/seed/seed.service"; -import { Seeder as SeederDecorator } from "@/seed/seeder.decorator"; @Injectable() @SeederDecorator("Organizations") diff --git a/apps/api/src/seed/seeders/user.seed.ts b/apps/api/src/seed/seeders/user.seed.ts index f717401..1134b8e 100644 --- a/apps/api/src/seed/seeders/user.seed.ts +++ b/apps/api/src/seed/seeders/user.seed.ts @@ -1,7 +1,5 @@ -import { CredentialsService, PrismaService, UserService } from "@cv/core"; +import { type Seeder, SeederDecorator, CredentialsService, PrismaService, UserService } from "@cv/core"; import { Injectable, Logger } from "@nestjs/common"; -import { Seeder } from "@/seed/seed.service"; -import { Seeder as SeederDecorator } from "@/seed/seeder.decorator"; @Injectable() @SeederDecorator("Users") diff --git a/apps/api/src/seed/seeders/vacancy.seed.ts b/apps/api/src/seed/seeders/vacancy.seed.ts index e5298eb..94e19c7 100644 --- a/apps/api/src/seed/seeders/vacancy.seed.ts +++ b/apps/api/src/seed/seeders/vacancy.seed.ts @@ -1,8 +1,6 @@ -import { PrismaService } from "@cv/core"; +import { type Seeder, SeederDecorator, PrismaService } from "@cv/core"; import { faker } from "@faker-js/faker"; import { Injectable, Logger } from "@nestjs/common"; -import { Seeder } from "@/seed/seed.service"; -import { Seeder as SeederDecorator } from "@/seed/seeder.decorator"; @Injectable() @SeederDecorator({ diff --git a/packages/core/src/modules/cv-template/cv-template.module.ts b/packages/core/src/modules/cv-template/cv-template.module.ts index 4321c7b..97cba79 100644 --- a/packages/core/src/modules/cv-template/cv-template.module.ts +++ b/packages/core/src/modules/cv-template/cv-template.module.ts @@ -10,7 +10,6 @@ import { CVDataAssemblerService } from "./cv-data-assembler.service"; import { CVRendererService } from "./cv-renderer.service"; import { CVTemplatePolicy } from "./cv-template.policy"; import { CVTemplateService } from "./cv-template.service"; -import { PdfDownloadController } from "./pdf-download.controller"; @Module({ imports: [ @@ -20,7 +19,6 @@ import { PdfDownloadController } from "./pdf-download.controller"; AuthorizationModule, ProfileModule, ], - controllers: [PdfDownloadController], providers: [ CVTemplateService, CVService, diff --git a/apps/api/src/seed/seeders/cv-template.seed.ts b/packages/core/src/modules/cv-template/cv-template.seed.ts similarity index 88% rename from apps/api/src/seed/seeders/cv-template.seed.ts rename to packages/core/src/modules/cv-template/cv-template.seed.ts index 587137a..4eb3562 100644 --- a/apps/api/src/seed/seeders/cv-template.seed.ts +++ b/packages/core/src/modules/cv-template/cv-template.seed.ts @@ -1,11 +1,11 @@ import { readFileSync } from "node:fs"; import { join } from "node:path"; -import { PrismaService } from "@cv/core"; import { Injectable, Logger } from "@nestjs/common"; -import { Seeder } from "@/seed/seed.service"; -import { Seeder as SeederDecorator } from "@/seed/seeder.decorator"; +import { PrismaService } from "../database/prisma.service"; +import { Seeder } from "../database/seed/seed.service"; +import { Seeder as SeederDecorator } from "../database/seed/seeder.decorator"; -const TEMPLATES_DIR = join(__dirname, "cv-templates"); +const TEMPLATES_DIR = join(__dirname, "templates"); const readTemplate = (name: string) => ({ body: readFileSync(join(TEMPLATES_DIR, `${name}.hbs`), "utf-8"), diff --git a/packages/core/src/modules/cv-template/index.ts b/packages/core/src/modules/cv-template/index.ts index fcf1907..bae74b2 100644 --- a/packages/core/src/modules/cv-template/index.ts +++ b/packages/core/src/modules/cv-template/index.ts @@ -10,5 +10,5 @@ export { CVTemplate, RenderedCV } from "./cv-template.entity"; export { cvTemplateMapper } from "./cv-template.mapper"; export { CVTemplateModule } from "./cv-template.module"; export { CVTemplatePolicy } from "./cv-template.policy"; +export { CVTemplateSeedService } from "./cv-template.seed"; export { CVTemplateService } from "./cv-template.service"; -export { PdfDownloadController } from "./pdf-download.controller"; diff --git a/apps/api/src/seed/seeders/cv-templates/classic-executive.css b/packages/core/src/modules/cv-template/templates/classic-executive.css similarity index 100% rename from apps/api/src/seed/seeders/cv-templates/classic-executive.css rename to packages/core/src/modules/cv-template/templates/classic-executive.css diff --git a/apps/api/src/seed/seeders/cv-templates/classic-executive.hbs b/packages/core/src/modules/cv-template/templates/classic-executive.hbs similarity index 100% rename from apps/api/src/seed/seeders/cv-templates/classic-executive.hbs rename to packages/core/src/modules/cv-template/templates/classic-executive.hbs diff --git a/apps/api/src/seed/seeders/cv-templates/creative-portfolio.css b/packages/core/src/modules/cv-template/templates/creative-portfolio.css similarity index 100% rename from apps/api/src/seed/seeders/cv-templates/creative-portfolio.css rename to packages/core/src/modules/cv-template/templates/creative-portfolio.css diff --git a/apps/api/src/seed/seeders/cv-templates/creative-portfolio.hbs b/packages/core/src/modules/cv-template/templates/creative-portfolio.hbs similarity index 100% rename from apps/api/src/seed/seeders/cv-templates/creative-portfolio.hbs rename to packages/core/src/modules/cv-template/templates/creative-portfolio.hbs diff --git a/apps/api/src/seed/seeders/cv-templates/modern-professional.css b/packages/core/src/modules/cv-template/templates/modern-professional.css similarity index 100% rename from apps/api/src/seed/seeders/cv-templates/modern-professional.css rename to packages/core/src/modules/cv-template/templates/modern-professional.css diff --git a/apps/api/src/seed/seeders/cv-templates/modern-professional.hbs b/packages/core/src/modules/cv-template/templates/modern-professional.hbs similarity index 100% rename from apps/api/src/seed/seeders/cv-templates/modern-professional.hbs rename to packages/core/src/modules/cv-template/templates/modern-professional.hbs diff --git a/packages/core/src/modules/database/index.ts b/packages/core/src/modules/database/index.ts index 570a387..2916a77 100644 --- a/packages/core/src/modules/database/index.ts +++ b/packages/core/src/modules/database/index.ts @@ -1,3 +1,11 @@ export * from "./database.module"; export type { TypedPrismaService } from "./prisma.service"; export * from "./prisma.service"; +export { type Seeder, SeedService } from "./seed/seed.service"; +export { + type SeederConfig, + SEEDER_METADATA_KEY, + Seeder as SeederDecorator, +} from "./seed/seeder.decorator"; +export { topologicalSort } from "./seed/topological-sort"; +export { ReferenceDataSeedService } from "./seed/seeders/reference-data.seed"; diff --git a/apps/api/src/seed/seed.service.ts b/packages/core/src/modules/database/seed/seed.service.ts similarity index 98% rename from apps/api/src/seed/seed.service.ts rename to packages/core/src/modules/database/seed/seed.service.ts index 33cc8da..e037523 100644 --- a/apps/api/src/seed/seed.service.ts +++ b/packages/core/src/modules/database/seed/seed.service.ts @@ -1,6 +1,6 @@ -import { PrismaService } from "@cv/core"; import { Injectable, Logger, type OnModuleInit } from "@nestjs/common"; import { DiscoveryService } from "@nestjs/core"; +import { PrismaService } from "../prisma.service"; import { SeederConfig } from "./seeder.decorator"; import { SEEDER_METADATA_KEY } from "./seeder.decorator"; import { topologicalSort } from "./topological-sort"; diff --git a/apps/api/src/seed/seeder.decorator.ts b/packages/core/src/modules/database/seed/seeder.decorator.ts similarity index 100% rename from apps/api/src/seed/seeder.decorator.ts rename to packages/core/src/modules/database/seed/seeder.decorator.ts diff --git a/apps/api/src/seed/seeders/reference-data.seed.ts b/packages/core/src/modules/database/seed/seeders/reference-data.seed.ts similarity index 97% rename from apps/api/src/seed/seeders/reference-data.seed.ts rename to packages/core/src/modules/database/seed/seeders/reference-data.seed.ts index 9eb3027..34e8469 100644 --- a/apps/api/src/seed/seeders/reference-data.seed.ts +++ b/packages/core/src/modules/database/seed/seeders/reference-data.seed.ts @@ -1,8 +1,8 @@ -import { PrismaService } from "@cv/core"; import { faker } from "@faker-js/faker"; import { Injectable, Logger } from "@nestjs/common"; -import { Seeder } from "@/seed/seed.service"; -import { Seeder as SeederDecorator } from "@/seed/seeder.decorator"; +import { PrismaService } from "../../prisma.service"; +import { Seeder } from "../seed.service"; +import { Seeder as SeederDecorator } from "../seeder.decorator"; @Injectable() @SeederDecorator("Reference Data") diff --git a/apps/api/src/seed/topological-sort.spec.ts b/packages/core/src/modules/database/seed/topological-sort.spec.ts similarity index 100% rename from apps/api/src/seed/topological-sort.spec.ts rename to packages/core/src/modules/database/seed/topological-sort.spec.ts diff --git a/apps/api/src/seed/topological-sort.ts b/packages/core/src/modules/database/seed/topological-sort.ts similarity index 100% rename from apps/api/src/seed/topological-sort.ts rename to packages/core/src/modules/database/seed/topological-sort.ts