test(17-02): D-06 ownerTenantId tagging for RSS ingestion + seed idempotency
- RssAdapter.fetchTenders tags every record from a feed with a tenantId with the same D-13 ownerTenantId origin marking email-alert records carry since Phase 14; platform-wide feeds (no tenantId) stay unmarked. The pure parseFeed mapping is untouched — tagging happens in the fan-out loop that knows which row a batch came from - Extracted the service.bund.de seed out of TendersModule.onModuleInit into seedServiceBundRssFeed() (tenders.seed.ts, same pattern as the existing seedTendersModule), so the find-then-create idempotency added in Task 1 is unit-tested directly instead of only via a Nest bootstrap - New rss-feed-migration-sql.spec.ts: text-only check of the Task 1 migration file (nullable columns, dropped/created indexes, no existing-row mutation, correct ordering) - Files modified: apps/api/src/tenders/adapters/rss.adapter.ts, apps/api/src/tenders/tenders.module.ts, apps/api/src/tenders/tenders.seed.ts, apps/api/src/tenders/adapters/rss.adapter.spec.ts, apps/api/src/tenders/tenders.seed.spec.ts, apps/api/src/tenders/rss-feed-migration-sql.spec.ts
This commit is contained in:
@@ -10,7 +10,7 @@ import { EmailAlertAdapter } from './adapters/email-alert.adapter';
|
||||
import { NetServerAdapter } from './adapters/netserver.adapter';
|
||||
import { RssAdapter } from './adapters/rss.adapter';
|
||||
import { SourceRegistry } from './source-registry';
|
||||
import { seedTendersModule } from './tenders.seed';
|
||||
import { seedServiceBundRssFeed, seedTendersModule } from './tenders.seed';
|
||||
import { TenderDedupService } from './tender-dedup.service';
|
||||
import { TenderDigestScheduler } from './tender-digest.scheduler';
|
||||
import { TenderEmailConfigService } from './tender-email-config.service';
|
||||
@@ -278,37 +278,13 @@ export class TendersModule implements OnModuleInit {
|
||||
}
|
||||
|
||||
try {
|
||||
// Phase 14, Plan 02 (D-14, RESEARCH.md Open Question 3): seed a
|
||||
// single default-active service.bund.de feed row — the one genuinely
|
||||
// national/global RSS source. subreport-elvis has no single
|
||||
// canonical URL (per-municipality instances, RESEARCH.md Pitfall 2)
|
||||
// — deliberately ZERO subreport-elvis rows seeded; admins/users add
|
||||
// the municipality feeds relevant to them via the RSS-Feeds UI
|
||||
// (Plan 14-02 Task 3).
|
||||
//
|
||||
// Phase 17, Plan 02 (D-02): "upsert on url" no longer works — the
|
||||
// unique index moved to (userId, url), and Prisma's generated
|
||||
// compound-unique input type REQUIRES userId as a plain `string`
|
||||
// (not `string | null | undefined`), so a platform-wide row
|
||||
// (userId = null) can never be addressed through it. Switched to
|
||||
// "find a platform-wide row with this url first, only create if
|
||||
// none exists" — an ordinary equality condition has no such
|
||||
// requirement. Still idempotent across repeated app starts.
|
||||
const existingServiceBundFeed = await this.prisma.tenderRssFeedSource.findFirst({
|
||||
where: {
|
||||
userId: null,
|
||||
url: 'https://www.service.bund.de/Content/Globals/Functions/RSSFeed/RSSGenerator_Ausschreibungen.xml',
|
||||
},
|
||||
});
|
||||
if (!existingServiceBundFeed) {
|
||||
await this.prisma.tenderRssFeedSource.create({
|
||||
data: {
|
||||
url: 'https://www.service.bund.de/Content/Globals/Functions/RSSFeed/RSSGenerator_Ausschreibungen.xml',
|
||||
label: 'service-bund',
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
// Phase 17, Plan 02 (Task 3): the actual find-then-create logic (and
|
||||
// why "upsert on url" stopped working, D-02) lives in
|
||||
// seedServiceBundRssFeed (tenders.seed.ts) now — extracted the same
|
||||
// way seedTendersModule already is, so it is a plain testable
|
||||
// function and not only reachable via a full Nest bootstrap
|
||||
// (idempotency proven in tenders.seed.spec.ts).
|
||||
await seedServiceBundRssFeed(this.prisma);
|
||||
this.logger.log('service.bund.de default RSS feed seeded (active)');
|
||||
} catch (error) {
|
||||
this.logger.error('Failed to seed service.bund.de RSS feed', error);
|
||||
|
||||
Reference in New Issue
Block a user