Skip to content

feat: add DAL (CM-951)#3836

Open
ulemons wants to merge 1 commit intofeat/add-project-discovery-workerfrom
feat/add-dal-automatic-project-discovery
Open

feat: add DAL (CM-951)#3836
ulemons wants to merge 1 commit intofeat/add-project-discovery-workerfrom
feat/add-dal-automatic-project-discovery

Conversation

@ulemons
Copy link
Contributor

@ulemons ulemons commented Feb 10, 2026

Note

Medium Risk
Adds new SQL DAL surfaces for reading/writing projectCatalog and evaluatedProjects, including bulk insert/upsert and status transitions; risk is mainly around correctness of new queries and JSON/typing conversions against the existing schema.

Overview
Adds new DAL modules for projectCatalog and evaluatedProjects, exposing typed CRUD/query functions (single lookups, listing with pagination, counts, and deletes) and wiring them into the library exports.

Includes bulk insert/upsert helpers (via jsonb_to_recordset) and specialized update helpers such as markEvaluatedProjectAsEvaluated, markEvaluatedProjectAsOnboarded, and a join query to fetch pending evaluated projects with catalog metadata.

Written by Cursor Bugbot for commit 82f29d9. This will update automatically on new commits. Configure here.

@ulemons ulemons self-assigned this Feb 10, 2026
@ulemons ulemons added the POC label Feb 11, 2026
@ulemons ulemons changed the title feat: add DAL feat: add DAL (CM-951) Feb 11, 2026
@ulemons ulemons force-pushed the feat/add-project-discovery-worker branch 2 times, most recently from b03cb7a to 425e4cb Compare March 24, 2026 10:23
@ulemons ulemons force-pushed the feat/add-dal-automatic-project-discovery branch from bb118d5 to f4cc9b8 Compare March 24, 2026 10:30
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@ulemons ulemons force-pushed the feat/add-dal-automatic-project-discovery branch 2 times, most recently from 3cbe8ec to 0af35ee Compare March 24, 2026 11:56
@ulemons ulemons marked this pull request as ready for review March 24, 2026 14:01
Copilot AI review requested due to automatic review settings March 24, 2026 14:01
@ulemons ulemons force-pushed the feat/add-project-discovery-worker branch from b5c3b03 to 7e6dc18 Compare March 24, 2026 14:01
Signed-off-by: Umberto Sgueglia <usgueglia@contractor.linuxfoundation.org>
@ulemons ulemons force-pushed the feat/add-dal-automatic-project-discovery branch from 0af35ee to 82f29d9 Compare March 24, 2026 14:02
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds new Data Access Layer (DAL) modules for the project catalog and evaluated projects domain, and re-exports them from the DAL package entrypoint.

Changes:

  • Introduces project-catalog DAL: types plus CRUD-ish query helpers (find/insert/bulk insert/upsert/update/delete).
  • Introduces evaluated-projects DAL: types plus query helpers for evaluation lifecycle and bulk insert.
  • Exports both modules via services/libs/data-access-layer/src/index.ts.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
services/libs/data-access-layer/src/project-catalog/types.ts Defines DB-facing types for project catalog records and create/update payloads.
services/libs/data-access-layer/src/project-catalog/projectCatalog.ts Adds SQL helpers for selecting/inserting/upserting/updating/deleting project catalog rows.
services/libs/data-access-layer/src/project-catalog/index.ts Barrel export for the project-catalog module.
services/libs/data-access-layer/src/evaluated-projects/types.ts Defines DB-facing types for evaluated projects and create/update payloads.
services/libs/data-access-layer/src/evaluated-projects/evaluatedProjects.ts Adds SQL helpers for evaluated project operations (find/insert/bulk insert/update/mark evaluated/onboarded/delete).
services/libs/data-access-layer/src/evaluated-projects/index.ts Barrel export for the evaluated-projects module.
services/libs/data-access-layer/src/index.ts Re-exports the newly added modules from the DAL package entrypoint.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

projectCatalogId: item.projectCatalogId,
evaluationStatus: item.evaluationStatus ?? 'pending',
evaluationScore: item.evaluationScore ?? null,
evaluation: item.evaluation ? JSON.stringify(item.evaluation) : null,
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In bulkInsertEvaluatedProjects, values pre-serializes evaluation with JSON.stringify(...), but the SQL recordset defines evaluation jsonb. This will cause the inserted JSONB to become a JSON string (or fail coercion), rather than storing the object. Pass the evaluation object directly in values (let JSON.stringify only happen once for the whole values payload) and keep the SQL cast to jsonb.

Suggested change
evaluation: item.evaluation ? JSON.stringify(item.evaluation) : null,
evaluation: item.evaluation ?? null,

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +9
export interface IDbProjectCatalog {
id: string
projectSlug: string
repoName: string
repoUrl: string
criticalityScore: number | null
syncedAt: string | null
createdAt: string | null
updatedAt: string | null
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DB migration for "projectCatalog" defines "ossfCriticalityScore" and "lfCriticalityScore" columns (backend/src/database/migrations/V1770653666__add-automatic_projects_discovery-tables.sql), but this DAL type uses a single criticalityScore field. As written, the queries in this module will select/insert/update a column that doesn't exist. Align the DAL types with the actual schema (e.g., expose both score columns, or rename to match whichever column you intend to persist).

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +15
const PROJECT_CATALOG_COLUMNS = [
'id',
'projectSlug',
'repoName',
'repoUrl',
'criticalityScore',
'syncedAt',
'createdAt',
'updatedAt',
]
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PROJECT_CATALOG_COLUMNS includes criticalityScore, but the "projectCatalog" table (per backend/src/database/migrations/V1770653666__add-automatic_projects_discovery-tables.sql) does not have a "criticalityScore" column (it has "ossfCriticalityScore" and "lfCriticalityScore"). This will cause runtime SQL errors on SELECT/RETURNING. Update the selected column list to match the real table columns.

Suggested change
const PROJECT_CATALOG_COLUMNS = [
'id',
'projectSlug',
'repoName',
'repoUrl',
'criticalityScore',
'syncedAt',
'createdAt',
'updatedAt',
]
const PROJECT_CATALOG_COLUMNS = [
'id',
'projectSlug',
'repoName',
'repoUrl',
'ossfCriticalityScore',
'lfCriticalityScore',
'syncedAt',
'createdAt',
'updatedAt',
]

Copilot uses AI. Check for mistakes.
Comment on lines +94 to +101
INSERT INTO "projectCatalog" (
"projectSlug",
"repoName",
"repoUrl",
"criticalityScore",
"createdAt",
"updatedAt"
)
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

insertProjectCatalog is inserting into a "criticalityScore" column, which does not exist in the current "projectCatalog" schema (see backend/src/database/migrations/V1770653666__add-automatic_projects_discovery-tables.sql). This INSERT will fail at runtime. Change the INSERT/params to use the actual score column(s) defined by the table.

Copilot uses AI. Check for mistakes.
Comment on lines +170 to +190
INSERT INTO "projectCatalog" (
"projectSlug",
"repoName",
"repoUrl",
"criticalityScore",
"createdAt",
"updatedAt"
)
VALUES (
$(projectSlug),
$(repoName),
$(repoUrl),
$(criticalityScore),
NOW(),
NOW()
)
ON CONFLICT ("repoUrl") DO UPDATE SET
"projectSlug" = EXCLUDED."projectSlug",
"repoName" = EXCLUDED."repoName",
"criticalityScore" = EXCLUDED."criticalityScore",
"updatedAt" = NOW()
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

upsertProjectCatalog uses "criticalityScore" in both the INSERT column list and the ON CONFLICT update, but the table schema defines "ossfCriticalityScore" / "lfCriticalityScore" instead. This will error at runtime and also means conflicts won't update the intended score fields. Update the statement to target the actual column name(s).

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +54
export type IDbEvaluatedProjectCreate = Omit<EvaluatedProjectWritable, 'projectCatalogId'> & {
projectCatalogId: string
} & {
evaluationStatus?: EvaluationStatus
evaluationScore?: number
evaluation?: Record<string, unknown>
evaluationReason?: string
evaluatedAt?: string
starsCount?: number
forksCount?: number
commitsCount?: number
pullRequestsCount?: number
issuesCount?: number
onboarded?: boolean
onboardedAt?: string
}
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDbEvaluatedProjectCreate allows onboarded/onboardedAt/evaluatedAt, but the insert/bulk-insert queries in evaluatedProjects.ts never write those columns (only defaults apply). This makes the API misleading and can silently ignore caller intent. Either remove these fields from the create type or include them in the INSERT statements (with appropriate default/null handling).

Copilot uses AI. Check for mistakes.
Comment on lines +43 to +68
evaluationScore?: number
evaluation?: Record<string, unknown>
evaluationReason?: string
evaluatedAt?: string
starsCount?: number
forksCount?: number
commitsCount?: number
pullRequestsCount?: number
issuesCount?: number
onboarded?: boolean
onboardedAt?: string
}

export type IDbEvaluatedProjectUpdate = Partial<{
evaluationStatus: EvaluationStatus
evaluationScore: number
evaluation: Record<string, unknown>
evaluationReason: string
evaluatedAt: string
starsCount: number
forksCount: number
commitsCount: number
pullRequestsCount: number
issuesCount: number
onboarded: boolean
onboardedAt: string
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDbEvaluatedProjectUpdate types nullable DB columns (e.g. evaluationScore, evaluationReason, evaluatedAt, counts) as non-nullable (number/string). That prevents clearing fields (setting to NULL) even though the table schema allows it. Consider typing these as number | null / string | null etc. so updates can intentionally null out values when needed.

Suggested change
evaluationScore?: number
evaluation?: Record<string, unknown>
evaluationReason?: string
evaluatedAt?: string
starsCount?: number
forksCount?: number
commitsCount?: number
pullRequestsCount?: number
issuesCount?: number
onboarded?: boolean
onboardedAt?: string
}
export type IDbEvaluatedProjectUpdate = Partial<{
evaluationStatus: EvaluationStatus
evaluationScore: number
evaluation: Record<string, unknown>
evaluationReason: string
evaluatedAt: string
starsCount: number
forksCount: number
commitsCount: number
pullRequestsCount: number
issuesCount: number
onboarded: boolean
onboardedAt: string
evaluationScore?: number | null
evaluation?: Record<string, unknown> | null
evaluationReason?: string | null
evaluatedAt?: string | null
starsCount?: number | null
forksCount?: number | null
commitsCount?: number | null
pullRequestsCount?: number | null
issuesCount?: number | null
onboarded?: boolean
onboardedAt?: string | null
}
export type IDbEvaluatedProjectUpdate = Partial<{
evaluationStatus: EvaluationStatus
evaluationScore: number | null
evaluation: Record<string, unknown> | null
evaluationReason: string | null
evaluatedAt: string | null
starsCount: number | null
forksCount: number | null
commitsCount: number | null
pullRequestsCount: number | null
issuesCount: number | null
onboarded: boolean
onboardedAt: string | null

Copilot uses AI. Check for mistakes.
Comment on lines +119 to +132
INSERT INTO "evaluatedProjects" (
"projectCatalogId",
"evaluationStatus",
"evaluationScore",
evaluation,
"evaluationReason",
"starsCount",
"forksCount",
"commitsCount",
"pullRequestsCount",
"issuesCount",
"createdAt",
"updatedAt"
)
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

insertEvaluatedProject ignores onboarded, onboardedAt, and evaluatedAt even though they are part of the writable model/type. This can lead to unexpected behavior if callers pass these fields (they'll be silently dropped). Include these columns in the INSERT (or remove them from the create type if they should only be set via dedicated update helpers).

Copilot uses AI. Check for mistakes.
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

@themarolt
Copy link
Contributor

@ulemons please check cursor bugbot comments - I think some are pretty valid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants