feat(17-02): RSS feeds get an owner — platform-wide vs personal (D-02)
- TenderRssFeedSource.userId/tenantId (nullable): null = platform-wide
(admin-managed, includes the existing service.bund.de default),
set = personal feed owned by exactly one user
- Migration replaces url @unique with @@unique([userId, url]) — two
users can now follow the same address independently; existing rows
keep an empty owner (platform-wide, unchanged behavior)
- Service: listForUser/createForUser/createPlatform replace list/create
- Controller: GET/POST /rss-feeds move from @Roles(ADMIN,SUPER_ADMIN) to
@UseModule('tender-radar'); POST with scope:'platform' still requires
ADMIN/SUPER_ADMIN, checked inline (T-17-08)
- tenders.module.ts seed switched from upsert-on-url to find-then-create
(Rule 3, pulled forward from Task 3): the new compound unique index
requires a non-null userId in Prisma's generated type, so a
platform-wide row can no longer be addressed via upsert
- Files modified: apps/api/prisma/schema.prisma, apps/api/prisma/migrations/20260812110000_tender_rss_feed_owner/migration.sql, apps/api/src/tenders/tender-rss-feed.service.ts, apps/api/src/tenders/dto/tender-rss-feed.dto.ts, apps/api/src/tenders/tenders.controller.ts, apps/api/src/tenders/tenders.module.ts, apps/api/src/tenders/tender-rss-feed.service.spec.ts, apps/api/src/tenders/tenders.controller.spec.ts
This commit is contained in:
@@ -282,20 +282,33 @@ export class TendersModule implements OnModuleInit {
|
||||
// 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 add the
|
||||
// municipality feeds relevant to them via the RSS-Feeds admin UI
|
||||
// — 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).
|
||||
await this.prisma.tenderRssFeedSource.upsert({
|
||||
//
|
||||
// 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',
|
||||
},
|
||||
update: {},
|
||||
create: {
|
||||
url: 'https://www.service.bund.de/Content/Globals/Functions/RSSFeed/RSSGenerator_Ausschreibungen.xml',
|
||||
label: 'service-bund',
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
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,
|
||||
},
|
||||
});
|
||||
}
|
||||
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