Skip to content

Commit f952712

Browse files
JeromeBuclaude
andcommitted
feat(api): add override fields to softwares table
Allow manually curated values in softwares to override external source data for 6 fields: isLibreSoftware, url, codeRepositoryUrl, softwareHelp, latestVersion, and programmingLanguages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 02b1d8e commit f952712

File tree

7 files changed

+118
-25
lines changed

7 files changed

+118
-25
lines changed

api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -158,17 +158,18 @@ export const createPgSoftwareRepository = (db: Kysely<Database>): SoftwareReposi
158158
// Combine all data
159159
return softwareRows.map(software => {
160160
const extData = externalDataRecord[software.id];
161+
const resolvedLatestVersion = software.latestVersion ?? extData?.latestVersion;
161162
return {
162163
id: software.id,
163164
name: software.name,
164165
description: software.description,
165166
image: extData?.image ?? software.image ?? undefined,
166-
latestVersion: extData?.latestVersion
167+
latestVersion: resolvedLatestVersion
167168
? {
168-
version: extData.latestVersion.version ?? undefined,
169+
version: resolvedLatestVersion.version ?? undefined,
169170
releaseDate:
170-
extData.latestVersion.releaseDate ??
171-
(extData.dateCreated ? extData.dateCreated.toISOString().slice(0, 10) : undefined)
171+
resolvedLatestVersion.releaseDate ??
172+
(extData?.dateCreated ? extData.dateCreated.toISOString().slice(0, 10) : undefined)
172173
}
173174
: undefined,
174175
addedTime: software.addedTime,
@@ -181,7 +182,7 @@ export const createPgSoftwareRepository = (db: Kysely<Database>): SoftwareReposi
181182
operatingSystems: (software.operatingSystems ?? {}) as Partial<Record<Os, boolean>>,
182183
runtimePlatforms: (software.runtimePlatforms ?? []) as RuntimePlatform[],
183184
customAttributes: software.customAttributes ?? undefined,
184-
programmingLanguages: extData?.programmingLanguages ?? [],
185+
programmingLanguages: software.programmingLanguages ?? extData?.programmingLanguages ?? [],
185186
authors: extData?.authors ?? [],
186187
userAndReferentCountByOrganization: countsMap[software.id] ?? {},
187188
similarSoftwares: similarMap[software.id] ?? []
@@ -274,17 +275,18 @@ export const createPgSoftwareRepository = (db: Kysely<Database>): SoftwareReposi
274275
return softwareRows.map(softwareRow => {
275276
const extData = externalDataRecord[softwareRow.id];
276277
const deref = softwareRow.dereferencing;
278+
const resolvedLatestVersion = softwareRow.latestVersion ?? extData?.latestVersion;
277279
return {
278280
id: softwareRow.id,
279281
name: softwareRow.name,
280282
description: softwareRow.description,
281283
image: extData?.image ?? softwareRow.image ?? undefined,
282-
latestVersion: extData?.latestVersion
284+
latestVersion: resolvedLatestVersion
283285
? {
284-
version: extData.latestVersion.version ?? undefined,
286+
version: resolvedLatestVersion.version ?? undefined,
285287
releaseDate:
286-
extData.latestVersion.releaseDate ??
287-
(extData.dateCreated ? extData.dateCreated.toISOString().slice(0, 10) : undefined)
288+
resolvedLatestVersion.releaseDate ??
289+
(extData?.dateCreated ? extData.dateCreated.toISOString().slice(0, 10) : undefined)
288290
}
289291
: undefined,
290292
addedTime: softwareRow.addedTime,
@@ -303,17 +305,17 @@ export const createPgSoftwareRepository = (db: Kysely<Database>): SoftwareReposi
303305
customAttributes: softwareRow.customAttributes ?? undefined,
304306
userAndReferentCountByOrganization: countsMap[softwareRow.id] ?? {},
305307
authors: extData?.authors ?? [],
306-
url: extData?.url ?? undefined,
307-
codeRepositoryUrl: extData?.codeRepositoryUrl ?? undefined,
308-
softwareHelp: extData?.softwareHelp ?? undefined,
308+
url: softwareRow.url ?? extData?.url ?? undefined,
309+
codeRepositoryUrl: softwareRow.codeRepositoryUrl ?? extData?.codeRepositoryUrl ?? undefined,
310+
softwareHelp: softwareRow.softwareHelp ?? extData?.softwareHelp ?? undefined,
309311
license: extData?.license ?? softwareRow.license,
310312
externalId: extData?.externalId,
311313
sourceSlug: extData?.sourceSlug,
312314
operatingSystems: (softwareRow.operatingSystems ?? {}) as Partial<Record<Os, boolean>>,
313315
runtimePlatforms: (softwareRow.runtimePlatforms ?? []) as RuntimePlatform[],
314316
similarSoftwares: similarMap[softwareRow.id] ?? [],
315317
keywords: softwareRow.keywords ?? [],
316-
programmingLanguages: extData?.programmingLanguages ?? [],
318+
programmingLanguages: softwareRow.programmingLanguages ?? extData?.programmingLanguages ?? [],
317319
providers: extData?.providers ?? [],
318320
referencePublications: extData?.referencePublications,
319321
identifiers: extData?.identifiers,
@@ -403,17 +405,19 @@ export const createPgSoftwareRepository = (db: Kysely<Database>): SoftwareReposi
403405

404406
const deref = softwareRow.dereferencing;
405407

408+
const resolvedLatestVersion = softwareRow.latestVersion ?? extData?.latestVersion;
409+
406410
return {
407411
id: softwareRow.id,
408412
name: softwareRow.name,
409413
description: softwareRow.description,
410414
image: extData?.image ?? softwareRow.image ?? undefined,
411-
latestVersion: extData?.latestVersion
415+
latestVersion: resolvedLatestVersion
412416
? {
413-
version: extData.latestVersion.version ?? undefined,
417+
version: resolvedLatestVersion.version ?? undefined,
414418
releaseDate:
415-
extData.latestVersion.releaseDate ??
416-
(extData.dateCreated ? extData.dateCreated.toISOString().slice(0, 10) : undefined)
419+
resolvedLatestVersion.releaseDate ??
420+
(extData?.dateCreated ? extData.dateCreated.toISOString().slice(0, 10) : undefined)
417421
}
418422
: undefined,
419423
addedTime: softwareRow.addedTime,
@@ -432,17 +436,17 @@ export const createPgSoftwareRepository = (db: Kysely<Database>): SoftwareReposi
432436
customAttributes: softwareRow.customAttributes ?? undefined,
433437
userAndReferentCountByOrganization,
434438
authors: extData?.authors ?? [],
435-
url: extData?.url ?? undefined,
436-
codeRepositoryUrl: extData?.codeRepositoryUrl ?? undefined,
437-
softwareHelp: extData?.softwareHelp ?? undefined,
439+
url: softwareRow.url ?? extData?.url ?? undefined,
440+
codeRepositoryUrl: softwareRow.codeRepositoryUrl ?? extData?.codeRepositoryUrl ?? undefined,
441+
softwareHelp: softwareRow.softwareHelp ?? extData?.softwareHelp ?? undefined,
438442
license: extData?.license ?? softwareRow.license,
439443
externalId: extData?.externalId,
440444
sourceSlug: extData?.sourceSlug,
441445
operatingSystems: (softwareRow.operatingSystems ?? {}) as Partial<Record<Os, boolean>>,
442446
runtimePlatforms: (softwareRow.runtimePlatforms ?? []) as RuntimePlatform[],
443447
similarSoftwares,
444448
keywords: softwareRow.keywords ?? [],
445-
programmingLanguages: extData?.programmingLanguages ?? [],
449+
programmingLanguages: softwareRow.programmingLanguages ?? extData?.programmingLanguages ?? [],
446450
providers: extData?.providers ?? [],
447451
referencePublications: extData?.referencePublications,
448452
identifiers: extData?.identifiers,
@@ -477,6 +481,12 @@ export const createPgSoftwareRepository = (db: Kysely<Database>): SoftwareReposi
477481
applicationCategories,
478482
keywords,
479483
addedByUserId,
484+
isLibreSoftware,
485+
url,
486+
codeRepositoryUrl,
487+
softwareHelp,
488+
latestVersion,
489+
programmingLanguages,
480490
...rest
481491
} = software;
482492

@@ -501,7 +511,13 @@ export const createPgSoftwareRepository = (db: Kysely<Database>): SoftwareReposi
501511
runtimePlatforms: JSON.stringify(runtimePlatforms),
502512
applicationCategories: JSON.stringify(applicationCategories),
503513
addedByUserId,
504-
keywords: JSON.stringify(keywords)
514+
keywords: JSON.stringify(keywords),
515+
isLibreSoftware: isLibreSoftware ?? null,
516+
url: url ?? null,
517+
codeRepositoryUrl: codeRepositoryUrl ?? null,
518+
softwareHelp: softwareHelp ?? null,
519+
latestVersion: latestVersion ? JSON.stringify(latestVersion) : null,
520+
programmingLanguages: programmingLanguages ? JSON.stringify(programmingLanguages) : null
505521
})
506522
.returning("id as softwareId")
507523
.executeTakeFirstOrThrow();
@@ -523,6 +539,12 @@ export const createPgSoftwareRepository = (db: Kysely<Database>): SoftwareReposi
523539
applicationCategories,
524540
keywords,
525541
addedByUserId,
542+
isLibreSoftware,
543+
url,
544+
codeRepositoryUrl,
545+
softwareHelp,
546+
latestVersion,
547+
programmingLanguages,
526548
...rest
527549
} = software;
528550

@@ -544,7 +566,13 @@ export const createPgSoftwareRepository = (db: Kysely<Database>): SoftwareReposi
544566
runtimePlatforms: JSON.stringify(runtimePlatforms),
545567
applicationCategories: JSON.stringify(applicationCategories),
546568
addedByUserId,
547-
keywords: JSON.stringify(keywords)
569+
keywords: JSON.stringify(keywords),
570+
isLibreSoftware: isLibreSoftware ?? null,
571+
url: url ?? null,
572+
codeRepositoryUrl: codeRepositoryUrl ?? null,
573+
softwareHelp: softwareHelp ?? null,
574+
latestVersion: latestVersion ? JSON.stringify(latestVersion) : null,
575+
programmingLanguages: programmingLanguages ? JSON.stringify(programmingLanguages) : null
548576
})
549577
.where("id", "=", softwareId)
550578
.execute();

api/src/core/adapters/dbApi/kysely/kysely.database.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,12 @@ type SoftwaresTable = {
212212
addedByUserId: number;
213213
image: string | null;
214214
keywords: JSONColumnType<string[]>;
215+
isLibreSoftware: boolean | null;
216+
url: string | null;
217+
codeRepositoryUrl: string | null;
218+
softwareHelp: string | null;
219+
latestVersion: JSONColumnType<{ version: string | null; releaseDate: string | null }> | null;
220+
programmingLanguages: JSONColumnType<string[]> | null;
215221
};
216222

217223
export namespace DatabaseRowOutput {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { Kysely } from "kysely";
2+
3+
export async function up(db: Kysely<any>): Promise<void> {
4+
await db.schema
5+
.alterTable("softwares")
6+
.addColumn("isLibreSoftware", "boolean")
7+
.addColumn("url", "text")
8+
.addColumn("codeRepositoryUrl", "text")
9+
.addColumn("softwareHelp", "text")
10+
.addColumn("latestVersion", "jsonb")
11+
.addColumn("programmingLanguages", "jsonb")
12+
.execute();
13+
}
14+
15+
export async function down(db: Kysely<any>): Promise<void> {
16+
await db.schema
17+
.alterTable("softwares")
18+
.dropColumn("isLibreSoftware")
19+
.dropColumn("url")
20+
.dropColumn("codeRepositoryUrl")
21+
.dropColumn("softwareHelp")
22+
.dropColumn("latestVersion")
23+
.dropColumn("programmingLanguages")
24+
.execute();
25+
}

api/src/core/ports/DbApiV2.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ export type SoftwareExtrinsicRow = Pick<
3636
| "applicationCategories"
3737
| "keywords"
3838
| "addedByUserId"
39+
| "isLibreSoftware"
40+
| "url"
41+
| "codeRepositoryUrl"
42+
| "softwareHelp"
43+
| "latestVersion"
44+
| "programmingLanguages"
3945
>;
4046

4147
export namespace DatabaseDataType {

api/src/core/usecases/createSoftware.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,18 @@ export const formDataToSoftwareRow = (softwareForm: SoftwareFormData, userId: nu
2525
applicationCategories: [],
2626
addedByUserId: userId,
2727
keywords: softwareForm.keywords,
28-
customAttributes: softwareForm.customAttributes
28+
customAttributes: softwareForm.customAttributes,
29+
isLibreSoftware: softwareForm.isLibreSoftware,
30+
url: softwareForm.url,
31+
codeRepositoryUrl: softwareForm.codeRepositoryUrl,
32+
softwareHelp: softwareForm.softwareHelp,
33+
latestVersion: softwareForm.latestVersion
34+
? {
35+
version: softwareForm.latestVersion.version ?? null,
36+
releaseDate: softwareForm.latestVersion.releaseDate ?? null
37+
}
38+
: undefined,
39+
programmingLanguages: softwareForm.programmingLanguages
2940
};
3041
};
3142

api/src/core/usecases/readWriteSillData/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ export type SoftwareFormData = {
111111
image: string | undefined;
112112
keywords: string[];
113113
customAttributes: CustomAttributes | undefined;
114+
isLibreSoftware?: boolean | undefined;
115+
url?: string | undefined;
116+
codeRepositoryUrl?: string | undefined;
117+
softwareHelp?: string | undefined;
118+
latestVersion?: { version: string | undefined; releaseDate: string | undefined } | undefined;
119+
programmingLanguages?: string[] | undefined;
114120
};
115121

116122
export type DeclarationFormData = DeclarationFormData.User | DeclarationFormData.Referent;

api/src/core/usecases/updateSoftware.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,18 @@ export const makeUpdateSoftware: (dbApi: DbApiV2) => UpdateSoftware =
3030
runtimePlatforms: formFields.runtimePlatforms,
3131
applicationCategories: [],
3232
addedByUserId: userId,
33-
keywords: formFields.keywords
33+
keywords: formFields.keywords,
34+
isLibreSoftware: formFields.isLibreSoftware,
35+
url: formFields.url,
36+
codeRepositoryUrl: formFields.codeRepositoryUrl,
37+
softwareHelp: formFields.softwareHelp,
38+
latestVersion: formFields.latestVersion
39+
? {
40+
version: formFields.latestVersion.version ?? null,
41+
releaseDate: formFields.latestVersion.releaseDate ?? null
42+
}
43+
: undefined,
44+
programmingLanguages: formFields.programmingLanguages
3445
},
3546
softwareId
3647
});

0 commit comments

Comments
 (0)